Compare commits

...

3 Commits

Author SHA1 Message Date
yo
5d4c54f5fa Update README 2024-09-22 19:30:43 +02:00
yo
c79ac4ac30 Update release with -r and -d flags 2024-09-22 19:30:39 +02:00
yo
76c720354c freebsd-update work directory is now configurable in gocage.conf.yml 2024-09-22 19:30:35 +02:00
5 changed files with 70 additions and 18 deletions

View File

@ -137,20 +137,36 @@ Stop jails
---------- ----------
`gocage stop test` `gocage stop test`
Update jails Update jails
---------- ----------
To update jail patch version, use gocage update : To update jail patch version, use gocage update :
`gocage update test` `gocage update test`
Update basejails/releases
----------
To update basejails, you need to update the release they are base on. Specify release with -r, and the datastore storing concerned release with -d :
`gocage update -d fastgocage -r 14.1-RELEASE`
Upgrade jails Upgrade jails
---------- ----------
To upgrade jail to newer release, use gocage upgrade : To upgrade jail to newer release, use gocage upgrade :
`gocage upgrade -r 13.2-RELEASE test` `gocage upgrade -r 13.2-RELEASE test`
A pre-upgrade snapshot wil be made so we can rollback if needed. A pre-upgrade snapshot wil be made so you can rollback if needed.
Upgrading basejail/release
----------
Upgrading basejails currently needs to be done manually, for each jail.
The idea is to stop the jail, change the content of its fstab file to point to the new release, then start jail.
If one change the fstab while the jail is running, its system directories won't be unmounted at stop time and this will provoke stop errors.
To minimize downtime, the change could be scripted:
`gocage stop jail1
sed -i .bak 's/14.0-RELEASE/14.1-RELEASE/' /iocage/jails/jail1/fstab
# Avoid race-condition by waiting for the update in fstab
until grep -q 14.1-RELEASE /iocage/jails/jail1/fstab; do sleep 0.2; done
gocage start jail1`
You can now update ports.
Delete jails Delete jails
---------- ----------

View File

@ -14,7 +14,7 @@ import (
) )
const ( const (
gVersion = "0.42b" gVersion = "0.42c"
// TODO : Get from $jail_zpool/defaults.json // TODO : Get from $jail_zpool/defaults.json
MIN_DYN_DEVFS_RULESET = 1000 MIN_DYN_DEVFS_RULESET = 1000
@ -68,6 +68,8 @@ var (
gFetchIntoDS string gFetchIntoDS string
gFetchFrom string gFetchFrom string
gUpgradeRelease string gUpgradeRelease string
gUpdateRelease string
gUpdateReleaseDS string
// For a based jail, these are directories binded to basejail // For a based jail, these are directories binded to basejail
gBaseDirs = []string{"bin", "boot", "lib", "libexec", "rescue", "sbin", "usr/bin", "usr/include", 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.Flags().StringVarP(&gUpgradeRelease, "release", "r", "", "Release to upgrade to (e.g.: \"13.1-RELEASE\"")
upgradeCmd.MarkFlagRequired("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().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().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.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 // Now declare commands
rootCmd.AddCommand(initCmd) rootCmd.AddCommand(initCmd)

View File

@ -6,33 +6,36 @@ import (
//"log" //"log"
"time" "time"
"strings" "strings"
"github.com/spf13/viper"
) )
// Internal usage only // Internal usage only
func updateJail(jail *Jail) error { func updateJail(jail *Jail, doUpdateVersion bool) error {
// Create default config as temporary file // Create default config as temporary file
cfgFile, err := os.CreateTemp("", "gocage-jail-update-") cfgFile, err := os.CreateTemp("", "gocage-jail-update-")
if err != nil { if err != nil {
return err return err
} }
cfgFile.Write([]byte(fbsdUpdateConfig)) // Folder containing update/upgrade temporary files. Mutualized so we save bandwith when upgrading multiple jails
uwd := viper.GetString("updateWorkDir")
defer cfgFile.Close() if len(uwd) == 0 {
defer os.Remove(cfgFile.Name()) return fmt.Errorf("updateWorkDir not set in configuration")
}
// Folder containing update/upgrade temporary files. Common so we save bandwith when upgrading multiple jails _, err = os.Stat(uwd)
// TODO: Variabilize /iocage/freebsd-update
_, err = os.Stat("/iocage/freebsd-update")
if os.IsNotExist(err) { if os.IsNotExist(err) {
if err := os.Mkdir("/iocage/freebsd-update", 0755); err != nil { if err := os.Mkdir(uwd, 0755); err != nil {
return err 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", 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) cfgFile.Name(), jail.RootPath, jail.Config.Release)
err = executeCommandWithOutputToStdout(cmd) err = executeCommandWithOutputToStdout(cmd)
if err != nil { if err != nil {
return err return err
@ -45,8 +48,10 @@ func updateJail(jail *Jail) error {
return err return err
} }
// Get and write new release into config.json // Get and write new release into config.json. Don't do that for fake jail (aka release updating)
if doUpdateVersion {
updateVersion(jail) updateVersion(jail)
}
return nil return nil
} }
@ -56,6 +61,28 @@ func UpdateJail(args []string) {
var cj *Jail var cj *Jail
var err error 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 { for _, a := range args {
// Check if jail exist and is distinctly named // Check if jail exist and is distinctly named
cj, err = getJailFromArray(a, []string{""}, gJails) 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(" > Snapshot jail %s: OK\n", cj.Name)
fmt.Printf(" > Update jail %s\n", cj.Name) fmt.Printf(" > Update jail %s\n", cj.Name)
err = updateJail(cj) err = updateJail(cj, true)
if err != nil { if err != nil {
fmt.Printf("ERROR: %s\n", err.Error()) fmt.Printf("ERROR: %s\n", err.Error())
} else { } else {

View File

@ -68,7 +68,7 @@ MergeChanges /etc/
# Directory in which to store downloaded updates and temporary # Directory in which to store downloaded updates and temporary
# files used by FreeBSD Update. # files used by FreeBSD Update.
WorkDir /iocage/freebsd-update WorkDir TO-BE-REPLACED-WITH-UPDATEWORKDIR
# Destination to send output of "freebsd-update cron" if an error # Destination to send output of "freebsd-update cron" if an error
# occurs or updates have been downloaded. # occurs or updates have been downloaded.

View File

@ -5,6 +5,9 @@ datastore:
# Prefix all commands with sudo # Prefix all commands with sudo
sudo: false sudo: false
# Directory used to store update temporary files. Mutualized so we save bandwith
updateWorkDir: /iocage/freebsd-updates
# Columns to display when "gocage list". Column names are struct fields, see cmd/struct.go # Columns to display when "gocage list". Column names are struct fields, see cmd/struct.go
outcol: 'JID,Name,Config.Release,Config.Ip4_addr,Running' outcol: 'JID,Name,Config.Release,Config.Ip4_addr,Running'