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  }