From a3637a7c2e4687a346243e04caf3b1020d7ba365 Mon Sep 17 00:00:00 2001 From: brl Date: Fri, 5 Jun 2015 12:39:45 -0400 Subject: [PATCH] Changes to support xpra --- fs/fs.go | 40 +++++++++++++++++++++++++++++----------- fs/item.go | 5 +++-- fs/resolve.go | 2 +- fs/setup.go | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/fs/fs.go b/fs/fs.go index 5f004f2..91af669 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -20,9 +20,11 @@ type directory struct { type Filesystem struct { log *logging.Logger - home string + user *user.User + name string base string root string + xpra string userID string noDefaults bool noSysAndProc bool @@ -34,6 +36,10 @@ func (fs *Filesystem) Root() string { return fs.root } +func (fs *Filesystem) Xpra() string { + return fs.xpra +} + func (fs *Filesystem) addWhitelist(path, target string, readonly bool) error { item, err := fs.newItem(path, target, readonly) if err != nil { @@ -65,8 +71,8 @@ func (fs *Filesystem) newItem(path, target string, readonly bool) (*mountItem, e }, nil } -func NewFromProfile(profile *oz.Profile, log *logging.Logger) *Filesystem { - fs := NewFilesystem(profile.Name, log) +func NewFromProfile(profile *oz.Profile, user *user.User, log *logging.Logger) *Filesystem { + fs := NewFilesystem(profile.Name, user, log) for _,wl := range profile.Whitelist { fs.addWhitelist(wl.Path, wl.Path, wl.ReadOnly) } @@ -75,24 +81,22 @@ func NewFromProfile(profile *oz.Profile, log *logging.Logger) *Filesystem { } fs.noDefaults = profile.NoDefaults fs.noSysAndProc = profile.NoSysProc + if profile.XServer.Enabled { + fs.xpra = path.Join(user.HomeDir, ".Xoz", profile.Name) + } return fs } -func NewFilesystem(name string, log *logging.Logger) *Filesystem { - +func NewFilesystem(name string, user *user.User, log *logging.Logger) *Filesystem { fs := new(Filesystem) fs.log = log + fs.name = name if log == nil { fs.log = logging.MustGetLogger("oz") } fs.base = path.Join("/srv/oz", name) fs.root = path.Join(fs.base, "rootfs") - - u, err := user.Current() - if err != nil { - panic("Failed to look up current user: " + err.Error()) - } - fs.home = u.HomeDir + fs.user = user fs.userID = strconv.Itoa(os.Getuid()) return fs @@ -205,3 +209,17 @@ func copyFileInfo(info os.FileInfo, target string) error { os.Chmod(target, info.Mode().Perm()) return nil } + +func createSubdirs(base string, uid,gid int, mode os.FileMode, subdirs ...string) error { + dir := base + for _,sd := range subdirs { + dir = path.Join(dir, sd) + if err := os.Mkdir(dir, mode); err != nil && !os.IsExist(err) { + return err + } + if err := os.Chown(dir, uid, gid); err != nil { + return err + } + } + return nil +} diff --git a/fs/item.go b/fs/item.go index bcbf1e8..57fe418 100644 --- a/fs/item.go +++ b/fs/item.go @@ -80,8 +80,9 @@ func (mi *mountItem) readSourceInfo(src string) (os.FileInfo, error) { return nil, fmt.Errorf("source path (%s) does not exist", src) } - if !strings.HasPrefix(src, mi.fs.home) { - return nil, fmt.Errorf("mount item (%s) has flag MountCreateIfAbsent, but is not child of home directory (%s)", src, mi.fs.home) + home := mi.fs.user.HomeDir + if !strings.HasPrefix(src, home) { + return nil, fmt.Errorf("mount item (%s) has flag MountCreateIfAbsent, but is not child of home directory (%s)", src, home) } if err := os.MkdirAll(src, 0750); err != nil { diff --git a/fs/resolve.go b/fs/resolve.go index ba2c697..8856201 100644 --- a/fs/resolve.go +++ b/fs/resolve.go @@ -30,7 +30,7 @@ func (fs *Filesystem) resolveVars(p string) (string, error) { return resolved, nil case strings.HasPrefix(p, homeVar): - return path.Join(fs.home, p[len(homeVar):]), nil + return path.Join(fs.user.HomeDir, p[len(homeVar):]), nil case strings.HasPrefix(p, uidVar): return strings.Replace(p, uidVar, fs.userID, -1), nil diff --git a/fs/setup.go b/fs/setup.go index 41e777b..08a9f3f 100644 --- a/fs/setup.go +++ b/fs/setup.go @@ -5,6 +5,9 @@ import ( "os" "path" "syscall" + "os/user" + "strconv" + "errors" ) var basicBindDirs = []string{ @@ -37,6 +40,16 @@ var basicSymlinks = [][2]string{ } func (fs *Filesystem) Setup() error { + if fs.xpra != "" { + if err := fs.createXpraDir(); err != nil { + return err + } + item,err := fs.newItem(fs.xpra, fs.xpra, false) + if err != nil { + return err + } + fs.whitelist = append(fs.whitelist, item) + } if err := fs.setupRootfs(); err != nil { return err } @@ -46,6 +59,30 @@ func (fs *Filesystem) Setup() error { return fs.setupMountItems() } +func (fs *Filesystem) createXpraDir() error { + uid,gid,err := userIds(fs.user) + if err != nil { + return err + } + dir := path.Join(fs.user.HomeDir, ".Xoz", fs.name) + if err := createSubdirs(fs.user.HomeDir, uid, gid, 0755, ".Xoz", fs.name); err != nil { + return fmt.Errorf("failed to create xpra directory (%s): %v", dir, err) + } + return nil +} + +func userIds(user *user.User) (int, int, error) { + uid,err := strconv.Atoi(user.Uid) + if err != nil { + return -1,-1, errors.New("failed to parse uid from user struct: "+ err.Error()) + } + gid,err := strconv.Atoi(user.Gid) + if err != nil { + return -1,-1, errors.New("failed to parse gid from user struct: "+ err.Error()) + } + return uid,gid,nil +} + func (fs *Filesystem) setupRootfs() error { if err := os.MkdirAll(fs.base, 0755); err != nil { return fmt.Errorf("unable to create directory (%s): %v", fs.base, err)