Install container runtime packages as assets - Misc

This commit is contained in:
Ciprian Hacman 2020-10-14 08:31:46 +03:00
parent 732a161313
commit 852bebe165
5 changed files with 66 additions and 118 deletions

View File

@ -20,6 +20,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"k8s.io/klog/v2"
@ -598,29 +599,31 @@ func (c *NodeupModelContext) GetPrivateKey(name string) ([]byte, error) {
func (b *NodeupModelContext) AddCNIBinAssets(c *fi.ModelBuilderContext, assetNames []string) error {
for _, assetName := range assetNames {
if err := b.addCNIBinAsset(c, assetName); err != nil {
re, err := regexp.Compile(fmt.Sprintf("^%s$", assetName))
if err != nil {
return err
}
if err := b.addCNIBinAsset(c, re); err != nil {
return err
}
}
return nil
}
func (b *NodeupModelContext) addCNIBinAsset(c *fi.ModelBuilderContext, assetName string) error {
assetPath := ""
asset, err := b.Assets.Find(assetName, assetPath)
if err != nil {
return fmt.Errorf("error trying to locate asset %q: %v", assetName, err)
}
if asset == nil {
return fmt.Errorf("unable to locate asset %q", assetName)
func (b *NodeupModelContext) addCNIBinAsset(c *fi.ModelBuilderContext, assetPath *regexp.Regexp) error {
a := b.Assets.FindMatches(assetPath)
if len(a) != 1 {
return fmt.Errorf("unable to locate asset %q", assetPath.String())
}
c.AddTask(&nodetasks.File{
Path: filepath.Join(b.CNIBinDir(), assetName),
Contents: asset,
Type: nodetasks.FileType_File,
Mode: fi.String("0755"),
})
for k, v := range a {
c.AddTask(&nodetasks.File{
Path: filepath.Join(b.CNIBinDir(), k),
Contents: v,
Type: nodetasks.FileType_File,
Mode: fi.String("0755"),
})
}
return nil
}

View File

@ -21,13 +21,10 @@ import (
"sort"
"strconv"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/architectures"
"k8s.io/kops/util/pkg/distributions"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
)
// s is a helper that builds a *string from a string value
@ -109,77 +106,3 @@ func addHostPathVolume(pod *v1.Pod, container *v1.Container, hostPath v1.HostPat
func convEtcdSettingsToMs(dur *metav1.Duration) string {
return strconv.FormatInt(dur.Nanoseconds()/1000000, 10)
}
// packageInfo - fields required for extra packages setup
type packageInfo struct {
Version string // Package version
Source string // URL to download the package from
Hash string // sha1sum of the package file
}
// packageVersion - fields required for downloaded packages setup
type packageVersion struct {
Name string
// Version is the version of docker, as specified in the kops
Version string
// Source is the url where the package/tarfile can be found
Source string
// Hash is the sha1 hash of the file
Hash string
// Extra packages to install during the same dpkg/yum transaction.
// This is used for:
// - On RHEL/CentOS, the SELinux policy needs to be installed.
// - Starting from Docker 18.09, the Docker package has been split in 3
// separate packages: one for the daemon, one for the CLI, one for
// containerd. All 3 must be installed at the same time when
// upgrading from an older version of Docker.
ExtraPackages map[string]packageInfo
PackageVersion string
Distros []distributions.Distribution
// List of dependencies that can be installed using the system's package
// manager (e.g. apt-get install or yum install).
Dependencies []string
Architectures []architectures.Architecture
// PlainBinary indicates that the Source is not an OS, but a "bare" tar.gz
PlainBinary bool
// MapFiles is the list of files to extract with corresponding directories for PlainBinary
MapFiles map[string]string
// MarkImmutable is a list of files on which we should perform a `chattr +i <file>`
MarkImmutable []string
}
// Match package version against configured values
func (d *packageVersion) matches(arch architectures.Architecture, packageVersion string, distro distributions.Distribution) bool {
if d.PackageVersion != packageVersion {
return false
}
foundDistro := false
if len(d.Distros) > 0 {
for _, d := range d.Distros {
if d == distro {
foundDistro = true
}
}
} else {
// Distro list is empty, assuming ANY
foundDistro = true
}
if !foundDistro {
return false
}
foundArch := false
for _, a := range d.Architectures {
if a == arch {
foundArch = true
}
}
return foundArch
}

View File

@ -185,6 +185,10 @@ func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *fie
allErrs = append(allErrs, validateContainerRuntime(&spec.ContainerRuntime, fieldPath.Child("containerRuntime"))...)
}
if spec.Containerd != nil {
allErrs = append(allErrs, validateContainerdConfig(spec.Containerd, fieldPath.Child("containerd"))...)
}
if spec.Docker != nil {
allErrs = append(allErrs, validateDockerConfig(spec.Docker, fieldPath.Child("docker"))...)
}
@ -1055,16 +1059,37 @@ func validateContainerRuntime(runtime *string, fldPath *field.Path) field.ErrorL
return allErrs
}
func validateContainerdConfig(config *kops.ContainerdConfig, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if config.Version != nil {
sv, err := semver.ParseTolerant(*config.Version)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version,
fmt.Sprintf("unable to parse version string: %s", err.Error())))
}
if sv.LT(semver.MustParse("1.2.6")) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version, "unsupported legacy version"))
}
}
return allErrs
}
func validateDockerConfig(config *kops.DockerConfig, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if config.Version != nil {
if strings.HasPrefix(*config.Version, "1.1") {
sv, err := semver.ParseTolerant(*config.Version)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version,
"version is no longer available: https://www.docker.com/blog/changes-dockerproject-org-apt-yum-repositories/"))
} else {
valid := []string{"17.03.2", "17.09.0", "18.03.1", "18.06.1", "18.06.2", "18.06.3", "18.09.3", "18.09.9", "19.03.4", "19.03.8", "19.03.11", "19.03.13"}
allErrs = append(allErrs, IsValidValue(fldPath.Child("version"), config.Version, valid)...)
fmt.Sprintf("unable to parse version string: %s", err.Error())))
}
if sv.LT(semver.MustParse("1.14.0")) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version,
"version is no longer available: https://www.docker.com/blog/changes-dockerproject-org-apt-yum-repositories"))
} else if sv.LT(semver.MustParse("17.3.0")) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version, "unsupported legacy version"))
}
}

View File

@ -20,6 +20,8 @@ import (
"fmt"
"strings"
"github.com/blang/semver/v4"
"k8s.io/klog/v2"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
@ -80,26 +82,17 @@ func (b *ContainerdOptionsBuilder) BuildOptions(o interface{}) error {
}
} else if clusterSpec.ContainerRuntime == "docker" {
if fi.StringValue(containerd.Version) == "" {
// Docker version should always be available
if fi.StringValue(clusterSpec.Docker.Version) == "" {
return fmt.Errorf("docker version is required")
// Docker version should always be available
dockerVersion := fi.StringValue(clusterSpec.Docker.Version)
if dockerVersion == "" {
return fmt.Errorf("docker version is required")
} else {
// Skip containerd setup for older versions without containerd service
sv, err := semver.ParseTolerant(dockerVersion)
if err != nil {
return fmt.Errorf("unable to parse version string: %q", dockerVersion)
}
// Set the containerd version for known Docker versions
switch fi.StringValue(clusterSpec.Docker.Version) {
case "19.03.13":
containerd.Version = fi.String("1.3.7")
case "19.03.8", "19.03.11":
containerd.Version = fi.String("1.2.13")
case "19.03.4":
containerd.Version = fi.String("1.2.10")
case "18.09.9":
containerd.Version = fi.String("1.2.10")
case "18.09.3":
containerd.Version = fi.String("1.2.4")
default:
// Old version of docker, single package
if sv.LT(semver.MustParse("18.9.0")) {
containerd.SkipInstall = true
return nil
}

View File

@ -5,8 +5,10 @@ go_library(
srcs = [
"apply_cluster.go",
"bootstrapchannelbuilder.go",
"containerd.go",
"defaults.go",
"dns.go",
"docker.go",
"loader.go",
"networking.go",
"new_cluster.go",
@ -98,9 +100,11 @@ go_test(
size = "small",
srcs = [
"bootstrapchannelbuilder_test.go",
"containerd_test.go",
"deepvalidate_test.go",
"defaults_test.go",
"dns_test.go",
"docker_test.go",
"networking_test.go",
"new_cluster_test.go",
"populatecluster_test.go",