veyron/services/mgmt/suidhelper: added remove functionality
When actually operating with chown, application workspaces and logs will
not be owned by the application's associated system name. Consequently,
the node manager will not be able to delete application instances. Extend
the helper with remove functionality.
Change-Id: Iab7094d5ed947909bc11900d545d906e4098efc4
diff --git a/services/mgmt/suidhelper/impl/args.go b/services/mgmt/suidhelper/impl/args.go
index 2c9da35..2cc26ae 100644
--- a/services/mgmt/suidhelper/impl/args.go
+++ b/services/mgmt/suidhelper/impl/args.go
@@ -22,6 +22,7 @@
argv []string
envv []string
dryrun bool
+ remove bool
}
type ArgsSavedForTest struct {
@@ -37,6 +38,7 @@
var (
flagUsername, flagWorkspace, flagStdoutLog, flagStderrLog, flagRun *string
flagMinimumUid *int64
+ flagRemove *bool
)
func init() {
@@ -53,11 +55,18 @@
flagStderrLog = sflag.StderrLog
flagRun = sflag.Run
flagMinimumUid = sflag.MinimumUid
+ flagRemove = sflag.Remove
}
// ParseArguments populates the WorkParameter object from the provided args
// and env strings.
func (wp *WorkParameters) ProcessArguments(fs *flag.FlagSet, env []string) error {
+ if *flagRemove {
+ wp.remove = true
+ wp.argv = fs.Args()
+ return nil
+ }
+
username := *flagUsername
if username == "" {
return fmt.Errorf("--username missing")
diff --git a/services/mgmt/suidhelper/impl/args_test.go b/services/mgmt/suidhelper/impl/args_test.go
index b3a86b1..a9f0cde 100644
--- a/services/mgmt/suidhelper/impl/args_test.go
+++ b/services/mgmt/suidhelper/impl/args_test.go
@@ -35,6 +35,8 @@
argv0: "",
argv: []string{""},
envv: []string{"A=B"},
+ dryrun: false,
+ remove: false,
},
},
@@ -52,6 +54,32 @@
argv0: "/bin/veyron",
argv: []string{"/bin/veyron", "one", "two"},
envv: []string{"A=B"},
+ dryrun: false,
+ remove: false,
+ },
+ },
+ {
+ []string{"setuidhelper", "--username", testUserName},
+ []string{"A=B"},
+ fmt.Errorf("suidhelper does not permit uids less than 501"),
+ WorkParameters{},
+ },
+
+ {
+ []string{"setuidhelper", "--rm", "hello", "vanadium"},
+ []string{"A=B"},
+ nil,
+ WorkParameters{
+ uid: 0,
+ gid: 0,
+ workspace: "",
+ stderrLog: "",
+ stdoutLog: "",
+ argv0: "",
+ argv: []string{"hello", "vanadium"},
+ envv: nil,
+ dryrun: false,
+ remove: true,
},
},
{
diff --git a/services/mgmt/suidhelper/impl/flag/flag.go b/services/mgmt/suidhelper/impl/flag/flag.go
index c21e1ca..674227e 100644
--- a/services/mgmt/suidhelper/impl/flag/flag.go
+++ b/services/mgmt/suidhelper/impl/flag/flag.go
@@ -15,6 +15,7 @@
var (
Username, Workspace, StdoutLog, StderrLog, Run *string
MinimumUid *int64
+ Remove *bool
)
func init() {
@@ -28,6 +29,7 @@
StderrLog = fs.String("stderrlog", "", "Path to the stdin log file.")
Run = fs.String("run", "", "Path to the application to exec.")
MinimumUid = fs.Int64("minuid", uidThreshold, "UIDs cannot be less than this number.")
+ Remove = fs.Bool("rm", false, "Remove the file trees given as command-line arguments.")
}
const uidThreshold = 501
diff --git a/services/mgmt/suidhelper/impl/run.go b/services/mgmt/suidhelper/impl/run.go
index bc7b6dd..99876ed 100644
--- a/services/mgmt/suidhelper/impl/run.go
+++ b/services/mgmt/suidhelper/impl/run.go
@@ -10,11 +10,13 @@
return err
}
- // 1. For each chown directory, chown.
+ if work.remove {
+ return work.Remove()
+ }
+
if err := work.Chown(); err != nil {
return err
}
- // 2. Run the command if it exists.
return work.Exec()
}
diff --git a/services/mgmt/suidhelper/impl/system.go b/services/mgmt/suidhelper/impl/system.go
index 3059e30..9df0f9b 100644
--- a/services/mgmt/suidhelper/impl/system.go
+++ b/services/mgmt/suidhelper/impl/system.go
@@ -43,3 +43,12 @@
}
return syscall.Exec(hw.argv0, hw.argv, hw.envv)
}
+
+func (hw *WorkParameters) Remove() error {
+ for _, p := range hw.argv {
+ if err := os.RemoveAll(p); err != nil {
+ return fmt.Errorf("os.RemoveAll(%s) failed: %v", p, err)
+ }
+ }
+ return nil
+}