// Upgrade the boot2docker ISO - preserving server state func cmdUpgrade() error { if runtime.GOOS == "darwin" || runtime.GOOS == "linux" { if B2D.Clobber { err := upgradeDockerClientBinary() if err != nil { return err } } else { fmt.Println("Skipping client binary download, use --clobber=true to enable...") } } if err := upgradeBoot2DockerBinary(); err != nil { return fmt.Errorf("Error upgrading boot2docker binary: %s", err) } m, err := driver.GetMachine(&B2D) if err == nil { if m.GetState() == driver.Running || m.GetState() == driver.Saved || m.GetState() == driver.Paused { // Windows won't let us move the ISO aside while it's in use if err = cmdStop(); err == nil { if err = cmdDownload(); err == nil { err = cmdUp() } } return err } } return cmdDownload() }
// Give the user the exact command to run to set the env. func cmdShellInit() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if m.GetState() != driver.Running { return vmNotRunningError(B2D.VM) } socket, err := RequestSocketFromSSH(m) if err != nil { return fmt.Errorf("Error requesting socket: %s\n", err) } certPath, err := RequestCertsUsingSSH(m) if err != nil { // These errors are not fatal fmt.Fprintf(os.Stderr, "Warning: error copying certificates: %s\n", err) } // Check if $DOCKER_* ENV vars are properly configured. if !checkEnvironment(socket, certPath) { printExport(socket, certPath) } else { fmt.Fprintf(os.Stderr, "Your environment variables are already set correctly.\n") } return nil }
// Initialize the boot2docker VM from scratch. func cmdInit() error { B2D.Init = false _, err := driver.GetMachine(&B2D) if err == nil { fmt.Printf("Virtual machine %s already exists\n", B2D.VM) return nil } if _, err := os.Stat(B2D.ISO); err != nil { if !os.IsNotExist(err) { return fmt.Errorf("Failed to open ISO image %q: %s", B2D.ISO, err) } if err := cmdDownload(); err != nil { return err } } if _, err := os.Stat(B2D.SSHKey); err != nil { if !os.IsNotExist(err) { return fmt.Errorf("Something wrong with SSH Key file %q: %s", B2D.SSHKey, err) } cmd := exec.Command(B2D.SSHGen, "-t", "rsa", "-N", "", "-f", B2D.SSHKey) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if B2D.Verbose { cmd.Stderr = os.Stderr fmt.Printf("executing: %v %v\n", cmd.Path, strings.Join(cmd.Args, " ")) } if err := cmd.Run(); err != nil { return fmt.Errorf("Error generating new SSH Key into %s: %s", B2D.SSHKey, err) } } //TODO: print a ~/.ssh/config entry for our b2d connection that the user can c&p B2D.Init = true _, err = driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to initialize machine %q: %s", B2D.VM, err) } fmt.Printf("Initialization of virtual machine %q complete.\n", B2D.VM) fmt.Printf("Use `boot2docker up` to start it.\n") return nil }
// Show the current state of the VM. func cmdStatus() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } fmt.Println(m.GetState()) return nil }
// Forcefully reset (equivalent to cold boot) the VM. Might corrupt disk image. func cmdReset() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if err := m.Reset(); err != nil { return fmt.Errorf("Failed to reset machine %q: %s", B2D.VM, err) } return nil }
// Forcefully power off the VM (equivalent to unplug power). Might corrupt disk // image. func cmdPoweroff() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if err := m.Poweroff(); err != nil { return fmt.Errorf("Failed to poweroff machine %q: %s", B2D.VM, err) } return nil }
// Suspend and save the current state of VM on disk. func cmdSave() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s\n", B2D.VM, err) } if err := m.Save(); err != nil { return fmt.Errorf("Failed to save machine %q: %s\n", B2D.VM, err) } return nil }
// Delete the VM and associated disk image. func cmdDelete() error { m, err := driver.GetMachine(&B2D) if err != nil { if err == driver.ErrMachineNotExist { return fmt.Errorf("Machine %q does not exist.", B2D.VM) } return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if err := m.Delete(); err != nil { return fmt.Errorf("Failed to delete machine %q: %s", B2D.VM, err) } return nil }
// Show detailed info of the VM. func cmdInfo() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } b, err := json.MarshalIndent(m, "", "\t") if err != nil { return fmt.Errorf("Failed to encode machine %q info: %s", B2D.VM, err) } os.Stdout.Write(b) return nil }
// Upgrade the boot2docker ISO - preserving server state func cmdUpgrade() error { m, err := driver.GetMachine(&B2D) if err == nil { if m.GetState() == driver.Running || m.GetState() == driver.Saved || m.GetState() == driver.Paused { // Windows won't let us move the ISO aside while it's in use if err = cmdStop(); err == nil { if err = cmdDownload(); err == nil { err = cmdUp() } } return err } } return cmdDownload() }
// Upgrade the boot2docker ISO - preserving server state func cmdUpgrade() error { if err := upgradeBoot2DockerBinary(); err != nil { return fmt.Errorf("Error upgrading boot2docker binary: %s", err) } m, err := driver.GetMachine(&B2D) if err == nil { if m.GetState() == driver.Running || m.GetState() == driver.Saved || m.GetState() == driver.Paused { // Windows won't let us move the ISO aside while it's in use if err = cmdStop(); err == nil { if err = cmdDownload(); err == nil { err = cmdUp() } } return err } } return cmdDownload() }
// Call the external SSH command to login into boot2docker VM. func cmdSSH() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if m.GetState() != driver.Running { return vmNotRunningError(B2D.VM) } // find the ssh cmd string and then pass any remaining strings to ssh // TODO: it's a shame to repeat the same code as in config.go, but I // didn't find a way to share the unsharable without more rework i := 1 for i < len(os.Args) && os.Args[i-1] != "ssh" { i++ } if err := cmdInteractive(m, os.Args[i:]...); err != nil { return fmt.Errorf("%s", err) } return nil }
func cmdIP() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if m.GetState() != driver.Running { return vmNotRunningError(B2D.VM) } IP := "" if B2D.Serial { if runtime.GOOS != "windows" { if IP, err = RequestIPFromSerialPort(m.GetSerialFile()); err != nil { if B2D.Verbose { fmt.Printf("Error getting IP via Serial: %s\n", err) } } } } if IP == "" { if IP, err = RequestIPFromSSH(m); err != nil { if B2D.Verbose { fmt.Printf("Error getting IP via SSH: %s\n", err) } } } if IP != "" { fmt.Println(IP) } else { fmt.Fprintf(os.Stderr, "\nFailed to get VM Host only IP address.\n") fmt.Fprintf(os.Stderr, "\tWas the VM initialized using boot2docker?\n") } return nil }
// Give the user the exact command to run to set the env. func cmdShellInit() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if m.GetState() != driver.Running { return fmt.Errorf("VM %q is not running.", B2D.VM) } socket, err := RequestSocketFromSSH(m) if err != nil { return fmt.Errorf("Error requesting socket: %s\n", err) } certPath, err := RequestCertsUsingSSH(m) if err != nil { // These errors are not fatal fmt.Fprintf(os.Stderr, "Warning: error copying certificates: %s\n", err) } printExport(socket, certPath) return nil }
// Bring up the VM from all possible states. func cmdUp() error { m, err := driver.GetMachine(&B2D) if err != nil { return fmt.Errorf("Failed to get machine %q: %s", B2D.VM, err) } if err := m.Start(); err != nil { return fmt.Errorf("Failed to start machine %q: %s", B2D.VM, err) } if err := m.Refresh(); err != nil { return fmt.Errorf("Failed to start machine %q: %s", B2D.VM, err) } if m.GetState() != driver.Running { return fmt.Errorf("Failed to start machine %q (run again with -v for details)", B2D.VM) } fmt.Println("Waiting for VM and Docker daemon to start...") //give the VM a little time to start, so we don't kill the Serial Pipe/Socket time.Sleep(time.Duration(B2D.Waittime) * time.Millisecond) natSSH := fmt.Sprintf("localhost:%d", m.GetSSHPort()) IP := "" for i := 1; i < B2D.Retries; i++ { print(".") if B2D.Serial && runtime.GOOS != "windows" { if IP, err = RequestIPFromSerialPort(m.GetSerialFile()); err == nil { break } } if err := read(natSSH, 1, time.Duration(B2D.Waittime)*time.Millisecond); err == nil { if IP, err = RequestIPFromSSH(m); err == nil { break } } } if B2D.Verbose { fmt.Printf("VM Host-only IP address: %s", IP) fmt.Printf("\nWaiting for Docker daemon to start...\n") } time.Sleep(time.Duration(B2D.Waittime) * time.Millisecond) socket := "" for i := 1; i < B2D.Retries; i++ { print("o") if socket, err = RequestSocketFromSSH(m); err == nil { break } if B2D.Verbose { fmt.Printf("Error requesting socket: %s\n", err) } time.Sleep(600 * time.Millisecond) } fmt.Printf("\nStarted.\n") if socket == "" { // lets try one more time time.Sleep(time.Duration(B2D.Waittime) * time.Millisecond) fmt.Printf(" Trying to get Docker socket one more time\n") if socket, err = RequestSocketFromSSH(m); err != nil { fmt.Printf("Error requesting socket: %s\n", err) } } // Copying the certs here - someone might have have written a Windows API client. certPath, err := RequestCertsUsingSSH(m) if err != nil { // These errors are not fatal fmt.Fprintf(os.Stderr, "Warning: error copying certificates: %s\n", err) } if socket == "" { fmt.Fprintf(os.Stderr, "Auto detection of the VM's Docker socket failed.\n") fmt.Fprintf(os.Stderr, "Please run `boot2docker -v up` to diagnose.\n") } else { // Check if $DOCKER_* ENV vars are properly configured. if !checkEnvironment(socket, certPath) { fmt.Printf("\nTo connect the Docker client to the Docker daemon, please set:\n") printExport(socket, certPath) } else { fmt.Printf("Your environment variables are already set correctly.\n") } } fmt.Printf("\n") return nil }