github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/upgrades/preupgradesteps.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package upgrades
     5  
     6  import (
     7  	"github.com/dustin/go-humanize"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/packaging/v3/manager"
    10  	"github.com/juju/utils/v3/du"
    11  
    12  	"github.com/juju/juju/agent"
    13  	corebase "github.com/juju/juju/core/base"
    14  	"github.com/juju/juju/state"
    15  )
    16  
    17  // PreUpgradeStepsFunc is the function type of PreUpgradeSteps. This may be
    18  // used to provide an alternative to PreUpgradeSteps to the upgrade steps
    19  // worker.
    20  type PreUpgradeStepsFunc = func(_ *state.StatePool, _ agent.Config, isController, isCaas bool) error
    21  
    22  // PreUpgradeSteps runs various checks and prepares for performing an upgrade.
    23  // If any check fails, an error is returned which aborts the upgrade.
    24  func PreUpgradeSteps(_ *state.StatePool, agentConf agent.Config, isController, isCaas bool) error {
    25  	if isCaas {
    26  		logger.Debugf("skipping disk space checks for k8s controllers")
    27  		return nil
    28  	}
    29  	if err := CheckFreeDiskSpace(agentConf.DataDir(), MinDiskSpaceMib); err != nil {
    30  		return errors.Trace(err)
    31  	}
    32  	if isController {
    33  		// Update distro info in case the new Juju controller version
    34  		// is aware of new supported series. We'll keep going if this
    35  		// fails, and the user can manually update it if they need to.
    36  		logger.Infof("updating distro-info")
    37  		err := updateDistroInfo()
    38  		return errors.Annotate(err, "failed to update distro-info")
    39  	}
    40  	return nil
    41  }
    42  
    43  // MinDiskSpaceMib is the standard amount of disk space free (in MiB)
    44  // we'll require before downloading a binary or starting an upgrade.
    45  var MinDiskSpaceMib = uint64(250)
    46  
    47  // CheckFreeDiskSpace returns a helpful error if there isn't at
    48  // least thresholdMib MiB of free space available on the volume
    49  // containing dir.
    50  func CheckFreeDiskSpace(dir string, thresholdMib uint64) error {
    51  	usage := du.NewDiskUsage(dir)
    52  	available := usage.Available()
    53  	if available < thresholdMib*humanize.MiByte {
    54  		return errors.Errorf("not enough free disk space on %q for upgrade: %s available, require %dMiB",
    55  			dir, humanize.IBytes(available), thresholdMib)
    56  	}
    57  	return nil
    58  }
    59  
    60  func updateDistroInfo() error {
    61  	pm := manager.NewAptPackageManager()
    62  	if err := pm.Update(); err != nil {
    63  		return errors.Annotate(err, "updating package list")
    64  	}
    65  	if err := pm.Install("distro-info"); err != nil {
    66  		return errors.Annotate(err, "updating distro-info package")
    67  	}
    68  	return corebase.UpdateSeriesVersions()
    69  }