Added mount/umount messages; readonly flag for oz-mount

master
xSmurf 10 years ago
parent 5a2b5ab375
commit 8ca77723e3

@ -102,6 +102,36 @@ func KillSandbox(id int) error {
} }
} }
func MountFiles(files []string) (error) {
resp, err := clientSend(&MountFilesMsg{Files: files})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
return errors.New(body.Msg)
case *OkMsg:
return nil
default:
return fmt.Errorf("Unexpected message received %+v", body)
}
}
func UnmountFile(file string) (error) {
resp, err := clientSend(&UnmountFileMsg{File: file})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
return errors.New(body.Msg)
case *OkMsg:
return nil
default:
return fmt.Errorf("Unexpected message received %+v", body)
}
}
func parseProfileArg(arg string) (int, string, error) { func parseProfileArg(arg string) (int, string, error) {
if len(arg) == 0 { if len(arg) == 0 {
return 0, "", errors.New("profile argument needed") return 0, "", errors.New("profile argument needed")

@ -37,6 +37,8 @@ func Main() {
d.handleLaunch, d.handleLaunch,
d.handleListSandboxes, d.handleListSandboxes,
d.handleKillSandbox, d.handleKillSandbox,
d.handleMountFiles,
d.handleUnmountFile,
d.handleLogs, d.handleLogs,
) )
if err != nil { if err != nil {
@ -257,6 +259,31 @@ func (d *daemonState) handleKillSandbox(msg *KillSandboxMsg, m *ipc.Message) err
return m.Respond(&OkMsg{}) return m.Respond(&OkMsg{})
} }
func (d *daemonState) handleMountFiles(msg *MountFilesMsg, m *ipc.Message) error {
sbox := d.sandboxById(msg.Id)
if sbox == nil {
return m.Respond(&ErrorMsg{fmt.Sprintf("no sandbox found with id = %d", msg.Id)})
}
if err := sbox.MountFiles(msg.Files, msg.ReadOnly, d.config.PrefixPath, d.log); err != nil {
return m.Respond(&ErrorMsg{fmt.Sprintf("Unable to unmount file `%+s` from sandbox `%s`: %v", msg.Files, sbox.profile.Name, err)})
}
return m.Respond(&OkMsg{})
}
func (d *daemonState) handleUnmountFile(msg *UnmountFileMsg, m *ipc.Message) error {
sbox := d.sandboxById(msg.Id)
if sbox == nil {
return m.Respond(&ErrorMsg{fmt.Sprintf("no sandbox found with id = %d", msg.Id)})
}
if err := sbox.UnmountFile(msg.File, d.config.PrefixPath, d.log); err != nil {
return m.Respond(&ErrorMsg{fmt.Sprintf("Unable to unmount file `%s` from sandbox `%s`: %v", msg.File, sbox.profile.Name, err)})
}
return m.Respond(&OkMsg{})
}
func (d *daemonState) sandboxById(id int) *Sandbox { func (d *daemonState) sandboxById(id int) *Sandbox {
for _, sb := range d.sandboxes { for _, sb := range d.sandboxes {
if sb.id == id { if sb.id == id {
@ -317,7 +344,7 @@ func (d *daemonState) getRunningSandboxByName(name string) *Sandbox {
func (d *daemonState) handleListSandboxes(list *ListSandboxesMsg, msg *ipc.Message) error { func (d *daemonState) handleListSandboxes(list *ListSandboxesMsg, msg *ipc.Message) error {
r := new(ListSandboxesResp) r := new(ListSandboxesResp)
for _, sb := range d.sandboxes { for _, sb := range d.sandboxes {
r.Sandboxes = append(r.Sandboxes, SandboxInfo{Id: sb.id, Address: sb.addr, Profile: sb.profile.Name}) r.Sandboxes = append(r.Sandboxes, SandboxInfo{Id: sb.id, Address: sb.addr, Mounts: sb.mountedFiles, Profile: sb.profile.Name})
} }
return msg.Respond(r) return msg.Respond(r)
} }

@ -26,18 +26,19 @@ import (
) )
type Sandbox struct { type Sandbox struct {
daemon *daemonState daemon *daemonState
id int id int
display int display int
profile *oz.Profile profile *oz.Profile
init *exec.Cmd init *exec.Cmd
cred *syscall.Credential cred *syscall.Credential
fs *fs.Filesystem fs *fs.Filesystem
stderr io.ReadCloser stderr io.ReadCloser
addr string addr string
xpra *xpra.Xpra xpra *xpra.Xpra
ready sync.WaitGroup ready sync.WaitGroup
network *network.SandboxNetwork network *network.SandboxNetwork
mountedFiles []string
} }
func createSocketPath(base string) (string, error) { func createSocketPath(base string) (string, error) {
@ -208,6 +209,56 @@ func (sbox *Sandbox) launchProgram(binpath, cpath, pwd string, args []string, lo
} }
} }
func (sbox *Sandbox) MountFiles(files []string, readonly bool, binpath string, log *logging.Logger) error {
pmnt := path.Join(binpath, "bin", "oz-mount")
args := files
if readonly {
args = append([]string{"--readonly"}, files...)
}
cmnt := exec.Command(pmnt, args...)
cmnt.Env = []string{"_OZ_NSPID=" + strconv.Itoa(sbox.init.Process.Pid)}
pout, err := cmnt.CombinedOutput()
if err != nil {
log.Warning("Unable to bind files to sandbox: %v", err)
log.Warning("%s", string(pout))
return err
}
for _, mfile := range files {
found := false
for _, mmfile := range sbox.mountedFiles {
if (mfile == mmfile) {
found = true
break;
}
}
if (!found) {
sbox.mountedFiles = append(sbox.mountedFiles, mfile)
}
}
log.Info("%s", string(pout))
return nil
}
func (sbox *Sandbox) UnmountFile(file, binpath string, log *logging.Logger) error {
pmnt := path.Join(binpath, "bin", "oz-umount")
cmnt := exec.Command(pmnt, file)
cmnt.Env = []string{"_OZ_NSPID=" + strconv.Itoa(sbox.init.Process.Pid)}
pout, err := cmnt.CombinedOutput()
if err != nil {
log.Warning("Unable to unbind files from sandbox: %v", err)
log.Warning("%s", string(pout))
return err
}
for i, item := range sbox.mountedFiles {
if item == file {
sbox.mountedFiles = append(sbox.mountedFiles[:i], sbox.mountedFiles[i+1:]...)
}
}
log.Info("%s", string(pout))
return nil
}
func (sbox *Sandbox) whitelistArgumentFiles(binpath, pwd string, args []string, log *logging.Logger) { func (sbox *Sandbox) whitelistArgumentFiles(binpath, pwd string, args []string, log *logging.Logger) {
var files []string var files []string
for _, fpath := range args { for _, fpath := range args {
@ -223,14 +274,7 @@ func (sbox *Sandbox) whitelistArgumentFiles(binpath, pwd string, args []string,
} }
} }
if len(files) > 0 { if len(files) > 0 {
pmnt := path.Join(binpath, "bin", "oz-mount") sbox.MountFiles(files, false, binpath, log);
cmnt := exec.Command(pmnt, files...)
cmnt.Env = []string{"_OZ_NSPID=" + strconv.Itoa(sbox.init.Process.Pid)}
pout, err := cmnt.CombinedOutput()
if err != nil {
log.Warning("Unable to bind files to sandbox: %v", err)
log.Warning("%s", string(pout))
}
} }
} }

@ -48,6 +48,7 @@ type SandboxInfo struct {
Id int Id int
Address string Address string
Profile string Profile string
Mounts []string
} }
type ListSandboxesResp struct { type ListSandboxesResp struct {
@ -58,6 +59,17 @@ type KillSandboxMsg struct {
Id int "KillSandbox" Id int "KillSandbox"
} }
type MountFilesMsg struct {
Id int "MountFiles"
Files []string
ReadOnly bool
}
type UnmountFileMsg struct {
Id int "UnmountFile"
File string
}
type LogsMsg struct { type LogsMsg struct {
Count int "Logs" Count int "Logs"
Follow bool Follow bool
@ -77,6 +89,8 @@ var messageFactory = ipc.NewMsgFactory(
new(ListSandboxesMsg), new(ListSandboxesMsg),
new(ListSandboxesResp), new(ListSandboxesResp),
new(KillSandboxMsg), new(KillSandboxMsg),
new(MountFilesMsg),
new(UnmountFileMsg),
new(LogsMsg), new(LogsMsg),
new(LogData), new(LogData),
) )

@ -37,17 +37,20 @@ func Main(mode int) {
} }
fsys := fs.NewFilesystem(config, log) fsys := fs.NewFilesystem(config, log)
for fii, fpath := range os.Args { start := 1;
if fii == 0 { readonly := false;
continue if os.Args[1] == "--readonly" {
} start = 2;
readonly = true;
}
for _, fpath := range os.Args[start:] {
if !strings.HasPrefix(fpath, "/home/") { if !strings.HasPrefix(fpath, "/home/") {
log.Warning("Ignored `%s`, only files inside of home are permitted!", fpath) log.Warning("Ignored `%s`, only files inside of home are permitted!", fpath)
continue continue
} }
switch mode { switch mode {
case MOUNT: case MOUNT:
mount(fpath, fsys, log) mount(fpath, readonly, fsys, log)
case UMOUNT: case UMOUNT:
unmount(fpath, fsys, log) unmount(fpath, fsys, log)
} }
@ -56,10 +59,14 @@ func Main(mode int) {
os.Exit(0) os.Exit(0)
} }
func mount(fpath string, fsys *fs.Filesystem, log *logging.Logger) { func mount(fpath string, readonly bool, fsys *fs.Filesystem, log *logging.Logger) {
if _, err := os.Stat(fpath); err == nil { if _, err := os.Stat(fpath); err == nil {
//log.Notice("Adding file `%s`.", fpath) //log.Notice("Adding file `%s`.", fpath)
if err := fsys.BindPath(fpath, fs.BindCanCreate, nil); err != nil { flags := fs.BindCanCreate
if readonly {
flags |= fs.BindReadOnly
}
if err := fsys.BindPath(fpath, flags, nil); err != nil {
log.Error("%v while adding `%s`!", err, fpath) log.Error("%v while adding `%s`!", err, fpath)
os.Exit(1) os.Exit(1)
} }

Loading…
Cancel
Save