提交 7758108e 编写于 作者: D dlorenc

Update docker-machine.

上级 8c64068a
{
"ImportPath": "k8s.io/minikube",
"GoVersion": "go1.7",
"GodepVersion": "v75",
"GoVersion": "go1.6",
"GodepVersion": "v74",
"Packages": [
"./..."
],
......@@ -810,158 +810,163 @@
},
{
"ImportPath": "github.com/docker/machine/commands/mcndirs",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/drivers/errdriver",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/drivers/hyperv",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/drivers/none",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/drivers/virtualbox",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/drivers/vmwarefusion",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/auth",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/cert",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/check",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/drivers",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/drivers/plugin",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/drivers/plugin/localbinary",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/drivers/rpc",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/engine",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/host",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/log",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/mcndockerclient",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/mcnerror",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/mcnflag",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/mcnutils",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/persist",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/provision",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/provision/pkgaction",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/provision/serviceaction",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/shell",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/ssh",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/state",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/swarm",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/version",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/libmachine/versioncmp",
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/machine/version",
"Comment": "docs-v0.8.2-2016-09-26-11-g91e368e",
"Rev": "91e368eb7422665278b1d5665139ee0f9980b588"
"Comment": "docs-v0.8.2-2016-09-26-84-g23ae711",
"Rev": "23ae71164f2ee083f360d25250398deaa0a34c68"
},
{
"ImportPath": "github.com/docker/spdystream",
......
......@@ -140,13 +140,13 @@ func listHostOnlyAdapters(vbox VBoxManager) (map[string]*hostOnlyNetwork, error)
n.NetworkName = val
if _, present := byName[n.NetworkName]; present {
return fmt.Errorf("VirtualBox is configured with multiple host-only adapters with the same name %q. Please remove one.", n.NetworkName)
return fmt.Errorf("VirtualBox is configured with multiple host-only adapters with the same name %q. Please remove one", n.NetworkName)
}
byName[n.NetworkName] = n
if len(n.IPv4.IP) != 0 {
if _, present := byIP[n.IPv4.IP.String()]; present {
return fmt.Errorf("VirtualBox is configured with multiple host-only adapters with the same IP %q. Please remove one.", n.IPv4.IP)
return fmt.Errorf("VirtualBox is configured with multiple host-only adapters with the same IP %q. Please remove one", n.IPv4.IP)
}
byIP[n.IPv4.IP.String()] = n
}
......
......@@ -69,6 +69,7 @@ type Driver struct {
NoShare bool
DNSProxy bool
NoVTXCheck bool
ShareFolder string
}
// NewDriver creates a new VirtualBox driver with default settings.
......@@ -190,6 +191,11 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
Usage: "Disable checking for the availability of hardware virtualization before the vm is started",
EnvVar: "VIRTUALBOX_NO_VTX_CHECK",
},
mcnflag.StringFlag{
EnvVar: "VIRTUALBOX_SHARE_FOLDER",
Name: "virtualbox-share-folder",
Usage: "Mount the specified directory instead of the default home location. Format: dir:name",
},
}
}
......@@ -242,6 +248,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.NoShare = flags.Bool("virtualbox-no-share")
d.DNSProxy = !flags.Bool("virtualbox-no-dns-proxy")
d.NoVTXCheck = flags.Bool("virtualbox-no-vtx-check")
d.ShareFolder = flags.String("virtualbox-share-folder")
return nil
}
......@@ -448,6 +455,11 @@ func (d *Driver) CreateVM() error {
shareName, shareDir := getShareDriveAndName()
if d.ShareFolder != "" {
split := strings.Split(d.ShareFolder, ":")
shareDir, shareName = split[0], split[1]
}
if shareDir != "" && !d.NoShare {
log.Debugf("setting up shareDir")
if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) {
......
package virtualbox
import (
"bytes"
"io/ioutil"
"github.com/docker/machine/libmachine/log"
)
// IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start.
// If we can't be sure it is disabled, we carry on and will check the vm logs after it's started.
// We want to check that either vmx or svm flags are present in /proc/cpuinfo.
func (d *Driver) IsVTXDisabled() bool {
cpuinfo, err := ioutil.ReadFile("/proc/cpuinfo")
if err != nil {
log.Debugf("Couldn't check that VT-X/AMD-v is enabled. Will check that the vm is properly created: %v", err)
return false
}
return isVTXDisabled(cpuinfo)
}
func isVTXDisabled(cpuinfo []byte) bool {
features := [2][]byte{
{'v', 'm', 'x'},
{'s', 'v', 'm'},
}
for _, v := range features {
if bytes.Contains(cpuinfo, v) {
return false
}
}
return true
}
func detectVBoxManageCmd() string {
return detectVBoxManageCmdInPath()
}
func getShareDriveAndName() (string, string) {
return "hosthome", "/home"
}
func isHyperVInstalled() bool {
return false
}
......@@ -40,7 +40,7 @@ func BootstrapCertificates(authOptions *auth.Options) error {
// check if the key path exists; if so, error
if _, err := os.Stat(caPrivateKeyPath); err == nil {
return errors.New("The CA key already exists. Please remove it or specify a different key/cert.")
return errors.New("certificate authority key already exists")
}
if err := GenerateCACertificate(caCertPath, caPrivateKeyPath, caOrg, bits); err != nil {
......@@ -54,7 +54,7 @@ func BootstrapCertificates(authOptions *auth.Options) error {
if _, err := os.Stat(certDir); err != nil {
if os.IsNotExist(err) {
if err := os.Mkdir(certDir, 0700); err != nil {
return fmt.Errorf("Creating machine client cert dir failed: %s", err)
return fmt.Errorf("failure creating machine client cert dir: %s", err)
}
} else {
return err
......@@ -63,7 +63,7 @@ func BootstrapCertificates(authOptions *auth.Options) error {
// check if the key path exists; if so, error
if _, err := os.Stat(clientKeyPath); err == nil {
return errors.New("The client key already exists. Please remove it or specify a different key/cert.")
return errors.New("client key already exists")
}
// Used to generate the client certificate.
......@@ -79,7 +79,7 @@ func BootstrapCertificates(authOptions *auth.Options) error {
}
if err := GenerateCert(certOptions); err != nil {
return fmt.Errorf("Generating client certificate failed: %s", err)
return fmt.Errorf("failure generating client certificate: %s", err)
}
}
......
......@@ -257,7 +257,7 @@ func (xcg *X509CertGenerator) ValidateCertificate(addr string, authOptions *auth
}
dialer := &net.Dialer{
Timeout: time.Second * 2,
Timeout: time.Second * 20,
}
_, err = tls.DialWithDialer(dialer, "tcp", addr, tlsConfig)
......
......@@ -17,7 +17,7 @@ var (
// plugin server.
defaultTimeout = 10 * time.Second
CurrentBinaryIsDockerMachine = false
CoreDrivers = [...]string{"amazonec2", "azure", "digitalocean",
CoreDrivers = []string{"amazonec2", "azure", "digitalocean",
"exoscale", "generic", "google", "hyperv", "none", "openstack",
"rackspace", "softlayer", "virtualbox", "vmwarefusion",
"vmwarevcloudair", "vmwarevsphere"}
......@@ -85,10 +85,11 @@ type Executor struct {
type ErrPluginBinaryNotFound struct {
driverName string
driverPath string
}
func (e ErrPluginBinaryNotFound) Error() string {
return fmt.Sprintf("Driver %q not found. Do you have the plugin binary accessible in your PATH?", e.driverName)
return fmt.Sprintf("Driver %q not found. Do you have the plugin binary %q accessible in your PATH?", e.driverName, e.driverPath)
}
// driverPath finds the path of a driver binary by its name.
......@@ -114,7 +115,7 @@ func NewPlugin(driverName string) (*Plugin, error) {
driverPath := driverPath(driverName)
binaryPath, err := exec.LookPath(driverPath)
if err != nil {
return nil, ErrPluginBinaryNotFound{driverName}
return nil, ErrPluginBinaryNotFound{driverName, driverPath}
}
log.Debugf("Found binary path at %s", binaryPath)
......
......@@ -44,11 +44,10 @@ func RunSSHCommandFromDriver(d Driver, command string) (string, error) {
output, err := client.Output(command)
log.Debugf("SSH cmd err, output: %v: %s", err, output)
if err != nil {
return "", fmt.Errorf(`Something went wrong running an SSH command!
return "", fmt.Errorf(`ssh command error:
command : %s
err : %v
output : %s
`, command, err, output)
output : %s`, command, err, output)
}
return output, nil
......
......@@ -20,7 +20,7 @@ import (
var (
validHostNamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9\-\.]*$`)
errMachineMustBeRunningForUpgrade = errors.New("Error: machine must be running to upgrade.")
errMachineMustBeRunningForUpgrade = errors.New("machine must be running to upgrade")
stdSSHClientCreator SSHClientCreator = &StandardSSHClientCreator{}
)
......
......@@ -12,7 +12,7 @@ import (
)
var (
errConfigFromFuture = errors.New("Config version is from the future, please upgrade your Docker Machine client.")
errConfigFromFuture = errors.New("config version is from the future -- you should upgrade your Docker Machine client")
)
type RawDataDriver struct {
......
......@@ -6,12 +6,17 @@ var CurrentDockerVersioner DockerVersioner = &defaultDockerVersioner{}
type DockerVersioner interface {
DockerVersion(host DockerHost) (string, error)
DockerAPIVersion(host DockerHost) (string, error)
}
func DockerVersion(host DockerHost) (string, error) {
return CurrentDockerVersioner.DockerVersion(host)
}
func DockerAPIVersion(host DockerHost) (string, error) {
return CurrentDockerVersioner.DockerAPIVersion(host)
}
type defaultDockerVersioner struct{}
func (dv *defaultDockerVersioner) DockerVersion(host DockerHost) (string, error) {
......@@ -27,3 +32,17 @@ func (dv *defaultDockerVersioner) DockerVersion(host DockerHost) (string, error)
return version.Version, nil
}
func (dv *defaultDockerVersioner) DockerAPIVersion(host DockerHost) (string, error) {
client, err := DockerClient(host)
if err != nil {
return "", fmt.Errorf("Unable to query docker API version: %s", err)
}
version, err := client.Version()
if err != nil {
return "", fmt.Errorf("Unable to query docker API version: %s", err)
}
return version.ApiVersion, nil
}
package mcndockerclient
type FakeDockerVersioner struct {
Version string
Err error
Version string
APIVersion string
Err error
}
func (dv *FakeDockerVersioner) DockerVersion(host DockerHost) (string, error) {
......@@ -12,3 +13,11 @@ func (dv *FakeDockerVersioner) DockerVersion(host DockerHost) (string, error) {
return dv.Version, nil
}
func (dv *FakeDockerVersioner) DockerAPIVersion(host DockerHost) (string, error) {
if dv.Err != nil {
return "", dv.Err
}
return dv.APIVersion, nil
}
......@@ -33,8 +33,7 @@ var (
)
var (
errGitHubAPIResponse = errors.New(`Error getting a version tag from the Github API response.
You may be getting rate limited by Github.`)
errGitHubAPIResponse = errors.New(`failure getting a version tag from the Github API response (are you getting rate limited by Github?)`)
)
var (
......
......@@ -43,13 +43,11 @@ func (provisioner *ArchProvisioner) Package(name string, action pkgaction.Packag
updateMetadata := true
switch action {
case pkgaction.Install:
case pkgaction.Install, pkgaction.Upgrade:
packageAction = "S"
case pkgaction.Remove:
packageAction = "R"
updateMetadata = false
case pkgaction.Upgrade:
packageAction = "U"
}
switch name {
......
......@@ -197,7 +197,7 @@ func (provisioner *Boot2DockerProvisioner) AttemptIPContact(dockerPort int) {
return
}
if conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, dockerPort), 20*time.Second); err != nil {
if conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, dockerPort), 5*time.Second); err != nil {
log.Warnf(`
This machine has been allocated an IP address, but Docker Machine could not
reach it successfully.
......
......@@ -11,6 +11,7 @@ import (
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/provision/pkgaction"
"github.com/docker/machine/libmachine/swarm"
"github.com/docker/machine/libmachine/versioncmp"
)
const (
......@@ -64,6 +65,16 @@ func (provisioner *CoreOSProvisioner) GenerateDockerOptions(dockerPort int) (*Do
driverNameLabel := fmt.Sprintf("provider=%s", provisioner.Driver.DriverName())
provisioner.EngineOptions.Labels = append(provisioner.EngineOptions.Labels, driverNameLabel)
dockerVersion, err := DockerClientVersion(provisioner)
if err != nil {
return nil, err
}
arg := "daemon"
if versioncmp.GreaterThanOrEqualTo(dockerVersion, "1.12.0") {
arg = ""
}
engineConfigTmpl := `[Unit]
Description=Docker Socket for the API
After=docker.socket early-docker.target network.target
......@@ -75,7 +86,7 @@ EnvironmentFile=-/run/flannel_docker_opts.env
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
ExecStart=/usr/lib/coreos/dockerd daemon --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:{{.DockerPort}} --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 }} \$DOCKER_OPTS \$DOCKER_OPT_BIP \$DOCKER_OPT_MTU \$DOCKER_OPT_IPMASQ
ExecStart=/usr/lib/coreos/dockerd ` + arg + ` --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:{{.DockerPort}} --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 }} \$DOCKER_OPTS \$DOCKER_OPT_BIP \$DOCKER_OPT_MTU \$DOCKER_OPT_IPMASQ
Environment={{range .EngineOptions.Env}}{{ printf "%q" . }} {{end}}
[Install]
......
......@@ -33,7 +33,7 @@ After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/docker daemon -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 }}
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 }}
ExecReload=/bin/kill -s HUP $MAINPID
MountFlags=slave
LimitNOFILE=infinity
......@@ -91,7 +91,6 @@ func (provisioner *RedHatProvisioner) SetHostname(hostname string) error {
return err
}
// ubuntu/debian use 127.0.1.1 for non "localhost" loopback hostnames: https://www.debian.org/doc/manuals/debian-reference/ch05.en.html#_the_hostname_resolution
if _, err := provisioner.SSHCommand(fmt.Sprintf(
"if grep -xq 127.0.1.1.* /etc/hosts; then sudo sed -i 's/^127.0.1.1.*/127.0.1.1 %s/g' /etc/hosts; else echo '127.0.1.1 %s' | sudo tee -a /etc/hosts; fi",
hostname,
......
......@@ -35,11 +35,10 @@ func (sshCmder RedHatSSHCommander) SSHCommand(args string) (string, error) {
log.Debugf("SSH cmd err, output: %v: %s", err, output)
if err != nil {
return "", fmt.Errorf(`Something went wrong running an SSH command!
return "", fmt.Errorf(`something went wrong running an SSH command
command : %s
err : %v
output : %s
`, args, err, output)
output : %s`, args, err, output)
}
return output, nil
......
package provision
import (
"bytes"
"fmt"
"text/template"
"strings"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/drivers"
......@@ -27,82 +26,34 @@ func init() {
})
}
func NewOpenSUSEProvisioner(d drivers.Driver) Provisioner {
func NewSLEDProvisioner(d drivers.Driver) Provisioner {
return &SUSEProvisioner{
GenericProvisioner{
SSHCommander: GenericSSHCommander{Driver: d},
DockerOptionsDir: "/etc/docker",
DaemonOptionsFile: "/etc/sysconfig/docker",
OsReleaseID: "opensuse",
Packages: []string{
"curl",
},
Driver: d,
},
NewSystemdProvisioner("sled", d),
}
}
func NewSLEDProvisioner(d drivers.Driver) Provisioner {
func NewSLESProvisioner(d drivers.Driver) Provisioner {
return &SUSEProvisioner{
GenericProvisioner{
SSHCommander: GenericSSHCommander{Driver: d},
DockerOptionsDir: "/etc/docker",
DaemonOptionsFile: "/etc/sysconfig/docker",
OsReleaseID: "sled",
Packages: []string{
"curl",
},
Driver: d,
},
NewSystemdProvisioner("sles", d),
}
}
func NewSLESProvisioner(d drivers.Driver) Provisioner {
func NewOpenSUSEProvisioner(d drivers.Driver) Provisioner {
return &SUSEProvisioner{
GenericProvisioner{
SSHCommander: GenericSSHCommander{Driver: d},
DockerOptionsDir: "/etc/docker",
DaemonOptionsFile: "/etc/sysconfig/docker",
OsReleaseID: "sles",
Packages: []string{
"curl",
},
Driver: d,
},
NewSystemdProvisioner("openSUSE", d),
}
}
type SUSEProvisioner struct {
GenericProvisioner
SystemdProvisioner
}
func (provisioner *SUSEProvisioner) String() string {
return "suse"
func (provisioner *SUSEProvisioner) CompatibleWithHost() bool {
return strings.ToLower(provisioner.OsReleaseInfo.ID) == strings.ToLower(provisioner.OsReleaseID)
}
func (provisioner *SUSEProvisioner) Service(name string, action serviceaction.ServiceAction) error {
reloadDaemon := false
switch action {
case serviceaction.Start, serviceaction.Restart:
reloadDaemon = true
}
// systemd needs reloaded when config changes on disk; we cannot
// be sure exactly when it changes from the provisioner so
// we call a reload on every restart to be safe
if reloadDaemon {
if _, err := provisioner.SSHCommand("sudo systemctl daemon-reload"); err != nil {
return err
}
}
command := fmt.Sprintf("sudo systemctl %s %s", action.String(), name)
if _, err := provisioner.SSHCommand(command); err != nil {
return err
}
return nil
func (provisioner *SUSEProvisioner) String() string {
return "openSUSE"
}
func (provisioner *SUSEProvisioner) Package(name string, action pkgaction.PackageAction) error {
......@@ -110,15 +61,17 @@ func (provisioner *SUSEProvisioner) Package(name string, action pkgaction.Packag
switch action {
case pkgaction.Install:
packageAction = "install"
packageAction = "in"
case pkgaction.Remove:
packageAction = "remove"
packageAction = "rm"
case pkgaction.Upgrade:
packageAction = "upgrade"
packageAction = "up"
}
command := fmt.Sprintf("sudo -E zypper -n %s %s", packageAction, name)
log.Debugf("zypper: action=%s name=%s", action.String(), name)
if _, err := provisioner.SSHCommand(command); err != nil {
return err
}
......@@ -145,96 +98,97 @@ func (provisioner *SUSEProvisioner) Provision(swarmOptions swarm.Options, authOp
provisioner.EngineOptions = engineOptions
swarmOptions.Env = engineOptions.Env
// figure out the filesytem used by /var/lib
fs, err := provisioner.SSHCommand("stat -f -c %T /var/lib/")
if err != nil {
return err
}
graphDriver := "overlay"
if strings.Contains(fs, "btrfs") {
graphDriver = "btrfs"
}
storageDriver, err := decideStorageDriver(provisioner, graphDriver, engineOptions.StorageDriver)
if err != nil {
return err
}
provisioner.EngineOptions.StorageDriver = storageDriver
log.Debug("Setting hostname")
if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil {
return err
}
if strings.ToLower(provisioner.OsReleaseInfo.ID) != "opensuse" {
// This is a SLE machine, enable the containers module to have access
// to the docker packages
if _, err := provisioner.SSHCommand("sudo -E SUSEConnect -p sle-module-containers/12/x86_64 -r ''"); err != nil {
return fmt.Errorf(
"Error while adding the 'containers' module, make sure this machine is registered either against SUSE Customer Center (SCC) or to a local Subscription Management Tool (SMT): %v",
err)
}
}
log.Debug("Installing base packages")
for _, pkg := range provisioner.Packages {
if err := provisioner.Package(pkg, pkgaction.Install); err != nil {
return err
}
}
// update OS -- this is needed for libdevicemapper and the docker install
if _, err := provisioner.SSHCommand("sudo zypper ref"); err != nil {
return err
}
if _, err := provisioner.SSHCommand("sudo zypper -n update"); err != nil {
log.Debug("Installing docker")
if err := provisioner.Package("docker", pkgaction.Install); err != nil {
return err
}
if err := installDockerGeneric(provisioner, engineOptions.InstallURL); err != nil {
// create symlinks for containerd, containerd-shim and runc.
// We have to do that because machine overrides the openSUSE systemd
// unit of docker
if _, err := provisioner.SSHCommand("sudo -E ln -s /usr/sbin/runc /usr/sbin/docker-runc"); err != nil {
return err
}
if _, err := provisioner.SSHCommand("sudo systemctl start docker"); err != nil {
if _, err := provisioner.SSHCommand("sudo -E ln -s /usr/sbin/containerd /usr/sbin/docker-containerd"); err != nil {
return err
}
if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil {
if _, err := provisioner.SSHCommand("sudo -E ln -s /usr/sbin/containerd-shim /usr/sbin/docker-containerd-shim"); err != nil {
return err
}
if _, err := provisioner.SSHCommand("sudo systemctl stop docker"); err != nil {
return err
// Is yast2 firewall installed?
if _, installed := provisioner.SSHCommand("rpm -q yast2-firewall"); installed == nil {
// Open the firewall port required by docker
if _, err := provisioner.SSHCommand("sudo -E /sbin/yast2 firewall services add ipprotocol=tcp tcpport=2376 zone=EXT"); err != nil {
return err
}
}
// open firewall port required by docker
if _, err := provisioner.SSHCommand("sudo /sbin/yast2 firewall services add ipprotocol=tcp tcpport=2376 zone=EXT"); err != nil {
log.Debug("Starting systemd docker service")
if err := provisioner.Service("docker", serviceaction.Start); err != nil {
return err
}
if err := makeDockerOptionsDir(provisioner); err != nil {
log.Debug("Waiting for docker daemon")
if err := mcnutils.WaitFor(provisioner.dockerDaemonResponding); err != nil {
return err
}
provisioner.AuthOptions = setRemoteAuthOptions(provisioner)
log.Debug("Configuring auth")
if err := ConfigureAuth(provisioner); err != nil {
return err
}
log.Debug("Configuring swarm")
if err := configureSwarm(provisioner, swarmOptions, provisioner.AuthOptions); err != nil {
return err
}
return nil
}
func (provisioner *SUSEProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptions, error) {
var (
engineCfg bytes.Buffer
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)
engineConfigTmpl := `# File automatically generated by docker-machine
DOCKER_OPTS=' -H tcp://0.0.0.0:{{.DockerPort}} {{ if .EngineOptions.StorageDriver }} --storage-driver {{.EngineOptions.StorageDriver}} {{ end }} --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 }}'
`
t, err := template.New("engineConfig").Parse(engineConfigTmpl)
if err != nil {
return nil, err
}
engineConfigContext := EngineConfigContext{
DockerPort: dockerPort,
AuthOptions: provisioner.AuthOptions,
EngineOptions: provisioner.EngineOptions,
DockerOptionsDir: provisioner.DockerOptionsDir,
// enable in systemd
log.Debug("Enabling docker in systemd")
if err := provisioner.Service("docker", serviceaction.Enable); err != nil {
return err
}
t.Execute(&engineCfg, engineConfigContext)
daemonOptsDir := configPath
return &DockerOptions{
EngineOptions: engineCfg.String(),
EngineOptionsPath: daemonOptsDir,
}, nil
return nil
}
......@@ -41,7 +41,7 @@ func (p *SystemdProvisioner) GenerateDockerOptions(dockerPort int) (*DockerOptio
p.EngineOptions.Labels = append(p.EngineOptions.Labels, driverNameLabel)
engineConfigTmpl := `[Service]
ExecStart=/usr/bin/docker daemon -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 }}
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 }}
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
......
......@@ -28,7 +28,7 @@ func installDockerGeneric(p Provisioner, baseURL string) error {
// install docker - until cloudinit we use ubuntu everywhere so we
// just install it using the docker repos
if output, err := p.SSHCommand(fmt.Sprintf("if ! type docker; then curl -sSL %s | sh -; fi", baseURL)); err != nil {
return fmt.Errorf("error installing docker: %s\n", output)
return fmt.Errorf("error installing docker: %s", output)
}
return nil
......@@ -272,3 +272,25 @@ func WaitForDocker(p Provisioner, dockerPort int) error {
return nil
}
// DockerClientVersion returns the version of the Docker client on the host
// that ssh is connected to, e.g. "1.12.1".
func DockerClientVersion(ssh SSHCommander) (string, error) {
// `docker version --format {{.Client.Version}}` would be preferrable, but
// that fails if the server isn't running yet.
//
// output is expected to be something like
//
// Docker version 1.12.1, build 7a86f89
output, err := ssh.SSHCommand("docker --version")
if err != nil {
return "", err
}
words := strings.Fields(output)
if len(words) < 3 || words[0] != "Docker" || words[1] != "version" {
return "", fmt.Errorf("DockerClientVersion: cannot parse version string from %q", output)
}
return strings.TrimRight(words[2], ","), nil
}
......@@ -46,6 +46,7 @@ type NativeClient struct {
Hostname string
Port int
openSession *ssh.Session
openClient *ssh.Client
}
type Auth struct {
......@@ -156,43 +157,49 @@ func NewNativeConfig(user string, auth *Auth) (ssh.ClientConfig, error) {
}
func (client *NativeClient) dialSuccess() bool {
if _, err := ssh.Dial("tcp", net.JoinHostPort(client.Hostname, strconv.Itoa(client.Port)), &client.Config); err != nil {
conn, err := ssh.Dial("tcp", net.JoinHostPort(client.Hostname, strconv.Itoa(client.Port)), &client.Config)
if err != nil {
log.Debugf("Error dialing TCP: %s", err)
return false
}
closeConn(conn)
return true
}
func (client *NativeClient) session(command string) (*ssh.Session, error) {
func (client *NativeClient) session(command string) (*ssh.Client, *ssh.Session, error) {
if err := mcnutils.WaitFor(client.dialSuccess); err != nil {
return nil, fmt.Errorf("Error attempting SSH client dial: %s", err)
return nil, nil, fmt.Errorf("Error attempting SSH client dial: %s", err)
}
conn, err := ssh.Dial("tcp", net.JoinHostPort(client.Hostname, strconv.Itoa(client.Port)), &client.Config)
if err != nil {
return nil, fmt.Errorf("Mysterious error dialing TCP for SSH (we already succeeded at least once) : %s", err)
return nil, nil, fmt.Errorf("Mysterious error dialing TCP for SSH (we already succeeded at least once) : %s", err)
}
session, err := conn.NewSession()
return conn.NewSession()
return conn, session, err
}
func (client *NativeClient) Output(command string) (string, error) {
session, err := client.session(command)
conn, session, err := client.session(command)
if err != nil {
return "", nil
}
defer closeConn(conn)
defer session.Close()
output, err := session.CombinedOutput(command)
defer session.Close()
return string(output), err
}
func (client *NativeClient) OutputWithPty(command string) (string, error) {
session, err := client.session(command)
conn, session, err := client.session(command)
if err != nil {
return "", nil
}
defer closeConn(conn)
defer session.Close()
fd := int(os.Stdin.Fd())
......@@ -214,13 +221,12 @@ func (client *NativeClient) OutputWithPty(command string) (string, error) {
}
output, err := session.CombinedOutput(command)
defer session.Close()
return string(output), err
}
func (client *NativeClient) Start(command string) (io.ReadCloser, io.ReadCloser, error) {
session, err := client.session(command)
conn, session, err := client.session(command)
if err != nil {
return nil, nil, err
}
......@@ -237,15 +243,27 @@ func (client *NativeClient) Start(command string) (io.ReadCloser, io.ReadCloser,
return nil, nil, err
}
client.openClient = conn
client.openSession = session
return ioutil.NopCloser(stdout), ioutil.NopCloser(stderr), nil
}
func (client *NativeClient) Wait() error {
err := client.openSession.Wait()
if err != nil {
return err
}
_ = client.openSession.Close()
err = client.openClient.Close()
if err != nil {
return err
}
client.openSession = nil
return err
client.openClient = nil
return nil
}
func (client *NativeClient) Shell(args ...string) error {
......@@ -256,6 +274,7 @@ func (client *NativeClient) Shell(args ...string) error {
if err != nil {
return err
}
defer closeConn(conn)
session, err := conn.NewSession()
if err != nil {
......@@ -414,3 +433,10 @@ func (client *ExternalClient) Wait() error {
client.cmd = nil
return err
}
func closeConn(c io.Closer) {
err := c.Close()
if err != nil {
log.Debugf("Error closing SSH Client: %s", err)
}
}
......@@ -82,7 +82,7 @@ func (kp *KeyPair) WriteToFile(privateKeyPath string, publicKeyPath string) erro
// windows does not support chmod
switch runtime.GOOS {
case "darwin", "linux":
case "darwin", "linux", "freebsd":
if err := f.Chmod(0600); err != nil {
return err
}
......
// Package versioncmp provides functions for comparing version strings.
//
// Version strings are dot-separated integers with an optional
// pre-release suffix. A pre-release suffix is an arbitrary string with a
// leading dash character. All functions ignore these suffixes, so "1.2" and
// "1.2-rc" are considered equivalent.
package versioncmp
import (
"strconv"
"strings"
)
// compare compares two version strings. compare returns -1 if v1 < v2, 1 if v1
// > v2, 0 otherwise.
//
// Non-numeric segments in either argument are considered equal, so
// compare("1.a", "1.b") == 0, but compare("2.a", "1.b") == 1.
func compare(v1, v2 string) int {
if n := strings.IndexByte(v1, '-'); n != -1 {
v1 = v1[:n]
}
if n := strings.IndexByte(v2, '-'); n != -1 {
v2 = v2[:n]
}
var (
currTab = strings.Split(v1, ".")
otherTab = strings.Split(v2, ".")
)
max := len(currTab)
if len(otherTab) > max {
max = len(otherTab)
}
for i := 0; i < max; i++ {
var currInt, otherInt int
if len(currTab) > i {
currInt, _ = strconv.Atoi(currTab[i])
}
if len(otherTab) > i {
otherInt, _ = strconv.Atoi(otherTab[i])
}
if currInt > otherInt {
return 1
}
if otherInt > currInt {
return -1
}
}
return 0
}
// LessThan checks if a version is less than another.
func LessThan(v, other string) bool {
return compare(v, other) == -1
}
// LessThanOrEqualTo checks if a version is less than or equal to another.
func LessThanOrEqualTo(v, other string) bool {
return compare(v, other) <= 0
}
// GreaterThan checks if a version is greater than another.
func GreaterThan(v, other string) bool {
return compare(v, other) == 1
}
// GreaterThanOrEqualTo checks if a version is greater than or equal to
// another.
func GreaterThanOrEqualTo(v, other string) bool {
return compare(v, other) >= 0
}
// Equal checks if a version is equal to another.
func Equal(v, other string) bool {
return compare(v, other) == 0
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册