| package impl |
| |
| import ( |
| "fmt" |
| "os" |
| "path/filepath" |
| "regexp" |
| "strings" |
| |
| "veyron.io/veyron/veyron2/services/mgmt/application" |
| "veyron.io/veyron/veyron2/vlog" |
| |
| // For VeyronEnvironment, see TODO. |
| "veyron.io/veyron/veyron/services/mgmt/device/config" |
| ) |
| |
| // InstallFrom takes a veyron object name denoting an application service where |
| // a device manager application envelope can be obtained. It downloads the |
| // latest version of the device manager and installs it. |
| func InstallFrom(origin string) error { |
| // TODO(caprita): Implement. |
| return nil |
| } |
| |
| var allowedVarsRE = regexp.MustCompile("VEYRON_.*|NAMESPACE_ROOT.*|PAUSE_BEFORE_STOP|TMPDIR") |
| |
| var deniedVarsRE = regexp.MustCompile("VEYRON_EXEC_VERSION") |
| |
| // filterEnvironment returns only the environment variables, specified by |
| // the env parameter, whose names match the supplied regexp. |
| func filterEnvironment(env []string, allow, deny *regexp.Regexp) []string { |
| var ret []string |
| for _, e := range env { |
| if eqIdx := strings.Index(e, "="); eqIdx > 0 { |
| key := e[:eqIdx] |
| if deny.MatchString(key) { |
| continue |
| } |
| if allow.MatchString(key) { |
| ret = append(ret, e) |
| } |
| } |
| } |
| return ret |
| } |
| |
| // VeyronEnvironment returns only this environment variables that are |
| // specific to the Veyron system. |
| func VeyronEnvironment(env []string) []string { |
| return filterEnvironment(env, allowedVarsRE, deniedVarsRE) |
| } |
| |
| // SelfInstall installs the device manager and configures it using the |
| // environment and the supplied command-line flags. |
| func SelfInstall(args, env []string) error { |
| configState, err := config.Load() |
| if err != nil { |
| return fmt.Errorf("failed to load config: %v", err) |
| } |
| |
| vlog.VI(1).Infof("Config for device manager: %v", configState) |
| configState.Name = "dummy" // Just so that Validate passes. |
| if err := configState.Validate(); err != nil { |
| return fmt.Errorf("invalid config %v: %v", configState, err) |
| } |
| |
| // Create device manager directory tree. |
| deviceDir := filepath.Join(configState.Root, "device-manager", "base") |
| if err := os.RemoveAll(deviceDir); err != nil { |
| return fmt.Errorf("RemoveAll(%v) failed: %v", deviceDir, err) |
| } |
| perm := os.FileMode(0700) |
| if err := os.MkdirAll(deviceDir, perm); err != nil { |
| return fmt.Errorf("MkdirAll(%v, %v) failed: %v", deviceDir, perm, err) |
| } |
| envelope := &application.Envelope{ |
| Args: args, |
| // TODO(caprita): Cleaning up env vars to avoid picking up all |
| // the garbage from the user's env. |
| // Alternatively, pass the env vars meant specifically for the |
| // device manager in a different way. |
| Env: VeyronEnvironment(env), |
| } |
| if err := linkSelf(deviceDir, "deviced"); err != nil { |
| return err |
| } |
| // We don't pass in the config state settings, since they're already |
| // contained in the environment. |
| if err := generateScript(deviceDir, nil, envelope); err != nil { |
| return err |
| } |
| |
| // TODO(caprita): Test the device manager we just installed. |
| return updateLink(filepath.Join(deviceDir, "deviced.sh"), configState.CurrentLink) |
| // TODO(caprita): Update system management daemon. |
| } |
| |
| // Uninstall undoes SelfInstall, removing the device manager's installation |
| // directory and soft link. |
| func Uninstall() error { |
| configState, err := config.Load() |
| if err != nil { |
| return fmt.Errorf("failed to load config: %v", err) |
| } |
| |
| vlog.VI(1).Infof("Config for device manager: %v", configState) |
| configState.Name = "dummy" // Just so that Validate passes. |
| if err := configState.Validate(); err != nil { |
| return fmt.Errorf("invalid config %v: %v", configState, err) |
| } |
| if err := os.RemoveAll(configState.Root); err != nil { |
| return fmt.Errorf("RemoveAll(%v) failed: %v", configState.Root, err) |
| } |
| return os.Remove(configState.CurrentLink) |
| // TODO(caprita): Update system management daemon. |
| } |