Skip to content

Commit

Permalink
Merge pull request #4277 from k0sproject/ignore-token-flag-until-needed
Browse files Browse the repository at this point in the history
Ignore token-file argument when value not needed

Both "k0s controller" and "k0s worker" take either [TOKEN] as an argument or a path to a file containing the join token via --token-file.

Before this PR, when --token-file was given, the file was read upon spin-up, even when the node has joined already and won't utilize the token for anything. As the token is not needed after join, you would expect that you can or even should remove the file, but that makes k0s refuse to start unless the --token-file argument is also removed from the systemd unit or other startup scripts.

This PR makes the controller and worker read the contents of the file only right before the value is getting used. This allows --token-file argument to be ignored when it is not needed and the file not existing will not generate an error.
  • Loading branch information
kke authored Apr 12, 2024
2 parents 6fd781e + df17744 commit 66b144c
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 25 deletions.
24 changes: 13 additions & 11 deletions cmd/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,13 @@ func NewControllerCmd() *cobra.Command {
if len(args) > 0 {
c.TokenArg = args[0]
}
if len(c.TokenArg) > 0 && len(c.TokenFile) > 0 {
if c.TokenArg != "" && c.TokenFile != "" {
return fmt.Errorf("you can only pass one token argument either as a CLI argument 'k0s controller [join-token]' or as a flag 'k0s controller --token-file [path]'")
}
if err := c.ControllerOptions.Normalize(); err != nil {
return err
}

if len(c.TokenFile) > 0 {
bytes, err := os.ReadFile(c.TokenFile)
if err != nil {
return err
}
c.TokenArg = string(bytes)
}
c.Logging = stringmap.Merge(c.CmdLogLevels, c.DefaultLogLevels)

if err := (&sysinfo.K0sSysinfoSpec{
Expand Down Expand Up @@ -177,8 +170,18 @@ func (c *command) start(ctx context.Context) error {

var joinClient *token.JoinClient

if c.TokenArg != "" && c.needToJoin() {
joinClient, err = joinController(ctx, c.TokenArg, c.K0sVars.CertRootDir)
if (c.TokenArg != "" || c.TokenFile != "") && c.needToJoin() {
var tokenData string
if c.TokenArg != "" {
tokenData = c.TokenArg
} else {
data, err := os.ReadFile(c.TokenFile)
if err != nil {
return fmt.Errorf("read token file %q: %w", c.TokenFile, err)
}
tokenData = string(data)
}
joinClient, err = joinController(ctx, tokenData, c.K0sVars.CertRootDir)
if err != nil {
return fmt.Errorf("failed to join controller: %w", err)
}
Expand Down Expand Up @@ -247,7 +250,6 @@ func (c *command) start(ctx context.Context) error {
EventEmitter: prober.NewEventEmitter(),
K0sControllersLeaseCounter: controllerLeaseCounter,
})

}

nodeComponents.Add(ctx, &controller.APIServer{
Expand Down
10 changes: 1 addition & 9 deletions cmd/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,10 @@ func NewWorkerCmd() *cobra.Command {
}

c.Logging = stringmap.Merge(c.CmdLogLevels, c.DefaultLogLevels)
if len(c.TokenArg) > 0 && len(c.TokenFile) > 0 {
if c.TokenArg != "" && c.TokenFile != "" {
return fmt.Errorf("you can only pass one token argument either as a CLI argument 'k0s worker [token]' or as a flag 'k0s worker --token-file [path]'")
}

if len(c.TokenFile) > 0 {
bytes, err := os.ReadFile(c.TokenFile)
if err != nil {
return err
}
c.TokenArg = string(bytes)
}

if err := (&sysinfo.K0sSysinfoSpec{
ControllerRoleEnabled: false,
WorkerRoleEnabled: true,
Expand Down
8 changes: 6 additions & 2 deletions inttest/hacontrolplane/hacontrolplane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func (s *HAControlplaneSuite) TestDeregistration() {
s.NoError(s.WaitJoinAPI(s.ControllerNode(0)))
token, err := s.GetJoinToken("controller")
s.Require().NoError(err)
s.NoError(s.InitController(1, token))
s.PutFile(s.ControllerNode(1), "/etc/k0s.token", token)
s.NoError(s.InitController(1, "--token-file=/etc/k0s.token"))
s.NoError(s.WaitJoinAPI(s.ControllerNode(1)))

ca0 := s.GetFileFromController(0, "/var/lib/k0s/pki/ca.crt")
Expand Down Expand Up @@ -108,7 +109,10 @@ func (s *HAControlplaneSuite) TestDeregistration() {
defer sshC1.Disconnect()
_, err = sshC1.ExecWithOutput(s.Context(), "kill $(pidof k0s) && while pidof k0s; do sleep 0.1s; done")
s.Require().NoError(err)
s.NoError(s.InitController(1, token))
// Delete the token file, as it shouldn't be needed after the controller has joined.
_, err = sshC1.ExecWithOutput(s.Context(), "rm -f /etc/k0s.token")
s.Require().NoError(err)
s.NoError(s.InitController(1, "--token-file=/etc/k0s.token"))
s.NoError(s.WaitJoinAPI(s.ControllerNode(1)))

// Make one member leave the etcd cluster
Expand Down
5 changes: 5 additions & 0 deletions inttest/upgrade/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ func (s *UpgradeSuite) TestK0sGetsUp() {
if err != nil {
return err
}
// Delete the token file, as it shouldn't be needed after the worker has joined.
_, err = ssh.ExecWithOutput(s.Context(), "rm -f /etc/k0s.token")
if err != nil {
return err
}
_, err = ssh.ExecWithOutput(s.Context(), "service k0sworker restart")
if err != nil {
return err
Expand Down
16 changes: 13 additions & 3 deletions pkg/component/worker/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,20 @@ func BootstrapKubeletKubeconfig(ctx context.Context, k0sVars *config.CfgVars, wo

// 3: A join token has been given.
// Bootstrap the kubelet kubeconfig via the embedded bootstrap config.
case workerOpts.TokenArg != "":
case workerOpts.TokenArg != "" || workerOpts.TokenFile != "":
var tokenData string
if workerOpts.TokenArg != "" {
tokenData = workerOpts.TokenArg
} else {
data, err := os.ReadFile(workerOpts.TokenFile)
if err != nil {
return fmt.Errorf("failed to read token file: %w", err)
}
tokenData = string(data)
}

// Join token given, so use that.
kubeconfig, err := token.DecodeJoinToken(workerOpts.TokenArg)
kubeconfig, err := token.DecodeJoinToken(tokenData)
if err != nil {
return fmt.Errorf("failed to decode join token: %w", err)
}
Expand Down Expand Up @@ -180,7 +191,6 @@ func writeKubeletBootstrapKubeconfig(kubeconfig []byte) (string, error) {

_, err = bootstrapFile.Write(kubeconfig)
err = multierr.Append(err, bootstrapFile.Close())

if err != nil {
if rmErr := os.Remove(bootstrapFile.Name()); rmErr != nil && !os.IsNotExist(rmErr) {
err = multierr.Append(err, rmErr)
Expand Down

0 comments on commit 66b144c

Please sign in to comment.