func init() { cmd := &cobra.Command{ Use: "exec [-u username] [-U username] UUID|TAG COMMAND", Short: "Execute command inside the jail.", Run: execCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if hostUser != "" && jailUser != "" { gologit.Fatalln("Cannot supply both -u and -U") } arglen := len(args) if arglen < 1 { gologit.Fatalln("Required UUID|TAG not provided") } if arglen < 2 { gologit.Fatalln("Required command not provided") } }, } cmd.Flags().StringVarP( &hostUser, "host-user", "u", "", "user name from host environment as whom the command should run") cmd.Flags().StringVarP( &jailUser, "jail-user", "U", "", "user name from jailed environment as whom the command should run") RootCmd.AddCommand(cmd) }
func setCmdRun(cmd *cobra.Command, args []string) { // requires root if !core.IsRoot() { gologit.Fatalf("Must be root to set properties\n") } if len(args) < 2 { gologit.Fatalln("Improper usage") } jail, err := core.FindJail(args[0]) if err != nil { gologit.Fatalf("No jail found by '%s'\n", args[0]) } props, err := ParseProps(args[1:]...) if err != nil { gologit.Fatalln(err) } for _, prop := range props { prefix := "" if _, ok := CustomProperties[prop[0]]; ok { prefix = "org.freebsd.iocage:" } zfsArgs := []string{ "set", fmt.Sprintf("%s%s=%s", prefix, prop[0], prop[1]), jail.Path, } core.ZFSMust(fmt.Errorf("Error setting property"), zfsArgs...) } }
func init() { ReleaseCmd := &cobra.Command{ Use: "release", Short: "Operations for listing and fetching releases", } ReleaseCmd.AddCommand(&cobra.Command{ Use: "list", Short: "List all releases", Run: releaseListCmdRun, }) ReleaseCmd.AddCommand(&cobra.Command{ Use: "destroy RELEASE", Short: "Remove a release", Run: releaseDestroyCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required RELEASE not provided") } }, }) fetchCommand := &cobra.Command{ Use: "fetch RELEASE", Short: "Fetch/add a release", Run: releaseFetchCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required RELEASE not provided") } }, } fetchCommand.Flags().StringVarP( &mirrorHost, "mirror-host", "", "ftp.freebsd.org", "set mirror hostname") fetchCommand.Flags().StringVarP( &mirrorDir, "mirror-dir", "", "/pub/FreeBSD/releases/amd64/amd64/", "set mirror hostname") fetchCommand.Flags().StringVarP( &fetchSets, "sets", "s", "base.txz doc.txz lib32.txz src.txz", "sets to fetch for a release") ReleaseCmd.AddCommand(fetchCommand) ReleaseCmd.AddCommand(&cobra.Command{ Use: "update RELEASE", Short: "Update a release to most recent patchset", Run: releaseUpdateCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required RELEASE not provided") } }, }) RootCmd.AddCommand(ReleaseCmd) }
func init() { cmd := &cobra.Command{ Use: "rollback UUID|TAG snapshotname", Short: "Rollback jail to a particular snapshot", Run: rollbackCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } if len(args) == 1 { gologit.Fatalln("Required snapshotname not provided") } }, } RootCmd.AddCommand(cmd) }
func init() { cmd := &cobra.Command{ Use: "snapremove UUID|TAG snapshotname [snapshotname ...]", Short: "Remove snapshots belonging to jail", Run: snapremoveCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } else if len(args) == 1 { gologit.Fatalln("Required snapshotname not provided") } }, } cmd.Flags().BoolVarP( &snapremoveRegex, "regex", "x", false, "snapshotname becomes a match regex") RootCmd.AddCommand(cmd) }
func init() { RootCmd.AddCommand(&cobra.Command{ Use: "console UUID|TAG", Short: "Execute login to have a shell inside the jail.", Run: consoleCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, }) }
func init() { RootCmd.AddCommand(&cobra.Command{ Use: "stop UUID|TAG", Short: "stop jail", Long: "Stop jail identified by UUID or TAG.", Run: stopCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, }) }
func rollbackCmdRun(cmd *cobra.Command, args []string) { // requires root if !core.IsRoot() { gologit.Fatalf("Must be root to rollback\n") } jail, err := core.FindJail(args[0]) if err != nil { gologit.Fatalf("No jail found by '%s'\n", args[0]) } snapname := strings.TrimLeft(args[1], "@") // get FS's lines := core.SplitOutput(core.ZFSMust( fmt.Errorf("Error listing jails"), "list", "-Hr", "-o", "name", path.Join(jail.Path, "root"))) if len(lines) < 1 { gologit.Fatalf("No datasets at jailpath!\n") } snapshots := []string{} for _, line := range lines { out := core.ZFSMust( fmt.Errorf("Error listing snapshots"), "list", "-Ht", "snapshot", "-o", "name", "-d1", fmt.Sprintf("%s@%s", line[0], snapname)) if len(out) != 0 { snapshots = append(snapshots, out) } } if len(snapshots) == 0 { gologit.Fatalln("Snapshot '%s' not found!", snapname) } for _, snapshot := range snapshots { i := strings.LastIndex(snapshot, "@") elemName := snapshot[:i] j := strings.LastIndex(snapshot, "/") elemName = elemName[j:] fmt.Printf("* Rolling back jail dataset '%s' to '@%s'\n", elemName, snapname) core.ZFSMust( fmt.Errorf("Error rolling back jail"), "rollback", "-r", snapshot) } }
func init() { cmd := &cobra.Command{ Use: "destroy UUID|TAG", Short: "destroy jail", Long: "destroy jail identified by UUID or TAG.", Run: destroyCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, } cmd.Flags().BoolVarP( &force, "force", "f", false, "attempt to remove jail without prompting for confirmation") RootCmd.AddCommand(cmd) }
func init() { RootCmd.AddCommand(&cobra.Command{ Use: "chroot UUID|TAG [command]", Short: "Chroot into jail, without actually starting the jail itself", Long: ` Chroot into jail, without actually starting the jail itself. Useful for initial setup (set root password, configure networking). You can specify a command just like with the normal system chroot tool.`, Run: chrootCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, }) }
func init() { cmd := &cobra.Command{ Use: "snapshot UUID|TAG snapshotname", Short: "Create a zfs snapshot for jail", Run: snapshotCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, } cmd.Flags().BoolVarP( &recusiveSnapshot, "recursive", "r", false, "do a recursive snapshot of the jail root") RootCmd.AddCommand(cmd) }
func init() { cmd := &cobra.Command{ Use: "runtime UUID|TAG", Short: "show runtime configuration of a jail", Long: "Show runtime configuration of a jail. Useful for debugging.", Run: runtimeCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, } cmd.Flags().BoolVarP( &ParsableValues, "parsable-values", "p", false, "output parsable (exact) values") RootCmd.AddCommand(cmd) }
func init() { cmd := &cobra.Command{ Use: "snaplist UUID|TAG [command]", Short: "List all snapshots belonging to jail", Run: snaplistCmdRun, PreRun: func(cmd *cobra.Command, args []string) { if len(args) == 0 { gologit.Fatalln("Required UUID|TAG not provided") } }, } cmd.Flags().BoolVarP( &ParsableValues, "parsable-values", "p", false, "output parsable (exact) values") cmd.Flags().StringVarP( &snaplistRegex, "regex", "x", "", "filter listed snapshots by regex match") RootCmd.AddCommand(cmd) }
func updateCmdRun(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]) } zfsArgs := []string{ "get", "-Ho", "value", "org.freebsd.iocage:release,mountpoint", jail.Path} out := strings.Split( core.ZFSMust(fmt.Errorf("Error getting properties"), zfsArgs...), "\n") release := out[0] mountpoint := out[1] resolvconf := path.Join(mountpoint, "root/etc/resolv.conf") if _, err := os.Stat(resolvconf); os.IsNotExist(err) { data, err := ioutil.ReadFile("/etc/resolv.conf") if err != nil { gologit.Fatalln("/etc/resolv.conf not present or not readable") } err = ioutil.WriteFile(resolvconf, data, 0755) if err != nil { gologit.Fatalf("Could not copy contents to '%s'\n", resolvconf) } } fmt.Println("* Creating back out snapshot") snappath := fmt.Sprintf( "%s/root@%s", jail.Path, fmt.Sprintf( "ioc-update-%s", time.Now().Format("2006-01-02_15:04:05"))) core.ZFSMust( fmt.Errorf("Error taking snapshot"), "snapshot", snappath) devroot := path.Join(mountpoint, "root/dev") ecmd := exec.Command("/sbin/mount", "-t", "devfs", "devfs", devroot) gologit.Debugln(ecmd.Args) eout, err := ecmd.CombinedOutput() if err != nil { gologit.Fatalf("Error mounting devfs: %s\n", err) } gologit.Debugln(string(eout)) defer func() { ecmd := exec.Command("/sbin/umount", devroot) gologit.Debugln(ecmd.Args) err := ecmd.Run() if err != nil { gologit.Fatalf("Error unmounting devfs: %s\n", err) } }() fmt.Println("* Updating jail...") root := path.Join(mountpoint, "root") ecmd = exec.Command("/usr/sbin/chroot", root, "/usr/sbin/freebsd-update", "--not-running-from-cron", "fetch", "install") ecmd.Env = []string{ "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin", fmt.Sprintf("UNAME_r=%s", release), "PAGER=/bin/cat", } gologit.Debugln(ecmd.Args) ecmd.Stdout = os.Stdout ecmd.Stderr = os.Stderr ecmd.Run() fmt.Println("* update finished") fmt.Println(" Once verified, don't forget to remove the snapshot!") }
func releaseUpdateCmdRun(cmd *cobra.Command, args []string) { // requires root if !core.IsRoot() { gologit.Fatalf("Must be root to update\n") } release, err := core.FindRelease(args[0]) if err != nil { gologit.Fatalf("Release '%s' not found!\n", args[0]) } mountpoint := release.Mountpoint resolvconf := path.Join(mountpoint, "root/etc/resolv.conf") if _, err := os.Stat(resolvconf); os.IsNotExist(err) { data, err := ioutil.ReadFile("/etc/resolv.conf") if err != nil { gologit.Fatalln("/etc/resolv.conf not present or not readable") } err = ioutil.WriteFile(resolvconf, data, 0755) if err != nil { gologit.Fatalf("Could not copy contents to '%s'\n", resolvconf) } } devroot := path.Join(mountpoint, "root/dev") ecmd := exec.Command("/sbin/mount", "-t", "devfs", "devfs", devroot) gologit.Debugln(ecmd.Args) eout, err := ecmd.CombinedOutput() if err != nil { gologit.Fatalf("Error mounting devfs: %s\n", err) } gologit.Debugln(string(eout)) defer func() { ecmd := exec.Command("/sbin/umount", devroot) gologit.Debugln(ecmd.Args) err := ecmd.Run() if err != nil { gologit.Fatalf("Error unmounting devfs: %s\n", err) } }() fmt.Println("* Updating release...") root := path.Join(mountpoint, "root") exargs := []string{root, "/usr/sbin/freebsd-update"} if release.Name != "9.3-RELEASE" && release.Name != "10.1-RELEASE" { exargs = append(exargs, "--not-running-from-cron") } exargs = append(exargs, "fetch", "install") ecmd = exec.Command("/usr/sbin/chroot", exargs...) unamer := release.Name if release.Patchlevel != "" { unamer = release.Patchlevel } ecmd.Env = []string{ "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin", fmt.Sprintf("UNAME_r=%s", unamer), "PAGER=/bin/cat", } gologit.Debugln(ecmd.Args) ecmd.Stdout = os.Stdout ecmd.Stderr = os.Stderr ecmd.Stdin = os.Stdin ecmd.Run() fmt.Println("* update finished") }