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

master
xSmurf 9 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) {
if len(arg) == 0 {
return 0, "", errors.New("profile argument needed")

@ -37,6 +37,8 @@ func Main() {
d.handleLaunch,
d.handleListSandboxes,
d.handleKillSandbox,
d.handleMountFiles,
d.handleUnmountFile,
d.handleLogs,
)
if err != nil {
@ -257,6 +259,31 @@ func (d *daemonState) handleKillSandbox(msg *KillSandboxMsg, m *ipc.Message) err
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 {
for _, sb := range d.sandboxes {
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 {
r := new(ListSandboxesResp)
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)
}

@ -26,18 +26,19 @@ import (
)
type Sandbox struct {
daemon *daemonState
id int
display int
profile *oz.Profile
init *exec.Cmd
cred *syscall.Credential
fs *fs.Filesystem
stderr io.ReadCloser
addr string
xpra *xpra.Xpra
ready sync.WaitGroup
network *network.SandboxNetwork
daemon *daemonState
id int
display int
profile *oz.Profile
init *exec.Cmd
cred *syscall.Credential
fs *fs.Filesystem
stderr io.ReadCloser
addr string
xpra *xpra.Xpra
ready sync.WaitGroup
network *network.SandboxNetwork
mountedFiles []string
}
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) {
var files []string
for _, fpath := range args {
@ -223,14 +274,7 @@ func (sbox *Sandbox) whitelistArgumentFiles(binpath, pwd string, args []string,
}
}
if len(files) > 0 {
pmnt := path.Join(binpath, "bin", "oz-mount")
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))
}
sbox.MountFiles(files, false, binpath, log);
}
}

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

@ -37,17 +37,20 @@ func Main(mode int) {
}
fsys := fs.NewFilesystem(config, log)
for fii, fpath := range os.Args {
if fii == 0 {
continue
}
start := 1;
readonly := false;
if os.Args[1] == "--readonly" {
start = 2;
readonly = true;
}
for _, fpath := range os.Args[start:] {
if !strings.HasPrefix(fpath, "/home/") {
log.Warning("Ignored `%s`, only files inside of home are permitted!", fpath)
continue
}
switch mode {
case MOUNT:
mount(fpath, fsys, log)
mount(fpath, readonly, fsys, log)
case UMOUNT:
unmount(fpath, fsys, log)
}
@ -56,10 +59,14 @@ func Main(mode int) {
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 {
//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)
os.Exit(1)
}

Loading…
Cancel
Save