summaryrefslogtreecommitdiffhomepage
path: root/runsc/config
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-09-01 18:15:36 +0000
committergVisor bot <gvisor-bot@google.com>2020-09-01 18:15:36 +0000
commitf5181c6067ad420d16557d21734453994fb42791 (patch)
tree58e768fc08664c0dd37b69bf5bfff42cb88ca7c9 /runsc/config
parent964da19b9b3361162209ad820eab7a957d10bc20 (diff)
parent71589b7f7e69b85820c9deb75fc6d0b6c5f00eb1 (diff)
Merge release-20200818.0-99-g71589b7f7 (automated)
Diffstat (limited to 'runsc/config')
-rw-r--r--runsc/config/config.go2
-rw-r--r--runsc/config/flags.go36
2 files changed, 38 insertions, 0 deletions
diff --git a/runsc/config/config.go b/runsc/config/config.go
index bca27ebf1..df134bb2f 100644
--- a/runsc/config/config.go
+++ b/runsc/config/config.go
@@ -157,6 +157,8 @@ type Config struct {
// Enables FUSE usage.
FUSE bool `flag:"fuse"`
+ AllowFlagOverride bool `flag:"allow-flag-override"`
+
// TestOnlyAllowRunAsCurrentUserWithoutChroot should only be used in
// tests. It allows runsc to start the sandbox process as the current
// user, and without chrooting the sandbox process. This can be
diff --git a/runsc/config/flags.go b/runsc/config/flags.go
index 488a4b9fb..eff46e938 100644
--- a/runsc/config/flags.go
+++ b/runsc/config/flags.go
@@ -48,6 +48,7 @@ func RegisterFlags() {
flag.Bool("log-packets", false, "enable network packet logging.")
flag.String("debug-log-format", "text", "log format: text (default), json, or json-k8s.")
flag.Bool("alsologtostderr", false, "send log messages to stderr.")
+ flag.Bool("allow-flag-override", false, "allow OCI annotations (dev.gvisor.flag.<name>) to override flags for debugging.")
// Debugging flags: strace related
flag.Bool("strace", false, "enable strace.")
@@ -149,6 +150,41 @@ func (c *Config) ToFlags() []string {
return rv
}
+// Override writes a new value to a flag.
+func (c *Config) Override(name string, value string) error {
+ if !c.AllowFlagOverride {
+ return fmt.Errorf("flag override disabled, use --allow-flag-override to enable it")
+ }
+
+ obj := reflect.ValueOf(c).Elem()
+ st := obj.Type()
+ for i := 0; i < st.NumField(); i++ {
+ f := st.Field(i)
+ fieldName, ok := f.Tag.Lookup("flag")
+ if !ok || fieldName != name {
+ // Not a flag field, or flag name doesn't match.
+ continue
+ }
+ fl := flag.CommandLine.Lookup(name)
+ if fl == nil {
+ // Flag must exist if there is a field match above.
+ panic(fmt.Sprintf("Flag %q not found", name))
+ }
+
+ // Use flag to convert the string value to the underlying flag type, using
+ // the same rules as the command-line for consistency.
+ if err := fl.Value.Set(value); err != nil {
+ return fmt.Errorf("error setting flag %s=%q: %w", name, value, err)
+ }
+ x := reflect.ValueOf(flag.Get(fl.Value))
+ obj.Field(i).Set(x)
+
+ // Validates the config again to ensure it's left in a consistent state.
+ return c.validate()
+ }
+ return fmt.Errorf("flag %q not found. Cannot set it to %q", name, value)
+}
+
func getVal(field reflect.Value) string {
if str, ok := field.Addr().Interface().(fmt.Stringer); ok {
return str.String()