func snapremoveCmdRun(cmd *cobra.Command, args []string) {
	// requires root
	if !core.IsRoot() {
		gologit.Fatalf("Must be root to snapremove\n")
	}

	jail, err := core.FindJail(args[0])
	if err != nil {
		gologit.Fatalf("No jail found by '%s'\n", args[0])
	}

	matchers := args[1:]
	gologit.Debugf("matchers: %#v\n", matchers)

	zfsArgs := []string{"list", "-Hrt", "snapshot",
		"-o", "name", "-d2", jail.Path}
	lines := core.SplitOutput(core.ZFSMust(
		fmt.Errorf("Error listing snapshots"),
		zfsArgs...))

	rmlist := []string{}
	for _, line := range lines {
		if len(line) == 0 || len(line[0]) == 0 {
			continue
		}
		snapname := strings.SplitN(line[0], "@", 2)[1]
		gologit.Debugf("source snapname: %#v\n", snapname)
		for _, m := range matchers {
			if snapremoveRegex {
				matched, err := regexp.MatchString(m, snapname)
				if err != nil {
					gologit.Fatalf("Regex error: %s", err)
				}
				if matched {
					rmlist = append(rmlist, line[0])
					continue
				}
			} else {
				if m == snapname {
					rmlist = append(rmlist, line[0])
					continue
				}
			}
		}
	}
	gologit.Debugf("match list: %#v\n", rmlist)

	for _, snap := range rmlist {
		fmt.Printf("Removing snapshot: %s\n", strings.SplitN(snap, "@", 2)[1])
		core.ZFSMust(
			fmt.Errorf("Error removing snapshot"),
			"destroy", "-r", snap)
	}
}
Beispiel #2
0
func validateURL(hmackey *[]byte, macbytes *[]byte, urlbytes *[]byte) bool {
	mac := hmac.New(sha1.New, *hmackey)
	mac.Write(*urlbytes)
	macSum := mac.Sum(nil)

	// ensure lengths are equal. if not, return false
	if len(macSum) != len(*macbytes) {
		gologit.Debugf("Bad signature: %x != %x\n", macSum, macbytes)
		return false
	}

	if subtle.ConstantTimeCompare(macSum, *macbytes) != 1 {
		gologit.Debugf("Bad signature: %x != %x\n", macSum, macbytes)
		return false
	}
	return true
}
Beispiel #3
0
func Cmd(name string, arg ...string) (string, error) {
	cmd := exec.Command(name, arg...)
	stdout := &bytes.Buffer{}
	stderr := &bytes.Buffer{}
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	err := cmd.Run()
	gologit.Debugf("cmd: %s\nstdout: %s\nstderr: %s", cmd.Args, stdout, stderr)
	return strings.TrimSpace(stdout.String()), err
}
Beispiel #4
0
func execCmdRun(cmd *cobra.Command, args []string) {
	// requires root
	if !core.IsRoot() {
		gologit.Fatalf("Must be root to use exec\n")
	}

	jail, err := core.FindJail(args[0])
	if err != nil {
		gologit.Fatalf("No jail found by '%s'\n", args[0])
	}

	if !jail.IsRunning() {
		gologit.Fatalf("Jail is not running!\n")
	}

	// get exec fib property
	lines := core.SplitOutput(core.ZFSMust(
		fmt.Errorf("Error listing jails"),
		"list", "-H",
		"-o", "org.freebsd.iocage:login_flags,org.freebsd.iocage:exec_fib",
		jail.Path))
	execFib := lines[0][1]

	jexec := []string{}
	if execFib != "0" {
		jexec = append(jexec, "/usr/sbin/setfib", execFib)
	}
	jexec = append(jexec, "/usr/sbin/jexec")
	if hostUser != "" {
		jexec = append(jexec, "-u", hostUser)
	}
	if jailUser != "" {
		jexec = append(jexec, "-U", jailUser)
	}
	jexec = append(jexec, fmt.Sprintf("ioc-%s", jail.HostUUID))
	jexec = append(jexec, args[1:]...)

	// set a default path
	environ := []string{
		"PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
	}
	// set a term from caller
	environ = append(environ, fmt.Sprintf("TERM=%s", os.Getenv("TERM")))

	gologit.Debugf("%#s\n", jexec)
	execErr := syscall.Exec(jexec[0], jexec, environ)
	if execErr != nil {
		gologit.Fatal(execErr)
	}
}
Beispiel #5
0
func umountCmd(args ...string) {
	cmd := exec.Command("/sbin/umount", args...)
	gologit.Debugln(append([]string{"/sbin/umount"}, args...))
	out, err := cmd.CombinedOutput()
	for _, line := range strings.Split(string(out), "\n") {
		if line != "" {
			gologit.Debugln(line)
		}
	}
	if err != nil {
		// some mounts are not present, so just fail
		// do not log exit status 1 unless debug logging
		gologit.Debugf("%s\n", err)
	}
}
Beispiel #6
0
// Fetch http file url to destination dest, with or without progress.
func FetchHTTPFile(url string, dest string, progress bool) (err error) {
	gologit.Debugf("Creating file: %s\n", dest)
	out, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer out.Close()

	var r io.Reader

	gologit.Debugf("Fetching url: %s\n", url)
	resp, err := http.Get(url)
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Server return non-200 status: %v", resp.Status)
	}

	msgPrefix := fmt.Sprintf("%s: ", path.Base(dest))
	var bar *pb.ProgressBar
	i, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
	if i > 0 && progress {
		bar = pb.New(i).Prefix(msgPrefix).SetUnits(pb.U_BYTES)
		bar.ShowSpeed = true
		bar.RefreshRate = time.Millisecond * 700
		bar.ShowFinalTime = false
		bar.ShowTimeLeft = false
		bar.Start()
		defer bar.Finish()
		r = bar.NewProxyReader(resp.Body)
	} else {
		r = resp.Body
	}
	_, err = io.Copy(out, r)
	return err
}
func snaplistCmdRun(cmd *cobra.Command, args []string) {
	jail, err := core.FindJail(args[0])
	if err != nil {
		gologit.Fatalf("No jail found by '%s'\n", args[0])
	}

	zfsArgs := []string{"list", "-Hrt", "snapshot",
		"-o", "name,creation,used,referenced", "-d2"}
	if ParsableValues {
		zfsArgs = append(zfsArgs, "-p")
	}
	zfsArgs = append(zfsArgs, jail.Path)

	lines := core.SplitOutput(core.ZFSMust(
		fmt.Errorf("Error listing snapshots"),
		zfsArgs...))
	gologit.Debugf("%#v", lines)
	if len(lines) == 0 || len(lines[0]) == 0 || len(lines[0][0]) == 0 {
		return
	}

	var rxmatch *regexp.Regexp
	if snaplistRegex != "" {
		rxmatch, err = regexp.Compile(snaplistRegex)
		if err != nil {
			gologit.Fatalf("Bad regex: %s", err)
		}
	}

	outputHeaders := []string{"name", "created", "rsize", "used"}
	wf := core.NewOutputWriter(outputHeaders, MachineOutput)
	for _, line := range lines {
		if len(line) < 4 {
			continue
		}

		snapname := strings.SplitN(line[0], "@", 2)[1]

		if rxmatch != nil && !rxmatch.MatchString(snapname) {
			continue
		}
		fmt.Fprintf(wf, "%s\t%s\t%s\t%s\n", snapname, line[1], line[2], line[3])
	}
	wf.Flush()
}
Beispiel #8
0
func releaseFetchCmdRun(cmd *cobra.Command, args []string) {
	// requires root
	if !core.IsRoot() {
		gologit.Fatalf("Must be root to fetch\n")
	}

	// find/verify release name
	releaseName := strings.ToUpper(args[0])

	found := false
	for _, release := range core.SupportedReleases {
		if releaseName == release {
			found = true
			break
		}
	}

	if !found {
		gologit.Fatalf("Release '%s' is not currently supported\n", releaseName)
	}

	// get some meta
	release, err := core.CreateRelease(releaseName)
	if err != nil {
		gologit.Fatalf("Couldn't create release '%s'\n", releaseName)
	}

	// fetch
	if !strings.HasPrefix(mirrorHost, "http://") {
		mirrorHost = "http://" + mirrorHost
	}
	u, err := url.Parse(mirrorHost)
	if err != nil {
		gologit.Fatalf("error parsing internal sets fetch url\n")
	}
	u.Path = mirrorDir
	fmt.Printf("Fetching sets:\n")
	tarset := []string{}
	for _, setname := range strings.Split(fetchSets, " ") {
		ux := *u
		ux.Path = path.Join(ux.Path, release.Name, setname)
		destPth := path.Join(release.Mountpoint, "sets", setname)
		tarset = append(tarset, destPth)
		if _, err := os.Stat(destPth); !os.IsNotExist(err) {
			fmt.Printf("'%s' already present -- skipping download\n", setname)
			continue
		}
		err := core.FetchHTTPFile(ux.String(), destPth, true)
		if err != nil {
			gologit.Fatalf("Failed to fetch: %s\n", ux.String())
		}
	}

	fmt.Printf("Extracting sets:\n")
	for _, pth := range tarset {
		basepth := path.Base(pth)
		fmt.Printf("* %s\n", basepth)
		excmd := exec.Command(
			"tar", "-C", path.Join(release.Mountpoint, "root"),
			"-xf", pth)
		excmd.Stdout = os.Stdout
		excmd.Stderr = os.Stdout
		err := excmd.Run()
		if err != nil {
			gologit.Debugf("Error: %s\n", err)
			gologit.Fatalf("Failed to extract: %s\n", basepth)
		}
	}
	err = os.MkdirAll(path.Join(release.Mountpoint, "root", "usr/home"), 0755)
	if err != nil {
		gologit.Fatalf("Failed to make: %s\n", "/usr/home")
	}
	err = os.MkdirAll(path.Join(release.Mountpoint, "root", "usr/ports"), 0755)
	if err != nil {
		gologit.Fatalf("Failed to make: %s\n", "/usr/ports")
	}
}