// isMounted returns true if the given path is a mountpoint func isMounted(path string) (bool, error) { cmd := exec.Command(mountpointCmd, path) // mountpoint uses translated messages, ensure we get the // english ones cmd.Env = []string{"LC_ALL=C"} output, err := cmd.CombinedOutput() exitCode, err := osutil.ExitCode(err) // if we get anything other than "ExitError" er error here if err != nil { return false, err } // mountpoint.c from util-linux always returns 0 or 1 // (unless e.g. signal) if exitCode != 0 && exitCode != 1 { return false, fmt.Errorf("got unexpected exit code %v from the mountpoint command: %s", exitCode, output) } // exitCode == 0 means it is a mountpoint, do we are done if exitCode == 0 { return true, nil } // exitCode == 1 either means something went wrong *or* // the path is not a mount point // (thanks mountpoint.c :/) if strings.Contains(string(output), "is not a mountpoint") { return false, nil } return false, fmt.Errorf("unexpected output from mountpoint: %s (%v)", output, exitCode) }
// run calls systemctl with the given args, returning its standard output (and wrapped error) func run(args ...string) ([]byte, error) { bs, err := exec.Command("systemctl", args...).CombinedOutput() if err != nil { exitCode, _ := osutil.ExitCode(err) return nil, &Error{cmd: args, exitCode: exitCode, msg: bs} } return bs, nil }
// jctl calls journalctl to get the JSON logs of the given services, wrapping the error if any. func jctl(svcs []string) ([]byte, error) { cmd := []string{"journalctl", "-o", "json"} for i := range svcs { cmd = append(cmd, "-u", svcs[i]) } bs, err := exec.Command(cmd[0], cmd[1:]...).Output() // journalctl can be messy with its stderr if err != nil { exitCode, _ := osutil.ExitCode(err) return nil, &Error{cmd: cmd, exitCode: exitCode, msg: bs} } return bs, nil }
// Lowlevel copy the snap data (but never override existing data) func copySnapDataDirectory(oldPath, newPath string) (err error) { if _, err := os.Stat(oldPath); err == nil { if _, err := os.Stat(newPath); err != nil { // there is no golang "CopyFile" cmd := exec.Command("cp", "-a", oldPath, newPath) if err := cmd.Run(); err != nil { if exitCode, err := osutil.ExitCode(err); err == nil { return &ErrDataCopyFailed{ OldPath: oldPath, NewPath: newPath, ExitCode: exitCode} } return err } } } return nil }