Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func runFirstBootCompleteMachineConfig(_ *cobra.Command, _ []string) error {
exitCh := make(chan error)
defer close(exitCh)

dn, err := daemon.New(daemon.NewNodeUpdaterClient(), exitCh)
dn, err := daemon.New(exitCh)
if err != nil {
return err
}
Expand Down
1 change: 0 additions & 1 deletion cmd/machine-config-daemon/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ func runStartCmd(cmd *cobra.Command, args []string) {
defer close(exitCh)

dn, err := daemon.New(
daemon.NewNodeUpdaterClient(),
exitCh,
)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/coreos/ign-converter v0.0.0-20201123214124-8dac862888aa
github.com/coreos/ignition v0.35.0
github.com/coreos/ignition/v2 v2.13.0
github.com/coreos/rpmostree-client-go v0.0.0-20220922143538-78889752c880
github.com/davecgh/go-spew v1.1.1
github.com/fsnotify/fsnotify v1.5.4
github.com/ghodss/yaml v1.0.0
Expand Down Expand Up @@ -202,9 +203,9 @@ require (
github.com/nishanths/exhaustive v0.8.1 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20220811233833-d265d74f4fad // indirect
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect
github.com/opencontainers/runc v1.1.3 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220809190508-9ee22abf867e // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.2 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
Expand Down
48 changes: 46 additions & 2 deletions go.sum

Large diffs are not rendered by default.

17 changes: 12 additions & 5 deletions pkg/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"

rpmostreeclient "github.com/coreos/rpmostree-client-go/pkg/client"
configv1 "github.com/openshift/api/config/v1"
mcoResourceRead "github.com/openshift/machine-config-operator/lib/resourceread"
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
Expand All @@ -55,8 +56,11 @@ type Daemon struct {
// mock is set if we're running as non-root, probably under unit tests
mock bool

// NodeUpdaterClient an instance of the client which interfaces with host content deployments
NodeUpdaterClient NodeUpdaterClient
// NodeUpdaterClient wraps rpm-ostree and will eventually be removed with a direct rpmostreeclient value
NodeUpdaterClient *RpmOstreeClient

// rpmostree is set if the host is an rpm-ostree based system
rpmostree *rpmostreeclient.Client

// bootID is a unique value per boot (generated by the kernel)
bootID string
Expand Down Expand Up @@ -202,7 +206,6 @@ func getBootID() (string, error) {
// New sets up the systemd and kubernetes connections needed to update the
// machine.
func New(
nodeUpdaterClient NodeUpdaterClient,
exitCh chan<- error,
) (*Daemon, error) {
mock := false
Expand All @@ -226,8 +229,12 @@ func New(
}
}

var nodeUpdaterClient *RpmOstreeClient

// Only pull the osImageURL from OSTree when we are on RHCOS or FCOS
if hostos.IsCoreOSVariant() {
nodeUpdaterClientVal := NewNodeUpdaterClient()
nodeUpdaterClient = &nodeUpdaterClientVal
err := nodeUpdaterClient.Initialize()
if err != nil {
return nil, fmt.Errorf("error initializing rpm-ostree: %w", err)
Expand Down Expand Up @@ -1289,11 +1296,11 @@ func (dn *Daemon) getStateAndConfigs(pendingConfigName string) (*stateAndConfigs
func (dn *Daemon) LogSystemData() {
// Print status if available
if dn.os.IsCoreOSVariant() {
status, err := dn.NodeUpdaterClient.GetStatus()
out, err := runGetOut("rpm-ostree", "status")
if err != nil {
glog.Fatalf("unable to get rpm-ostree status: %s", err)
}
glog.Info(status)
glog.Info(out)

logProvisioningInformation()
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/daemon/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (f *fixture) newController() *Daemon {
i := informers.NewSharedInformerFactory(f.client, noResyncPeriodFunc())
k8sI := kubeinformers.NewSharedInformerFactory(f.kubeclient, noResyncPeriodFunc())

d, err := New(NewNodeUpdaterClient(), nil)
d, err := New(nil)
if err != nil {
f.t.Fatalf("can't bring up daemon: %v", err)
}
Expand Down
104 changes: 18 additions & 86 deletions pkg/daemon/rpm-ostree.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/containers/image/v5/types"
rpmostreeclient "github.com/coreos/rpmostree-client-go/pkg/client"
"github.com/golang/glog"
"github.com/opencontainers/go-digest"
pivotutils "github.com/openshift/machine-config-operator/pkg/daemon/pivot/utils"
Expand All @@ -24,31 +25,6 @@ const (
kubeletAuthFile = "/var/lib/kubelet/config.json"
)

// rpmOstreeState houses zero or more RpmOstreeDeployments
// Subset of `rpm-ostree status --json`
// https://github.com/projectatomic/rpm-ostree/blob/bce966a9812df141d38e3290f845171ec745aa4e/src/daemon/rpmostreed-deployment-utils.c#L227
type rpmOstreeState struct {
Deployments []RpmOstreeDeployment
Transaction *[]string
}

// RpmOstreeDeployment represents a single deployment on a node
type RpmOstreeDeployment struct {
ID string `json:"id"`
OSName string `json:"osname"`
Serial int32 `json:"serial"`
Checksum string `json:"checksum"`
BaseChecksum string `json:"base-checksum,omitempty"`
Version string `json:"version"`
Timestamp uint64 `json:"timestamp"`
Booted bool `json:"booted"`
Staged bool `json:"staged"`
LiveReplaced string `json:"live-replaced,omitempty"`
Origin string `json:"origin"`
CustomOrigin []string `json:"custom-origin"`
ContainerImageReference string `json:"container-image-reference"`
}

// imageInspection is a public implementation of
// https://github.com/containers/skopeo/blob/82186b916faa9c8c70cfa922229bafe5ae024dec/cmd/skopeo/inspect.go#L20-L31
type imageInspection struct {
Expand All @@ -64,27 +40,19 @@ type imageInspection struct {
Layers []string
}

// NodeUpdaterClient is an interface describing how to interact with the host
// around content deployment
type NodeUpdaterClient interface {
Initialize() error
GetStatus() (string, error)
GetBootedOSImageURL() (string, string, string, error)
Rebase(string, string) (bool, error)
RebaseLayered(string) error
IsBootableImage(string) (bool, error)
GetBootedAndStagedDeployment() (*RpmOstreeDeployment, *RpmOstreeDeployment, error)
}

// RpmOstreeClient provides all RpmOstree related methods in one structure.
// This structure implements DeploymentClient
//
// TODO(runcom): make this private to pkg/daemon!!!
type RpmOstreeClient struct{}
type RpmOstreeClient struct {
client rpmostreeclient.Client
}

// NewNodeUpdaterClient returns a new instance of the default DeploymentClient (RpmOstreeClient)
func NewNodeUpdaterClient() NodeUpdaterClient {
return &RpmOstreeClient{}
// NewNodeUpdaterClient is a wrapper to create an RpmOstreeClient
func NewNodeUpdaterClient() RpmOstreeClient {
return RpmOstreeClient{
client: rpmostreeclient.NewClient("machine-config-daemon"),
}
}

// Synchronously invoke rpm-ostree, writing its stdout to our stdout,
Expand All @@ -94,20 +62,6 @@ func runRpmOstree(args ...string) error {
return runCmdSync("rpm-ostree", args...)
}

func (r *RpmOstreeClient) loadStatus() (*rpmOstreeState, error) {
var rosState rpmOstreeState
output, err := runGetOut("rpm-ostree", "status", "--json")
if err != nil {
return nil, err
}

if err := json.Unmarshal(output, &rosState); err != nil {
return nil, fmt.Errorf("failed to parse `rpm-ostree status --json` output (%s): %w", truncate(string(output), 30), err)
}

return &rosState, nil
}

// See https://bugzilla.redhat.com/show_bug.cgi?id=2111817
func bug2111817Workaround() error {
targetUnit := "/run/systemd/system/rpm-ostreed.service.d/bug2111817.conf"
Expand Down Expand Up @@ -147,15 +101,19 @@ func (r *RpmOstreeClient) Initialize() error {
return nil
}

func (r *RpmOstreeClient) Peel() *rpmostreeclient.Client {
return &r.client
}

// GetBootedDeployment returns the current deployment found
func (r *RpmOstreeClient) GetBootedAndStagedDeployment() (booted, staged *RpmOstreeDeployment, err error) {
status, err := r.loadStatus()
func (r *RpmOstreeClient) GetBootedAndStagedDeployment() (booted, staged *rpmostreeclient.Deployment, err error) {
status, err := r.client.QueryStatus()
if err != nil {
return nil, nil, err
}

booted, err = status.getBootedDeployment()
staged = status.getStagedDeployment()
booted, err = status.GetBootedDeployment()
staged = status.GetStagedDeployment()

return
}
Expand Down Expand Up @@ -201,13 +159,7 @@ func (r *RpmOstreeClient) GetBootedOSImageURL() (string, string, string, error)
}
}

// BaseChecksum is populated if the system has been modified in a way that changes the base checksum
// (like via an RPM install) so prefer BaseCheksum that if it's present, otherwise just use Checksum.
baseChecksum := bootedDeployment.Checksum
if bootedDeployment.BaseChecksum != "" {
baseChecksum = bootedDeployment.BaseChecksum
}

baseChecksum := bootedDeployment.GetBaseChecksum()
return osImageURL, bootedDeployment.Version, baseChecksum, nil
}

Expand Down Expand Up @@ -457,23 +409,3 @@ func runGetOut(command string, args ...string) ([]byte, error) {
}
return rawOut, nil
}

func (state *rpmOstreeState) getBootedDeployment() (*RpmOstreeDeployment, error) {
for num := range state.Deployments {
deployment := state.Deployments[num]
if deployment.Booted {
return &deployment, nil
}
}
return &RpmOstreeDeployment{}, fmt.Errorf("not currently booted in a deployment")
}

func (state *rpmOstreeState) getStagedDeployment() *RpmOstreeDeployment {
for num := range state.Deployments {
deployment := state.Deployments[num]
if deployment.Staged {
return &deployment
}
}
return &RpmOstreeDeployment{}
}
Loading