cord-776 create build / runtime containers for autmation uservices
Change-Id: I246973192adef56a250ffe93a5f65fff488840c1
diff --git a/switchq/vendor/github.com/juju/utils/file_windows.go b/switchq/vendor/github.com/juju/utils/file_windows.go
new file mode 100644
index 0000000..9bb3936
--- /dev/null
+++ b/switchq/vendor/github.com/juju/utils/file_windows.go
@@ -0,0 +1,142 @@
+// Copyright 2013 Canonical Ltd.
+// Licensed under the LGPLv3, see LICENCE file for details.
+
+// +build windows
+
+package utils
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "syscall"
+ "unsafe"
+
+ "github.com/juju/errors"
+)
+
+const (
+ movefile_replace_existing = 0x1
+ movefile_write_through = 0x8
+)
+
+//sys moveFileEx(lpExistingFileName *uint16, lpNewFileName *uint16, dwFlags uint32) (err error) = MoveFileExW
+
+// MoveFile atomically moves the source file to the destination, returning
+// whether the file was moved successfully. If the destination already exists,
+// it returns an error rather than overwrite it.
+func MoveFile(source, destination string) (bool, error) {
+ src, err := syscall.UTF16PtrFromString(source)
+ if err != nil {
+ return false, &os.LinkError{"move", source, destination, err}
+ }
+ dest, err := syscall.UTF16PtrFromString(destination)
+ if err != nil {
+ return false, &os.LinkError{"move", source, destination, err}
+ }
+
+ // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365240(v=vs.85).aspx
+ if err := moveFileEx(src, dest, movefile_write_through); err != nil {
+ return false, &os.LinkError{"move", source, destination, err}
+ }
+ return true, nil
+
+}
+
+// ReplaceFile atomically replaces the destination file or directory with the source.
+// The errors that are returned are identical to those returned by os.Rename.
+func ReplaceFile(source, destination string) error {
+ src, err := syscall.UTF16PtrFromString(source)
+ if err != nil {
+ return &os.LinkError{"replace", source, destination, err}
+ }
+ dest, err := syscall.UTF16PtrFromString(destination)
+ if err != nil {
+ return &os.LinkError{"replace", source, destination, err}
+ }
+
+ // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365240(v=vs.85).aspx
+ if err := moveFileEx(src, dest, movefile_replace_existing|movefile_write_through); err != nil {
+ return &os.LinkError{"replace", source, destination, err}
+ }
+ return nil
+}
+
+// MakeFileURL returns a proper file URL for the given path/directory
+func MakeFileURL(in string) string {
+ in = filepath.ToSlash(in)
+ // for windows at least should be <letter>: to be considered valid
+ // so we cant do anything with less than that.
+ if len(in) < 2 {
+ return in
+ }
+ if string(in[1]) != ":" {
+ return in
+ }
+ // since go 1.6 http client will only take this format.
+ return "file://" + in
+}
+
+func getUserSID(username string) (string, error) {
+ sid, _, _, e := syscall.LookupSID("", username)
+ if e != nil {
+ return "", e
+ }
+ sidStr, err := sid.String()
+ return sidStr, err
+}
+
+func readRegString(h syscall.Handle, key string) (value string, err error) {
+ var typ uint32
+ var buf uint32
+
+ // Get size of registry key
+ err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(key), nil, &typ, nil, &buf)
+ if err != nil {
+ return value, err
+ }
+
+ n := make([]uint16, buf/2+1)
+ err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(key), nil, &typ, (*byte)(unsafe.Pointer(&n[0])), &buf)
+ if err != nil {
+ return value, err
+ }
+ return syscall.UTF16ToString(n[:]), err
+}
+
+func homeFromRegistry(sid string) (string, error) {
+ var h syscall.Handle
+ // This key will exist on all platforms we support the agent on (windows server 2008 and above)
+ keyPath := fmt.Sprintf("Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%s", sid)
+ err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
+ syscall.StringToUTF16Ptr(keyPath),
+ 0, syscall.KEY_READ, &h)
+ if err != nil {
+ return "", err
+ }
+ defer syscall.RegCloseKey(h)
+ str, err := readRegString(h, "ProfileImagePath")
+ if err != nil {
+ return "", err
+ }
+ return str, nil
+}
+
+// homeDir returns a local user home dir on Windows
+// user.Lookup() does not populate Gid and HomeDir on Windows,
+// so we get it from the registry
+func homeDir(user string) (string, error) {
+ u, err := getUserSID(user)
+ if err != nil {
+ return "", errors.NewUserNotFound(err, "no such user")
+ }
+ return homeFromRegistry(u)
+}
+
+// ChownPath is not implemented for Windows.
+func ChownPath(path, username string) error {
+ // This only exists to allow building on Windows. User lookup and
+ // file ownership needs to be handled in a completely different
+ // way and hasn't yet been implemented.
+ return nil
+}