github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/nodeagent/dep/cri/dep.go (about) 1 package cri 2 3 import ( 4 "errors" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "os/exec" 9 "regexp" 10 "strings" 11 12 "github.com/caos/orbos/internal/operator/common" 13 "github.com/caos/orbos/internal/operator/nodeagent" 14 "github.com/caos/orbos/internal/operator/nodeagent/dep" 15 "github.com/caos/orbos/internal/operator/nodeagent/dep/middleware" 16 "github.com/caos/orbos/mntr" 17 ) 18 19 const installContainerdVersion = "1.4.3" 20 21 type Installer interface { 22 isCRI() 23 nodeagent.Installer 24 } 25 26 // TODO: Add support for containerd, cri-o, ... 27 type criDep struct { 28 monitor mntr.Monitor 29 os dep.OperatingSystemMajor 30 manager *dep.PackageManager 31 dockerVersionPrunerRegexp *regexp.Regexp 32 systemd *dep.SystemD 33 } 34 35 // New returns a dependency that implements the kubernetes container runtime interface 36 func New(monitor mntr.Monitor, os dep.OperatingSystemMajor, manager *dep.PackageManager, systemd *dep.SystemD) Installer { 37 return &criDep{monitor, os, manager, regexp.MustCompile(`\d+\.\d+\.\d+`), systemd} 38 } 39 40 func (criDep) Is(other nodeagent.Installer) bool { 41 _, ok := middleware.Unwrap(other).(Installer) 42 return ok 43 } 44 45 func (c criDep) isCRI() {} 46 47 func (c criDep) String() string { return "Container Runtime" } 48 49 func (s *criDep) Equals(other nodeagent.Installer) bool { 50 _, ok := other.(*criDep) 51 return ok 52 } 53 54 func (c *criDep) InstalledFilter() []string { 55 return []string{"docker-ce", "containerd.io", "device-mapper-persistent-data", "lvm2"} 56 } 57 58 func (c *criDep) Current() (pkg common.Package, err error) { 59 if !c.systemd.Active("docker") { 60 return pkg, err 61 } 62 63 var ( 64 dockerVersion string 65 containerdVersion string 66 ) 67 for _, installedPkg := range c.manager.CurrentVersions("docker-ce", "containerd.io") { 68 switch installedPkg.Package { 69 case "docker-ce": 70 dockerVersion = fmt.Sprintf("%s %s %s", dockerVersion, installedPkg.Package, "v"+c.dockerVersionPrunerRegexp.FindString(installedPkg.Version)) 71 continue 72 case "containerd.io": 73 containerdVersion = installedPkg.Version 74 continue 75 default: 76 panic(fmt.Errorf("unexpected installed package %s", installedPkg.Package)) 77 } 78 } 79 pkg.Version = strings.TrimSpace(dockerVersion) 80 if !strings.Contains(containerdVersion, "1.4.3") { 81 if pkg.Config == nil { 82 pkg.Config = map[string]string{} 83 } 84 pkg.Config["containerd.io"] = containerdVersion 85 } else { 86 // Deprecated Code: Ensure existing containerd versions get locked 87 // TODO: Remove in ORBOS v4 88 lock, err := exec.Command("yum", "versionlock", "list").Output() 89 if err != nil { 90 return pkg, err 91 } 92 if !strings.Contains(string(lock), "containerd.io-1.4.3") { 93 if pkg.Config == nil { 94 pkg.Config = map[string]string{} 95 } 96 pkg.Config["containerd.io"] = containerdVersion 97 } 98 } 99 100 daemonJson, _ := ioutil.ReadFile("/etc/docker/daemon.json") 101 if pkg.Config == nil { 102 pkg.Config = map[string]string{} 103 } 104 pkg.Config["daemon.json"] = string(daemonJson) 105 return pkg, nil 106 } 107 108 func (c *criDep) Ensure(_ common.Package, install common.Package, leaveOSRepositories bool) error { 109 110 if install.Config == nil { 111 return errors.New("Docker config is nil") 112 } 113 114 if err := os.MkdirAll("/etc/docker", 600); err != nil { 115 return err 116 } 117 118 if err := ioutil.WriteFile("/etc/docker/daemon.json", []byte(install.Config["daemon.json"]), 600); err != nil { 119 return err 120 } 121 122 fields := strings.Fields(install.Version) 123 if len(fields) != 2 { 124 return fmt.Errorf("container runtime must have the form [runtime] [version], but got %s", install) 125 } 126 127 if fields[0] != "docker-ce" { 128 return errors.New("Only docker-ce is supported yet") 129 } 130 131 version := strings.TrimLeft(fields[1], "v") 132 133 switch c.os.OperatingSystem { 134 case dep.Ubuntu: 135 return c.ensureUbuntu(fields[0], version, leaveOSRepositories) 136 case dep.CentOS: 137 return c.ensureCentOS(fields[0], version, leaveOSRepositories) 138 } 139 return fmt.Errorf("operating system %s is not supported", c.os) 140 }