From d3ee30be508cb4c94c200a092de7f16b5a7cc660 Mon Sep 17 00:00:00 2001 From: Nathan LeClaire Date: Wed, 22 Feb 2017 14:52:26 -0800 Subject: [PATCH] Add support for upgrade to new CE edition Signed-off-by: Nathan LeClaire --- libmachine/host/host.go | 53 ++++++++++++++++++++ libmachine/provision/arch.go | 2 + libmachine/provision/debian.go | 3 ++ libmachine/provision/pkgaction/pkg_action.go | 2 + libmachine/provision/provisioner.go | 4 ++ libmachine/provision/redhat.go | 13 ++--- libmachine/provision/ubuntu_systemd.go | 5 +- 7 files changed, 71 insertions(+), 11 deletions(-) diff --git a/libmachine/host/host.go b/libmachine/host/host.go index 284c6e9e..36015b27 100644 --- a/libmachine/host/host.go +++ b/libmachine/host/host.go @@ -7,6 +7,7 @@ import ( "github.com/docker/machine/libmachine/drivers" "github.com/docker/machine/libmachine/engine" "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcndockerclient" "github.com/docker/machine/libmachine/mcnerror" "github.com/docker/machine/libmachine/mcnutils" "github.com/docker/machine/libmachine/provision" @@ -15,6 +16,7 @@ import ( "github.com/docker/machine/libmachine/ssh" "github.com/docker/machine/libmachine/state" "github.com/docker/machine/libmachine/swarm" + "github.com/docker/machine/libmachine/versioncmp" ) var ( @@ -162,6 +164,24 @@ func (h *Host) Restart() error { return h.WaitForDocker() } +func (h *Host) DockerVersion() (string, error) { + url, err := h.Driver.GetURL() + if err != nil { + return "", err + } + + dockerHost := &mcndockerclient.RemoteDocker{ + HostURL: url, + AuthOption: h.AuthOptions(), + } + dockerVersion, err := mcndockerclient.DockerVersion(dockerHost) + if err != nil { + return "", err + } + + return dockerVersion, nil +} + func (h *Host) Upgrade() error { machineState, err := h.Driver.GetState() if err != nil { @@ -180,6 +200,39 @@ func (h *Host) Upgrade() error { return err } + dockerVersion, err := h.DockerVersion() + if err != nil { + return err + } + + // If we're upgrading from a pre-CE (e.g., 1.13.1) release to a CE + // release (e.g., 17.03.0-ce), we should simply uninstall and + // re-install from scratch, since the official package names will + // change from 'docker-engine' to 'docker-ce'. + if versioncmp.LessThanOrEqualTo(dockerVersion, provision.LastReleaseBeforeCEVersioning) && + // RancherOS and boot2docker, being 'static ISO builds', have + // an upgrade process which simply grabs the latest if it's + // different, and so do not need to jump through this hoop to + // upgrade safely. + provisioner.String() != "rancheros" && + provisioner.String() != "boot2docker" { + + // Name of pacakge 'docker-engine' will fall through in this + // case, so that we execute, e.g., + // + // 'sudo apt-get purge -y docker-engine' + if err := provisioner.Package("docker-engine", pkgaction.Purge); err != nil { + return err + } + + // Then we kick off the normal provisioning process which will + // go off and install Docker (get.docker.com script should work + // fine to install Docker from scratch after removing the old + // packages, and images/containers etc. should be preserved in + // /var/lib/docker) + return h.Provision() + } + log.Info("Upgrading docker...") if err := provisioner.Package("docker", pkgaction.Upgrade); err != nil { return err diff --git a/libmachine/provision/arch.go b/libmachine/provision/arch.go index d18670ba..4c60e312 100644 --- a/libmachine/provision/arch.go +++ b/libmachine/provision/arch.go @@ -51,6 +51,8 @@ func (provisioner *ArchProvisioner) Package(name string, action pkgaction.Packag } switch name { + case "docker-engine": + name = "docker" case "docker": name = "docker" } diff --git a/libmachine/provision/debian.go b/libmachine/provision/debian.go index 76301aab..b76c1f9e 100644 --- a/libmachine/provision/debian.go +++ b/libmachine/provision/debian.go @@ -44,6 +44,9 @@ func (provisioner *DebianProvisioner) Package(name string, action pkgaction.Pack case pkgaction.Remove: packageAction = "remove" updateMetadata = false + case pkgaction.Purge: + packageAction = "purge" + updateMetadata = false } switch name { diff --git a/libmachine/provision/pkgaction/pkg_action.go b/libmachine/provision/pkgaction/pkg_action.go index 643a9332..b7cf7e32 100644 --- a/libmachine/provision/pkgaction/pkg_action.go +++ b/libmachine/provision/pkgaction/pkg_action.go @@ -6,12 +6,14 @@ const ( Install PackageAction = iota Remove Upgrade + Purge ) var packageActions = []string{ "install", "remove", "upgrade", + "purge", } func (s PackageAction) String() string { diff --git a/libmachine/provision/provisioner.go b/libmachine/provision/provisioner.go index 81e005a0..81fc1ebe 100644 --- a/libmachine/provision/provisioner.go +++ b/libmachine/provision/provisioner.go @@ -17,6 +17,10 @@ var ( detector Detector = &StandardDetector{} ) +const ( + LastReleaseBeforeCEVersioning = "1.13.1" +) + type SSHCommander interface { // Short-hand for accessing an SSH command from the driver. SSHCommand(args string) (string, error) diff --git a/libmachine/provision/redhat.go b/libmachine/provision/redhat.go index a57e0d2e..ae6861ef 100644 --- a/libmachine/provision/redhat.go +++ b/libmachine/provision/redhat.go @@ -19,20 +19,11 @@ import ( var ( ErrUnknownYumOsRelease = errors.New("unknown OS for Yum repository") - - packageListTemplate = `[docker] -name=Docker Stable Repository -baseurl=https://yum.dockerproject.org/repo/main/{{.OsRelease}}/{{.OsReleaseVersion}} -priority=1 -enabled=1 -gpgkey=https://yum.dockerproject.org/gpg -` - engineConfigTemplate = `[Service] + engineConfigTemplate = `[Service] ExecStart= ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:{{.DockerPort}} -H unix:///var/run/docker.sock --storage-driver {{.EngineOptions.StorageDriver}} --tlsverify --tlscacert {{.AuthOptions.CaCertRemotePath}} --tlscert {{.AuthOptions.ServerCertRemotePath}} --tlskey {{.AuthOptions.ServerKeyRemotePath}} {{ range .EngineOptions.Labels }}--label {{.}} {{ end }}{{ range .EngineOptions.InsecureRegistry }}--insecure-registry {{.}} {{ end }}{{ range .EngineOptions.RegistryMirror }}--registry-mirror {{.}} {{ end }}{{ range .EngineOptions.ArbitraryFlags }}--{{.}} {{ end }} Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} ` - majorVersionRE = regexp.MustCompile(`^(\d+)(\..*)?`) ) @@ -95,6 +86,8 @@ func (provisioner *RedHatProvisioner) Package(name string, action pkgaction.Pack packageAction = "install" case pkgaction.Remove: packageAction = "remove" + case pkgaction.Purge: + packageAction = "remove" case pkgaction.Upgrade: packageAction = "upgrade" } diff --git a/libmachine/provision/ubuntu_systemd.go b/libmachine/provision/ubuntu_systemd.go index c178d3be..c99493af 100644 --- a/libmachine/provision/ubuntu_systemd.go +++ b/libmachine/provision/ubuntu_systemd.go @@ -60,11 +60,14 @@ func (provisioner *UbuntuSystemdProvisioner) Package(name string, action pkgacti case pkgaction.Remove: packageAction = "remove" updateMetadata = false + case pkgaction.Purge: + packageAction = "purge" + updateMetadata = false } switch name { case "docker": - name = "docker-engine" + name = "docker-ce" } if updateMetadata {