Skip to content

Commit

Permalink
Merge pull request k0sproject#2522 from makhov/autopilot-download-bin…
Browse files Browse the repository at this point in the history
…ary-path-fix

k0s binary path detection for autopilot
  • Loading branch information
makhov authored Dec 16, 2022
2 parents 84775c0 + f5aed02 commit a6b8efd
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 16 deletions.
8 changes: 8 additions & 0 deletions inttest/ap-single/single_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ type plansSingleControllerSuite struct {
func (s *plansSingleControllerSuite) SetupTest() {
s.Require().NoError(s.WaitForSSH(s.ControllerNode(0), 2*time.Minute, 1*time.Second))

// Move the k0s binary to a new location, so we can check the binary location detection
ssh, err := s.SSH(s.ControllerNode(0))
s.Require().NoError(err)
defer ssh.Disconnect()
_, err = ssh.ExecWithOutput(s.Context(), "cp /dist/k0s /tmp/k0s")
s.Require().NoError(err)

s.Require().NoError(s.InitController(0), "--disable-components=metrics-server")
s.Require().NoError(s.WaitJoinAPI(s.ControllerNode(0)))

Expand Down Expand Up @@ -114,6 +121,7 @@ spec:
func TestPlansSingleControllerSuite(t *testing.T) {
suite.Run(t, &plansSingleControllerSuite{
common.FootlooseSuite{
K0sFullPath: "/tmp/k0s",
ControllerCount: 1,
WorkerCount: 0,
LaunchMode: common.LaunchModeOpenRC,
Expand Down
28 changes: 18 additions & 10 deletions pkg/autopilot/controller/signal/k0s/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
"net/url"
"os"
"path"
"path/filepath"

apcomm "github.com/k0sproject/k0s/pkg/autopilot/common"
apconst "github.com/k0sproject/k0s/pkg/autopilot/constant"
apdel "github.com/k0sproject/k0s/pkg/autopilot/controller/delegate"
apsigpred "github.com/k0sproject/k0s/pkg/autopilot/controller/signal/common/predicate"
apsigv2 "github.com/k0sproject/k0s/pkg/autopilot/signaling/v2"
Expand Down Expand Up @@ -58,27 +58,35 @@ func applyingUpdateEventFilter(hostname string, handler apsigpred.ErrorHandler)
}

type applyingUpdate struct {
log *logrus.Entry
client crcli.Client
delegate apdel.ControllerDelegate
log *logrus.Entry
client crcli.Client
delegate apdel.ControllerDelegate
k0sBinaryDir string
}

// registeryApplyingUpdate registers the 'applying-update' controller to the
// controller-runtime manager.
//
// This controller is only interested in taking the downloaded update, and
// applying it to the current k0s install.
func registerApplyingUpdate(logger *logrus.Entry, mgr crman.Manager, eventFilter crpred.Predicate, delegate apdel.ControllerDelegate) error {
func registerApplyingUpdate(
logger *logrus.Entry,
mgr crman.Manager,
eventFilter crpred.Predicate,
delegate apdel.ControllerDelegate,
k0sBinaryDir string,
) error {
logger.Infof("Registering 'applying-update' reconciler for '%s'", delegate.Name())

return cr.NewControllerManagedBy(mgr).
For(delegate.CreateObject()).
WithEventFilter(eventFilter).
Complete(
&applyingUpdate{
log: logger.WithFields(logrus.Fields{"reconciler": "applying-update", "object": delegate.Name()}),
client: mgr.GetClient(),
delegate: delegate,
log: logger.WithFields(logrus.Fields{"reconciler": "applying-update", "object": delegate.Name()}),
client: mgr.GetClient(),
delegate: delegate,
k0sBinaryDir: k0sBinaryDir,
},
)
}
Expand Down Expand Up @@ -107,7 +115,7 @@ func (r *applyingUpdate) Reconcile(ctx context.Context, req cr.Request) (cr.Resu

// TODO: make the filename part random
updateFilename := path.Base(updateURL.Path)
updateFilenamePath := path.Join(apconst.K0sBinaryDir, updateFilename)
updateFilenamePath := path.Join(r.k0sBinaryDir, updateFilename)

// Ensure that the expected file exists
if _, err := os.Stat(updateFilenamePath); errors.Is(err, os.ErrNotExist) {
Expand All @@ -120,7 +128,7 @@ func (r *applyingUpdate) Reconcile(ctx context.Context, req cr.Request) (cr.Resu
}

// Perform the update atomically
if err := os.Rename(updateFilenamePath, "/usr/local/bin/k0s"); err != nil {
if err := os.Rename(updateFilenamePath, filepath.Join(r.k0sBinaryDir, "k0s")); err != nil {
return cr.Result{}, fmt.Errorf("unable to update (rename) to the new file: %w", err)
}

Expand Down
10 changes: 6 additions & 4 deletions pkg/autopilot/controller/signal/k0s/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"crypto/sha256"

apcomm "github.com/k0sproject/k0s/pkg/autopilot/common"
apconst "github.com/k0sproject/k0s/pkg/autopilot/constant"
apdel "github.com/k0sproject/k0s/pkg/autopilot/controller/delegate"
apsigcomm "github.com/k0sproject/k0s/pkg/autopilot/controller/signal/common"
apsigpred "github.com/k0sproject/k0s/pkg/autopilot/controller/signal/common/predicate"
Expand Down Expand Up @@ -55,6 +54,7 @@ func downloadEventFilter(hostname string, handler apsigpred.ErrorHandler) crpred
}

type downloadManifestBuilderK0s struct {
k0sBinaryDir string
}

var _ apsigcomm.DownloadManifestBuilder = (*downloadManifestBuilderK0s)(nil)
Expand All @@ -65,14 +65,16 @@ var _ apsigcomm.DownloadManifestBuilder = (*downloadManifestBuilderK0s)(nil)
// This controller is only interested when autopilot signaling annotations have
// moved to a `Downloading` status. At this point, it will attempt to download
// the file provided in the update request.
func registerDownloading(logger *logrus.Entry, mgr crman.Manager, eventFilter crpred.Predicate, delegate apdel.ControllerDelegate) error {
func registerDownloading(logger *logrus.Entry, mgr crman.Manager, eventFilter crpred.Predicate, delegate apdel.ControllerDelegate, k0sBinaryDir string) error {
logger.Infof("Registering k0s 'downloading' reconciler for '%s'", delegate.Name())

return cr.NewControllerManagedBy(mgr).
For(delegate.CreateObject()).
WithEventFilter(eventFilter).
Complete(
apsigcomm.NewDownloadController(logger, mgr.GetClient(), delegate, &downloadManifestBuilderK0s{}),
apsigcomm.NewDownloadController(logger, mgr.GetClient(), delegate, &downloadManifestBuilderK0s{
k0sBinaryDir: k0sBinaryDir,
}),
)
}

Expand All @@ -84,7 +86,7 @@ func (b downloadManifestBuilderK0s) Build(signalNode crcli.Object, signalData ap
URL: signalData.Command.K0sUpdate.URL,
ExpectedHash: signalData.Command.K0sUpdate.Sha256,
Hasher: sha256.New(),
DownloadDir: apconst.K0sBinaryDir,
DownloadDir: b.k0sBinaryDir,
},
SuccessState: Cordoning,
}
Expand Down
12 changes: 10 additions & 2 deletions pkg/autopilot/controller/signal/k0s/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package k0s
import (
"context"
"fmt"
"os"
"path/filepath"

apcomm "github.com/k0sproject/k0s/pkg/autopilot/common"
apconst "github.com/k0sproject/k0s/pkg/autopilot/constant"
Expand Down Expand Up @@ -49,21 +51,27 @@ func RegisterControllers(ctx context.Context, logger *logrus.Entry, mgr crman.Ma
return fmt.Errorf("unable to determine hostname for controlnode 'signal' reconciler: %w", err)
}

k0sBinaryPath, err := os.Executable()
if err != nil {
return fmt.Errorf("unable to determine k0s binary path for controlnode 'signal' reconciler: %w", err)
}
k0sBinaryDir := filepath.Dir(k0sBinaryPath)

logger.Infof("Using effective hostname = '%v'", hostname)

if err := registerSignalController(logger, mgr, signalControllerEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s signal")), delegate, clusterID); err != nil {
return fmt.Errorf("unable to register k0s 'signal' controller: %w", err)
}

if err := registerDownloading(logger, mgr, downloadEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s downloading")), delegate); err != nil {
if err := registerDownloading(logger, mgr, downloadEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s downloading")), delegate, k0sBinaryDir); err != nil {
return fmt.Errorf("unable to register k0s 'downloading' controller: %w", err)
}

if err := registerCordoning(logger, mgr, cordoningEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s cordoning")), delegate); err != nil {
return fmt.Errorf("unable to register k0s 'cordoning' controller: %w", err)
}

if err := registerApplyingUpdate(logger, mgr, applyingUpdateEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s applying-update")), delegate); err != nil {
if err := registerApplyingUpdate(logger, mgr, applyingUpdateEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s applying-update")), delegate, k0sBinaryDir); err != nil {
return fmt.Errorf("unable to register k0s 'applying-update' controller: %w", err)
}

Expand Down

0 comments on commit a6b8efd

Please sign in to comment.