Merge pull request #2559 from RainbowMango/pr_update_kind
Update kind dependency to get ready for testing against kubernetes v1.25
This commit is contained in:
commit
10990cd96c
4
go.mod
4
go.mod
|
@ -41,7 +41,7 @@ require (
|
|||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
|
||||
sigs.k8s.io/cluster-api v1.0.1
|
||||
sigs.k8s.io/controller-runtime v0.12.2
|
||||
sigs.k8s.io/kind v0.14.0
|
||||
sigs.k8s.io/kind v0.15.0
|
||||
sigs.k8s.io/mcs-api v0.1.0
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
|
@ -163,7 +163,7 @@ require (
|
|||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.2.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||
|
|
7
go.sum
7
go.sum
|
@ -1486,8 +1486,9 @@ gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
|
@ -1595,8 +1596,8 @@ sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WG
|
|||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
|
||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
|
||||
sigs.k8s.io/kind v0.8.1/go.mod h1:oNKTxUVPYkV9lWzY6CVMNluVq8cBsyq+UgPJdvA3uu4=
|
||||
sigs.k8s.io/kind v0.14.0 h1:cNmI3jGBvp7UegEGbC5we8plDtCUmaNRL+bod7JoSCE=
|
||||
sigs.k8s.io/kind v0.14.0/go.mod h1:UrFRPHG+2a5j0Q7qiR4gtJ4rEyn8TuMQwuOPf+m4oHg=
|
||||
sigs.k8s.io/kind v0.15.0 h1:Fskj234L4hjQlsScCgeYvCBIRt06cjLzc7+kbr1u8Tg=
|
||||
sigs.k8s.io/kind v0.15.0/go.mod h1:cKTqagdRyUQmihhBOd+7p43DpOPRn9rHsUC08K1Jbsk=
|
||||
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
|
||||
sigs.k8s.io/kustomize/api v0.11.4 h1:/0Mr3kfBBNcNPOW5Qwk/3eb8zkswCwnqQxxKtmrTkRo=
|
||||
sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI=
|
||||
|
|
|
@ -100,7 +100,10 @@ func (p *parser) peek() yaml_event_type_t {
|
|||
if p.event.typ != yaml_NO_EVENT {
|
||||
return p.event.typ
|
||||
}
|
||||
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||
// It's curious choice from the underlying API to generally return a
|
||||
// positive result on success, but on this case return true in an error
|
||||
// scenario. This was the source of bugs in the past (issue #666).
|
||||
if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR {
|
||||
p.fail()
|
||||
}
|
||||
return p.event.typ
|
||||
|
@ -320,6 +323,8 @@ type decoder struct {
|
|||
decodeCount int
|
||||
aliasCount int
|
||||
aliasDepth int
|
||||
|
||||
mergedFields map[interface{}]bool
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -808,6 +813,11 @@ func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
|
|||
}
|
||||
}
|
||||
|
||||
mergedFields := d.mergedFields
|
||||
d.mergedFields = nil
|
||||
|
||||
var mergeNode *Node
|
||||
|
||||
mapIsNew := false
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeMap(outt))
|
||||
|
@ -815,11 +825,18 @@ func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
|
|||
}
|
||||
for i := 0; i < l; i += 2 {
|
||||
if isMerge(n.Content[i]) {
|
||||
d.merge(n.Content[i+1], out)
|
||||
mergeNode = n.Content[i+1]
|
||||
continue
|
||||
}
|
||||
k := reflect.New(kt).Elem()
|
||||
if d.unmarshal(n.Content[i], k) {
|
||||
if mergedFields != nil {
|
||||
ki := k.Interface()
|
||||
if mergedFields[ki] {
|
||||
continue
|
||||
}
|
||||
mergedFields[ki] = true
|
||||
}
|
||||
kkind := k.Kind()
|
||||
if kkind == reflect.Interface {
|
||||
kkind = k.Elem().Kind()
|
||||
|
@ -833,6 +850,12 @@ func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.mergedFields = mergedFields
|
||||
if mergeNode != nil {
|
||||
d.merge(n, mergeNode, out)
|
||||
}
|
||||
|
||||
d.stringMapType = stringMapType
|
||||
d.generalMapType = generalMapType
|
||||
return true
|
||||
|
@ -844,7 +867,8 @@ func isStringMap(n *Node) bool {
|
|||
}
|
||||
l := len(n.Content)
|
||||
for i := 0; i < l; i += 2 {
|
||||
if n.Content[i].ShortTag() != strTag {
|
||||
shortTag := n.Content[i].ShortTag()
|
||||
if shortTag != strTag && shortTag != mergeTag {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -861,7 +885,6 @@ func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
|
|||
var elemType reflect.Type
|
||||
if sinfo.InlineMap != -1 {
|
||||
inlineMap = out.Field(sinfo.InlineMap)
|
||||
inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
|
||||
elemType = inlineMap.Type().Elem()
|
||||
}
|
||||
|
||||
|
@ -870,6 +893,9 @@ func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
|
|||
d.prepare(n, field)
|
||||
}
|
||||
|
||||
mergedFields := d.mergedFields
|
||||
d.mergedFields = nil
|
||||
var mergeNode *Node
|
||||
var doneFields []bool
|
||||
if d.uniqueKeys {
|
||||
doneFields = make([]bool, len(sinfo.FieldsList))
|
||||
|
@ -879,13 +905,20 @@ func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
|
|||
for i := 0; i < l; i += 2 {
|
||||
ni := n.Content[i]
|
||||
if isMerge(ni) {
|
||||
d.merge(n.Content[i+1], out)
|
||||
mergeNode = n.Content[i+1]
|
||||
continue
|
||||
}
|
||||
if !d.unmarshal(ni, name) {
|
||||
continue
|
||||
}
|
||||
if info, ok := sinfo.FieldsMap[name.String()]; ok {
|
||||
sname := name.String()
|
||||
if mergedFields != nil {
|
||||
if mergedFields[sname] {
|
||||
continue
|
||||
}
|
||||
mergedFields[sname] = true
|
||||
}
|
||||
if info, ok := sinfo.FieldsMap[sname]; ok {
|
||||
if d.uniqueKeys {
|
||||
if doneFields[info.Id] {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type()))
|
||||
|
@ -911,6 +944,11 @@ func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
|
|||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type()))
|
||||
}
|
||||
}
|
||||
|
||||
d.mergedFields = mergedFields
|
||||
if mergeNode != nil {
|
||||
d.merge(n, mergeNode, out)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -918,19 +956,29 @@ func failWantMap() {
|
|||
failf("map merge requires map or sequence of maps as the value")
|
||||
}
|
||||
|
||||
func (d *decoder) merge(n *Node, out reflect.Value) {
|
||||
switch n.Kind {
|
||||
func (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) {
|
||||
mergedFields := d.mergedFields
|
||||
if mergedFields == nil {
|
||||
d.mergedFields = make(map[interface{}]bool)
|
||||
for i := 0; i < len(parent.Content); i += 2 {
|
||||
k := reflect.New(ifaceType).Elem()
|
||||
if d.unmarshal(parent.Content[i], k) {
|
||||
d.mergedFields[k.Interface()] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch merge.Kind {
|
||||
case MappingNode:
|
||||
d.unmarshal(n, out)
|
||||
d.unmarshal(merge, out)
|
||||
case AliasNode:
|
||||
if n.Alias != nil && n.Alias.Kind != MappingNode {
|
||||
if merge.Alias != nil && merge.Alias.Kind != MappingNode {
|
||||
failWantMap()
|
||||
}
|
||||
d.unmarshal(n, out)
|
||||
d.unmarshal(merge, out)
|
||||
case SequenceNode:
|
||||
// Step backwards as earlier nodes take precedence.
|
||||
for i := len(n.Content) - 1; i >= 0; i-- {
|
||||
ni := n.Content[i]
|
||||
for i := 0; i < len(merge.Content); i++ {
|
||||
ni := merge.Content[i]
|
||||
if ni.Kind == AliasNode {
|
||||
if ni.Alias != nil && ni.Alias.Kind != MappingNode {
|
||||
failWantMap()
|
||||
|
@ -943,6 +991,8 @@ func (d *decoder) merge(n *Node, out reflect.Value) {
|
|||
default:
|
||||
failWantMap()
|
||||
}
|
||||
|
||||
d.mergedFields = mergedFields
|
||||
}
|
||||
|
||||
func isMerge(n *Node) bool {
|
||||
|
|
|
@ -687,6 +687,9 @@ func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, i
|
|||
func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
|
||||
if first {
|
||||
token := peek_token(parser)
|
||||
if token == nil {
|
||||
return false
|
||||
}
|
||||
parser.marks = append(parser.marks, token.start_mark)
|
||||
skip_token(parser)
|
||||
}
|
||||
|
@ -786,7 +789,7 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
|
|||
}
|
||||
|
||||
token := peek_token(parser)
|
||||
if token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
|
||||
if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -813,6 +816,9 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
|
|||
func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
|
||||
if first {
|
||||
token := peek_token(parser)
|
||||
if token == nil {
|
||||
return false
|
||||
}
|
||||
parser.marks = append(parser.marks, token.start_mark)
|
||||
skip_token(parser)
|
||||
}
|
||||
|
@ -922,6 +928,9 @@ func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_ev
|
|||
func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
|
||||
if first {
|
||||
token := peek_token(parser)
|
||||
if token == nil {
|
||||
return false
|
||||
}
|
||||
parser.marks = append(parser.marks, token.start_mark)
|
||||
skip_token(parser)
|
||||
}
|
||||
|
|
|
@ -751,7 +751,7 @@ gopkg.in/square/go-jose.v2/json
|
|||
# gopkg.in/yaml.v2 v2.4.0
|
||||
## explicit; go 1.15
|
||||
gopkg.in/yaml.v2
|
||||
# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
# gopkg.in/yaml.v3 v3.0.1
|
||||
## explicit
|
||||
gopkg.in/yaml.v3
|
||||
# k8s.io/api v0.24.2
|
||||
|
@ -1539,7 +1539,7 @@ sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics
|
|||
## explicit; go 1.17
|
||||
sigs.k8s.io/json
|
||||
sigs.k8s.io/json/internal/golang/encoding/json
|
||||
# sigs.k8s.io/kind v0.14.0
|
||||
# sigs.k8s.io/kind v0.15.0
|
||||
## explicit; go 1.14
|
||||
sigs.k8s.io/kind/pkg/apis/config/defaults
|
||||
sigs.k8s.io/kind/pkg/apis/config/v1alpha4
|
||||
|
|
|
@ -18,4 +18,4 @@ limitations under the License.
|
|||
package defaults
|
||||
|
||||
// Image is the default for the Config.Image field, aka the default node image.
|
||||
const Image = "kindest/node:v1.24.0@sha256:0866296e693efe1fed79d5e6c7af8df71fc73ae45e3679af05342239cdc5bc8e"
|
||||
const Image = "kindest/node:v1.25.0@sha256:428aaa17ec82ccde0131cb2d1ca6547d13cf5fdabcc0bbecf749baa935387cbf"
|
||||
|
|
|
@ -18,33 +18,33 @@ package v1alpha4
|
|||
|
||||
// Cluster contains kind cluster configuration
|
||||
type Cluster struct {
|
||||
TypeMeta `yaml:",inline"`
|
||||
TypeMeta `yaml:",inline" json:",inline"`
|
||||
|
||||
// The cluster name.
|
||||
// Optional, this will be overridden by --name / KIND_CLUSTER_NAME
|
||||
Name string `yaml:"name,omitempty"`
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
|
||||
// Nodes contains the list of nodes defined in the `kind` Cluster
|
||||
// If unset this will default to a single control-plane node
|
||||
// Note that if more than one control plane is specified, an external
|
||||
// control plane load balancer will be provisioned implicitly
|
||||
Nodes []Node `yaml:"nodes,omitempty"`
|
||||
Nodes []Node `yaml:"nodes,omitempty" json:"nodes,omitempty"`
|
||||
|
||||
/* Advanced fields */
|
||||
|
||||
// Networking contains cluster wide network settings
|
||||
Networking Networking `yaml:"networking,omitempty"`
|
||||
Networking Networking `yaml:"networking,omitempty" json:"networking,omitempty"`
|
||||
|
||||
// FeatureGates contains a map of Kubernetes feature gates to whether they
|
||||
// are enabled. The feature gates specified here are passed to all Kubernetes components as flags or in config.
|
||||
//
|
||||
// https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
|
||||
FeatureGates map[string]bool `yaml:"featureGates,omitempty"`
|
||||
FeatureGates map[string]bool `yaml:"featureGates,omitempty" json:"featureGates,omitempty"`
|
||||
|
||||
// RuntimeConfig Keys and values are translated into --runtime-config values for kube-apiserver, separated by commas.
|
||||
//
|
||||
// Use this to enable alpha APIs.
|
||||
RuntimeConfig map[string]string `yaml:"runtimeConfig,omitempty"`
|
||||
RuntimeConfig map[string]string `yaml:"runtimeConfig,omitempty" json:"runtimeConfig,omitempty"`
|
||||
|
||||
// KubeadmConfigPatches are applied to the generated kubeadm config as
|
||||
// merge patches. The `kind` field must match the target object, and
|
||||
|
@ -55,7 +55,7 @@ type Cluster struct {
|
|||
// https://tools.ietf.org/html/rfc7386
|
||||
//
|
||||
// The cluster-level patches are applied before the node-level patches.
|
||||
KubeadmConfigPatches []string `yaml:"kubeadmConfigPatches,omitempty"`
|
||||
KubeadmConfigPatches []string `yaml:"kubeadmConfigPatches,omitempty" json:"kubeadmConfigPatches,omitempty"`
|
||||
|
||||
// KubeadmConfigPatchesJSON6902 are applied to the generated kubeadm config
|
||||
// as JSON 6902 patches. The `kind` field must match the target object, and
|
||||
|
@ -70,53 +70,53 @@ type Cluster struct {
|
|||
// https://tools.ietf.org/html/rfc6902
|
||||
//
|
||||
// The cluster-level patches are applied before the node-level patches.
|
||||
KubeadmConfigPatchesJSON6902 []PatchJSON6902 `yaml:"kubeadmConfigPatchesJSON6902,omitempty"`
|
||||
KubeadmConfigPatchesJSON6902 []PatchJSON6902 `yaml:"kubeadmConfigPatchesJSON6902,omitempty" json:"kubeadmConfigPatchesJSON6902,omitempty"`
|
||||
|
||||
// ContainerdConfigPatches are applied to every node's containerd config
|
||||
// in the order listed.
|
||||
// These should be toml stringsto be applied as merge patches
|
||||
ContainerdConfigPatches []string `yaml:"containerdConfigPatches,omitempty"`
|
||||
ContainerdConfigPatches []string `yaml:"containerdConfigPatches,omitempty" json:"containerdConfigPatches,omitempty"`
|
||||
|
||||
// ContainerdConfigPatchesJSON6902 are applied to every node's containerd config
|
||||
// in the order listed.
|
||||
// These should be YAML or JSON formatting RFC 6902 JSON patches
|
||||
ContainerdConfigPatchesJSON6902 []string `yaml:"containerdConfigPatchesJSON6902,omitempty"`
|
||||
ContainerdConfigPatchesJSON6902 []string `yaml:"containerdConfigPatchesJSON6902,omitempty" json:"containerdConfigPatchesJSON6902,omitempty"`
|
||||
}
|
||||
|
||||
// TypeMeta partially copies apimachinery/pkg/apis/meta/v1.TypeMeta
|
||||
// No need for a direct dependence; the fields are stable.
|
||||
type TypeMeta struct {
|
||||
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
|
||||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||
Kind string `yaml:"kind,omitempty" json:"kind,omitempty"`
|
||||
APIVersion string `yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
// Node contains settings for a node in the `kind` Cluster.
|
||||
// A node in kind config represent a container that will be provisioned with all the components
|
||||
// required for the assigned role in the Kubernetes cluster
|
||||
type Node struct {
|
||||
// Role defines the role of the node in the in the Kubernetes cluster
|
||||
// Role defines the role of the node in the Kubernetes cluster
|
||||
// created by kind
|
||||
//
|
||||
// Defaults to "control-plane"
|
||||
Role NodeRole `yaml:"role,omitempty"`
|
||||
Role NodeRole `yaml:"role,omitempty" json:"role,omitempty"`
|
||||
|
||||
// Image is the node image to use when creating this node
|
||||
// If unset a default image will be used, see defaults.Image
|
||||
Image string `yaml:"image,omitempty"`
|
||||
Image string `yaml:"image,omitempty" json:"image,omitempty"`
|
||||
|
||||
// Labels are the labels with which the respective node will be labeled
|
||||
Labels map[string]string `yaml:"labels,omitempty"`
|
||||
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
|
||||
|
||||
/* Advanced fields */
|
||||
|
||||
// TODO: cri-like types should be inline instead
|
||||
// ExtraMounts describes additional mount points for the node container
|
||||
// These may be used to bind a hostPath
|
||||
ExtraMounts []Mount `yaml:"extraMounts,omitempty"`
|
||||
ExtraMounts []Mount `yaml:"extraMounts,omitempty" json:"extraMounts,omitempty"`
|
||||
|
||||
// ExtraPortMappings describes additional port mappings for the node container
|
||||
// binded to a host Port
|
||||
ExtraPortMappings []PortMapping `yaml:"extraPortMappings,omitempty"`
|
||||
ExtraPortMappings []PortMapping `yaml:"extraPortMappings,omitempty" json:"extraPortMappings,omitempty"`
|
||||
|
||||
// KubeadmConfigPatches are applied to the generated kubeadm config as
|
||||
// merge patches. The `kind` field must match the target object, and
|
||||
|
@ -128,7 +128,7 @@ type Node struct {
|
|||
//
|
||||
// The node-level patches will be applied after the cluster-level patches
|
||||
// have been applied. (See Cluster.KubeadmConfigPatches)
|
||||
KubeadmConfigPatches []string `yaml:"kubeadmConfigPatches,omitempty"`
|
||||
KubeadmConfigPatches []string `yaml:"kubeadmConfigPatches,omitempty" json:"kubeadmConfigPatches,omitempty"`
|
||||
|
||||
// KubeadmConfigPatchesJSON6902 are applied to the generated kubeadm config
|
||||
// as JSON 6902 patches. The `kind` field must match the target object, and
|
||||
|
@ -144,7 +144,7 @@ type Node struct {
|
|||
//
|
||||
// The node-level patches will be applied after the cluster-level patches
|
||||
// have been applied. (See Cluster.KubeadmConfigPatchesJSON6902)
|
||||
KubeadmConfigPatchesJSON6902 []PatchJSON6902 `yaml:"kubeadmConfigPatchesJSON6902,omitempty"`
|
||||
KubeadmConfigPatchesJSON6902 []PatchJSON6902 `yaml:"kubeadmConfigPatchesJSON6902,omitempty" json:"kubeadmConfigPatchesJSON6902,omitempty"`
|
||||
}
|
||||
|
||||
// NodeRole defines possible role for nodes in a Kubernetes cluster managed by `kind`
|
||||
|
@ -163,7 +163,7 @@ const (
|
|||
// Networking contains cluster wide network settings
|
||||
type Networking struct {
|
||||
// IPFamily is the network cluster model, currently it can be ipv4 or ipv6
|
||||
IPFamily ClusterIPFamily `yaml:"ipFamily,omitempty"`
|
||||
IPFamily ClusterIPFamily `yaml:"ipFamily,omitempty" json:"ipFamily,omitempty"`
|
||||
// APIServerPort is the listen port on the host for the Kubernetes API Server
|
||||
// Defaults to a random port on the host obtained by kind
|
||||
//
|
||||
|
@ -171,24 +171,24 @@ type Networking struct {
|
|||
// (docker, podman...) will be left to pick the port instead.
|
||||
// This is potentially useful for remote hosts, BUT it means when the container
|
||||
// is restarted it will be randomized. Leave this unset to allow kind to pick it.
|
||||
APIServerPort int32 `yaml:"apiServerPort,omitempty"`
|
||||
APIServerPort int32 `yaml:"apiServerPort,omitempty" json:"apiServerPort,omitempty"`
|
||||
// APIServerAddress is the listen address on the host for the Kubernetes
|
||||
// API Server. This should be an IP address.
|
||||
//
|
||||
// Defaults to 127.0.0.1
|
||||
APIServerAddress string `yaml:"apiServerAddress,omitempty"`
|
||||
APIServerAddress string `yaml:"apiServerAddress,omitempty" json:"apiServerAddress,omitempty"`
|
||||
// PodSubnet is the CIDR used for pod IPs
|
||||
// kind will select a default if unspecified
|
||||
PodSubnet string `yaml:"podSubnet,omitempty"`
|
||||
PodSubnet string `yaml:"podSubnet,omitempty" json:"podSubnet,omitempty"`
|
||||
// ServiceSubnet is the CIDR used for services VIPs
|
||||
// kind will select a default if unspecified for IPv6
|
||||
ServiceSubnet string `yaml:"serviceSubnet,omitempty"`
|
||||
ServiceSubnet string `yaml:"serviceSubnet,omitempty" json:"serviceSubnet,omitempty"`
|
||||
// If DisableDefaultCNI is true, kind will not install the default CNI setup.
|
||||
// Instead the user should install their own CNI after creating the cluster.
|
||||
DisableDefaultCNI bool `yaml:"disableDefaultCNI,omitempty"`
|
||||
DisableDefaultCNI bool `yaml:"disableDefaultCNI,omitempty" json:"disableDefaultCNI,omitempty"`
|
||||
// KubeProxyMode defines if kube-proxy should operate in iptables or ipvs mode
|
||||
// Defaults to 'iptables' mode
|
||||
KubeProxyMode ProxyMode `yaml:"kubeProxyMode,omitempty"`
|
||||
KubeProxyMode ProxyMode `yaml:"kubeProxyMode,omitempty" json:"kubeProxyMode,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterIPFamily defines cluster network IP family
|
||||
|
@ -217,11 +217,11 @@ const (
|
|||
// https://tools.ietf.org/html/rfc6902
|
||||
type PatchJSON6902 struct {
|
||||
// these fields specify the patch target resource
|
||||
Group string `yaml:"group"`
|
||||
Version string `yaml:"version"`
|
||||
Kind string `yaml:"kind"`
|
||||
Group string `yaml:"group" json:"group"`
|
||||
Version string `yaml:"version" json:"version"`
|
||||
Kind string `yaml:"kind" json:"kind"`
|
||||
// Patch should contain the contents of the json patch as a string
|
||||
Patch string `yaml:"patch"`
|
||||
Patch string `yaml:"patch" json:"patch"`
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -236,36 +236,39 @@ https://github.com/kubernetes/kubernetes/blob/063e7ff358fdc8b0916e6f39beedc0d025
|
|||
// names on disk as opposed to the int32 values, and the serialized field names
|
||||
// have been made closer to core/v1 VolumeMount field names
|
||||
// In yaml this looks like:
|
||||
// containerPath: /foo
|
||||
// hostPath: /bar
|
||||
// readOnly: true
|
||||
// selinuxRelabel: false
|
||||
// propagation: None
|
||||
//
|
||||
// containerPath: /foo
|
||||
// hostPath: /bar
|
||||
// readOnly: true
|
||||
// selinuxRelabel: false
|
||||
// propagation: None
|
||||
//
|
||||
// Propagation may be one of: None, HostToContainer, Bidirectional
|
||||
type Mount struct {
|
||||
// Path of the mount within the container.
|
||||
ContainerPath string `yaml:"containerPath,omitempty"`
|
||||
ContainerPath string `yaml:"containerPath,omitempty" json:"containerPath,omitempty"`
|
||||
// Path of the mount on the host. If the hostPath doesn't exist, then runtimes
|
||||
// should report error. If the hostpath is a symbolic link, runtimes should
|
||||
// follow the symlink and mount the real destination to container.
|
||||
HostPath string `yaml:"hostPath,omitempty"`
|
||||
HostPath string `yaml:"hostPath,omitempty" json:"hostPath,omitempty"`
|
||||
// If set, the mount is read-only.
|
||||
Readonly bool `yaml:"readOnly,omitempty"`
|
||||
Readonly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
|
||||
// If set, the mount needs SELinux relabeling.
|
||||
SelinuxRelabel bool `yaml:"selinuxRelabel,omitempty"`
|
||||
SelinuxRelabel bool `yaml:"selinuxRelabel,omitempty" json:"selinuxRelabel,omitempty"`
|
||||
// Requested propagation mode.
|
||||
Propagation MountPropagation `yaml:"propagation,omitempty"`
|
||||
Propagation MountPropagation `yaml:"propagation,omitempty" json:"propagation,omitempty"`
|
||||
}
|
||||
|
||||
// PortMapping specifies a host port mapped into a container port.
|
||||
// In yaml this looks like:
|
||||
// containerPort: 80
|
||||
// hostPort: 8000
|
||||
// listenAddress: 127.0.0.1
|
||||
// protocol: TCP
|
||||
//
|
||||
// containerPort: 80
|
||||
// hostPort: 8000
|
||||
// listenAddress: 127.0.0.1
|
||||
// protocol: TCP
|
||||
type PortMapping struct {
|
||||
// Port within the container.
|
||||
ContainerPort int32 `yaml:"containerPort,omitempty"`
|
||||
ContainerPort int32 `yaml:"containerPort,omitempty" json:"containerPort,omitempty"`
|
||||
// Port on the host.
|
||||
//
|
||||
// If unset, a random port will be selected.
|
||||
|
@ -274,11 +277,11 @@ type PortMapping struct {
|
|||
// (docker, podman...) will be left to pick the port instead.
|
||||
// This is potentially useful for remote hosts, BUT it means when the container
|
||||
// is restarted it will be randomized. Leave this unset to allow kind to pick it.
|
||||
HostPort int32 `yaml:"hostPort,omitempty"`
|
||||
HostPort int32 `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
|
||||
// TODO: add protocol (tcp/udp) and port-ranges
|
||||
ListenAddress string `yaml:"listenAddress,omitempty"`
|
||||
ListenAddress string `yaml:"listenAddress,omitempty" json:"listenAddress,omitempty"`
|
||||
// Protocol (TCP/UDP/SCTP)
|
||||
Protocol PortMappingProtocol `yaml:"protocol,omitempty"`
|
||||
Protocol PortMappingProtocol `yaml:"protocol,omitempty" json:"protocol,omitempty"`
|
||||
}
|
||||
|
||||
// MountPropagation represents an "enum" for mount propagation options,
|
||||
|
|
|
@ -131,7 +131,7 @@ func waitForReady(node nodes.Node, until time.Time, selectorLabel string) bool {
|
|||
})
|
||||
}
|
||||
|
||||
// helper that calls `try()`` in a loop until the deadline `until`
|
||||
// helper that calls `try()“ in a loop until the deadline `until`
|
||||
// has passed or `try()`returns true, returns whether try ever returned true
|
||||
func tryUntil(until time.Time, try func() bool) bool {
|
||||
for until.After(time.Now()) {
|
||||
|
|
|
@ -75,14 +75,16 @@ type ConfigData struct {
|
|||
// Labels are the labels, in the format "key1=val1,key2=val2", with which the respective node will be labeled
|
||||
NodeLabels string
|
||||
|
||||
// DerivedConfigData is populated by Derive()
|
||||
// These auto-generated fields are available to Config templates,
|
||||
// but not meant to be set by hand
|
||||
DerivedConfigData
|
||||
|
||||
// Provider is running with rootless mode, so kube-proxy needs to be configured
|
||||
// not to fail on sysctl error.
|
||||
// RootlessProvider is true if kind is running with rootless mode
|
||||
RootlessProvider bool
|
||||
|
||||
// DisableLocalStorageCapacityIsolation is typically set true based on RootlessProvider
|
||||
// based on the Kubernetes version, if true kubelet localStorageCapacityIsolation is set false
|
||||
DisableLocalStorageCapacityIsolation bool
|
||||
|
||||
// DerivedConfigData contains fields computed from the other fields for use
|
||||
// in the config templates and should only be populated by calling Derive()
|
||||
DerivedConfigData
|
||||
}
|
||||
|
||||
// DerivedConfigData fields are automatically derived by
|
||||
|
@ -266,7 +268,7 @@ evictionHard:
|
|||
imagefs.available: "0%"
|
||||
{{if .FeatureGates}}featureGates:
|
||||
{{ range $key := .SortedFeatureGateKeys }}
|
||||
"{{ $key }}": {{$.FeatureGates $key }}
|
||||
"{{ $key }}": {{index $.FeatureGates $key }}
|
||||
{{end}}{{end}}
|
||||
{{if ne .KubeProxyMode "None"}}
|
||||
---
|
||||
|
@ -537,6 +539,7 @@ evictionHard:
|
|||
{{ range $key := .SortedFeatureGateKeys }}
|
||||
"{{ $key }}": {{ index $.FeatureGates $key }}
|
||||
{{end}}{{end}}
|
||||
{{if .DisableLocalStorageCapacityIsolation}}localStorageCapacityIsolation: false{{end}}
|
||||
{{if ne .KubeProxyMode "None"}}
|
||||
---
|
||||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||
|
@ -585,7 +588,13 @@ func Config(data ConfigData) (config string, err error) {
|
|||
|
||||
// For avoiding err="failed to get rootfs info: failed to get device for dir \"/var/lib/kubelet\": could not find device with major: 0, minor: 41 in cached partitions map"
|
||||
// https://github.com/kubernetes-sigs/kind/issues/2524
|
||||
data.FeatureGates["LocalStorageCapacityIsolation"] = false
|
||||
if ver.LessThan(version.MustParseSemantic("v1.25.0-alpha.3.440+0064010cddfa00")) {
|
||||
// this feature gate was removed in v1.25 and replaced by an opt-out to disable
|
||||
data.FeatureGates["LocalStorageCapacityIsolation"] = false
|
||||
} else {
|
||||
// added in v1.25 https://github.com/kubernetes/kubernetes/pull/111513
|
||||
data.DisableLocalStorageCapacityIsolation = true
|
||||
}
|
||||
}
|
||||
|
||||
// assume the latest API version, then fallback if the k8s version is too low
|
||||
|
|
2
vendor/sigs.k8s.io/kind/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go
generated
vendored
2
vendor/sigs.k8s.io/kind/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go
generated
vendored
|
@ -31,7 +31,7 @@ const kubeconfigEnv = "KUBECONFIG"
|
|||
paths returns the list of paths to be considered for kubeconfig files
|
||||
where explicitPath is the value of --kubeconfig
|
||||
|
||||
Logic based on kubectl
|
||||
# Logic based on kubectl
|
||||
|
||||
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package loadbalancer
|
||||
|
||||
// Image defines the loadbalancer image:tag
|
||||
const Image = "kindest/haproxy:v20220510-a42b3ea0"
|
||||
const Image = "kindest/haproxy:v20220607-9a4d8d2a"
|
||||
|
||||
// ConfigPath defines the path to the config file in the image
|
||||
const ConfigPath = "/usr/local/etc/haproxy/haproxy.cfg"
|
||||
|
|
|
@ -18,6 +18,7 @@ package podman
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"path/filepath"
|
||||
|
@ -37,7 +38,16 @@ import (
|
|||
func planCreation(cfg *config.Cluster, networkName string) (createContainerFuncs []func() error, err error) {
|
||||
// these apply to all container creation
|
||||
nodeNamer := common.MakeNodeNamer(cfg.Name)
|
||||
genericArgs, err := commonArgs(cfg, networkName)
|
||||
names := make([]string, len(cfg.Nodes))
|
||||
for i, node := range cfg.Nodes {
|
||||
name := nodeNamer(string(node.Role)) // name the node
|
||||
names[i] = name
|
||||
}
|
||||
haveLoadbalancer := config.ClusterHasImplicitLoadBalancer(cfg)
|
||||
if haveLoadbalancer {
|
||||
names = append(names, nodeNamer(constants.ExternalLoadBalancerNodeRoleValue))
|
||||
}
|
||||
genericArgs, err := commonArgs(cfg, networkName, names)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -58,7 +68,7 @@ func planCreation(cfg *config.Cluster, networkName string) (createContainerFuncs
|
|||
apiServerAddress = "::1" // only the LB needs to be non-local
|
||||
}
|
||||
// plan loadbalancer node
|
||||
name := nodeNamer(constants.ExternalLoadBalancerNodeRoleValue)
|
||||
name := names[len(names)-1]
|
||||
createContainerFuncs = append(createContainerFuncs, func() error {
|
||||
args, err := runArgsForLoadBalancer(cfg, name, genericArgs)
|
||||
if err != nil {
|
||||
|
@ -69,9 +79,9 @@ func planCreation(cfg *config.Cluster, networkName string) (createContainerFuncs
|
|||
}
|
||||
|
||||
// plan normal nodes
|
||||
for _, node := range cfg.Nodes {
|
||||
node := node.DeepCopy() // copy so we can modify
|
||||
name := nodeNamer(string(node.Role)) // name the node
|
||||
for i, node := range cfg.Nodes {
|
||||
node := node.DeepCopy() // copy so we can modify
|
||||
name := names[i]
|
||||
|
||||
// fixup relative paths, podman can only handle absolute paths
|
||||
for i := range node.ExtraMounts {
|
||||
|
@ -116,7 +126,7 @@ func planCreation(cfg *config.Cluster, networkName string) (createContainerFuncs
|
|||
}
|
||||
|
||||
// commonArgs computes static arguments that apply to all containers
|
||||
func commonArgs(cfg *config.Cluster, networkName string) ([]string, error) {
|
||||
func commonArgs(cfg *config.Cluster, networkName string, nodeNames []string) ([]string, error) {
|
||||
// standard arguments all nodes containers need, computed once
|
||||
args := []string{
|
||||
"--detach", // run the container detached
|
||||
|
@ -134,7 +144,7 @@ func commonArgs(cfg *config.Cluster, networkName string) ([]string, error) {
|
|||
}
|
||||
|
||||
// pass proxy environment variables
|
||||
proxyEnv, err := getProxyEnv(cfg, networkName)
|
||||
proxyEnv, err := getProxyEnv(cfg, networkName, nodeNames)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "proxy setup error")
|
||||
}
|
||||
|
@ -241,7 +251,7 @@ func runArgsForLoadBalancer(cfg *config.Cluster, name string, args []string) ([]
|
|||
return append(args, image), nil
|
||||
}
|
||||
|
||||
func getProxyEnv(cfg *config.Cluster, networkName string) (map[string]string, error) {
|
||||
func getProxyEnv(cfg *config.Cluster, networkName string, nodeNames []string) (map[string]string, error) {
|
||||
envs := common.GetProxyEnvs(cfg)
|
||||
// Specifically add the podman network subnets to NO_PROXY if we are using a proxy
|
||||
if len(envs) > 0 {
|
||||
|
@ -251,11 +261,13 @@ func getProxyEnv(cfg *config.Cluster, networkName string) (map[string]string, er
|
|||
return nil, err
|
||||
}
|
||||
noProxyList := append(subnets, envs[common.NOProxy])
|
||||
// Add pod and service dns names to no_proxy to allow in cluster
|
||||
noProxyList = append(noProxyList, nodeNames...)
|
||||
// Add pod,service and all the cluster nodes' dns names to no_proxy to allow in cluster
|
||||
// Note: this is best effort based on the default CoreDNS spec
|
||||
// https://github.com/kubernetes/dns/blob/master/docs/specification.md
|
||||
// Any user created pod/service hostnames, namespaces, custom DNS services
|
||||
// are expected to be no-proxied by the user explicitly.
|
||||
|
||||
noProxyList = append(noProxyList, ".svc", ".svc.cluster", ".svc.cluster.local")
|
||||
noProxyJoined := strings.Join(noProxyList, ",")
|
||||
envs[common.NOProxy] = noProxyJoined
|
||||
|
@ -264,15 +276,54 @@ func getProxyEnv(cfg *config.Cluster, networkName string) (map[string]string, er
|
|||
return envs, nil
|
||||
}
|
||||
|
||||
type podmanNetworks []struct {
|
||||
// v4+
|
||||
Subnets []struct {
|
||||
Subnet string `json:"subnet"`
|
||||
Gateway string `json:"gateway"`
|
||||
} `json:"subnets"`
|
||||
// v3 and anything still using CNI/IPAM
|
||||
Plugins []struct {
|
||||
Ipam struct {
|
||||
Ranges [][]struct {
|
||||
Gateway string `json:"gateway"`
|
||||
Subnet string `json:"subnet"`
|
||||
} `json:"ranges"`
|
||||
} `json:"ipam,omitempty"`
|
||||
} `json:"plugins"`
|
||||
}
|
||||
|
||||
func getSubnets(networkName string) ([]string, error) {
|
||||
// TODO: unmarshall json and get rid of this complex query
|
||||
format := `{{ range (index (index (index (index . "plugins") 0 ) "ipam" ) "ranges")}}{{ index ( index . 0 ) "subnet" }} {{end}}`
|
||||
cmd := exec.Command("podman", "network", "inspect", "-f", format, networkName)
|
||||
lines, err := exec.OutputLines(cmd)
|
||||
cmd := exec.Command("podman", "network", "inspect", networkName)
|
||||
out, err := exec.Output(cmd)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get subnets")
|
||||
}
|
||||
return strings.Split(strings.TrimSpace(lines[0]), " "), nil
|
||||
|
||||
networks := podmanNetworks{}
|
||||
jsonErr := json.Unmarshal([]byte(out), &networks)
|
||||
if jsonErr != nil {
|
||||
return nil, errors.Wrap(jsonErr, "failed to get subnets")
|
||||
}
|
||||
subnets := []string{}
|
||||
for _, network := range networks {
|
||||
if len(network.Subnets) > 0 {
|
||||
for _, subnet := range network.Subnets {
|
||||
subnets = append(subnets, subnet.Subnet)
|
||||
}
|
||||
}
|
||||
if len(network.Plugins) > 0 {
|
||||
for _, plugin := range network.Plugins {
|
||||
for _, r := range plugin.Ipam.Ranges {
|
||||
for _, rr := range r {
|
||||
subnets = append(subnets, rr.Subnet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return subnets, nil
|
||||
}
|
||||
|
||||
// generateMountBindings converts the mount list to a list of args for podman
|
||||
|
|
|
@ -126,3 +126,31 @@ func ImageID(n nodes.Node, image string) (string, error) {
|
|||
}
|
||||
return crictlOut.Status.ID, nil
|
||||
}
|
||||
|
||||
// ImageTags is used to perform a reverse lookup of the ImageID to list set of available
|
||||
// RepoTags corresponding to the ImageID in question
|
||||
func ImageTags(n nodes.Node, imageID string) (map[string]bool, error) {
|
||||
var out bytes.Buffer
|
||||
tags := make(map[string]bool, 0)
|
||||
if err := n.Command("crictl", "inspecti", imageID).SetStdout(&out).Run(); err != nil {
|
||||
return tags, err
|
||||
}
|
||||
crictlOut := struct {
|
||||
Status struct {
|
||||
RepoTags []string `json:"repoTags"`
|
||||
} `json:"status"`
|
||||
}{}
|
||||
if err := json.Unmarshal(out.Bytes(), &crictlOut); err != nil {
|
||||
return tags, err
|
||||
}
|
||||
for _, tag := range crictlOut.Status.RepoTags {
|
||||
tags[tag] = true
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
// ReTagImage is used to tag an ImageID with a custom tag specified by imageName parameter
|
||||
func ReTagImage(n nodes.Node, imageID, imageName string) error {
|
||||
var out bytes.Buffer
|
||||
return n.Command("ctr", "--namespace=k8s.io", "images", "tag", "--force", imageID, imageName).SetStdout(&out).Run()
|
||||
}
|
||||
|
|
|
@ -29,15 +29,19 @@ import (
|
|||
|
||||
// Version returns the kind CLI Semantic Version
|
||||
func Version() string {
|
||||
v := VersionCore
|
||||
v := versionCore
|
||||
// add pre-release version info if we have it
|
||||
if VersionPreRelease != "" {
|
||||
v += "-" + VersionPreRelease
|
||||
if versionPreRelease != "" {
|
||||
v += "-" + versionPreRelease
|
||||
// If gitCommitCount was set, add to the pre-release version
|
||||
if gitCommitCount != "" {
|
||||
v += "." + gitCommitCount
|
||||
}
|
||||
// if commit was set, add the + <build>
|
||||
// we only do this for pre-release versions
|
||||
if GitCommit != "" {
|
||||
if gitCommit != "" {
|
||||
// NOTE: use 14 character short hash, like Kubernetes
|
||||
v += "+" + truncate(GitCommit, 14)
|
||||
v += "+" + truncate(gitCommit, 14)
|
||||
}
|
||||
}
|
||||
return v
|
||||
|
@ -49,16 +53,20 @@ func DisplayVersion() string {
|
|||
return "kind v" + Version() + " " + runtime.Version() + " " + runtime.GOOS + "/" + runtime.GOARCH
|
||||
}
|
||||
|
||||
// VersionCore is the core portion of the kind CLI version per Semantic Versioning 2.0.0
|
||||
const VersionCore = "0.14.0"
|
||||
// versionCore is the core portion of the kind CLI version per Semantic Versioning 2.0.0
|
||||
const versionCore = "0.15.0"
|
||||
|
||||
// VersionPreRelease is the pre-release portion of the kind CLI version per
|
||||
// versionPreRelease is the base pre-release portion of the kind CLI version per
|
||||
// Semantic Versioning 2.0.0
|
||||
const VersionPreRelease = ""
|
||||
const versionPreRelease = ""
|
||||
|
||||
// GitCommit is the commit used to build the kind binary, if available.
|
||||
// gitCommitCount count the commits since the last release.
|
||||
// It is injected at build time.
|
||||
var GitCommit = ""
|
||||
var gitCommitCount = ""
|
||||
|
||||
// gitCommit is the commit used to build the kind binary, if available.
|
||||
// It is injected at build time.
|
||||
var gitCommit = ""
|
||||
|
||||
// NewCommand returns a new cobra.Command for version
|
||||
func NewCommand(logger log.Logger, streams cmd.IOStreams) *cobra.Command {
|
||||
|
|
|
@ -194,11 +194,13 @@ type PatchJSON6902 struct {
|
|||
// names on disk as opposed to the int32 values, and the serialized field names
|
||||
// have been made closer to core/v1 VolumeMount field names
|
||||
// In yaml this looks like:
|
||||
// containerPath: /foo
|
||||
// hostPath: /bar
|
||||
// readOnly: true
|
||||
// selinuxRelabel: false
|
||||
// propagation: None
|
||||
//
|
||||
// containerPath: /foo
|
||||
// hostPath: /bar
|
||||
// readOnly: true
|
||||
// selinuxRelabel: false
|
||||
// propagation: None
|
||||
//
|
||||
// Propagation may be one of: None, HostToContainer, Bidirectional
|
||||
type Mount struct {
|
||||
// Path of the mount within the container.
|
||||
|
@ -217,10 +219,11 @@ type Mount struct {
|
|||
|
||||
// PortMapping specifies a host port mapped into a container port.
|
||||
// In yaml this looks like:
|
||||
// containerPort: 80
|
||||
// hostPort: 8000
|
||||
// listenAddress: 127.0.0.1
|
||||
// protocol: TCP
|
||||
//
|
||||
// containerPort: 80
|
||||
// hostPort: 8000
|
||||
// listenAddress: 127.0.0.1
|
||||
// protocol: TCP
|
||||
type PortMapping struct {
|
||||
// Port within the container.
|
||||
ContainerPort int32
|
||||
|
|
Loading…
Reference in New Issue