mirror of
https://github.com/kubernetes-sigs/kind.git
synced 2025-12-01 07:26:05 +07:00
@@ -26,6 +26,7 @@ import (
|
||||
type flags struct {
|
||||
Source string
|
||||
Image string
|
||||
Tag string
|
||||
}
|
||||
|
||||
// NewCommand returns a new cobra.Command for building the base image
|
||||
@@ -41,14 +42,24 @@ func NewCommand() *cobra.Command {
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&flags.Source, "source", "", "path to the base image sources")
|
||||
cmd.Flags().StringVar(&flags.Image, "image", "kind-base", "name of the resulting image to be built")
|
||||
cmd.Flags().StringVar(
|
||||
&flags.Image, "image",
|
||||
base.DefaultImageName,
|
||||
"name of the resulting image to be built",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&flags.Tag, "tag",
|
||||
base.DefaultImageTag,
|
||||
"tag of the resulting image to be built",
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func run(flags *flags, cmd *cobra.Command, args []string) {
|
||||
// TODO(bentheelder): make this more configurable
|
||||
ctx := base.NewBuildContext(
|
||||
base.WithImageTag(flags.Image),
|
||||
base.WithImageName(flags.Image),
|
||||
base.WithImageTag(flags.Tag),
|
||||
base.WithSourceDir(flags.Source),
|
||||
)
|
||||
err := ctx.Build()
|
||||
|
||||
@@ -27,7 +27,9 @@ type flags struct {
|
||||
Source string
|
||||
BuildType string
|
||||
ImageName string
|
||||
ImageTag string
|
||||
BaseImageName string
|
||||
BaseImageTag string
|
||||
}
|
||||
|
||||
// NewCommand returns a new cobra.Command for building the node image
|
||||
@@ -42,9 +44,30 @@ func NewCommand() *cobra.Command {
|
||||
run(flags, cmd, args)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&flags.BuildType, "type", "docker", "build type, one of [bazel, docker, apt]")
|
||||
cmd.Flags().StringVar(&flags.ImageName, "image", "kind-node", "name of the resulting image to be built")
|
||||
cmd.Flags().StringVar(&flags.BaseImageName, "base-image", "kind-base", "name of the base image to use for the build")
|
||||
cmd.Flags().StringVar(
|
||||
&flags.BuildType, "type",
|
||||
"docker", "build type, one of [bazel, docker, apt]",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&flags.ImageName, "image",
|
||||
node.DefaultImageName,
|
||||
"name of the resulting image to be built",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&flags.ImageTag, "tag",
|
||||
node.DefaultImageTag,
|
||||
"tag of the resulting image to be built",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&flags.BaseImageName, "base-image",
|
||||
node.DefaultBaseImageName,
|
||||
"name of the base image to use for the build",
|
||||
)
|
||||
cmd.Flags().StringVar(
|
||||
&flags.BaseImageTag, "base-tag",
|
||||
node.DefaultBaseImageTag,
|
||||
"tag of the base image to use for the build",
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -52,8 +75,10 @@ func run(flags *flags, cmd *cobra.Command, args []string) {
|
||||
// TODO(bentheelder): make this more configurable
|
||||
ctx, err := node.NewBuildContext(
|
||||
node.WithMode(flags.BuildType),
|
||||
node.WithImageTag(flags.ImageName),
|
||||
node.WithBaseImage(flags.BaseImageName),
|
||||
node.WithImageName(flags.ImageName),
|
||||
node.WithImageTag(flags.ImageTag),
|
||||
node.WithBaseImageName(flags.BaseImageName),
|
||||
node.WithBaseImageTag(flags.BaseImageTag),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating build context: %v", err)
|
||||
|
||||
@@ -44,9 +44,9 @@ func NewCommand() *cobra.Command {
|
||||
run(flags, cmd, args)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&flags.Name, "name", "1", "the cluster name")
|
||||
cmd.Flags().StringVar(&flags.Config, "config", "", "path to create config file")
|
||||
cmd.Flags().StringVar(&flags.ImageName, "image", "", "name of the image to use for booting the cluster. If this is non-empty, it will override the value specified in the --config file.")
|
||||
cmd.Flags().StringVar(&flags.Name, "name", "1", "the cluster context name")
|
||||
cmd.Flags().StringVar(&flags.Config, "config", "", "path to a kind config file")
|
||||
cmd.Flags().StringVar(&flags.ImageName, "image", "", "node docker image to use for booting the cluster")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
46
hack/build/push-base.sh
Executable file
46
hack/build/push-base.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# cd to the repo root
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
# place to stick temp binaries
|
||||
BINDIR="${REPO_ROOT}/_output/bin"
|
||||
|
||||
# install kind from the repo into $BINDIR
|
||||
get_kind() {
|
||||
# build kind from the repo and use that ...
|
||||
GOBIN="${BINDIR}" go install .
|
||||
echo "${BINDIR}/kind"
|
||||
}
|
||||
|
||||
# select kind binary to use
|
||||
KIND="${KIND:-$(get_kind)}"
|
||||
|
||||
# generate tag
|
||||
DATE="$(date +v%Y%m%d)"
|
||||
TAG="${DATE}-$(git describe --tags --always --dirty)"
|
||||
|
||||
# build
|
||||
(set -x; "${KIND}" build base --tag="${TAG}")
|
||||
|
||||
# push
|
||||
docker push kindest/base:"${TAG}"
|
||||
|
||||
53
hack/build/push-node.sh
Executable file
53
hack/build/push-node.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# cd to the repo root
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
# place to stick temp binaries
|
||||
BINDIR="${REPO_ROOT}/_output/bin"
|
||||
|
||||
# install kind from the repo into $BINDIR
|
||||
get_kind() {
|
||||
# build kind from the repo and use that ...
|
||||
GOBIN="${BINDIR}" go install .
|
||||
echo "${BINDIR}/kind"
|
||||
}
|
||||
|
||||
# select kind binary to use
|
||||
KIND="${KIND:-$(get_kind)}"
|
||||
|
||||
# generate tag
|
||||
DATE="$(date +v%Y%m%d)"
|
||||
TAG="${DATE}-$(git describe --tags --always --dirty)"
|
||||
|
||||
# build
|
||||
set -x
|
||||
"${KIND}" build node --tag="${TAG}" --base-tag="${TAG}"
|
||||
|
||||
# re-tag with kubernetes version
|
||||
IMG="kindest/node:${TAG}"
|
||||
KUBE_VERSION="$(docker run --rm --entrypoint=cat "${IMG}" /kind/version)"
|
||||
docker tag "${IMG}" "kindest/node:${KUBE_VERSION}"
|
||||
|
||||
# push
|
||||
docker push kindest/node:"${KUBE_VERSION}"
|
||||
|
||||
|
||||
@@ -24,20 +24,28 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"sigs.k8s.io/kind/pkg/build/base/sources"
|
||||
"sigs.k8s.io/kind/pkg/docker"
|
||||
"sigs.k8s.io/kind/pkg/exec"
|
||||
"sigs.k8s.io/kind/pkg/fs"
|
||||
)
|
||||
|
||||
// DefaultImageName is the default name of the built base image
|
||||
const DefaultImageName = "kind-base"
|
||||
const DefaultImageName = "kindest/base"
|
||||
|
||||
// DefaultImageTag is the default tag of the built base image
|
||||
const DefaultImageTag = "latest"
|
||||
|
||||
// BuildContext is used to build the kind node base image, and contains
|
||||
// build configuration
|
||||
type BuildContext struct {
|
||||
// option fields
|
||||
sourceDir string
|
||||
imageName string
|
||||
imageTag string
|
||||
goCmd string
|
||||
arch string
|
||||
// non option fields
|
||||
image string
|
||||
goCmd string // TODO(bentheelder): should be an option possibly
|
||||
arch string // TODO(bentheelder): should be an option
|
||||
}
|
||||
|
||||
// Option is BuildContext configuration option supplied to NewBuildContext
|
||||
@@ -50,6 +58,13 @@ func WithSourceDir(sourceDir string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithImageName configures a NewBuildContext to tag the built image with `name`
|
||||
func WithImageName(name string) Option {
|
||||
return func(b *BuildContext) {
|
||||
b.imageName = name
|
||||
}
|
||||
}
|
||||
|
||||
// WithImageTag configures a NewBuildContext to tag the built image with `tag`
|
||||
func WithImageTag(tag string) Option {
|
||||
return func(b *BuildContext) {
|
||||
@@ -61,13 +76,16 @@ func WithImageTag(tag string) Option {
|
||||
// default configuration
|
||||
func NewBuildContext(options ...Option) *BuildContext {
|
||||
ctx := &BuildContext{
|
||||
imageTag: DefaultImageName,
|
||||
goCmd: "go",
|
||||
arch: "amd64",
|
||||
imageName: DefaultImageName,
|
||||
imageTag: DefaultImageTag,
|
||||
goCmd: "go",
|
||||
arch: "amd64",
|
||||
}
|
||||
for _, option := range options {
|
||||
option(ctx)
|
||||
}
|
||||
// normalize name and tag into an image reference
|
||||
ctx.image = docker.JoinNameAndTag(ctx.imageName, ctx.imageTag)
|
||||
return ctx
|
||||
}
|
||||
|
||||
@@ -135,7 +153,7 @@ func (c *BuildContext) buildEntrypoint(dir string) error {
|
||||
|
||||
func (c *BuildContext) buildImage(dir string) error {
|
||||
// build the image, tagged as tagImageAs, using the our tempdir as the context
|
||||
cmd := exec.Command("docker", "build", "-t", c.imageTag, dir)
|
||||
cmd := exec.Command("docker", "build", "-t", c.image, dir)
|
||||
cmd.Debug = true
|
||||
cmd.InheritOutput = true
|
||||
|
||||
|
||||
@@ -27,15 +27,24 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"sigs.k8s.io/kind/pkg/build/kube"
|
||||
"sigs.k8s.io/kind/pkg/docker"
|
||||
"sigs.k8s.io/kind/pkg/exec"
|
||||
"sigs.k8s.io/kind/pkg/fs"
|
||||
)
|
||||
|
||||
// DefaultTag is the default tag for the built image
|
||||
const DefaultTag = "kind-node"
|
||||
// DefaultImageName is the default name for the built image
|
||||
const DefaultImageName = "kindest/node"
|
||||
|
||||
// DefaultBaseImage is the default base image used
|
||||
const DefaultBaseImage = "kind-base"
|
||||
// DefaultImageTag is the default tag for the built image
|
||||
const DefaultImageTag = "latest"
|
||||
|
||||
// DefaultBaseImageName is the default base image name used
|
||||
const DefaultBaseImageName = "kindest/base"
|
||||
|
||||
// DefaultBaseImageTag is the default base image tag used
|
||||
// TODO(bentheelder): add tooling to automanage this,
|
||||
// and document using --base-tag=latest for local builds
|
||||
const DefaultBaseImageTag = "v20180920-afa27a7"
|
||||
|
||||
// DefaultMode is the default kubernetes build mode for the built image
|
||||
// see pkg/build/kube.Bits
|
||||
@@ -44,6 +53,13 @@ const DefaultMode = "docker"
|
||||
// Option is BuildContext configuration option supplied to NewBuildContext
|
||||
type Option func(*BuildContext)
|
||||
|
||||
// WithImageName configures a NewBuildContext to tag the built image with `name`
|
||||
func WithImageName(name string) Option {
|
||||
return func(b *BuildContext) {
|
||||
b.imageName = name
|
||||
}
|
||||
}
|
||||
|
||||
// WithImageTag configures a NewBuildContext to tag the built image with `tag`
|
||||
func WithImageTag(tag string) Option {
|
||||
return func(b *BuildContext) {
|
||||
@@ -51,10 +67,17 @@ func WithImageTag(tag string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithBaseImage configures a NewBuildContext to use `image` as the base image
|
||||
func WithBaseImage(image string) Option {
|
||||
// WithBaseImageName configures a NewBuildContext to use `image` as the base image name
|
||||
func WithBaseImageName(image string) Option {
|
||||
return func(b *BuildContext) {
|
||||
b.baseImage = image
|
||||
b.baseImageName = image
|
||||
}
|
||||
}
|
||||
|
||||
// WithBaseImageTag configures a NewBuildContext to use `tag` as the base image tag
|
||||
func WithBaseImageTag(tag string) Option {
|
||||
return func(b *BuildContext) {
|
||||
b.baseImageTag = tag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +92,17 @@ func WithMode(mode string) Option {
|
||||
// build configuration
|
||||
type BuildContext struct {
|
||||
// option fields
|
||||
mode string
|
||||
imageTag string
|
||||
arch string
|
||||
baseImage string
|
||||
mode string
|
||||
imageName string
|
||||
imageTag string
|
||||
baseImageName string
|
||||
baseImageTag string
|
||||
// non-option fields
|
||||
kubeRoot string
|
||||
bits kube.Bits
|
||||
arch string // TODO(bentheelder): this should be an option
|
||||
image string
|
||||
baseImage string
|
||||
kubeRoot string
|
||||
bits kube.Bits
|
||||
}
|
||||
|
||||
// NewBuildContext creates a new BuildContext with default configuration,
|
||||
@@ -83,15 +110,20 @@ type BuildContext struct {
|
||||
func NewBuildContext(options ...Option) (ctx *BuildContext, err error) {
|
||||
// default options
|
||||
ctx = &BuildContext{
|
||||
mode: DefaultMode,
|
||||
imageTag: DefaultTag,
|
||||
arch: "amd64",
|
||||
baseImage: DefaultBaseImage,
|
||||
mode: DefaultMode,
|
||||
imageName: DefaultImageName,
|
||||
imageTag: DefaultImageTag,
|
||||
arch: "amd64",
|
||||
baseImageName: DefaultBaseImageName,
|
||||
baseImageTag: DefaultBaseImageTag,
|
||||
}
|
||||
// apply user options
|
||||
for _, option := range options {
|
||||
option(ctx)
|
||||
}
|
||||
// normalize name and tag into an image reference
|
||||
ctx.image = docker.JoinNameAndTag(ctx.imageName, ctx.imageTag)
|
||||
ctx.baseImage = docker.JoinNameAndTag(ctx.baseImageName, ctx.baseImageTag)
|
||||
// lookup kuberoot unless mode == "apt",
|
||||
// apt should not fail on finding kube root as it does not use it
|
||||
kubeRoot := ""
|
||||
@@ -249,7 +281,7 @@ func (c *BuildContext) buildImage(dir string) error {
|
||||
}
|
||||
|
||||
// Save the image changes to a new image
|
||||
cmd := exec.Command("docker", "commit", containerID, c.imageTag)
|
||||
cmd := exec.Command("docker", "commit", containerID, c.image)
|
||||
cmd.Debug = true
|
||||
cmd.InheritOutput = true
|
||||
if err = cmd.Run(); err != nil {
|
||||
|
||||
@@ -26,7 +26,8 @@ func New() *Config {
|
||||
// ApplyDefaults replaces unset fields with defaults
|
||||
func (c *Config) ApplyDefaults() {
|
||||
if c.Image == "" {
|
||||
c.Image = "kind-node"
|
||||
// TODO(bentheelder): move this to a constant
|
||||
c.Image = "kindest/node:v1.11.3"
|
||||
}
|
||||
if c.NumNodes == 0 {
|
||||
c.NumNodes = 1
|
||||
|
||||
@@ -24,6 +24,7 @@ package config
|
||||
// Other API versions can be converted to this struct with Convert()
|
||||
type Config struct {
|
||||
// Image is the node image to use when running the cluster
|
||||
// TODO(bentheelder): split this into image and tag?
|
||||
Image string `json:"image,omitempty"`
|
||||
// NumNodes is the number of nodes to create (currently only one is supported)
|
||||
NumNodes int `json:"numNodes,omitempty"`
|
||||
|
||||
35
pkg/docker/docker.go
Normal file
35
pkg/docker/docker.go
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package docker contains helpers for working with docker
|
||||
package docker
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// JoinNameAndTag combines a docker image name and tag
|
||||
// The tag may be empty, a tag as in name:tag, or a a sha as in `@sha256:asdf`
|
||||
func JoinNameAndTag(name, tag string) string {
|
||||
// Join the name and tag with a colon IFF the tag is not any of:
|
||||
// - empty, in which case we can just the name
|
||||
// - starts with @, this is either a digest, or an invalid value
|
||||
// - starts with :, we can gracefully not double up the :
|
||||
if tag != "" && !strings.HasPrefix(tag, "@") && !strings.HasPrefix(tag, ":") {
|
||||
return name + ":" + tag
|
||||
}
|
||||
return name + tag
|
||||
}
|
||||
Reference in New Issue
Block a user