Пример #1
0
func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, nets map[string]*hostOnlyNetwork, vbox VBoxManager) (*hostOnlyNetwork, error) {
	// Search for an existing host-only adapter.
	hostOnlyAdapter := getHostOnlyAdapter(nets, hostIP, netmask)
	if hostOnlyAdapter != nil {
		return hostOnlyAdapter, nil
	}

	// No existing host-only adapter found. Create a new one.
	_, err := createHostonlyAdapter(vbox)
	if err != nil {
		// Sometimes the host-only adapter fails to create. See https://www.virtualbox.org/ticket/14040
		// BUT, it is created in fact! So let's wait until it appears last in the list
		log.Warnf("Creating a new host-only adapter produced an error: %s", err)
		log.Warn("This is a known VirtualBox bug. Let's try to recover anyway...")
	}

	// It can take some time for an adapter to appear. Let's poll.
	hostOnlyAdapter, err = waitForNewHostOnlyNetwork(nets, vbox)
	if err != nil {
		// Sometimes, Vbox says it created it but then it cannot be found...
		return nil, errNewHostOnlyAdapterNotVisible
	}

	log.Warnf("Found a new host-only adapter: %q", hostOnlyAdapter.Name)

	hostOnlyAdapter.IPv4.IP = hostIP
	hostOnlyAdapter.IPv4.Mask = netmask
	if err := hostOnlyAdapter.Save(vbox); err != nil {
		return nil, err
	}

	return hostOnlyAdapter, nil
}
Пример #2
0
func (d *Driver) Start() error {
	log.Debugf("Starting VM %s", d.MachineName)
	d.validateVMRef()
	err := d.VM.Create()
	if err != nil {
		log.Warnf("Failed to start: %s", err)
		return err
	}

	// They wont start immediately
	time.Sleep(5 * time.Second)

	for i := 0; i < 90; i++ {
		time.Sleep(time.Second)
		ip, _ := d.GetIP()
		if ip != "" {
			// Add a second to let things settle
			time.Sleep(time.Second)
			return nil
		}
		log.Debugf("Waiting for the VM to come up... %d", i)
	}
	log.Warnf("Unable to determine VM's IP address, did it fail to boot?")
	return err
}
Пример #3
0
func (d *Driver) getIPByMacFromSettings(mac string) (string, error) {
	network, err := d.conn.LookupNetworkByName(d.PrivateNetwork)
	if err != nil {
		log.Warnf("Failed to find network: %s", err)
		return "", err
	}
	bridge_name, err := network.GetBridgeName()
	if err != nil {
		log.Warnf("Failed to get network bridge: %s", err)
		return "", err
	}
	statusFile := fmt.Sprintf(dnsmasqStatus, bridge_name)
	data, err := ioutil.ReadFile(statusFile)
	type Lease struct {
		Ip_address  string `json:"ip-address"`
		Mac_address string `json:"mac-address"`
		// Other unused fields omitted
	}
	var s []Lease

	err = json.Unmarshal(data, &s)
	if err != nil {
		log.Warnf("Failed to decode dnsmasq lease status: %s", err)
		return "", err
	}
	for _, value := range s {
		if strings.ToLower(value.Mac_address) == strings.ToLower(mac) {
			log.Debugf("IP address: %s", value.Ip_address)
			return value.Ip_address, nil
		}
	}
	return "", nil
}
Пример #4
0
// closeAll - cleanup sessions on the OV and ICSP appliances
func closeAll(d *Driver) {
	err := d.ClientOV.SessionLogout()
	if err != nil {
		log.Warnf("OV Session Logout : %s", err)
	}
	err = d.ClientICSP.SessionLogout()
	if err != nil {
		log.Warnf("ICSP Session Logout : %s", err)
	}
}
Пример #5
0
// removeOrphanDHCPServers removed the DHCP servers linked to no host-only adapter
func removeOrphanDHCPServers(vbox VBoxManager) error {
	dhcps, err := listDHCPServers(vbox)
	if err != nil {
		return err
	}

	if len(dhcps) == 0 {
		return nil
	}

	nets, err := listHostOnlyAdapters(vbox)
	if err != nil {
		return err
	}

	for name := range dhcps {
		if strings.HasPrefix(name, dhcpPrefix) {
			if _, present := nets[name]; !present {
				if err := vbox.vbm("dhcpserver", "remove", "--netname", name); err != nil {
					log.Warnf("Unable to remove orphan dhcp server %q: %s", name, err)
				}
			}
		}
	}

	return nil
}
Пример #6
0
// Submit desired power state and wait
// Most of our concurrency will happen in PowerExecutor
func (pt *PowerTask) PowerExecutor(s PowerState) error {
	currenttime := 0
	pt.State = P_UKNOWN
	pt.ResetTask()
	go pt.SubmitPowerState(s)
	for !pt.TaskIsDone && (currenttime < pt.Timeout) {
		if err := pt.GetCurrentTaskStatus(); err != nil {
			return err
		}
		if pt.URI != "" && T_COMPLETED.Equal(pt.TaskState) {
			pt.TaskIsDone = true
		}
		if pt.URI != "" {
			log.Debugf("Waiting to set power state %s for blade %s, %s", s, pt.Blade.Name)
			log.Infof("Working on power state,%d%%, %s.", pt.ComputedPercentComplete, pt.TaskStatus)
		} else {
			log.Info("Working on power state.")
		}

		// wait time before next check
		time.Sleep(time.Millisecond * (1000 * pt.WaitTime)) // wait 10sec before checking the status again
		currenttime++
	}
	if !(currenttime < pt.Timeout) {
		log.Warnf("Power %s state timed out for %s.", s, pt.Blade.Name)
	}
	log.Infof("Power Task Execution Completed")
	return nil
}
Пример #7
0
// get current power state
func (pt *PowerTask) GetCurrentPowerState() error {
	// Quick check to make sure we have a proper hardware blade
	if pt.Blade.URI.IsNil() {
		pt.State = P_UKNOWN
		return errors.New("Can't get power on blade without hardware")
	}

	// get the latest state based on current blade uri
	b, err := pt.Blade.Client.GetServerHardware(pt.Blade.URI)
	if err != nil {
		return err
	}
	log.Debugf("GetCurrentPowerState() blade -> %+v", b)
	// Set the current state of the blade as a constant
	if P_OFF.Equal(b.PowerState) {
		pt.State = P_OFF
	} else if P_ON.Equal(b.PowerState) {
		pt.State = P_ON
	} else {
		log.Warnf("Un-known power state detected %s, for %s.", b.PowerState, b.Name)
		pt.State = P_UKNOWN
	}
	// Reassign the current blade and state of that blade
	pt.Blade = b
	return nil
}
Пример #8
0
func (c *RPCClientDriver) GetSSHPassword() string {
	sshPassword, err := c.rpcStringCall(GetSSHPasswordMethod)
	if err != nil {
		log.Warnf("Error attempting call to get SSH password: %s", err)
	}
	return sshPassword
}
Пример #9
0
func (c *RPCClientDriver) GetOS() string {
	OS, err := c.rpcStringCall(GetOSMethod)
	if err != nil {
		log.Warnf("Error attempting call to get OS: %s", err)
	}
	return OS
}
Пример #10
0
func (d *Driver) PreCreateCheck() error {
	conn, err := d.getConn()
	if err != nil {
		return err
	}

	// TODO We could look at conn.GetCapabilities()
	// parse the XML, and look for kvm
	log.Debug("About to check libvirt version")

	// TODO might want to check minimum version
	_, err = conn.GetLibVersion()
	if err != nil {
		log.Warnf("Unable to get libvirt version")
		return err
	}
	err = d.validatePrivateNetwork()
	if err != nil {
		return err
	}
	err = d.validateNetwork(d.Network)
	if err != nil {
		return err
	}
	// Others...?
	return nil
}
Пример #11
0
func (d *Driver) configureTags(tagGroups string) error {

	tags := []*ec2.Tag{}
	tags = append(tags, &ec2.Tag{
		Key:   aws.String("Name"),
		Value: &d.MachineName,
	})

	if tagGroups != "" {
		t := strings.Split(tagGroups, ",")
		if len(t) > 0 && len(t)%2 != 0 {
			log.Warnf("Tags are not key value in pairs. %d elements found", len(t))
		}
		for i := 0; i < len(t)-1; i += 2 {
			tags = append(tags, &ec2.Tag{
				Key:   &t[i],
				Value: &t[i+1],
			})
		}
	}

	_, err := d.getClient().CreateTags(&ec2.CreateTagsInput{
		Resources: []*string{&d.InstanceId},
		Tags:      tags,
	})

	if err != nil {
		return err
	}

	return nil
}
Пример #12
0
func (d *Driver) Stop() error {
	log.Debugf("Stopping VM %s", d.MachineName)
	d.validateVMRef()
	s, err := d.GetState()
	if err != nil {
		return err
	}

	if s != state.Stopped {
		err := d.VM.DestroyFlags(libvirt.VIR_DOMAIN_DESTROY_GRACEFUL)
		if err != nil {
			log.Warnf("Failed to gracefully shutdown VM")
			return err
		}
		for i := 0; i < 90; i++ {
			time.Sleep(time.Second)
			s, _ := d.GetState()
			log.Debugf("VM state: %s", s)
			if s == state.Stopped {
				return nil
			}
		}
		return errors.New("VM Failed to gracefully shutdown, try the kill command")
	}
	return nil
}
Пример #13
0
func (b *B2dUtils) UpdateISOCache(isoURL string) error {
	// recreate the cache dir if it has been manually deleted
	if _, err := os.Stat(b.imgCachePath); os.IsNotExist(err) {
		log.Infof("Image cache directory does not exist, creating it at %s...", b.imgCachePath)
		if err := os.Mkdir(b.imgCachePath, 0700); err != nil {
			return err
		}
	}

	exists := b.exists()

	if isoURL != "" {
		if exists {
			// Warn that the b2d iso won't be updated if isoURL is set
			log.Warnf("Boot2Docker URL was explicitly set to %q at create time, so Docker Machine cannot upgrade this machine to the latest version.", isoURL)
		}
		// Non-default B2D are not cached
		return nil
	}

	if !exists {
		log.Info("No default Boot2Docker ISO found locally, downloading the latest release...")
		return b.DownloadLatestBoot2Docker("")
	}

	latest := b.isLatest()
	if !latest {
		log.Info("Default Boot2Docker ISO is out-of-date, downloading the latest release...")
		return b.DownloadLatestBoot2Docker("")
	}

	return nil
}
Пример #14
0
func NewRpcClientDriver(rawDriverData []byte, driverName string) (*RpcClientDriver, error) {
	mcnName := ""

	p := localbinary.NewLocalBinaryPlugin(driverName)

	go func() {
		if err := p.Serve(); err != nil {
			// If we can't safely load the server, best to just
			// bail.
			log.Fatal(err)
		}
	}()

	addr, err := p.Address()
	if err != nil {
		return nil, fmt.Errorf("Error attempting to get plugin server address for RPC: %s", err)
	}

	rpcclient, err := rpc.DialHTTP("tcp", addr)
	if err != nil {
		return nil, err
	}

	c := &RpcClientDriver{
		Client:          NewInternalClient(rpcclient),
		heartbeatDoneCh: make(chan bool),
	}

	go func(heartbeatDoneCh <-chan bool) {
		for {
			select {
			case <-heartbeatDoneCh:
				return
			default:
				if err := c.Client.Call("RpcServerDriver.Heartbeat", struct{}{}, nil); err != nil {
					log.Warnf("Error attempting heartbeat call to plugin server: %s", err)
				}
				time.Sleep(heartbeatInterval)
			}
		}
	}(c.heartbeatDoneCh)

	var version int
	if err := c.Client.Call("RpcServerDriver.GetVersion", struct{}{}, &version); err != nil {
		return nil, err
	}
	log.Debug("Using API Version ", version)

	if err := c.SetConfigRaw(rawDriverData); err != nil {
		return nil, err
	}

	mcnName = c.GetMachineName()
	p.MachineName = mcnName
	c.Client.MachineName = mcnName
	c.plugin = p

	return c, nil
}
Пример #15
0
func (c *RpcClientDriver) GetSSHPassword() string {
	password, err := c.rpcStringCall("RpcServerDriver.GetSSHPassword")
	if err != nil {
		log.Warnf("Error attempting call to get SSH password: %s", err)
	}

	return password
}
Пример #16
0
func (c *RPCClientDriver) GlobalArtifactPath() string {
	globalArtifactPath, err := c.rpcStringCall("RPCServerDriver.GlobalArtifactPath")
	if err != nil {
		log.Warnf("Error attempting call to get GlobalArtifactPath: %s", err)
	}

	return globalArtifactPath
}
Пример #17
0
func (c *RPCClientDriver) GetSSHUsername() string {
	username, err := c.rpcStringCall("RPCServerDriver.GetSSHUsername")
	if err != nil {
		log.Warnf("Error attempting call to get SSH username: %s", err)
	}

	return username
}
Пример #18
0
// GetSSHKeyPath returns the key path
// TODO:  This method doesn't even make sense to have with RPC.
func (c *RPCClientDriver) GetSSHKeyPath() string {
	path, err := c.rpcStringCall("RPCServerDriver.GetSSHKeyPath")
	if err != nil {
		log.Warnf("Error attempting call to get SSH key path: %s", err)
	}

	return path
}
Пример #19
0
func (c *RPCClientDriver) GetMachineName() string {
	name, err := c.rpcStringCall("RPCServerDriver.GetMachineName")
	if err != nil {
		log.Warnf("Error attempting call to get machine name: %s", err)
	}

	return name
}
Пример #20
0
// DriverName returns the name of the driver
func (c *RPCClientDriver) DriverName() string {
	driverName, err := c.rpcStringCall("RPCServerDriver.DriverName")
	if err != nil {
		log.Warnf("Error attempting call to get driver name: %s", err)
	}

	return driverName
}
Пример #21
0
func (*b2dReleaseGetter) download(dir, file, isoURL string) error {
	u, err := url.Parse(isoURL)

	var src io.ReadCloser
	if u.Scheme == "file" || u.Scheme == "" {
		s, err := os.Open(u.Path)
		if err != nil {
			return err
		}

		src = s
	} else {
		client := getClient()
		s, err := client.Get(isoURL)
		if err != nil {
			return err
		}

		src = &ReaderWithProgress{
			ReadCloser:     s.Body,
			out:            os.Stdout,
			expectedLength: s.ContentLength,
		}
	}

	defer src.Close()

	// Download to a temp file first then rename it to avoid partial download.
	f, err := ioutil.TempFile(dir, file+".tmp")
	if err != nil {
		return err
	}

	defer func() {
		if err := removeFileIfExists(f.Name()); err != nil {
			log.Warnf("Error removing file: %s", err)
		}
	}()

	if _, err := io.Copy(f, src); err != nil {
		return err
	}

	if err := f.Close(); err != nil {
		return err
	}

	// Dest is the final path of the boot2docker.iso file.
	dest := filepath.Join(dir, file)

	// Windows can't rename in place, so remove the old file before
	// renaming the temporary downloaded file.
	if err := removeFileIfExists(dest); err != nil {
		return err
	}

	return os.Rename(f.Name(), dest)
}
Пример #22
0
func stream(scanner *bufio.Scanner, streamOutCh chan<- string) {
	for scanner.Scan() {
		line := scanner.Text()
		if err := scanner.Err(); err != nil {
			log.Warnf("Scanning stream: %s", err)
		}
		streamOutCh <- strings.Trim(line, "\n")
	}
}
Пример #23
0
func (d *Driver) Create() error {
	b2dutils := mcnutils.NewB2dUtils(d.StorePath)
	if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
		return err
	}

	log.Infof("Creating SSH key...")
	if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil {
		return err
	}

	if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil {
		return err
	}

	// Libvirt typically runs as a deprivileged service account and
	// needs the execute bit set for directories that contain disks
	for dir := d.ResolveStorePath("."); dir != "/"; dir = filepath.Dir(dir) {
		log.Debugf("Verifying executable bit set on %s", dir)
		info, err := os.Stat(dir)
		if err != nil {
			return err
		}
		mode := info.Mode()
		if mode&0001 != 1 {
			log.Debugf("Setting executable bit set on %s", dir)
			mode |= 0001
			os.Chmod(dir, mode)
		}
	}

	log.Debugf("Creating VM data disk...")
	if err := d.generateDiskImage(d.DiskSize); err != nil {
		return err
	}

	log.Debugf("Defining VM...")
	tmpl, err := template.New("domain").Parse(domainXMLTemplate)
	if err != nil {
		return err
	}
	var xml bytes.Buffer
	err = tmpl.Execute(&xml, d)
	if err != nil {
		return err
	}

	vm, err := d.conn.DomainDefineXML(xml.String())
	if err != nil {
		log.Warnf("Failed to create the VM: %s", err)
		return err
	}
	d.VM = &vm
	d.vmLoaded = true

	return d.Start()
}
Пример #24
0
func (provisioner *SUSEProvisioner) dockerDaemonResponding() bool {
	if _, err := provisioner.SSHCommand("sudo docker version"); err != nil {
		log.Warnf("Error getting SSH command to check if the daemon is up: %s", err)
		return false
	}

	// The daemon is up if the command worked.  Carry on.
	return true
}
Пример #25
0
func (c *RPCClientDriver) LocalArtifactPath(file string) string {
	var path string

	if err := c.Client.Call("RPCServerDriver.LocalArtifactPath", file, &path); err != nil {
		log.Warnf("Error attempting call to get LocalArtifactPath: %s", err)
	}

	return path
}
Пример #26
0
func (c *RPCClientDriver) GetCreateFlags() []mcnflag.Flag {
	var flags []mcnflag.Flag

	if err := c.Client.Call("RPCServerDriver.GetCreateFlags", struct{}{}, &flags); err != nil {
		log.Warnf("Error attempting call to get create flags: %s", err)
	}

	return flags
}
Пример #27
0
func (c *RpcClientDriver) SSHSudo(command string) string {
	var escaped string

	if err := c.Client.Call("RpcServerDriver.SSHSudo", command, &escaped); err != nil {
		log.Warnf("Error attempting call to get SSHSudo: %s", err)
	}

	return escaped
}
Пример #28
0
// Download boot2docker ISO image for the given tag and save it at dest.
func (b *B2dUtils) DownloadISO(dir, file, isoUrl string) error {
	u, err := url.Parse(isoUrl)
	var src io.ReadCloser
	if u.Scheme == "file" || u.Scheme == "" {
		s, err := os.Open(u.Path)
		if err != nil {
			return err
		}
		src = s
	} else {
		client := getClient()
		s, err := client.Get(isoUrl)
		if err != nil {
			return err
		}
		src = s.Body
	}

	defer src.Close()

	// Download to a temp file first then rename it to avoid partial download.
	f, err := ioutil.TempFile(dir, file+".tmp")
	if err != nil {
		return err
	}

	defer func() {
		if err := removeFileIfExists(f.Name()); err != nil {
			log.Warnf("Error removing file: %s", err)
		}
	}()

	if _, err := io.Copy(f, src); err != nil {
		// TODO: display download progress?
		return err
	}

	if err := f.Close(); err != nil {
		return err
	}

	// Dest is the final path of the boot2docker.iso file.
	dest := filepath.Join(dir, file)

	// Windows can't rename in place, so remove the old file before
	// renaming the temporary downloaded file.
	if err := removeFileIfExists(dest); err != nil {
		return err
	}

	if err := os.Rename(f.Name(), dest); err != nil {
		return err
	}

	return nil
}
Пример #29
0
func (provisioner *UbuntuProvisioner) dockerDaemonResponding() bool {
	docker_version_command := provisioner.Driver.SSHSudo("docker version")
	if _, err := provisioner.SSHCommand(docker_version_command); err != nil {
		log.Warnf("Error getting SSH command to check if the daemon is up: %s", err)
		return false
	}

	// The daemon is up if the command worked.  Carry on.
	return true
}
Пример #30
0
func generateId() string {
	rb := make([]byte, 10)
	_, err := rand.Read(rb)
	if err != nil {
		log.Warnf("Unable to generate id: %s", err)
	}

	h := md5.New()
	io.WriteString(h, string(rb))
	return fmt.Sprintf("%x", h.Sum(nil))
}