Skip to content

Commit

Permalink
refactor: separate rpm-ostree and bootc drivers w/ new format
Browse files Browse the repository at this point in the history
  • Loading branch information
tulilirockz committed Dec 11, 2024
1 parent 3d04f4d commit 7772a72
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 151 deletions.
75 changes: 57 additions & 18 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,6 @@ func Update(cmd *cobra.Command, args []string) {
initConfiguration.DryRun = dryRun
initConfiguration.Verbose = verboseRun

systemUpdater, err := drv.SystemUpdater{}.New(*initConfiguration)
if err != nil {
systemUpdater.Config.Enabled = false
} else {
enableUpd, err := systemUpdater.Check()
if err != nil {
slog.Error("Failed checking for updates")
}
systemUpdater.Config.Enabled = enableUpd
if !enableUpd {
slog.Debug("No system update found, disabiling module")
}
}

brewUpdater, err := drv.BrewUpdater{}.New(*initConfiguration)
brewUpdater.Config.Enabled = err == nil

Expand All @@ -87,7 +73,45 @@ func Update(cmd *cobra.Command, args []string) {
distroboxUpdater.Config.Enabled = err == nil
distroboxUpdater.SetUsers(users)

totalSteps := brewUpdater.Steps() + systemUpdater.Steps() + flatpakUpdater.Steps() + distroboxUpdater.Steps()
var enableUpd bool = true
var systemOutdated bool = false

Check failure on line 77 in cmd/update.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to systemOutdated (ineffassign)

rpmOstreeUpdater, err := drv.RpmOstreeUpdater{}.New(*initConfiguration)
if err != nil {
enableUpd = false
}

systemUpdater, err := drv.SystemUpdater{}.New(*initConfiguration)
if err != nil {
enableUpd = false
}

// FIXME: Bootc can also only be used whenever there are no layered packages, we should account for that!
isBootc, err := drv.BootcCompatible(systemUpdater.BinaryPath)
if err != nil {
isBootc = false
}

if !isBootc {
slog.Debug("Using rpm-ostree fallback as system driver")
}

systemUpdater.Config.Enabled = enableUpd && isBootc
rpmOstreeUpdater.Config.Enabled = enableUpd && !isBootc

if systemUpdater.Config.Enabled {
enableUpd, err = systemUpdater.Check()
} else {
enableUpd, err = rpmOstreeUpdater.Check()
}
if err != nil {
slog.Error("Failed checking for updates")
}
if !enableUpd {
slog.Debug("No system update found, disabiling module")
}

totalSteps := brewUpdater.Steps() + systemUpdater.Steps() + rpmOstreeUpdater.Steps() + flatpakUpdater.Steps() + distroboxUpdater.Steps()
pw := lib.NewProgressWriter()
pw.SetNumTrackersExpected(1)
pw.SetAutoStop(false)
Expand Down Expand Up @@ -119,7 +143,17 @@ func Update(cmd *cobra.Command, args []string) {

var outputs = []drv.CommandOutput{}

if systemUpdater.Outdated {
if systemUpdater.Config.Enabled {
systemOutdated, err = systemUpdater.Outdated()
} else {
systemOutdated, err = rpmOstreeUpdater.Outdated()
}

if err != nil {
slog.Error("Failed checking if system is out of date")
}

if systemOutdated {
const OUTDATED_WARNING = "There hasn't been an update in over a month. Consider rebooting or running updates manually"
err := lib.Notify("System Warning", OUTDATED_WARNING)
if err != nil {
Expand All @@ -128,9 +162,14 @@ func Update(cmd *cobra.Command, args []string) {
slog.Warn(OUTDATED_WARNING)
}

if systemUpdater.Config.Enabled {
if enableUpd {
lib.ChangeTrackerMessageFancy(pw, tracker, progressEnabled, lib.TrackerMessage{Title: systemUpdater.Config.Title, Description: systemUpdater.Config.Description})
out, err := systemUpdater.Update()
var out *[]drv.CommandOutput
if rpmOstreeUpdater.Config.Enabled {
out, err = rpmOstreeUpdater.Update()
} else {
out, err = systemUpdater.Update()
}
outputs = append(outputs, *out...)
tracker.IncrementSection(err)
}
Expand Down
121 changes: 121 additions & 0 deletions drv/rpm-ostree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package drv

// Temporary: WILL get removed at some point.
// FIXME: Remove this on Spring 2025 when we all move to dnf5 and bootc ideally

import (
"encoding/json"
"os/exec"
"strings"
"time"
)

type rpmOstreeStatus struct {
Deployments []struct {
Timestamp int64 `json:"timestamp"`
} `json:"deployments"`
}

type RpmOstreeUpdater struct {
Config DriverConfiguration
BinaryPath string
}

func (dr RpmOstreeUpdater) Outdated() (bool, error) {
if dr.Config.DryRun {
return false, nil
}
oneMonthAgo := time.Now().AddDate(0, -1, 0)
var timestamp time.Time

cmd := exec.Command(dr.BinaryPath, "status", "--json", "--booted")
out, err := cmd.CombinedOutput()
if err != nil {
return false, err
}
var status rpmOstreeStatus
err = json.Unmarshal(out, &status)
if err != nil {
return false, err
}
timestamp = time.Unix(status.Deployments[0].Timestamp, 0).UTC()

return timestamp.Before(oneMonthAgo), nil
}

func (dr RpmOstreeUpdater) Update() (*[]CommandOutput, error) {
var finalOutput = []CommandOutput{}
var cmd *exec.Cmd = nil

Check failure on line 48 in drv/rpm-ostree.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to cmd (ineffassign)
binaryPath := dr.BinaryPath
cli := []string{binaryPath, "upgrade"}
cmd = exec.Command(cli[0], cli[1:]...)
out, err := cmd.CombinedOutput()
tmpout := CommandOutput{}.New(out, err)
tmpout.Cli = cli
tmpout.Failure = err != nil
tmpout.Context = "System Update"
finalOutput = append(finalOutput, *tmpout)
return &finalOutput, err
}

func (dr RpmOstreeUpdater) UpdateAvailable() (bool, error) {
// This function may or may not be accurate, rpm-ostree updgrade --check has issues... https://github.com/coreos/rpm-ostree/issues/1579
// Not worried because we will end up removing rpm-ostree from the equation soon
cmd := exec.Command(dr.BinaryPath, "upgrade", "--check")
out, err := cmd.CombinedOutput()
if err != nil {
return true, err
}
return strings.Contains(string(out), "AvailableUpdate"), nil
}

func (up RpmOstreeUpdater) Steps() int {
if up.Config.Enabled {
return 1
}
return 0
}

func BootcCompatible(binaryPath string) (bool, error) {
cmd := exec.Command(binaryPath, "status", "--format=json")
out, err := cmd.CombinedOutput()
if err != nil {
return false, nil
}
var status bootcStatus
err = json.Unmarshal(out, &status)
if err != nil {
return false, nil
}
return !(status.Status.Booted.Incompatible || status.Status.Staged.Incompatible), nil
}

func (up RpmOstreeUpdater) New(config UpdaterInitConfiguration) (RpmOstreeUpdater, error) {
up.Config = DriverConfiguration{
Title: "System",
Description: "System Updates",
Enabled: !config.Ci,
DryRun: config.DryRun,
}

if up.Config.DryRun {
return up, nil
}

binaryPath, exists := config.Environment["UUPD_RPMOSTREE_BINARY"]
if !exists || binaryPath == "" {
up.BinaryPath = "/usr/bin/rpm-ostree"
} else {
up.BinaryPath = binaryPath
}

return up, nil
}

func (up RpmOstreeUpdater) Check() (bool, error) {
if up.Config.DryRun {
return true, nil
}

return up.UpdateAvailable()
}
Loading

0 comments on commit 7772a72

Please sign in to comment.