// 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 }
// 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, } }
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) } } }
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 }
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 }
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 }
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 } }
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 }
// // 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 }
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 }
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 }
// // 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 }
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 }
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 }
func collectError(message string, force bool, errorOccured []string) []string { if force { log.Error(message) } return append(errorOccured, message) }
// 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 }
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) } }
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 }
// 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 }
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 }
// // 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 }
// 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 } }
// 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 }
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) } }