Files
docker-machine/drivers/hyperv/powershell.go

115 lines
2.4 KiB
Go
Raw Normal View History

package hyperv
import (
"bufio"
"bytes"
"errors"
"os/exec"
"strings"
"fmt"
Make libmachine usable by outside world - Clear out some cruft tightly coupling libmachine to filestore - Comment out drivers other than virtualbox for now - Change way too many things - Mostly, break out the code to be more modular. - Destroy all traces of "provider" in its current form. It will be brought back as something more sensible, instead of something which overlaps in function with both Host and Store. - Fix mis-managed config passthru - Remove a few instances of state stored in env vars - This should be explicitly communicated in Go-land, not through the shell. - Rename "store" module to "persist" - This is done mostly to avoid confusion about the fact that a concrete instance of a "Store" interface is oftentimes referred to as "store" in the code. - Rip out repetitive antipattern for getting store - This replaces the previous repetive idiom for getting the cert info, and consequently the store, with a much less repetitive idiom. - Also, some redundant methods in commands.go for accessing hosts have either been simplified or removed entirely. - First steps towards fixing up tests - Test progress continues - Replace unit tests with integration tests - MAKE ALL UNIT TESTS PASS YAY - Add helper test files - Don't write to disk in libmachine/host - Heh.. coverage check strikes again - Fix remove code - Move cert code around - Continued progress: simplify Driver - Fixups and make creation work with new model - Move drivers module inside of libmachine - Move ssh module inside of libmachine - Move state module to libmachine - Move utils module to libmachine - Move version module to libmachine - Move log module to libmachine - Modify some constructor methods around - Change Travis build dep structure - Boring gofmt fix - Add version module - Move NewHost to store - Update some boring cert path infos to make API easier to use - Fix up some issues around the new model - Clean up some cert path stuff - Don't use shady functions to get store path :D - Continue artifact work - Fix silly machines dir bug - Continue fixing silly path issues - Change up output of vbm a bit - Continue work to make example go - Change output a little more - Last changes needed to make create finish properly - Fix config.go to use libmachine - Cut down code duplication and make both methods work with libmachine - Add pluggable logging implementation - Return error when machine already in desired state - Update example to show log method - Fix file:// bug - Fix Swarm defaults - Remove unused TLS settings from Engine and Swarm options - Remove spurious error - Correct bug detecting if migration was performed - Fix compilation errors from tests - Fix most of remaining test issues - Fix final silly bug in tests - Remove extraneous debug code - Add -race to test command - Appease the gofmt - Appease the generate coverage - Making executive decision to remove Travis coverage check In the early days I thought this would be a good idea because it would encourage people to write tests in case they added a new module. Well, in fact it has just turned into a giant nuisance and made refactoring work like this even more difficult. - Move Get to Load - Move HostListItem code to CLI Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
2015-08-18 11:26:42 +09:00
"github.com/docker/machine/libmachine/log"
)
var powershell string
var (
ErrPowerShellNotFound = errors.New("Powershell was not found in the path")
ErrNotAdministrator = errors.New("Hyper-v commands have to be run as an Administrator")
ErrNotInstalled = errors.New("Hyper-V PowerShell Module is not available")
)
func init() {
powershell, _ = exec.LookPath("powershell.exe")
}
func cmdOut(args ...string) (string, error) {
args = append([]string{"-NoProfile", "-NonInteractive"}, args...)
cmd := exec.Command(powershell, args...)
log.Debugf("[executing ==>] : %v %v", powershell, strings.Join(args, " "))
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
log.Debugf("[stdout =====>] : %s", stdout.String())
log.Debugf("[stderr =====>] : %s", stderr.String())
return stdout.String(), err
}
func cmd(args ...string) error {
_, err := cmdOut(args...)
return err
}
func parseLines(stdout string) []string {
resp := []string{}
s := bufio.NewScanner(strings.NewReader(stdout))
for s.Scan() {
resp = append(resp, s.Text())
}
return resp
}
func hypervAvailable() error {
stdout, err := cmdOut("@(Get-Command Get-VM).ModuleName")
if err != nil {
return err
}
resp := parseLines(stdout)
if resp[0] != "Hyper-V" {
return ErrNotInstalled
}
return nil
}
func isAdministrator() (bool, error) {
hypervAdmin := isHypervAdministrator()
if hypervAdmin {
return true, nil
}
windowsAdmin, err := isWindowsAdministrator()
if err != nil {
return false, err
}
return windowsAdmin, nil
}
func isHypervAdministrator() bool {
stdout, err := cmdOut(`@([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Hyper-V Administrators")`)
if err != nil {
log.Debug(err)
return false
}
resp := parseLines(stdout)
return resp[0] == "True"
}
func isWindowsAdministrator() (bool, error) {
stdout, err := cmdOut(`@([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")`)
if err != nil {
return false, err
}
resp := parseLines(stdout)
return resp[0] == "True", nil
}
func quote(text string) string {
return fmt.Sprintf("'%s'", text)
}
func toMb(value int) string {
return fmt.Sprintf("%dMB", value)
}