func runCommand(cmdStr ...string) error { cmd := exec.Command(cmdStr[0], cmdStr[1:]...) if output, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("cannot run %v: %s", cmdStr, osutil.OutputErr(output, err)) } return nil }
func removeMountUnit(baseDir string, meter progress.Meter) error { sysd := systemd.New(dirs.GlobalRootDir, meter) unit := systemd.MountUnitPath(dirs.StripRootDir(baseDir), "mount") if osutil.FileExists(unit) { // use umount -l (lazy) to ensure that even busy mount points // can be unmounted. // note that the long option --lazy is not supported on trusty. if output, err := exec.Command("umount", "-l", baseDir).CombinedOutput(); err != nil { return osutil.OutputErr(output, err) } if err := sysd.Stop(filepath.Base(unit), time.Duration(1*time.Second)); err != nil { return err } if err := sysd.Disable(filepath.Base(unit)); err != nil { return err } if err := os.Remove(unit); err != nil { return err } // daemon-reload to ensure that systemd actually really // forgets about this mount unit if err := sysd.DaemonReload(); err != nil { return err } } return nil }
func (b Backend) DiscardSnapNamespace(snapName string) error { mntFile := mountNsPath(snapName) // If there's a .mnt file that was created by snap-confine we should ask // snap-confine to discard it appropriately. if osutil.FileExists(mntFile) { snapDiscardNs := filepath.Join(dirs.LibExecDir, "snap-discard-ns") cmd := exec.Command(snapDiscardNs, snapName) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("cannot discard preserved namespaces of snap %q: %s", snapName, osutil.OutputErr(output, err)) } } return nil }
func tryMount(deviceName string) (string, error) { tmpMountTarget, err := ioutil.TempDir("", "snapd-auto-import-mount-") if err != nil { err = fmt.Errorf("cannot create temporary mount point: %v", err) logger.Noticef("error: %v", err) return "", err } // udev does not provide much environment ;) if os.Getenv("PATH") == "" { os.Setenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin") } // not using syscall.Mount() because we don't know the fs type in advance cmd := exec.Command("mount", "-o", "ro", "--make-private", deviceName, tmpMountTarget) if output, err := cmd.CombinedOutput(); err != nil { os.Remove(tmpMountTarget) err = fmt.Errorf("cannot mount %s: %s", deviceName, osutil.OutputErr(output, err)) logger.Noticef("error: %v", err) return "", err } return tmpMountTarget, nil }
// Start the Daemon func (d *Daemon) Start() { // die when asked to restart (systemd should get us back up!) d.overlord.SetRestartHandler(func(t state.RestartType) { switch t { case state.RestartDaemon: d.tomb.Kill(nil) case state.RestartSystem: cmd := exec.Command("shutdown", "+10", "-r", shutdownMsg) if out, err := cmd.CombinedOutput(); err != nil { logger.Noticef("%s", osutil.OutputErr(out, err)) } default: logger.Noticef("internal error: restart handler called with unknown restart type: %v", t) d.tomb.Kill(nil) } }) // the loop runs in its own goroutine d.overlord.Loop() d.tomb.Go(func() error { if d.snapListener != nil { d.tomb.Go(func() error { if err := http.Serve(d.snapListener, logit(d.router)); err != nil && d.tomb.Err() == tomb.ErrStillAlive { return err } return nil }) } if err := http.Serve(d.snapdListener, logit(d.router)); err != nil && d.tomb.Err() == tomb.ErrStillAlive { return err } return nil }) }
// doRunHook actually runs the hook that was requested. // // Note that this method is synchronous, as the task is already running in a // goroutine. func (m *HookManager) doRunHook(task *state.Task, tomb *tomb.Tomb) error { task.State().Lock() setup := &HookSetup{} err := task.Get("hook-setup", setup) task.State().Unlock() if err != nil { return fmt.Errorf("cannot extract hook setup from task: %s", err) } context, err := NewContext(task, setup, nil) if err != nil { return err } // Obtain a handler for this hook. The repository returns a list since it's // possible for regular expressions to overlap, but multiple handlers is an // error (as is no handler). handlers := m.repository.generateHandlers(context) handlersCount := len(handlers) if handlersCount == 0 { return fmt.Errorf("no registered handlers for hook %q", setup.Hook) } if handlersCount > 1 { return fmt.Errorf("%d handlers registered for hook %q, expected 1", handlersCount, setup.Hook) } context.handler = handlers[0] contextID := context.ID() m.contextsMutex.Lock() m.contexts[contextID] = context m.contextsMutex.Unlock() defer func() { m.contextsMutex.Lock() delete(m.contexts, contextID) m.contextsMutex.Unlock() }() // About to run the hook-- notify the handler if err = context.Handler().Before(); err != nil { return err } // Actually run the hook output, err := runHookAndWait(setup.Snap, setup.Revision, setup.Hook, contextID, tomb) if err != nil { err = osutil.OutputErr(output, err) if handlerErr := context.Handler().Error(err); handlerErr != nil { return handlerErr } return err } // Assuming no error occurred, notify the handler that the hook has // finished. if err = context.Handler().Done(); err != nil { return err } // Let the context know we're finished with it. context.Lock() defer context.Unlock() if err = context.Done(); err != nil { return err } return nil }
// doRunHook actually runs the hook that was requested. // // Note that this method is synchronous, as the task is already running in a // goroutine. func (m *HookManager) doRunHook(task *state.Task, tomb *tomb.Tomb) error { task.State().Lock() hooksup, snapst, err := hookSetup(task) task.State().Unlock() if err != nil { return err } info, err := snapst.CurrentInfo() if err != nil { return fmt.Errorf("cannot read %q snap details: %v", hooksup.Snap, err) } hookExists := info.Hooks[hooksup.Hook] != nil if !hookExists && !hooksup.Optional { return fmt.Errorf("snap %q has no %q hook", hooksup.Snap, hooksup.Hook) } context, err := NewContext(task, hooksup, nil) if err != nil { return err } // Obtain a handler for this hook. The repository returns a list since it's // possible for regular expressions to overlap, but multiple handlers is an // error (as is no handler). handlers := m.repository.generateHandlers(context) handlersCount := len(handlers) if handlersCount == 0 { return fmt.Errorf("internal error: no registered handlers for hook %q", hooksup.Hook) } if handlersCount > 1 { return fmt.Errorf("internal error: %d handlers registered for hook %q, expected 1", handlersCount, hooksup.Hook) } context.handler = handlers[0] contextID := context.ID() m.contextsMutex.Lock() m.contexts[contextID] = context m.contextsMutex.Unlock() defer func() { m.contextsMutex.Lock() delete(m.contexts, contextID) m.contextsMutex.Unlock() }() if err = context.Handler().Before(); err != nil { return err } if hookExists { output, err := runHook(context, tomb) if err != nil { err = osutil.OutputErr(output, err) if handlerErr := context.Handler().Error(err); handlerErr != nil { return handlerErr } return err } } if err = context.Handler().Done(); err != nil { return err } context.Lock() defer context.Unlock() if err = context.Done(); err != nil { return err } return nil }
func LoadModule(module string) error { if output, err := exec.Command("modprobe", "--syslog", module).CombinedOutput(); err != nil { return fmt.Errorf("cannot load module %s: %s", module, osutil.OutputErr(output, err)) } return nil }