diff --git a/libmachine/provision/boot2docker.go b/libmachine/provision/boot2docker.go index 1486181b7b..485cfb852e 100644 --- a/libmachine/provision/boot2docker.go +++ b/libmachine/provision/boot2docker.go @@ -172,6 +172,10 @@ func (provisioner *Boot2DockerProvisioner) SetOsReleaseInfo(info *OsRelease) { provisioner.OsReleaseInfo = info } +func (provisioner *Boot2DockerProvisioner) GetOsReleaseInfo() (*OsRelease, error) { + return provisioner.OsReleaseInfo, nil +} + func (provisioner *Boot2DockerProvisioner) Provision(swarmOptions swarm.SwarmOptions, authOptions auth.AuthOptions, engineOptions engine.EngineOptions) error { provisioner.SwarmOptions = swarmOptions provisioner.AuthOptions = authOptions diff --git a/libmachine/provision/centos.go b/libmachine/provision/centos.go index 8226cd1ab9..b348e005e0 100644 --- a/libmachine/provision/centos.go +++ b/libmachine/provision/centos.go @@ -4,13 +4,6 @@ import ( "github.com/docker/machine/drivers" ) -const ( - // TODO: eventually the RPM install process will be integrated - // into the get.docker.com install script; for now - // we install via vendored RPMs - dockerCentosRPMPath = "https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.centos.x86_64.rpm" -) - func init() { Register("Centos", &RegisteredProvisioner{ New: NewCentosProvisioner, @@ -28,7 +21,6 @@ func NewCentosProvisioner(d drivers.Driver) Provisioner { p := &CentosProvisioner{ RedHatProvisioner{ GenericProvisioner: g, - DockerRPMPath: dockerCentosRPMPath, }, } return p diff --git a/libmachine/provision/centos_test.go b/libmachine/provision/centos_test.go new file mode 100644 index 0000000000..df6bfc9653 --- /dev/null +++ b/libmachine/provision/centos_test.go @@ -0,0 +1,28 @@ +package provision + +import ( + "regexp" + "testing" +) + +func TestCentosGenerateYumRepoList(t *testing.T) { + info := &OsRelease{ + Id: "centos", + } + p := NewCentosProvisioner(nil) + p.SetOsReleaseInfo(info) + + buf, err := generateYumRepoList(p) + if err != nil { + t.Fatal(err) + } + + m, err := regexp.MatchString(".*centos/7.*", buf.String()) + if err != nil { + t.Fatal(err) + } + + if !m { + t.Fatalf("expected match for centos/7") + } +} diff --git a/libmachine/provision/fedora.go b/libmachine/provision/fedora.go index 1b71cb6232..a201fe7a9d 100644 --- a/libmachine/provision/fedora.go +++ b/libmachine/provision/fedora.go @@ -4,13 +4,6 @@ import ( "github.com/docker/machine/drivers" ) -const ( - // TODO: eventually the RPM install process will be integrated - // into the get.docker.com install script; for now - // we install via vendored RPMs - dockerFedoraRPMPath = "https://get.docker.com/rpm/1.7.0/fedora-21/RPMS/x86_64/docker-engine-1.7.0-1.fc21.x86_64.rpm" -) - func init() { Register("Fedora", &RegisteredProvisioner{ New: NewFedoraProvisioner, @@ -28,7 +21,6 @@ func NewFedoraProvisioner(d drivers.Driver) Provisioner { p := &FedoraProvisioner{ RedHatProvisioner{ GenericProvisioner: g, - DockerRPMPath: dockerFedoraRPMPath, }, } return p diff --git a/libmachine/provision/fedora_test.go b/libmachine/provision/fedora_test.go new file mode 100644 index 0000000000..8bc0180393 --- /dev/null +++ b/libmachine/provision/fedora_test.go @@ -0,0 +1,28 @@ +package provision + +import ( + "regexp" + "testing" +) + +func TestFedoraGenerateYumRepoList(t *testing.T) { + info := &OsRelease{ + Id: "fedora", + } + p := NewCentosProvisioner(nil) + p.SetOsReleaseInfo(info) + + buf, err := generateYumRepoList(p) + if err != nil { + t.Fatal(err) + } + + m, err := regexp.MatchString(".*fedora/22.*", buf.String()) + if err != nil { + t.Fatal(err) + } + + if !m { + t.Fatalf("expected match for fedora/22") + } +} diff --git a/libmachine/provision/generic.go b/libmachine/provision/generic.go index 04ab390029..1b174f24b1 100644 --- a/libmachine/provision/generic.go +++ b/libmachine/provision/generic.go @@ -68,6 +68,10 @@ func (provisioner *GenericProvisioner) SetOsReleaseInfo(info *OsRelease) { provisioner.OsReleaseInfo = info } +func (provisioner *GenericProvisioner) GetOsReleaseInfo() (*OsRelease, error) { + return provisioner.OsReleaseInfo, nil +} + func (provisioner *GenericProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) { var ( engineCfg bytes.Buffer diff --git a/libmachine/provision/provisioner.go b/libmachine/provision/provisioner.go index 0ed994b155..3d0184432a 100644 --- a/libmachine/provision/provisioner.go +++ b/libmachine/provision/provisioner.go @@ -56,6 +56,9 @@ type Provisioner interface { // Set the OS Release info depending on how it's represented // internally SetOsReleaseInfo(info *OsRelease) + + // Get the OS Release info for the current provisioner + GetOsReleaseInfo() (*OsRelease, error) } // Detection diff --git a/libmachine/provision/redhat.go b/libmachine/provision/redhat.go index 271e5d5ee1..ec199da6fb 100644 --- a/libmachine/provision/redhat.go +++ b/libmachine/provision/redhat.go @@ -2,6 +2,7 @@ package provision import ( "bytes" + "errors" "fmt" "text/template" @@ -15,13 +16,31 @@ import ( "github.com/docker/machine/utils" ) -const ( - // TODO: eventually the RPM install process will be integrated - // into the get.docker.com install script; for now - // we install via vendored RPMs - dockerRHELRPMPath = "https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.centos.x86_64.rpm" +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] +ExecStart=/usr/bin/docker -d -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 }} +MountFlags=slave +LimitNOFILE=1048576 +LimitNPROC=1048576 +LimitCORE=infinity +Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} +` ) +type PackageListInfo struct { + OsRelease string + OsReleaseVersion string +} + func init() { Register("RedHat", &RegisteredProvisioner{ New: NewRedHatProvisioner, @@ -39,13 +58,11 @@ func NewRedHatProvisioner(d drivers.Driver) Provisioner { }, Driver: d, }, - DockerRPMPath: dockerRHELRPMPath, } } type RedHatProvisioner struct { GenericProvisioner - DockerRPMPath string } func (provisioner *RedHatProvisioner) SSHCommand(args string) (string, error) { @@ -155,7 +172,11 @@ func installDocker(provisioner *RedHatProvisioner) error { func (provisioner *RedHatProvisioner) installOfficialDocker() error { log.Debug("installing docker") - if _, err := provisioner.SSHCommand(fmt.Sprintf("sudo yum install -y --nogpgcheck %s", provisioner.DockerRPMPath)); err != nil { + if err := provisioner.ConfigurePackageList(); err != nil { + return err + } + + if _, err := provisioner.SSHCommand("sudo yum install -y docker-engine"); err != nil { return err } @@ -230,25 +251,12 @@ func (provisioner *RedHatProvisioner) GenerateDockerOptions(dockerPort int) (*Do configPath = provisioner.DaemonOptionsFile ) - // remove existing - //if _, err := provisioner.SSHCommand(fmt.Sprintf("sudo rm %s", configPath)); err != nil { - // return nil, err - //} - driverNameLabel := fmt.Sprintf("provider=%s", provisioner.Driver.DriverName()) provisioner.EngineOptions.Labels = append(provisioner.EngineOptions.Labels, driverNameLabel) // systemd / redhat will not load options if they are on newlines // instead, it just continues with a different set of options; yeah... - engineConfigTmpl := `[Service] -ExecStart=/usr/bin/docker -d -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 }} -MountFlags=slave -LimitNOFILE=1048576 -LimitNPROC=1048576 -LimitCORE=infinity -Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} -` - t, err := template.New("engineConfig").Parse(engineConfigTmpl) + t, err := template.New("engineConfig").Parse(engineConfigTemplate) if err != nil { return nil, err } @@ -268,3 +276,53 @@ Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}} EngineOptionsPath: daemonOptsDir, }, nil } + +func generateYumRepoList(provisioner Provisioner) (*bytes.Buffer, error) { + packageListInfo := &PackageListInfo{} + + releaseInfo, err := provisioner.GetOsReleaseInfo() + if err != nil { + return nil, err + } + + switch releaseInfo.Id { + case "rhel", "centos": + // rhel and centos both use the "centos" repo + packageListInfo.OsRelease = "centos" + packageListInfo.OsReleaseVersion = "7" + case "fedora": + packageListInfo.OsRelease = "fedora" + packageListInfo.OsReleaseVersion = "22" + default: + return nil, ErrUnknownYumOsRelease + } + + t, err := template.New("packageList").Parse(packageListTemplate) + if err != nil { + return nil, err + } + + var buf bytes.Buffer + + if err := t.Execute(&buf, packageListInfo); err != nil { + return nil, err + } + + return &buf, nil +} + +func (provisioner *RedHatProvisioner) ConfigurePackageList() error { + buf, err := generateYumRepoList(provisioner) + if err != nil { + return err + } + + // we cannot use %q here as it combines the newlines in the formatting + // on transport causing yum to not use the repo + packageCmd := fmt.Sprintf("echo \"%s\" | sudo tee /etc/yum.repos.d/docker.repo", buf.String()) + if _, err := provisioner.SSHCommand(packageCmd); err != nil { + return err + } + + return nil +} diff --git a/libmachine/provision/redhat_test.go b/libmachine/provision/redhat_test.go new file mode 100644 index 0000000000..27d0f46706 --- /dev/null +++ b/libmachine/provision/redhat_test.go @@ -0,0 +1,28 @@ +package provision + +import ( + "regexp" + "testing" +) + +func TestRedHatGenerateYumRepoList(t *testing.T) { + info := &OsRelease{ + Id: "rhel", + } + p := NewRedHatProvisioner(nil) + p.SetOsReleaseInfo(info) + + buf, err := generateYumRepoList(p) + if err != nil { + t.Fatal(err) + } + + m, err := regexp.MatchString(".*centos/7.*", buf.String()) + if err != nil { + t.Fatal(err) + } + + if !m { + t.Fatalf("expected match for centos/7") + } +}