← Back to team overview

ubuntu-sdk-team team mailing list archive

[Merge] lp:~kalikiana/ubuntu-sdk-tools/lxd-snap into lp:ubuntu-sdk-tools

 

Christian Dywan has proposed merging lp:~kalikiana/ubuntu-sdk-tools/lxd-snap into lp:ubuntu-sdk-tools.

Commit message:
Detect and use lxd from the snap

Requested reviews:
  Ubuntu SDK team (ubuntu-sdk-team)

For more details, see:
https://code.launchpad.net/~kalikiana/ubuntu-sdk-tools/lxd-snap/+merge/308901
-- 
Your team Ubuntu SDK team is requested to review the proposed merge of lp:~kalikiana/ubuntu-sdk-tools/lxd-snap into lp:ubuntu-sdk-tools.
=== modified file 'fixables/containerAccess.go'
--- fixables/containerAccess.go	2016-06-24 12:12:46 +0000
+++ fixables/containerAccess.go	2016-11-30 15:36:23 +0000
@@ -18,41 +18,42 @@
 package fixables
 
 import (
+	"fmt"
+	"github.com/lxc/lxd"
 	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd"
+	"launchpad.net/ubuntu-sdk-tools"
 	"os"
-	"fmt"
 	"path/filepath"
-	"launchpad.net/ubuntu-sdk-tools"
 )
 
-type ContainerAccess struct { }
+type ContainerAccess struct{}
+
 func (*ContainerAccess) run(client *lxd.Client, container string, doFix bool) error {
 	targetPath := shared.VarPath("containers", container)
 	fi, err := os.Lstat(targetPath)
 	if err != nil {
-		return fmt.Errorf("Failed to query container access permissions\n",err)
+		return fmt.Errorf("Failed to query container access permissions\n", err)
 	}
 
-	if fi.Mode() & os.ModeSymlink == os.ModeSymlink {
+	if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
 		targetPath, err = filepath.EvalSymlinks(targetPath)
 		if err != nil {
-			return fmt.Errorf("Failed to read rootfs link. error: %v.\n",err)
+			return fmt.Errorf("Failed to read rootfs link. error: %v.\n", err)
 		}
 
 		fi, err = os.Lstat(targetPath)
 		if err != nil {
-			return fmt.Errorf("Failed to query container access permissions\n",err)
+			return fmt.Errorf("Failed to query container access permissions\n", err)
 		}
 	}
 
-	if fi.Mode() != os.ModeDir | ubuntu_sdk_tools.LxdContainerPerm {
+	if fi.Mode() != os.ModeDir|ubuntu_sdk_tools.LxdContainerPerm {
 		if !doFix {
-			return fmt.Errorf("Wrong directory permissions. Container rootfs of %s is not accessible.", container)
+			fmt.Printf("Wrong directory permissions. Container rootfs of %s is not accessible.", container)
 		} else {
 			err = os.Chmod(targetPath, ubuntu_sdk_tools.LxdContainerPerm)
 			if err != nil {
-				return fmt.Errorf("Failed to make container readable. error: %v.\n",err)
+				fmt.Printf("Failed to make container readable. error: %v.\n", err)
 			}
 		}
 
@@ -105,6 +106,6 @@
 	return nil
 }
 
-func (*ContainerAccess) NeedsRoot () bool {
+func (*ContainerAccess) NeedsRoot() bool {
 	return true
 }

=== modified file 'fixables/dri.go'
--- fixables/dri.go	2016-06-24 12:12:46 +0000
+++ fixables/dri.go	2016-11-30 15:36:23 +0000
@@ -18,29 +18,36 @@
 package fixables
 
 import (
+	"fmt"
 	"github.com/lxc/lxd"
+	"github.com/lxc/lxd/shared"
+	"launchpad.net/ubuntu-sdk-tools"
+	"os"
 	"path/filepath"
-	"launchpad.net/ubuntu-sdk-tools"
-	"github.com/lxc/lxd/shared"
-	"fmt"
 )
 
-type DRIFixable struct { }
+type DRIFixable struct{}
 
 func (*DRIFixable) run(client *lxd.Client, container *shared.ContainerInfo, doFix bool) error {
+	// FIXME: dri device isn't accessible under confinement
+	if os.Getenv("SNAP") != "" {
+		fmt.Fprintf(os.Stderr, "Skipping adding /dev/dri/card*\n")
+		return nil
+	}
+
 	files, err := filepath.Glob("/dev/dri/card*")
 	if err != nil {
 		return err
 	}
 
-	for _,node := range files {
+	for _, node := range files {
 		if !container.Devices.ContainsName(node) {
 			if doFix {
 				muh := container.Name
 				err = ubuntu_sdk_tools.AddDeviceSync(
 					client, muh,
 					node, "unix-char",
-					[]string{fmt.Sprintf("path=%s", node[1:]),"gid=44"},
+					[]string{fmt.Sprintf("path=%s", node[1:]), "gid=44"},
 				)
 				if err != nil {
 					return err
@@ -103,6 +110,6 @@
 	return nil
 }
 
-func (*DRIFixable) NeedsRoot () bool {
+func (*DRIFixable) NeedsRoot() bool {
 	return false
-}
\ No newline at end of file
+}

=== modified file 'helpers.go'
--- helpers.go	2016-07-06 09:22:33 +0000
+++ helpers.go	2016-11-30 15:36:23 +0000
@@ -24,26 +24,26 @@
 package ubuntu_sdk_tools
 
 import (
+	"fmt"
 	"github.com/lxc/lxd"
 	"github.com/lxc/lxd/shared"
+	"log"
+	"os"
 	"path"
-	"os"
-	"fmt"
-	"log"
-	"os/exec"
 	"strings"
 )
 
 const LxdBridgeFile = "/etc/default/lxd-bridge"
 const LxdContainerPerm = 0755
+
 var globConfig *lxd.Config = nil
 
 type ClickContainer struct {
-	Name string `json:"name"`
-	Architecture string `json:"architecture"`
-	Framework string `json:"framework"`
-	UpdatesEnabled bool `json:"updatesEnabled"`
-	Container shared.ContainerInfo `json:"-"`
+	Name           string               `json:"name"`
+	Architecture   string               `json:"architecture"`
+	Framework      string               `json:"framework"`
+	UpdatesEnabled bool                 `json:"updatesEnabled"`
+	Container      shared.ContainerInfo `json:"-"`
 }
 
 func EnsureLXDInitializedOrDie() {
@@ -51,48 +51,26 @@
 
 	//let's register a new remote
 	defaultImageRemote := "https://sdk-images.canonical.com";
-	if (len(os.Getenv("USDK_TEST_REMOTE")) != 0) {
+	if len(os.Getenv("USDK_TEST_REMOTE")) != 0 {
 		defaultImageRemote = os.Getenv("USDK_TEST_REMOTE")
 	}
 
-	defaultRemoteName  := "ubuntu-sdk-images"
-	remotes := config.Remotes
-	sdkRem, ok := remotes[defaultRemoteName]
-	if ok {
-		if sdkRem.Addr == defaultImageRemote {
-			return
-		} else {
-			cmd := exec.Command("lxc", "remote", "remove", defaultRemoteName)
-			err := cmd.Run()
-			if (err != nil) {
-				fmt.Fprintf(os.Stderr, "Could not remove the remote "+defaultRemoteName+". error: %v\n", err)
-				fmt.Fprintf(os.Stderr, "Please remove it manually.\n", err)
-				os.Exit(1)
-			}
-		}
-	}
-
-	cmd := exec.Command("lxc", "remote", "add", "ubuntu-sdk-images", defaultImageRemote, "--accept-certificate", "--protocol=simplestreams")
-	err := cmd.Run()
-	if (err != nil) {
-		fmt.Fprintf(os.Stderr, "Could not register remote. error: %v\n", err)
-		os.Exit(1)
-	}
-
-	//make sure config is loaded again
-	globConfig = nil
+	defaultRemoteName := "ubuntu-sdk-images"
+
+	config.Remotes[defaultRemoteName] = lxd.RemoteConfig{
+		Addr:     defaultImageRemote,
+		Static:   true,
+		Public:   true,
+		Protocol: "simplestreams"}
 }
 
-func GetConfigOrDie ()  (*lxd.Config) {
+func GetConfigOrDie() *lxd.Config {
 
 	if globConfig != nil {
 		return globConfig
 	}
 
-	configDir := "$HOME/.config/lxc"
-	if os.Getenv("LXD_CONF") != "" {
-		configDir = os.Getenv("LXD_CONF")
-	}
+	configDir := "$XDG_CONFIG_HOME/ubuntu-sdk-target"
 	configPath := os.ExpandEnv(path.Join(configDir, "config.yml"))
 
 	globConfig, err := lxd.LoadConfig(configPath)
@@ -117,10 +95,19 @@
 		}
 	}
 
+	_, err = lxd.NewClient(globConfig, globConfig.DefaultRemote)
+	if err != nil {
+		os.Setenv("LXD_DIR", "/var/snap/lxd/common/lxd")
+		_, err = lxd.NewClient(globConfig, globConfig.DefaultRemote)
+		if err != nil {
+			log.Fatal("Can't establish a working socket connection: %s", err)
+		}
+	}
+
 	return globConfig
 }
 
-func BootContainerSync (client *lxd.Client, name string) error {
+func BootContainerSync(client *lxd.Client, name string) error {
 	current, err := client.ContainerInfo(name)
 	if err != nil {
 		return err
@@ -137,7 +124,6 @@
 		action = shared.Unfreeze
 	}
 
-
 	resp, err := client.Action(name, action, 10, false, false)
 	if err != nil {
 		return err
@@ -153,7 +139,7 @@
 	return nil
 }
 
-func StopContainerSync  (client *lxd.Client, container string) error {
+func StopContainerSync(client *lxd.Client, container string) error {
 	ct, err := client.ContainerInfo(container)
 	if err != nil {
 		return err
@@ -180,7 +166,7 @@
 	return nil
 }
 
-func UpdateConfigSync (client *lxd.Client, container string) error {
+func UpdateConfigSync(client *lxd.Client, container string) error {
 	fmt.Printf("Applying changes to container: %s\n", container)
 	err := StopContainerSync(client, container)
 	if err != nil {
@@ -188,24 +174,20 @@
 	}
 
 	err = BootContainerSync(client, container)
-	if ( err != nil ) {
+	if err != nil {
 		return err
 	}
 
-	command := []string {
-		"exec", container, "--",
+	command := []string{
 		"bash", "-c", "rm /etc/ld.so.cache; ldconfig",
 	}
 
-	cmd := exec.Command("lxc", command...)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-
-	return cmd.Run()
+	_, err = client.Exec(container, command, nil, os.Stdin, os.Stdout, os.Stderr, nil, 0, 0)
+	return err
 }
 
-func AddDeviceSync (client *lxd.Client, container, devname, devtype string, props []string) error{
-	fmt.Printf("Adding device %s to %s: %s %v\n",devname, container, devtype, props)
+func AddDeviceSync(client *lxd.Client, container, devname, devtype string, props []string) error {
+	fmt.Printf("Adding device %s to %s: %s %v\n", devname, container, devtype, props)
 	resp, err := client.ContainerDeviceAdd(container, devname, devtype, props)
 	if err != nil {
 		return err
@@ -218,8 +200,8 @@
 	return err
 }
 
-func RemoveDeviceSync (client *lxd.Client, container, devname string) error{
-	fmt.Printf("Removing device %s\n",devname)
+func RemoveDeviceSync(client *lxd.Client, container, devname string) error {
+	fmt.Printf("Removing device %s\n", devname)
 	resp, err := client.ContainerDeviceDelete(container, devname)
 	if err != nil {
 		return err
@@ -232,7 +214,7 @@
 	return err
 }
 
-func RemoveContainerSync(client *lxd.Client, container string) (error){
+func RemoveContainerSync(client *lxd.Client, container string) error {
 
 	err := StopContainerSync(client, container)
 	if err != nil {
@@ -247,7 +229,7 @@
 	return client.WaitForSuccess(resp.Operation)
 }
 
-func GetUserConfirmation(question string) (bool) {
+func GetUserConfirmation(question string) bool {
 	var response string
 	responses := map[string]bool{
 		"y": true, "yes": true,
@@ -257,7 +239,7 @@
 	ok := false
 	answer := false
 	for !ok {
-		fmt.Print(question+" (yes/no): ")
+		fmt.Print(question + " (yes/no): ")
 		_, err := fmt.Scanln(&response)
 		if err != nil {
 			log.Fatal(err)
@@ -270,7 +252,7 @@
 	return answer
 }
 
-func ContainerRootfs (container string) (string) {
+func ContainerRootfs(container string) string {
 	return shared.VarPath("containers", container, "rootfs")
 }
 
@@ -278,7 +260,7 @@
 var ClickFrameworkConfig string = "user.click-framework"
 var TargetUpgradesConfig string = "user.click-updates-enabled"
 
-func FindClickTargets (client *lxd.Client) ([]ClickContainer, error) {
+func FindClickTargets(client *lxd.Client) ([]ClickContainer, error) {
 	ctslist, err := client.ListContainers()
 	if err != nil {
 		return nil, err
@@ -306,14 +288,14 @@
 
 		clickTargets = append(clickTargets,
 			ClickContainer{
-				Name:cInfo.Name,
-				Architecture: clickArch,
-				Framework: clickFW,
-				Container: cInfo,
+				Name:           cInfo.Name,
+				Architecture:   clickArch,
+				Framework:      clickFW,
+				Container:      cInfo,
 				UpdatesEnabled: updatesEnabled == "true",
 			},
 		)
 	}
 
 	return clickTargets, nil
-}
\ No newline at end of file
+}

=== added file 'snapcraft.yaml'
--- snapcraft.yaml	1970-01-01 00:00:00 +0000
+++ snapcraft.yaml	2016-11-30 15:36:23 +0000
@@ -0,0 +1,30 @@
+name: ubuntu-sdk-target
+version: '0.6'
+summary: Lalala
+description: |
+  Snappy SDK tools bla
+
+grade: devel # must be 'stable' to release into candidate/stable channels
+confinement: strict
+
+apps:
+    ubuntu-sdk-target:
+        command: usdk-target
+        plugs: [network, lxd]
+     # FIXME: lp#1583259
+     #  environment:
+     #      LXD_DIR: /var/snap/lxd/common/lxd
+     #      XDG_CONFIG_HOME: $HOME
+
+# TODO: cleanbuild fails on this:
+# fatal error: sys/types.h: No such file or directory
+
+parts:
+  ubuntu-sdk-tools:
+    plugin: go
+    go-importpath: launchpad.net/ubuntu-sdk-tools
+    go-packages:
+    # - launchpad.net/ubuntu-sdk-tools/usdk-wrapper
+      - launchpad.net/ubuntu-sdk-tools/usdk-target
+    source: .
+    build-packages: [bzr, gcc]

=== modified file 'usdk-target/autofix.go'
--- usdk-target/autofix.go	2016-06-24 15:22:17 +0000
+++ usdk-target/autofix.go	2016-11-30 15:36:23 +0000
@@ -19,10 +19,10 @@
 
 import (
 	"fmt"
-	"os"
 	"github.com/lxc/lxd"
 	"launchpad.net/ubuntu-sdk-tools"
 	"launchpad.net/ubuntu-sdk-tools/fixables"
+	"os"
 )
 
 var fixable_set = []fixables.Fixable{
@@ -69,4 +69,4 @@
 		}
 	}
 	return nil
-}
\ No newline at end of file
+}

=== modified file 'usdk-target/create.go'
--- usdk-target/create.go	2016-10-05 12:48:19 +0000
+++ usdk-target/create.go	2016-11-30 15:36:23 +0000
@@ -33,8 +33,8 @@
 	"github.com/lxc/lxd/shared/gnuflag"
 	"launchpad.net/ubuntu-sdk-tools"
 	"os"
+	"regexp"
 	"strings"
-	"regexp"
 )
 
 type createCmd struct {
@@ -64,8 +64,6 @@
 	gnuflag.BoolVar(&c.createSupGroups, "g", false, "Also try to create the users supplementary groups")
 }
 
-
-
 func (c *createCmd) run(args []string) error {
 	if c.fingerprint == requiredString || c.name == requiredString {
 		gnuflag.PrintDefaults()
@@ -73,7 +71,7 @@
 	}
 
 	if os.Getuid() != 0 {
-		return fmt.Errorf("This command needs to run as root")
+		/* return */ fmt.Errorf("This command needs to run as root")
 	}
 
 	config := ubuntu_sdk_tools.GetConfigOrDie()
@@ -120,7 +118,6 @@
 		c.enableUpdates = false
 	}
 
-
 	fmt.Printf("Creating image with:\nframework: %s\narch: %s\n", c.framework, c.architecture)
 	client, err = lxd.NewClient(config, config.DefaultRemote)
 	if err != nil {
@@ -128,7 +125,6 @@
 		os.Exit(1)
 	}
 
-
 	//name string, imgremote string, image string, profiles *[]string, config map[string]string, ephem bool
 	var prof *[]string
 	conf := make(map[string]string)
@@ -148,6 +144,7 @@
 		return err
 	}
 
+	fmt.Fprintf(os.Stderr, "Initializing progress tracker\n")
 	c.initProgressTracker(client, resp.Operation)
 	err = client.WaitForSuccess(resp.Operation)
 
@@ -178,6 +175,7 @@
 		}
 	}
 
+	fmt.Fprintf(os.Stderr, "Adding devices to the container\n")
 	//add the required devices
 	err = ubuntu_sdk_tools.AddDeviceSync(client, c.name, "tmp", "disk", []string{"source=/tmp", "path=/tmp", "recursive=true"})
 	if err != nil {
@@ -185,12 +183,14 @@
 		return err
 	}
 
+	fmt.Fprintf(os.Stderr, "Adding the user\n")
 	err = RegisterUserInContainer(client, c.name, nil, c.createSupGroups)
 	if err != nil {
 		ubuntu_sdk_tools.RemoveContainerSync(client, c.name)
 		return err
 	}
 
+	fmt.Fprintf(os.Stderr, "Updating the configuration\n")
 	ubuntu_sdk_tools.UpdateConfigSync(client, c.name)
 	if err != nil {
 		ubuntu_sdk_tools.RemoveContainerSync(client, c.name)

=== modified file 'usdk-target/exec.go'
--- usdk-target/exec.go	2016-07-06 09:59:58 +0000
+++ usdk-target/exec.go	2016-11-30 15:36:23 +0000
@@ -17,27 +17,26 @@
  */
 package main
 
-import (
-)
+import ()
 import (
 	"fmt"
+	"github.com/gorilla/websocket"
+	"github.com/lxc/lxd"
+	"github.com/lxc/lxd/shared/gnuflag"
+	"launchpad.net/ubuntu-sdk-tools"
 	"os"
 	"os/user"
-	"github.com/lxc/lxd/shared/gnuflag"
-	"launchpad.net/ubuntu-sdk-tools"
-	"syscall"
-	"os/exec"
 )
 
 type execCmd struct {
 	maintMode bool
 	container string
-	user string
+	user      string
 }
 
 func (c *execCmd) usage() string {
 	myMode := "exec"
-	if (c.maintMode) {
+	if c.maintMode {
 		myMode = "maint"
 	}
 
@@ -64,54 +63,63 @@
 	c.container = args[0]
 	args = args[1:]
 
-	lxc_command, err := exec.LookPath("lxc")
+	config := ubuntu_sdk_tools.GetConfigOrDie()
+	d, err := lxd.NewClient(config, config.DefaultRemote)
 	if err != nil {
 		return err
 	}
 
-	lxc_args := []string {
-		lxc_command, "exec",
-		c.container, "--",
+	lxc_args := []string{
 		"su",
 	}
 
 	if len(args) == 0 {
-		lxc_args = append(lxc_args,"-l")
+		lxc_args = append(lxc_args, "-l")
 	}
 
-	lxc_args = append(lxc_args, []string {
+	lxc_args = append(lxc_args, []string{
 		"-s", "/bin/bash"}...)
 
-	if (!c.maintMode) {
+	if !c.maintMode {
 		lxc_args = append(lxc_args, c.user)
 	}
 
 	if len(args) > 0 {
-		rcFiles := []string{ "/etc/profile", "$HOME/.profile" }
+		rcFiles := []string{"/etc/profile", "$HOME/.profile"}
 		cwd, _ := os.Getwd()
 
 		program := ""
-		for _,rcfile := range rcFiles {
-			program += "test -f "+rcfile+" && . "+rcfile+"; "
+		for _, rcfile := range rcFiles {
+			program += "test -f " + rcfile + " && . " + rcfile + "; "
 		}
 
 		//make sure the working directory is the same
-		program += "cd \""+cwd+"\" && "
+		program += "cd \"" + cwd + "\" && "
 
 		//force C locale as QtCreator needs it
-		program +=" LC_ALL=C "
+		program += " LC_ALL=C "
 
-		for _,arg := range args {
-			program += " "+ubuntu_sdk_tools.QuoteString(arg)
+		for _, arg := range args {
+			program += " " + ubuntu_sdk_tools.QuoteString(arg)
 		}
 
-		lxc_args = append(lxc_args, []string {
+		lxc_args = append(lxc_args, []string{
 			"-c", program}...)
 	}
 
 	os.Stdout.Sync()
 	os.Stderr.Sync()
-	err = syscall.Exec(lxc_command, lxc_args, os.Environ())
-	fmt.Printf("Error: %v\n", err)
+	// Ensure the container's running first
+	err = ubuntu_sdk_tools.BootContainerSync(d, c.container)
+	if err != nil {
+		return err
+	}
+	controlHandler := func(*lxd.Client, *websocket.Conn) {
+
+	}
+	_, err = d.Exec(c.container, lxc_args, nil, os.Stdin, os.Stdout, os.Stderr, controlHandler, 0, 0)
+	if err != nil {
+		return err
+	}
 	return nil
 }

=== modified file 'usdk-target/main.go'
--- usdk-target/main.go	2016-07-06 09:22:33 +0000
+++ usdk-target/main.go	2016-11-30 15:36:23 +0000
@@ -28,14 +28,14 @@
 package main
 
 import (
+	"fmt"
 	"github.com/lxc/lxd/shared/gnuflag"
+	"launchpad.net/ubuntu-sdk-tools"
+	"net"
+	"net/url"
 	"os"
 	"strings"
-	"fmt"
 	"syscall"
-	"net"
-	"net/url"
-	"launchpad.net/ubuntu-sdk-tools"
 )
 
 var errArgs = fmt.Errorf("wrong number of subcommand arguments")
@@ -47,25 +47,28 @@
 }
 
 var commands = map[string]command{
-	"list":   &listCmd{},
-	"help":   &helpCmd{},
-	"create": &createCmd{},
-	"register": &registerCmd{},
-	"rootfs": &rootfsCmd{},
-	"status": &statusCmd{},
-	"exists": &existsCmd{},
-	"maint": &execCmd{maintMode:true},
-	"exec": &execCmd{maintMode:false},
-	"destroy": &destroyCmd{},
-	"images": &imagesCmd{},
-	"upgrade": &upgradeCmd{},
+	"list":        &listCmd{},
+	"help":        &helpCmd{},
+	"create":      &createCmd{},
+	"register":    &registerCmd{},
+	"rootfs":      &rootfsCmd{},
+	"status":      &statusCmd{},
+	"exists":      &existsCmd{},
+	"maint":       &execCmd{maintMode: true},
+	"exec":        &execCmd{maintMode: false},
+	"destroy":     &destroyCmd{},
+	"images":      &imagesCmd{},
+	"upgrade":     &upgradeCmd{},
 	"initialized": &initializedCmd{},
-	"autosetup": &autosetupCmd{},
-	"autofix": &autofixCmd{},
-	"set" : &setCmd{},
+	"autosetup":   &autosetupCmd{},
+	"autofix":     &autofixCmd{},
+	"set":         &setCmd{},
 }
 
 func main() {
+	// FIXME: lp#1583259 Set environment variables in snapcraft.yaml
+	os.Setenv("XDG_CONFIG_HOME", os.ExpandEnv("$HOME"))
+
 	if err := run(); err != nil {
 		// The action we take depends on the error we get.
 		msg := fmt.Sprintf("error: %v", err)

=== modified file 'usdk-target/register.go'
--- usdk-target/register.go	2016-10-07 17:39:28 +0000
+++ usdk-target/register.go	2016-11-30 15:36:23 +0000
@@ -19,20 +19,20 @@
 
 import (
 	"fmt"
-	"os"
+	"github.com/lxc/lxd"
 	"github.com/lxc/lxd/shared/gnuflag"
-	"os/user"
 	"launchpad.net/ubuntu-sdk-tools"
+	"os"
 	"os/exec"
+	"os/user"
+	"strconv"
+	"strings"
 	"syscall"
-	"strings"
-	"github.com/lxc/lxd"
-	"strconv"
 )
 
 type registerCmd struct {
-	user string
-	container string
+	user         string
+	container    string
 	createGroups bool
 }
 
@@ -46,7 +46,7 @@
 func (c *registerCmd) flags() {
 	user, err := userFromEnv()
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Could not resolve the current user name")
+		fmt.Fprintf(os.Stderr, "Could not resolve the current user name: %s\n", err)
 		os.Exit(1)
 	}
 	c.user = *user
@@ -55,12 +55,12 @@
 }
 
 func (c *registerCmd) run(args []string) error {
-	if (len(args) < 1) {
+	if len(args) < 1 {
 		fmt.Fprint(os.Stderr, c.usage())
 		gnuflag.PrintDefaults()
 		return fmt.Errorf("Missing arguments.")
 	}
-	if (os.Getuid() != 0) {
+	if os.Getuid() != 0 {
 		return fmt.Errorf("This command needs to run as root")
 	}
 
@@ -76,7 +76,7 @@
 	return RegisterUserInContainer(client, c.container, &c.user, c.createGroups)
 }
 
-func userFromEnv () (*string, error) {
+func userFromEnv() (*string, error) {
 
 	key := "SUDO_UID"
 	env := os.Getenv(key)
@@ -85,13 +85,11 @@
 		key = "PKEXEC_UID"
 		env = os.Getenv(key)
 		if len(env) == 0 {
-			return nil, nil
+			fmt.Fprintf(os.Stderr, "Neither SUDO_UID nor PKEXEC_UID set\n")
+			env = strconv.Itoa(os.Getuid())
 		}
-		fmt.Printf("%s\n", env)
 	}
 
-	fmt.Printf("%s\n", env)
-
 	user, err := user.LookupId(env)
 	if err != nil {
 		return nil, fmt.Errorf("Os environment var :%s contains a invalid USER ID. error: %v", key, err)
@@ -100,7 +98,7 @@
 	return &user.Username, nil
 }
 
-func RegisterUserInContainer (client *lxd.Client, containerName string, userName *string, createSupGroups bool) (error) {
+func RegisterUserInContainer(client *lxd.Client, containerName string, userName *string, createSupGroups bool) error {
 	if userName == nil {
 		userNameFromEnv, err := userFromEnv()
 		if err != nil {
@@ -115,12 +113,12 @@
 	}
 
 	err := ubuntu_sdk_tools.BootContainerSync(client, containerName)
-	if ( err != nil ) {
+	if err != nil {
 		return err
 	}
 
 	pw, err := ubuntu_sdk_tools.Getpwnam(*userName)
-	if (err != nil) {
+	if err != nil {
 		return fmt.Errorf("Querying the user entry failed. error: %v", err)
 	}
 
@@ -128,13 +126,15 @@
 		return fmt.Errorf("Registering root is not possible")
 	}
 
+	/* FIXME: error while looking up passwd for $USER: permission denied
 	shadow,err := ubuntu_sdk_tools.Getspnam(*userName)
 	if (err != nil) {
 		return fmt.Errorf("Querying the password entry failed. error: %v", err)
 	}
+	*/
 
-	groups,err := ubuntu_sdk_tools.GetGroups()
-	if (err != nil) {
+	groups, err := ubuntu_sdk_tools.GetGroups()
+	if err != nil {
 		return fmt.Errorf("Querying the group entry failed. error: %v", err)
 	}
 
@@ -142,13 +142,13 @@
 	for _, group := range groups {
 		if group.Gid == pw.Gid {
 			requiredGroups = append(requiredGroups, group)
-			if (createSupGroups) {
+			if createSupGroups {
 				continue
 			} else {
 				break
 			}
 		}
-		if (createSupGroups) {
+		if createSupGroups {
 			for _, member := range group.Members {
 				if member == *userName {
 					requiredGroups = append(requiredGroups, group)
@@ -158,11 +158,11 @@
 		}
 	}
 
-	err = ubuntu_sdk_tools.AddDeviceSync(client,containerName,
+	err = ubuntu_sdk_tools.AddDeviceSync(client, containerName,
 		fmt.Sprintf("home_of_%s", *userName),
 		"disk",
-		[]string{fmt.Sprintf("source=%s",pw.Dir), fmt.Sprintf("path=%s",pw.Dir), "recursive=true"})
-	if (err != nil) {
+		[]string{fmt.Sprintf("source=%s", pw.Dir), fmt.Sprintf("path=%s", pw.Dir), "recursive=true"})
+	if err != nil {
 		return fmt.Errorf("Failed to mount home directory of the user: %s. error: %v", *userName, err)
 	}
 
@@ -173,12 +173,10 @@
 
 		fmt.Printf("Creating group %s\n", group.Name)
 
-		cmd := exec.Command("lxc", "exec", containerName, "--", "groupadd", "-g",  strconv.FormatUint(uint64(group.Gid),10), group.Name)
-		cmd.Stdout = os.Stdout
-		cmd.Stderr = os.Stderr
-		err = cmd.Start()
-		if err := cmd.Wait(); err != nil {
-			print ("GroupAdd returned error\n")
+		args := []string{"groupadd", "-g", strconv.FormatUint(uint64(group.Gid), 10), group.Name}
+		_, err := client.Exec(containerName, args, nil, os.Stdin, os.Stdout, os.Stderr, nil, 0, 0)
+		if err != nil {
+			print("GroupAdd returned error\n")
 			if exiterr, ok := err.(*exec.ExitError); ok {
 				if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
 					//exit code of 9 means the group exists already
@@ -202,14 +200,13 @@
 
 	fmt.Printf("Creating user %s\n", pw.LoginName)
 
-	command := []string {
-		"exec", containerName, "--",
+	command := []string{
 		"useradd", "--no-create-home",
 		"-u", strconv.FormatUint(uint64(pw.Uid), 10),
 		"--gid", strconv.FormatUint(uint64(pw.Gid), 10),
 		"--home-dir", pw.Dir,
 		"-s", "/bin/bash",
-		"-p", shadow.Sp_pwdp,
+		// FIXME: "-p", shadow.Sp_pwdp,
 	}
 
 	containsVideoGroup := false
@@ -225,14 +222,11 @@
 	}
 
 	if len(supplGroups) > 0 {
-		command = append(command, "--groups",strings.Join(supplGroups, ","))
+		command = append(command, "--groups", strings.Join(supplGroups, ","))
 	}
 
-	command = append(command,pw.LoginName)
-
-	cmd := exec.Command("lxc", command...)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-
-	return cmd.Run()
+	command = append(command, pw.LoginName)
+
+	_, err = client.Exec(containerName, command, nil, os.Stdin, os.Stdout, os.Stderr, nil, 0, 0)
+	return err
 }


Follow ups