Пример #1
0
// NewNetConfigInterface - creates an interface object for NetConfig
func (n *NetConfig) NewNetConfigInterface(
	enable bool,
	macaddr string,
	isdhcp bool,
	isipv6 bool,
	ipv6gateway utils.Nstring, // ipv6 gateway, required with isipv6 is true
	ipv4gateway utils.Nstring, // ipv4 gateway, required when isdhcp is false
	staticnets utils.Nstring, // comma seperated list of ip's, required when isdhcp is false
	name utils.Nstring, // optional name
	wins utils.Nstring, // comma seperated list of wins servers
	dnsservers utils.Nstring, // comma seperated list of dns servers
	dnssearch utils.Nstring,
	vlandid int) NetConfigInterface { // comma seperated list of dns search

	var inetconfig NetConfigInterface

	inetconfig = NetConfigInterface{
		Enabled:        enable,
		MACAddr:        macaddr,
		DHCPv4:         isdhcp,
		IPv6Autoconfig: isipv6,
		VlanID:         vlandid,
	}
	if macaddr == "" {
		log.Error("Network configuration (NetConfigInterface) requires a MAC Address to create a new interface object.")
	}
	if isipv6 {
		if ipv6gateway.IsNil() {
			log.Error("Gateway for ipv6 is required, configure IPv6Gateway")
		}
		inetconfig.IPv6Gateway = ipv6gateway.String()
	}
	if !isdhcp {
		if ipv4gateway.IsNil() {
			log.Error("Static ipv4 configuration requires a gateway configured (IPv4Gateway)")
		}
		inetconfig.IPv4Gateway = ipv4gateway.String()
		if staticnets.IsNil() {
			log.Error("Static ipv4 configuration requires static network list")
		}
		inetconfig.StaticNetworks = strings.Split(staticnets.String(), SplitSep)
	}
	if !name.IsNil() {
		inetconfig.Name = name.String()
	}
	if !wins.IsNil() {
		inetconfig.WINSServers = strings.Split(wins.String(), SplitSep)
	}
	if !dnsservers.IsNil() {
		inetconfig.DNSServers = strings.Split(dnsservers.String(), SplitSep)
	}
	if !dnssearch.IsNil() {
		inetconfig.DNSSearch = strings.Split(dnssearch.String(), SplitSep)
	}
	return inetconfig
}
Пример #2
0
// NewServerCreate make a new servercreate object
func (sc ServerCreate) NewServerCreate(user string, pass string, ip string, port int) ServerCreate {
	if user == "" {
		log.Error("ilo user missing, please specify with ONEVIEW_ILO_USER or --oneview-ilo-user arguments.")
	}
	if user == "" {
		log.Error("ilo password missing, please specify with ONEVIEW_ILO_PASSWORD or --oneview-ilo-password arguments.")
	}
	return ServerCreate{
		// Type:      "OSDIlo", //TODO: this causes notmal os-deployment-servers actions to fail.
		UserName:  user,
		Password:  pass,
		IPAddress: ip,
		Port:      port,
	}
}
Пример #3
0
func runCommand(command func(commandLine CommandLine, api libmachine.API) error) func(context *cli.Context) {
	return func(context *cli.Context) {
		api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir())
		defer api.Close()

		if context.GlobalBool("native-ssh") {
			api.SSHClientType = ssh.Native
		}
		api.GithubAPIToken = context.GlobalString("github-api-token")
		api.Filestore.Path = context.GlobalString("storage-path")

		// TODO (nathanleclaire): These should ultimately be accessed
		// through the libmachine client by the rest of the code and
		// not through their respective modules.  For now, however,
		// they are also being set the way that they originally were
		// set to preserve backwards compatibility.
		mcndirs.BaseDir = api.Filestore.Path
		mcnutils.GithubAPIToken = api.GithubAPIToken
		ssh.SetDefaultClient(api.SSHClientType)

		if err := command(&contextCommandLine{context}, api); err != nil {
			log.Error(err)

			if crashErr, ok := err.(crashreport.CrashError); ok {
				crashReporter := crashreport.NewCrashReporter(mcndirs.GetBaseDir(), context.GlobalString("bugsnag-api-token"))
				crashReporter.Send(crashErr)
			}

			osExit(1)
		}
	}
}
Пример #4
0
func (d *Driver) Start() error {
	uuid := d.UUID
	vmlinuz := d.ResolveStorePath("vmlinuz64")
	initrd := d.ResolveStorePath("initrd.img")
	iso := d.ResolveStorePath(isoFilename)
	img := d.ResolveStorePath(d.MachineName + ".img")
	bootcmd := d.BootCmd

	cmd := exec.Command("goxhyve",
		fmt.Sprintf("%s", uuid),
		fmt.Sprintf("%d", d.CPU),
		fmt.Sprintf("%d", d.Memory),
		fmt.Sprintf("%s", iso),
		fmt.Sprintf("%s", img),
		fmt.Sprintf("kexec,%s,%s,%s", vmlinuz, initrd, bootcmd),
		"-d", //TODO fix daemonize flag
	)
	log.Debug(cmd)
	go func() {
		err := cmd.Run()
		if err != nil {
			log.Error(err, cmd.Stdout)
		}
	}()

	return nil
}
Пример #5
0
func (d *Driver) Start() error {
	if err := d.PreCommandCheck(); err != nil {
		return err
	}

	pid := d.ResolveStorePath(d.MachineName + ".pid")
	if _, err := os.Stat(pid); err == nil {
		os.Remove(pid)
	}

	d.attachDiskImage()

	args := d.xhyveArgs()
	args = append(args, "-F", fmt.Sprintf("%s", pid))

	log.Debug(args)

	cmd := exec.Command(os.Args[0], args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	err := cmd.Start()
	if err != nil {
		return err
	}

	go func() {
		err := cmd.Wait()
		if err != nil {
			log.Error(err, cmd.Stdout, cmd.Stderr)
		}
	}()

	return d.waitForIP()
}
func (d *Driver) generateQcow2Image(size int64) error {
	diskPath := filepath.Join(d.ResolveStorePath("."), d.MachineName+".qcow2")
	opts := &qcow2.Opts{
		Filename:      diskPath,
		Size:          d.DiskSize * 107374,
		Fmt:           qcow2.DriverQCow2,
		ClusterSize:   65536,
		Preallocation: qcow2.PREALLOC_MODE_OFF,
		Encryption:    false,
		LazyRefcounts: true,
	}

	img, err := qcow2.Create(opts)
	if err != nil {
		log.Error(err)
	}

	tarBuf, err := d.generateKeyBundle()
	if err != nil {
		return err
	}

	// TODO(zchee): hardcoded
	zeroFill(tarBuf, 109569)
	tarBuf.Write(diskimageFooter)

	// TODO(zchee): hardcoded
	zeroFill(tarBuf, 16309)
	tarBuf.Write(efipartFooter)

	img.Write(tarBuf.Bytes())

	return nil
}
Пример #7
0
func (c *GenericClient) SetTLSConfig(d *Driver) error {

	config := &tls.Config{}
	config.InsecureSkipVerify = d.Insecure

	if d.CaCert != "" {
		// Use custom CA certificate(s) for root of trust
		certpool := x509.NewCertPool()
		pem, err := ioutil.ReadFile(d.CaCert)
		if err != nil {
			log.Error("Unable to read specified CA certificate(s)")
			return err
		}

		ok := certpool.AppendCertsFromPEM(pem)
		if !ok {
			return fmt.Errorf("Ill-formed CA certificate(s) PEM file")
		}
		config.RootCAs = certpool
	}

	transport := &http.Transport{TLSClientConfig: config}
	c.Provider.HTTPClient.Transport = transport
	return nil
}
Пример #8
0
func main() {
	log.SetDebug(true)

	client := libmachine.NewClient("/tmp/automatic", "/tmp/automatic/certs")
	defer client.Close()

	hostName := "myfunhost"

	// Set some options on the provider...
	driver := virtualbox.NewDriver(hostName, "/tmp/automatic")
	driver.CPU = 2
	driver.Memory = 2048

	data, err := json.Marshal(driver)
	if err != nil {
		log.Error(err)
		return
	}

	h, err := client.NewHost("virtualbox", data)
	if err != nil {
		log.Error(err)
		return
	}

	h.HostOptions.EngineOptions.StorageDriver = "overlay"

	if err := client.Create(h); err != nil {
		log.Error(err)
		return
	}

	out, err := h.RunSSHCommand("df -h")
	if err != nil {
		log.Error(err)
		return
	}

	fmt.Printf("Results of your disk space query:\n%s\n", out)

	fmt.Println("Powering down machine now...")
	if err := h.Stop(); err != nil {
		log.Error(err)
		return
	}
}
Пример #9
0
func hdiutil(args ...string) error {
	cmd := exec.Command("hdiutil", args...)

	log.Debugf("executing: %v %v", cmd, strings.Join(args, " "))

	err := cmd.Run()
	if err != nil {
		log.Error(err)
	}

	return nil
}
Пример #10
0
//
// configureForLinux sets up the VM role for Linux specific configuration
//
// Paramters:
//   role: role that needs to be updated with Linux configuration
//   dnsName: name of the machine that we are trying to create
//
// Returns:
//   error: errors from reading certs, getting thumbprint and adding
//   certificate to hostedservice
//
func (d *Driver) configureForLinux(role *virtualmachine.Role, dnsName string) error {

	// Get the Azure client
	client, err := d.getClient()
	if err != nil {
		return err
	}

	mediaLink := fmt.Sprintf("http://%s.blob.core.windows.net/vhds/%s.vhd",
		d.StorageAccount, dnsName)

	// Setup the image configuration
	vmutils.ConfigureDeploymentFromPlatformImage(
		role,
		d.Image,
		mediaLink,
		"")

	// Read the certificate
	data, err := ioutil.ReadFile(d.azureCertPath())
	if err != nil {
		return err
	}

	// Add the certificate to the hostedservice
	if _, err := hostedservice.NewClient(client).AddCertificate(dnsName, data, "pfx", ""); err != nil {
		return err
	}

	thumbPrint, err := getServiceCertFingerprint(d.azureCertPath())
	if err != nil {
		return err
	}

	vmutils.ConfigureForLinux(role, dnsName, d.SSHUser, d.UserPassword, thumbPrint)
	vmutils.ConfigureWithPublicSSH(role)

	role.UseCertAuth = true
	role.CertPath = d.azureCertPath()

	// Attach VM to a specific subnet
	if d.Subnet != "" {
		err = vmutils.ConfigureWithSubnet(role, d.Subnet)
		if err != nil {
			log.Error("failed to configure subnet:", d.Subnet, ", err:", err)
			return err
		}
		log.Debug("subnet is:", d.Subnet)
	}

	return nil
}
Пример #11
0
func (provisioner *WindowsProvisioner) Service(name string, action serviceaction.ServiceAction) error {
	ip, err := provisioner.Driver.GetIP()
	if err != nil {
		return err
	}
	d := provisioner.Driver
	out, stderr, exit, err := drivers.WinRMRunCmdWithNTLM(ip, d.GetSSHUsername(), d.GetSSHPassword(), fmt.Sprintf("net %s %s", action.String(), name))
	if (err != nil) || (exit != 0) {
		log.Error("service stdout:", out, ", stderr:", stderr, ", err:", err, ", exit:", exit)
		return err
	}
	return nil
}
Пример #12
0
func (d *Driver) Remove() error {

	if err := d.setUserSubscription(); err != nil {
		return err
	}

	client, err := d.getClient()
	if err != nil {
		return err
	}

	hostedClient := hostedservice.NewClient(client)
	availabilityResponse, err := hostedClient.CheckHostedServiceNameAvailability(d.MachineName)
	if err != nil {
		log.Error("Failed to check service name availability")
		return err
	}

	if availabilityResponse.Result == true {
		log.Error("Hosted service does not exist and cannot be deleted")
		return err
	}

	// Note: this only removes the VHD file of a hosted service reliably.
	// An associated xxx.status file is left behind for certain deletions
	opID, err := hostedClient.DeleteHostedService(d.MachineName, true)
	if err != nil {
		log.Error("Error deleting hosted service. Err:", err)
		return err
	}

	if err = client.WaitForOperation(opID, nil); err != nil {
		log.Error("Error deleting hosted service. Err:", err)
		return err
	}

	return nil
}
Пример #13
0
//
// WinRMRunCmdWithNTLM runs a command on a Windows Server (specifically
// an Azure VM with Windows). Uses WinRM with NTLM support enabled.
// WinRM should be enabled on the target server.
//
// Ref: https://github.com/masterzen/winrm/blob/master/README.md#pluggable-authentication-example-negotiatentlm-authentication
//
// Parameters:
//   host: target Windows server host
//   username: username for the host
//   password: password for the host
//   command: command to run
// Returns:
//   string: stdout from command execution
//   string: stderr from command execution
//   int:   exit status from the command being run
//   error: errors from establishing connection and running command
//
func WinRMRunCmdWithNTLM(host string, username string, password string, command string) (string, string, int, error) {
	var err error
	params := newwinrm.DefaultParameters()
	params.TransportDecorator = func(t *http.Transport) http.RoundTripper { return ntlmssp.Negotiator{t} }
	client, err := newwinrm.NewClientWithParameters(&newwinrm.Endpoint{Host: host,
		Port:     5986,
		HTTPS:    true,
		Insecure: true},
		username, password, params)
	if err != nil {
		log.Error("failed to create shell: ", err)
		return "", "", -1, err
	}

	stdout, stderr, exitcode, err := client.RunWithString(command, "")
	if err != nil {
		log.Error("failed to run cmd: ", err)
		return "", "", -1, err
	}
	log.Debug("stdout:", stdout, "stderr:", stderr, "exitcode:", exitcode)

	return stdout, stderr, exitcode, err
}
Пример #14
0
func matchesName(host *host.Host, names []string) bool {
	if len(names) == 0 {
		return true
	}
	for _, n := range names {
		r, err := regexp.Compile(n)
		if err != nil {
			log.Error(err)
			os.Exit(1) // TODO: Can we get rid of this call, and exit 'properly' ?
		}
		if r.MatchString(host.Driver.GetMachineName()) {
			return true
		}
	}
	return false
}
Пример #15
0
func (d *Driver) Start() error {
	var Password string
	log.Infof("Creating %s xhyve VM...", d.MachineName)
	cmd := exec.Command("sudo", "xhyve", // TODO
		fmt.Sprintf("-m %dM", d.Memory),
		"-s 0:0,hostbridge -s 31,lpc",
		"-l com1,stdio",
		"-s 2:0,virtio-net",
		fmt.Sprintf("-s 2:1,virtio-tap,tap1"),
		fmt.Sprintf("-s 3,ahci-cd,%s", path.Join(d.LocalArtifactPath("."), isoFilename)),
		fmt.Sprintf("-s 4,virtio-blk,%s", path.Join(d.LocalArtifactPath("."), d.MachineName+".img")),
		fmt.Sprintf("-U %s", d.UUID),
		fmt.Sprintf("-f kexec,%s,%s,loglevel=3 user=docker console=ttyS0 console=tty0 noembed nomodeset norestore waitusb=10:LABEL=boot2docker-data base", path.Join(d.LocalArtifactPath("."), "vmlinuz64"), path.Join(d.LocalArtifactPath("."), "initrd.img")),
	)
	//	cmd := exec.Command("sudo xhyve -m 4G -c 4 -s 0:0,hostbridge -s 31,lpc -l com1,stdio -s 2:0,virtio-net -s 3,ahci-cd,'/Users/zchee/.docker/machine/machines/xhyve-test/boot2docker.iso' -s 4,virtio-blk,'/Users/zchee/.docker/machine/machines/xhyve-test/xhyve-test.img' -U D2B9B60C-2465-4AF7-BCB6-522D795B043E -f 'kexec,vmlinuz64,initrd.img,loglevel=3 user=docker console=ttyS0 console=tty0 noembed nomodeset norestore waitusb=10:LABEL=boot2docker-data base'")
	cmd.Stdin = strings.NewReader(Password)
	log.Debug(cmd)
	err := cmd.Run()
	if err != nil {
		log.Error(err, cmd.Stdout)
	}

	return nil
}
Пример #16
0
func collectError(message string, force bool, errorOccured []string) []string {
	if force {
		log.Error(message)
	}
	return append(errorOccured, message)
}
Пример #17
0
// Create - create server for docker
func (d *Driver) Create() error {
	log.Infof("Generating SSH keys...")
	if err := d.createKeyPair(); err != nil {
		return fmt.Errorf("unable to create key pair: %s", err)
	}

	log.Debugf("ICSP Endpoint is: %s", d.ClientICSP.Endpoint)
	log.Debugf("OV Endpoint is: %s", d.ClientOV.Endpoint)
	// create the server profile in oneview, we need a hostname and a template name

	log.Debugf("***> CreateMachine")
	// create d.Hardware and d.Profile
	if err := d.ClientOV.CreateMachine(d.MachineName, d.ServerTemplate); err != nil {
		return err
	}

	if err := d.getBlade(); err != nil {
		return err
	}

	// power off let customization bring the server online
	if err := d.Hardware.PowerOff(); err != nil {
		return err
	}

	// add the server to icsp, TestCreateServer
	// apply a build plan, TestApplyDeploymentJobs
	var sp *icsp.CustomServerAttributes
	sp = sp.New()
	sp.Set("docker_user", d.SSHUser)
	sp.Set("public_key", d.SSHPublicKey)
	// TODO: make a util for this
	if len(os.Getenv("proxy_enable")) > 0 {
		sp.Set("proxy_enable", os.Getenv("proxy_enable"))
	} else {
		sp.Set("proxy_enable", "false")
	}

	strProxy := os.Getenv("proxy_config")
	sp.Set("proxy_config", strProxy)

	sp.Set("docker_hostname", d.MachineName+"-@server_name@")

	sp.Set("interface", "@interface@") // this is populated later

	// Get the mac address for public Connection on server profile
	var publicmac string
	if d.PublicConnectionName != "" {
		conn, err := d.Profile.GetConnectionByName(d.PublicConnectionName)
		if err != nil {
			return err
		}
		publicmac = conn.MAC.String()
	} else {
		publicmac = ""
	}

	// arguments for customize server
	cs := icsp.CustomizeServer{
		HostName:         d.MachineName,                   // machine-rack-enclosure-bay
		SerialNumber:     d.Profile.SerialNumber.String(), // get it
		ILoUser:          d.IloUser,
		IloPassword:      d.IloPassword,
		IloIPAddress:     d.Hardware.GetIloIPAddress(), // MpIpAddress for v1
		IloPort:          d.IloPort,
		OSBuildPlan:      d.OSBuildPlan,  // name of the OS build plan
		PublicSlotID:     d.PublicSlotID, // this is the slot id of the public interface
		PublicMAC:        publicmac,      // Server profile mac address, overrides slotid
		ServerProperties: sp,
	}
	// create d.Server and apply a build plan and configure the custom attributes
	if err := d.ClientICSP.CustomizeServer(cs); err != nil {
		return err
	}

	ip, err := d.GetIP()
	if err != nil {
		return err
	}
	d.IPAddress = ip

	// use ssh to set keys, and test ssh
	sshClient, err := d.getLocalSSHClient()
	if err != nil {
		return err
	}

	pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath())
	if err != nil {
		return err
	}

	if out, err := sshClient.Output(fmt.Sprintf(
		"printf '%%s' '%s' | tee /home/%s/.ssh/authorized_keys",
		string(pubKey),
		d.GetSSHUsername(),
	)); err != nil {
		log.Error(out)
		return err
	}
	log.Infof("%s, Completed all create steps, docker provisioning will continue.", d.DriverName())

	defer closeAll(d)
	return nil
}
Пример #18
0
func main() {
	if os.Getenv(localbinary.PluginEnvKey) == localbinary.PluginEnvVal {
		driverName := os.Getenv(localbinary.PluginEnvDriverName)
		runDriver(driverName)
		return
	}

	localbinary.CurrentBinaryIsDockerMachine = true

	setDebugOutputLevel()
	cli.AppHelpTemplate = AppHelpTemplate
	cli.CommandHelpTemplate = CommandHelpTemplate
	app := cli.NewApp()
	app.Name = filepath.Base(os.Args[0])
	app.Author = "Docker Machine Contributors"
	app.Email = "https://github.com/docker/machine"

	app.Commands = commands.Commands
	app.CommandNotFound = cmdNotFound
	app.Usage = "Create and manage machines running Docker."
	app.Version = version.FullVersion()

	log.Debug("Docker Machine Version: ", app.Version)

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug, D",
			Usage: "Enable debug mode",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_STORAGE_PATH",
			Name:   "s, storage-path",
			Value:  mcndirs.GetBaseDir(),
			Usage:  "Configures storage path",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CA_CERT",
			Name:   "tls-ca-cert",
			Usage:  "CA to verify remotes against",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CA_KEY",
			Name:   "tls-ca-key",
			Usage:  "Private key to generate certificates",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CLIENT_CERT",
			Name:   "tls-client-cert",
			Usage:  "Client cert to use for TLS",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CLIENT_KEY",
			Name:   "tls-client-key",
			Usage:  "Private key used in client TLS auth",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_GITHUB_API_TOKEN",
			Name:   "github-api-token",
			Usage:  "Token to use for requests to the Github API",
			Value:  "",
		},
		cli.BoolFlag{
			EnvVar: "MACHINE_NATIVE_SSH",
			Name:   "native-ssh",
			Usage:  "Use the native (Go-based) SSH implementation.",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_BUGSNAG_API_TOKEN",
			Name:   "bugsnag-api-token",
			Usage:  "BugSnag API token for crash reporting",
			Value:  "",
		},
	}

	if err := app.Run(os.Args); err != nil {
		log.Error(err)
	}
}
Пример #19
0
func (d *Driver) Create() error {

	var (
		err error
	)
	VpcId := d.VpcId
	VSwitchId := d.VSwitchId

	if err := d.checkPrereqs(); err != nil {
		return err
	}
	log.Infof("%s | Creating key pair for instance ...", d.MachineName)

	if err := d.createKeyPair(); err != nil {
		return fmt.Errorf("%s | Failed to create key pair: %v", d.MachineName, err)
	}

	log.Infof("%s | Configuring security groups instance ...", d.MachineName)
	if err := d.configureSecurityGroup(VpcId, d.SecurityGroupName); err != nil {
		return err
	}

	// TODO Support data disk
	if d.SSHPassword == "" {
		d.SSHPassword = randomPassword()
		log.Infof("%s | Launching instance with generated password, please update password in console or log in with ssh key.", d.MachineName)
	}

	imageID := d.GetImageID(d.ImageID)
	log.Infof("%s | Creating instance with image %s ...", d.MachineName, imageID)

	args := ecs.CreateInstanceArgs{
		RegionId:           d.Region,
		InstanceName:       d.GetMachineName(),
		ImageId:            imageID,
		InstanceType:       d.InstanceType,
		SecurityGroupId:    d.SecurityGroupId,
		InternetChargeType: internetChargeType,
		Password:           d.SSHPassword,
		VSwitchId:          VSwitchId,
		ZoneId:             d.Zone,
		ClientToken:        d.getClient().GenerateClientToken(),
	}

	if d.DiskSize > 0 { // Allocate Data Disk

		disk := ecs.DataDiskType{
			DiskName:           d.MachineName + "_data",
			Description:        "Data volume for Docker",
			Size:               d.DiskSize,
			Category:           d.DiskCategory,
			Device:             "/dev/xvdb",
			DeleteWithInstance: true,
		}

		args.DataDisk = []ecs.DataDiskType{disk}

	}

	// Set InternetMaxBandwidthOut only for classic network
	if VSwitchId == "" {
		args.InternetMaxBandwidthOut = d.InternetMaxBandwidthOut
	}

	// Create instance
	instanceId, err := d.getClient().CreateInstance(&args)

	if err != nil {
		err = fmt.Errorf("%s | Failed to create instance: %s", d.MachineName, err)
		log.Error(err)
		return err
	}
	log.Infof("%s | Create instance %s successfully", d.MachineName, instanceId)

	d.InstanceId = instanceId

	// Wait for creation successfully
	err = d.getClient().WaitForInstance(instanceId, ecs.Stopped, timeout)

	if err != nil {
		err = fmt.Errorf("%s | Failed to wait instance to 'stopped': %s", d.MachineName, err)
		log.Error(err)
	}

	if err == nil {
		err = d.configNetwork(VpcId, instanceId)
	}

	if err == nil {
		// Start instance
		log.Infof("%s | Starting instance %s ...", d.MachineName, instanceId)
		err = d.getClient().StartInstance(instanceId)
		if err == nil {
			// Wait for running
			err = d.getClient().WaitForInstance(instanceId, ecs.Running, timeout)
			if err == nil {
				log.Infof("%s | Start instance %s successfully", d.MachineName, instanceId)
				instance, err := d.getInstance()

				if err == nil {
					d.Zone = instance.ZoneId
					d.PrivateIPAddress = d.GetPrivateIP(instance)

					d.IPAddress = d.getIP(instance)

					ssh.SetDefaultClient(ssh.Native)

					d.uploadKeyPair()

					log.Infof("%s | Created instance %s successfully with public IP address %s and private IP address %s",
						d.MachineName,
						d.InstanceId,
						d.IPAddress,
						d.PrivateIPAddress,
					)
				}
			} else {
				err = fmt.Errorf("%s | Failed to wait instance to running state: %s", d.MachineName, err)
			}
		} else {
			err = fmt.Errorf("%s | Failed to start instance %s: %v", d.MachineName, instanceId, err)
		}
	}

	// Add instance tags
	if len(d.Tags) > 0 {
		log.Infof("%s | Adding tags %v to instance %s ...", d.MachineName, d.Tags, instanceId)
		args := ecs.AddTagsArgs{
			RegionId:     d.Region,
			ResourceId:   instanceId,
			ResourceType: ecs.TagResourceInstance,
			Tag:          d.Tags,
		}
		err2 := d.getClient().AddTags(&args)
		if err2 != nil {
			log.Warnf("%s | Failed to add tags %v to instance %s: %v", d.MachineName, d.Tags, instanceId, err)
		}
	}

	if err != nil {
		log.Warn(err)
		d.Remove()
	}

	return err
}
Пример #20
0
// Authenticate fetches a token from the local file cache or initiates a consent
// flow and waits for token to be obtained.
func Authenticate(env azure.Environment, subscriptionID string) (*azure.ServicePrincipalToken, error) {
	clientID, ok := clientIDs[env.Name]
	if !ok {
		return nil, fmt.Errorf("docker-machine application not set up for Azure environment %q", env.Name)
	}

	// First we locate the tenant ID of the subscription as we store tokens per
	// tenant (which could have multiple subscriptions)
	log.Debug("Looking up AAD Tenant ID.", logutil.Fields{
		"subs": subscriptionID})
	tenantID, err := findTenantID(env, subscriptionID)
	if err != nil {
		return nil, err
	}
	log.Debug("Found AAD Tenant ID.", logutil.Fields{
		"tenant": tenantID,
		"subs":   subscriptionID})

	oauthCfg, err := env.OAuthConfigForTenant(tenantID)
	if err != nil {
		return nil, fmt.Errorf("Failed to obtain oauth config for azure environment: %v", err)
	}

	// for AzurePublicCloud (https://management.core.windows.net/), this old
	// Service Management scope covers both ASM and ARM.
	apiScope := env.ServiceManagementEndpoint

	tokenPath := tokenCachePath(tenantID)
	saveToken := mkTokenCallback(tokenPath)
	saveTokenCallback := func(t azure.Token) error {
		log.Debug("Azure token expired. Saving the refreshed token...")
		return saveToken(t)
	}
	f := logutil.Fields{"path": tokenPath}

	// Lookup the token cache file for an existing token.
	spt, err := tokenFromFile(*oauthCfg, tokenPath, clientID, apiScope, saveTokenCallback)
	if err != nil {
		return nil, err
	}
	if spt != nil {
		log.Debug("Auth token found in file.", f)

		// NOTE(ahmetalpbalkan): The token file we found might be containng an
		// expired access_token. In that case, the first call to Azure SDK will
		// attempt to refresh the token using refresh_token –which might have
		// expired[1], in that case we will get an error and we shall remove the
		// token file and initiate token flow again so that the user would not
		// need removing the token cache file manually.
		//
		// [1]: expiration date of refresh_token is not returned in AAD /token
		//      response, we just know it is 14 days. Therefore user’s token
		//      will go stale every 14 days and we will delete the token file,
		//      re-initiate the device flow.
		log.Debug("Validating the token.")
		if err := validateToken(env, spt); err != nil {
			log.Debug(fmt.Sprintf("Error: %v", err))
			log.Info("Stored Azure credentials expired. Please reauthenticate.")
			log.Debug(fmt.Sprintf("Deleting %s", tokenPath))
			if err := os.RemoveAll(tokenPath); err != nil {
				return nil, fmt.Errorf("Error deleting stale token file: %v", err)
			}
		} else {
			log.Debug("Token works.")
			return spt, nil
		}
	}

	// Start an OAuth 2.0 device flow
	log.Debug("Initiating device flow.", f)
	spt, err = tokenFromDeviceFlow(*oauthCfg, tokenPath, clientID, apiScope)
	if err != nil {
		return nil, err
	}
	log.Debug("Obtained service principal token.")
	if err := saveToken(spt.Token); err != nil {
		log.Error("Error occurred saving token to cache file.")
		return nil, err
	}
	return spt, nil
}
Пример #21
0
func main() {
	setDebugOutputLevel()
	cli.AppHelpTemplate = AppHelpTemplate
	cli.CommandHelpTemplate = CommandHelpTemplate
	app := cli.NewApp()
	app.Name = path.Base(os.Args[0])
	app.Author = "Docker Machine Contributors"
	app.Email = "https://github.com/docker/machine"
	app.Before = func(c *cli.Context) error {
		// TODO: Need better handling of config, everything is too
		// complected together right now.
		if c.GlobalBool("native-ssh") {
			ssh.SetDefaultClient(ssh.Native)
		}
		mcnutils.GithubApiToken = c.GlobalString("github-api-token")
		mcndirs.BaseDir = c.GlobalString("storage-path")
		return nil
	}

	app.Commands = commands.Commands
	app.CommandNotFound = cmdNotFound
	app.Usage = "Create and manage machines running Docker."
	app.Version = version.Version + " (" + version.GitCommit + ")"

	log.Debug("Docker Machine Version: ", app.Version)

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug, D",
			Usage: "Enable debug mode",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_STORAGE_PATH",
			Name:   "s, storage-path",
			Value:  mcndirs.GetBaseDir(),
			Usage:  "Configures storage path",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CA_CERT",
			Name:   "tls-ca-cert",
			Usage:  "CA to verify remotes against",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CA_KEY",
			Name:   "tls-ca-key",
			Usage:  "Private key to generate certificates",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CLIENT_CERT",
			Name:   "tls-client-cert",
			Usage:  "Client cert to use for TLS",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CLIENT_KEY",
			Name:   "tls-client-key",
			Usage:  "Private key used in client TLS auth",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_GITHUB_API_TOKEN",
			Name:   "github-api-token",
			Usage:  "Token to use for requests to the Github API",
			Value:  "",
		},
		cli.BoolFlag{
			EnvVar: "MACHINE_NATIVE_SSH",
			Name:   "native-ssh",
			Usage:  "Use the native (Go-based) SSH implementation.",
		},
	}

	go commands.DeferClosePluginServers()

	// Cleanup to run in case the user sends an interrupt (CTRL+C) to the
	// Machine program.  Ensure that we do not leave dangling OS processes.
	signalCh := make(chan os.Signal, 1)
	signal.Notify(signalCh, os.Interrupt)

	// Atypical exit condition -- write to the cleanup done channel after
	// ensuring that we have closed all exec-ed plugin servers.
	go func() {
		for range signalCh {
			log.Info("\nReceieved an interrupt, performing cleanup work...")
			close(commands.RpcClientDriversCh)
			<-commands.RpcDriversClosedCh
			os.Exit(1)
		}
	}()

	// TODO: Close plugin servers in case of client panic.
	if err := app.Run(os.Args); err != nil {
		log.Error(err)
	}

	close(commands.RpcClientDriversCh)
	<-commands.RpcDriversClosedCh
}
Пример #22
0
//
// configureForWindows sets up the VM role for Windows specific configuration
//
// Paramters:
//   role: role that needs to be updated with Windows configuration
//   dnsName: name of the machine that we are trying to create
//
// Returns:
//   None
//
func (d *Driver) configureForWindows(role *virtualmachine.Role, dnsName string) error {

	// Get the Azure client
	client, err := d.getClient()
	if err != nil {
		return err
	}

	mediaLocation := fmt.Sprintf("http://%s.blob.core.windows.net/vhds/%s.vhd",
		d.StorageAccount, dnsName)

	// Setup the image configuration
	vmutils.ConfigureDeploymentFromPlatformImage(
		role,
		d.Image,
		mediaLocation,
		"")
	log.Debug("Configured deployment from platform image")

	vmutils.ConfigureForWindows(role, dnsName, d.SSHUser, d.UserPassword, true, "")
	log.Debug("Configured for windows")

	vmutils.ConfigureWithPublicSSH(role)
	log.Debug("Configured for SSH")

	vmutils.ConfigureWithPublicRDP(role)
	log.Debug("Configured for RDP")

	vmutils.ConfigureWithPublicPowerShell(role)
	log.Debug("Configured with Powershell")

	vmutils.ConfigureWithExternalPort(role, "WinRMu", 5985, 5985,
		virtualmachine.InputEndpointProtocolTCP)
	log.Debug("Configured WinRM port 5985")

	// Read the certificate
	data, err := ioutil.ReadFile(d.azureCertPath())
	if err != nil {
		return err
	}
	log.Debug("Read certificate from Azure cert path: ", d.azureCertPath())

	// Add the certificate to the hostedservice
	if _, err := hostedservice.NewClient(client).AddCertificate(dnsName, data, "pfx", ""); err != nil {
		log.Error("failed to add certificate:", err)
		return err
	}
	log.Debug("Added certificate to hostedservice")

	vmutils.ConfigureWinRMOverHTTP(role)
	log.Debug("Configured WinRM over HTTP")

	vmutils.ConfigureWinRMOverHTTPS(role, "")
	log.Debug("Configured WinRM over HTTPS without using a thumbprint")

	// Attach VM to a specific subnet
	if d.Subnet != "" {
		err = vmutils.ConfigureWithSubnet(role, d.Subnet)
		if err != nil {
			log.Error("failed to configure subnet:", d.Subnet, ", err:", err)
			return err
		}
		log.Debug("subnet is:", d.Subnet)
	}

	return nil
}
Пример #23
0
// Streaming the output of an SSH session in virtualbox.
func streaming() {
	log.SetDebug(true)

	client := libmachine.NewClient("/tmp/automatic", "/tmp/automatic/certs")
	defer client.Close()

	hostName := "myfunhost"

	// Set some options on the provider...
	driver := virtualbox.NewDriver(hostName, "/tmp/automatic")
	data, err := json.Marshal(driver)
	if err != nil {
		log.Error(err)
		return
	}

	h, err := client.NewHost("virtualbox", data)
	if err != nil {
		log.Error(err)
		return
	}

	if err := client.Create(h); err != nil {
		log.Error(err)
		return
	}

	h.HostOptions.EngineOptions.StorageDriver = "overlay"

	sshClient, err := h.CreateSSHClient()
	if err != nil {
		log.Error(err)
		return
	}

	stdout, stderr, err := sshClient.Start("yes | head -n 10000")
	if err != nil {
		log.Error(err)
		return
	}
	defer func() {
		_ = stdout.Close()
		_ = stderr.Close()
	}()

	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		log.Error(err)
	}
	if err := sshClient.Wait(); err != nil {
		log.Error(err)
	}

	fmt.Println("Powering down machine now...")
	if err := h.Stop(); err != nil {
		log.Error(err)
		return
	}
}
Пример #24
0
// AuthenticateDeviceFlow fetches a token from the local file cache or initiates a consent
// flow and waits for token to be obtained. Obtained token is stored in a file cache for
// future use and refreshing.
func AuthenticateDeviceFlow(env azure.Environment, subscriptionID string) (*azure.ServicePrincipalToken, error) {
	// First we locate the tenant ID of the subscription as we store tokens per
	// tenant (which could have multiple subscriptions)
	tenantID, err := loadOrFindTenantID(env, subscriptionID)
	if err != nil {
		return nil, err
	}
	oauthCfg, err := env.OAuthConfigForTenant(tenantID)
	if err != nil {
		return nil, fmt.Errorf("Failed to obtain oauth config for azure environment: %v", err)
	}

	tokenPath := tokenCachePath(tenantID)
	saveToken := mkTokenCallback(tokenPath)
	saveTokenCallback := func(t azure.Token) error {
		log.Debug("Azure token expired. Saving the refreshed token...")
		return saveToken(t)
	}
	f := logutil.Fields{"path": tokenPath}

	appID, ok := appIDs[env.Name]
	if !ok {
		return nil, fmt.Errorf("docker-machine application not set up for Azure environment %q", env.Name)
	}
	scope := getScope(env)

	// Lookup the token cache file for an existing token.
	spt, err := tokenFromFile(*oauthCfg, tokenPath, appID, scope, saveTokenCallback)
	if err != nil {
		return nil, err
	}
	if spt != nil {
		log.Debug("Auth token found in file.", f)

		// NOTE(ahmetalpbalkan): The token file we found might be containing an
		// expired access_token. In that case, the first call to Azure SDK will
		// attempt to refresh the token using refresh_token –which might have
		// expired[1], in that case we will get an error and we shall remove the
		// token file and initiate token flow again so that the user would not
		// need removing the token cache file manually.
		//
		// [1]: for device flow auth, the expiration date of refresh_token is
		//      not returned in AAD /token response, we just know it is 14
		//      days. Therefore user’s token will go stale every 14 days and we
		//      will delete the token file, re-initiate the device flow. Service
		//      Principal Account tokens are not subject to this limitation.
		log.Debug("Validating the token.")
		if err := validateToken(env, spt); err != nil {
			log.Debug(fmt.Sprintf("Error: %v", err))
			log.Debug(fmt.Sprintf("Deleting %s", tokenPath))
			if err := os.RemoveAll(tokenPath); err != nil {
				return nil, fmt.Errorf("Error deleting stale token file: %v", err)
			}
		} else {
			log.Debug("Token works.")
			return spt, nil
		}
	}

	log.Debug("Obtaining a token.", f)
	spt, err = deviceFlowAuth(*oauthCfg, appID, scope)
	if err != nil {
		return nil, err
	}
	log.Debug("Obtained a token.")
	if err := saveToken(spt.Token); err != nil {
		log.Error("Error occurred saving token to cache file.")
		return nil, err
	}
	return spt, nil
}
Пример #25
0
func main() {
	setDebugOutputLevel()
	cli.AppHelpTemplate = AppHelpTemplate
	cli.CommandHelpTemplate = CommandHelpTemplate
	app := cli.NewApp()
	app.Name = path.Base(os.Args[0])
	app.Author = "Docker Machine Contributors"
	app.Email = "https://github.com/docker/machine"
	app.Before = func(c *cli.Context) error {
		// TODO: Need better handling of config, everything is too
		// complected together right now.
		if c.GlobalBool("native-ssh") {
			ssh.SetDefaultClient(ssh.Native)
		}
		mcnutils.GithubAPIToken = c.GlobalString("github-api-token")
		mcndirs.BaseDir = c.GlobalString("storage-path")
		return nil
	}

	app.Commands = commands.Commands
	app.CommandNotFound = cmdNotFound
	app.Usage = "Create and manage machines running Docker."
	app.Version = version.Version + " (" + version.GitCommit + ")"

	log.Debug("Docker Machine Version: ", app.Version)

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "debug, D",
			Usage: "Enable debug mode",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_STORAGE_PATH",
			Name:   "s, storage-path",
			Value:  mcndirs.GetBaseDir(),
			Usage:  "Configures storage path",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CA_CERT",
			Name:   "tls-ca-cert",
			Usage:  "CA to verify remotes against",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CA_KEY",
			Name:   "tls-ca-key",
			Usage:  "Private key to generate certificates",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CLIENT_CERT",
			Name:   "tls-client-cert",
			Usage:  "Client cert to use for TLS",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_TLS_CLIENT_KEY",
			Name:   "tls-client-key",
			Usage:  "Private key used in client TLS auth",
			Value:  "",
		},
		cli.StringFlag{
			EnvVar: "MACHINE_GITHUB_API_TOKEN",
			Name:   "github-api-token",
			Usage:  "Token to use for requests to the Github API",
			Value:  "",
		},
		cli.BoolFlag{
			EnvVar: "MACHINE_NATIVE_SSH",
			Name:   "native-ssh",
			Usage:  "Use the native (Go-based) SSH implementation.",
		},
	}

	// TODO: Close plugin servers in case of client panic.
	if err := app.Run(os.Args); err != nil {
		log.Error(err)
	}
}