package cmd import ( "os" "fmt" //"log" "time" "strings" ) // Internal usage only func upgradeJail(jail *Jail, version string) error { // Create default config as temporary file cfgFile, err := os.CreateTemp("", "gocage-jail-upgrade-") if err != nil { return err } cfgFile.Write([]byte(fbsdUpdateConfig)) defer cfgFile.Close() defer os.Remove(cfgFile.Name()) // Folder containing update/uipgrade temporary files. Common so we save bandwith when upgrading multiple jails // TODO: Variabilize /iocage/freebsd-update _, err = os.Stat("/iocage/freebsd-update") if os.IsNotExist(err) { if err := os.Mkdir("/iocage/freebsd-update", 0755); err != nil { return err } } // Get current version. Won't work on stopped jail. fbsdvers, err := executeCommandInJail(jail, "/bin/freebsd-version") if err != nil { fmt.Printf("ERROR executeCommandInJail: %s\n", err.Error()) return err } fbsdvers = strings.TrimRight(fbsdvers, "\n") //fbsdvers := jail.Config.Release cmd := fmt.Sprintf("/usr/sbin/freebsd-update -f %s -b %s --currently-running %s -r %s upgrade", cfgFile.Name(), jail.RootPath, fbsdvers, version) //fmt.Printf("DEBUG: Prepare to execute \"%s\"\n", cmd) // Need to give user control, bc there could be merge edit needs err = executeCommandWithStdinStdoutStderr(cmd) if err != nil { return err } cmd = fmt.Sprintf("/usr/sbin/freebsd-update -f %s -b %s --currently-running %s -r %s install", cfgFile.Name(), jail.RootPath, fbsdvers, version) //fmt.Printf("DEBUG: Prepare to execute \"%s\"\n", cmd) err = executeCommandWithStdinStdoutStderr(cmd) if err != nil { return err } cmd = fmt.Sprintf("/usr/sbin/freebsd-update -f %s -b %s --currently-running %s -r %s install", cfgFile.Name(), jail.RootPath, fbsdvers, version) //fmt.Printf("DEBUG: Prepare to execute \"%s\"\n", cmd) err = executeCommandWithStdinStdoutStderr(cmd) if err != nil { return err } cmd = fmt.Sprintf("/usr/local/sbin/pkg-static -j %d install -q -f -y pkg", jail.JID) err = executeCommandWithStdinStdoutStderr(cmd) if err != nil { return err } // Get and write new release into config.json updateVersion(jail) return nil } func UpgradeJail(args []string) { // Current jail were stopping var cj *Jail var err error for _, a := range args { // Check if jail exist and is distinctly named cj, err = getJailFromArray(a, []string{""}, gJails) if err != nil { fmt.Printf("Error getting jail: %s\n", err) continue } if cj.Running == false { fmt.Printf("Error: jail must be running for upgrade.\n") return } fmt.Printf(" > Snapshot jail %s\n", cj.Name) // Set snapshot name dt := time.Now() curDate := fmt.Sprintf("%s", dt.Format("2006-01-02_15-04-05")) gSnapshotName = fmt.Sprintf("goc_upgrade_%s_%s", cj.Config.Release, curDate) err := createJailSnapshot(*cj) if err != nil { fmt.Printf(" > Snapshot jail %s: ERROR: %s\n", cj.Name, err.Error()) return } fmt.Printf(" > Snapshot jail %s: OK\n", cj.Name) fmt.Printf(" > Upgrade jail %s to %s\n", cj.Name, gUpgradeRelease) err = upgradeJail(cj, gUpgradeRelease) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) } else { fmt.Printf(" > Upgrade jail %s: OK\n", cj.Name) } } }