diff --git a/cmd/root.go b/cmd/root.go index 1cf8dfe..77a3c43 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,7 +14,7 @@ import ( ) const ( - gVersion = "0.42b" + gVersion = "0.42c" // TODO : Get from $jail_zpool/defaults.json MIN_DYN_DEVFS_RULESET = 1000 @@ -68,6 +68,8 @@ var ( gFetchIntoDS string gFetchFrom string gUpgradeRelease string + gUpdateRelease string + gUpdateReleaseDS string // For a based jail, these are directories binded to basejail gBaseDirs = []string{"bin", "boot", "lib", "libexec", "rescue", "sbin", "usr/bin", "usr/include", @@ -422,10 +424,14 @@ func init() { upgradeCmd.Flags().StringVarP(&gUpgradeRelease, "release", "r", "", "Release to upgrade to (e.g.: \"13.1-RELEASE\"") upgradeCmd.MarkFlagRequired("release") + updateCmd.Flags().StringVarP(&gUpdateRelease, "release", "r", "", "Release to update (e.g.: \"13.1-RELEASE\"") + updateCmd.Flags().StringVarP(&gUpdateReleaseDS, "datastore", "d", "", "Datastore release is stored on") + updateCmd.MarkFlagsRequiredTogether("release", "datastore") + createCmd.Flags().StringVarP(&gCreateArgs.Release, "release", "r", "", "Release for the jail (e.g.: \"13.1-RELEASE\"") createCmd.Flags().BoolVarP(&gCreateArgs.BaseJail, "basejail", "b", false, "Basejail. This will create a jail mounted read only from a release, so every up(date|grade) made to this release will immediately propagate to new jail.\n") createCmd.Flags().StringVarP(&gCreateArgs.Datastore, "datastore", "d", "", "Datastore to create the jail on. Defaults to first declared in config.") - createCmd.Flags().StringVarP(&gCreateArgs.Properties, "configuration", "p", "", "Configuration properties with format k1=v1,k2=v2 (Ex: \"Config.Ip4_addr='vnet0|192.168.1.2',Config.Ip6=none\")") + createCmd.Flags().StringVarP(&gCreateArgs.Properties, "configuration", "p", "", "Configuration properties with format k1=v1,k2=v2 (Ex: \"Config.Ip4_addr=vnet0|192.168.1.2,Config.Ip6=none\")") // Now declare commands rootCmd.AddCommand(initCmd) diff --git a/cmd/update.go b/cmd/update.go index 7ecbfe5..b607191 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -6,33 +6,36 @@ import ( //"log" "time" "strings" + "github.com/spf13/viper" ) // Internal usage only -func updateJail(jail *Jail) error { +func updateJail(jail *Jail, doUpdateVersion bool) error { // Create default config as temporary file cfgFile, err := os.CreateTemp("", "gocage-jail-update-") if err != nil { return err } - cfgFile.Write([]byte(fbsdUpdateConfig)) - - defer cfgFile.Close() - defer os.Remove(cfgFile.Name()) - - // Folder containing update/upgrade temporary files. Common so we save bandwith when upgrading multiple jails - // TODO: Variabilize /iocage/freebsd-update - _, err = os.Stat("/iocage/freebsd-update") + // Folder containing update/upgrade temporary files. Mutualized so we save bandwith when upgrading multiple jails + uwd := viper.GetString("updateWorkDir") + if len(uwd) == 0 { + return fmt.Errorf("updateWorkDir not set in configuration") + } + _, err = os.Stat(uwd) if os.IsNotExist(err) { - if err := os.Mkdir("/iocage/freebsd-update", 0755); err != nil { + if err := os.Mkdir(uwd, 0755); err != nil { return err } } + cfgFile.Write([]byte(strings.Replace(fbsdUpdateConfig, "TO-BE-REPLACED-WITH-UPDATEWORKDIR", uwd, 1))) + defer cfgFile.Close() + defer os.Remove(cfgFile.Name()) cmd := fmt.Sprintf("/usr/sbin/freebsd-update --not-running-from-cron -f %s -b %s --currently-running %s fetch", cfgFile.Name(), jail.RootPath, jail.Config.Release) + err = executeCommandWithOutputToStdout(cmd) if err != nil { return err @@ -45,8 +48,10 @@ func updateJail(jail *Jail) error { return err } - // Get and write new release into config.json - updateVersion(jail) + // Get and write new release into config.json. Don't do that for fake jail (aka release updating) + if doUpdateVersion { + updateVersion(jail) + } return nil } @@ -56,6 +61,28 @@ func UpdateJail(args []string) { var cj *Jail var err error + // User is updateing a release, fake a jail + if len(gUpdateRelease) > 0 { + // get datastore mountpoing from datastore name + ds, err := getDatastoreFromArray(gUpdateReleaseDS, gDatastores) + if err != nil { + fmt.Printf("Error gettting datastore %s: %v\n", gUpdateReleaseDS, err) + return + } + rp := fmt.Sprintf("%s/releases/%s/root", ds.Mountpoint, gUpdateRelease) + fakeJail := Jail{RootPath: rp} + v, err := getVersion(&fakeJail) + if err != nil { + fmt.Printf("Error getting version of release %s: %v\n", gUpdateRelease, err) + return + } + fakeJail.Config.Release = v + if err = updateJail(&fakeJail, false); err != nil { + fmt.Printf("Error updating release %s: %v\n", gUpdateRelease, err) + } + return + } + for _, a := range args { // Check if jail exist and is distinctly named cj, err = getJailFromArray(a, []string{""}, gJails) @@ -83,7 +110,7 @@ func UpdateJail(args []string) { fmt.Printf(" > Snapshot jail %s: OK\n", cj.Name) fmt.Printf(" > Update jail %s\n", cj.Name) - err = updateJail(cj) + err = updateJail(cj, true) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) } else {