Skip to content
Merged
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/k0sproject/k0s/cmd/kubeconfig"
"github.com/k0sproject/k0s/cmd/kubectl"
"github.com/k0sproject/k0s/cmd/start"
"github.com/k0sproject/k0s/cmd/status"
"github.com/k0sproject/k0s/cmd/stop"
"github.com/k0sproject/k0s/cmd/sysinfo"
"github.com/k0sproject/k0s/cmd/token"
Expand Down Expand Up @@ -46,6 +47,7 @@ func NewRootCmd() *cobra.Command {
cmd.AddCommand(kubectl.NewK0sKubectlCmd())
cmd.AddCommand(start.NewStartCmd())
cmd.AddCommand(stop.NewStopCmd())
cmd.AddCommand(status.NewStatusCmd())
cmd.AddCommand(sysinfo.NewSysinfoCmd())
cmd.AddCommand(token.NewTokenCmd())
cmd.AddCommand(validate.NewValidateCmd()) // hidden+deprecated
Expand Down
2 changes: 0 additions & 2 deletions cmd/root_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/k0sproject/k0s/cmd/keepalived"
"github.com/k0sproject/k0s/cmd/reset"
"github.com/k0sproject/k0s/cmd/restore"
"github.com/k0sproject/k0s/cmd/status"

"github.com/spf13/cobra"
)
Expand All @@ -20,5 +19,4 @@ func addPlatformSpecificCommands(root *cobra.Command) {
root.AddCommand(keepalived.NewKeepalivedSetStateCmd()) // hidden
root.AddCommand(reset.NewResetCmd())
root.AddCommand(restore.NewRestoreCmd())
root.AddCommand(status.NewStatusCmd())
}
12 changes: 9 additions & 3 deletions cmd/status/status.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build unix

// SPDX-FileCopyrightText: 2021 k0s authors
// SPDX-License-Identifier: Apache-2.0

Expand All @@ -9,6 +7,7 @@ import (
"encoding/json"
"fmt"
"io"
"runtime"

"github.com/k0sproject/k0s/cmd/internal"
"github.com/k0sproject/k0s/pkg/component/status"
Expand Down Expand Up @@ -51,7 +50,14 @@ func NewStatusCmd() *cobra.Command {

pflags := cmd.PersistentFlags()
debugFlags.AddToFlagSet(pflags)
pflags.String("status-socket", "", "Full file path to the socket file. (default: <rundir>/status.sock)")
var socketDefault string
if runtime.GOOS == "windows" {
socketDefault = status.DefaultSocketPath
} else {
socketDefault = "<rundir>/status.sock"
}

pflags.String("status-socket", "", "Full path to the k0s status socket (default: "+socketDefault+")")

cmd.AddCommand(NewStatusSubCmdComponents())

Expand Down
23 changes: 23 additions & 0 deletions cmd/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import (
"github.com/k0sproject/k0s/internal/pkg/stringmap"
"github.com/k0sproject/k0s/internal/pkg/sysinfo"
"github.com/k0sproject/k0s/internal/supervised"
"github.com/k0sproject/k0s/pkg/build"
"github.com/k0sproject/k0s/pkg/component/iptables"
"github.com/k0sproject/k0s/pkg/component/manager"
"github.com/k0sproject/k0s/pkg/component/prober"
"github.com/k0sproject/k0s/pkg/component/status"
"github.com/k0sproject/k0s/pkg/component/worker"
workerconfig "github.com/k0sproject/k0s/pkg/component/worker/config"
"github.com/k0sproject/k0s/pkg/component/worker/containerd"
Expand Down Expand Up @@ -298,6 +300,27 @@ func (c *Command) Start(ctx context.Context, nodeName apitypes.NodeName, kubelet

addPlatformSpecificComponents(ctx, componentManager, c.K0sVars, controller, certManager)

if controller == nil {
// if running inside a controller, status component is already running
componentManager.Add(ctx, &status.Status{
Prober: prober.DefaultProber,
StatusInformation: status.K0sStatus{
Pid: os.Getpid(),
Role: "worker",
Args: os.Args,
Version: build.Version,
Workloads: true,
SingleNode: false,
K0sVars: c.K0sVars,
// worker does not have cluster config. this is only shown in "k0s status -o json".
// todo: if it's needed, a worker side config client can be set up and used to load the config
ClusterConfig: nil,
},
CertManager: certManager,
Socket: c.K0sVars.StatusSocketPath,
})
}

// extract needed components
if err := componentManager.Init(ctx); err != nil {
return err
Expand Down
25 changes: 0 additions & 25 deletions cmd/worker/worker_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,15 @@ package worker

import (
"context"
"os"

"github.com/k0sproject/k0s/pkg/build"
"github.com/k0sproject/k0s/pkg/component/manager"
"github.com/k0sproject/k0s/pkg/component/prober"
"github.com/k0sproject/k0s/pkg/component/status"
"github.com/k0sproject/k0s/pkg/component/worker"
"github.com/k0sproject/k0s/pkg/config"
)

func initLogging(context.Context, string) error { return nil }

func addPlatformSpecificComponents(ctx context.Context, m *manager.Manager, k0sVars *config.CfgVars, controller EmbeddingController, certManager *worker.CertificateManager) {
// if running inside a controller, status component is already running
if controller == nil {
m.Add(ctx, &status.Status{
Prober: prober.DefaultProber,
StatusInformation: status.K0sStatus{
Pid: os.Getpid(),
Role: "worker",
Args: os.Args,
Version: build.Version,
Workloads: true,
SingleNode: false,
K0sVars: k0sVars,
// worker does not have cluster config. this is only shown in "k0s status -o json".
// todo: if it's needed, a worker side config client can be set up and used to load the config
ClusterConfig: nil,
},
CertManager: certManager,
Socket: k0sVars.StatusSocketPath,
})
}

m.Add(ctx, &worker.Autopilot{
K0sVars: k0sVars,
CertManager: certManager,
Expand Down
2 changes: 1 addition & 1 deletion cmd/worker/worker_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ func initLogging(ctx context.Context, logDir string) error {
return nil
}

func addPlatformSpecificComponents(context.Context, *manager.Manager, *config.CfgVars, EmbeddingController, *worker.CertificateManager) {
func addPlatformSpecificComponents(ctx context.Context, m *manager.Manager, k0sVars *config.CfgVars, controller EmbeddingController, certManager *worker.CertificateManager) {
// no-op
}
5 changes: 1 addition & 4 deletions pkg/autopilot/controller/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,6 @@ func (sc *setupController) createControlNode(ctx context.Context, cf apcli.Facto
return nil
}

// TODO re-use from somewhere else
const DefaultK0sStatusSocketPath = "/run/k0s/status.sock"

func getControlNodeAddresses(hostname string) ([]corev1.NodeAddress, error) {
addresses := []corev1.NodeAddress{}
apiAddress, err := getControllerAPIAddress()
Expand All @@ -201,7 +198,7 @@ func getControlNodeAddresses(hostname string) ([]corev1.NodeAddress, error) {
}

func getControllerAPIAddress() (string, error) {
status, err := status.GetStatusInfo(DefaultK0sStatusSocketPath)
status, err := status.GetStatusInfo(status.DefaultSocketPath)
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/autopilot/controller/signal/k0s/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func RegisterControllers(ctx context.Context, logger *logrus.Entry, mgr crman.Ma
logger.Infof("Using effective hostname = '%v'", hostname)

k0sVersionHandler := func() (string, error) {
return getK0sVersion(DefaultK0sStatusSocketPath)
return getK0sVersion(status.DefaultSocketPath)
}

if err := registerSignalController(logger, mgr, signalControllerEventFilter(hostname, apsigpred.DefaultErrorHandler(logger, "k0s signal")), delegate, clusterID, k0sVersionHandler); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/autopilot/controller/signal/k0s/restart_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (r *restart) Reconcile(ctx context.Context, req cr.Request) (cr.Result, err

// Get the current version of k0s
logger.Info("Determining the current version of k0s")
k0sVersion, err := getK0sVersion(DefaultK0sStatusSocketPath)
k0sVersion, err := getK0sVersion(status.DefaultSocketPath)
if err != nil {
logger.Info("Unable to determine current verion of k0s; requeuing")
return cr.Result{}, fmt.Errorf("unable to get k0s version: %w", err)
Expand Down Expand Up @@ -128,7 +128,7 @@ func (r *restart) Reconcile(ctx context.Context, req cr.Request) (cr.Result, err

logger.Info("Preparing to restart k0s")

k0sPid, err := getK0sPid(DefaultK0sStatusSocketPath)
k0sPid, err := getK0sPid(status.DefaultSocketPath)
if err != nil {
logger.Info("Unable to determine current k0s pid; requeuing")
return cr.Result{RequeueAfter: restartRequeueDuration}, fmt.Errorf("unable to get k0s pid: %w", err)
Expand Down
3 changes: 2 additions & 1 deletion pkg/autopilot/controller/signal/k0s/restarted_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
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"
"github.com/k0sproject/k0s/pkg/component/status"

"github.com/sirupsen/logrus"
cr "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -86,7 +87,7 @@ func (r *restarted) Reconcile(ctx context.Context, req cr.Request) (cr.Result, e

// Get the current version of k0s
logger.Info("Determining the current version of k0s")
k0sVersion, err := getK0sVersion(DefaultK0sStatusSocketPath)
k0sVersion, err := getK0sVersion(status.DefaultSocketPath)
if err != nil {
logger.Info("Unable to determine current verion of k0s; requeuing")
return cr.Result{}, fmt.Errorf("unable to get k0s version: %w", err)
Expand Down
1 change: 0 additions & 1 deletion pkg/autopilot/controller/signal/k0s/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (

const (
SignalResponseProcessingTimeout = 1 * time.Minute
DefaultK0sStatusSocketPath = "/run/k0s/status.sock"
)

type k0sVersionHandlerFunc func() (string, error)
Expand Down
3 changes: 1 addition & 2 deletions pkg/autopilot/controller/updates/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
apv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2"
apcli "github.com/k0sproject/k0s/pkg/autopilot/client"
appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core"
"github.com/k0sproject/k0s/pkg/autopilot/controller/signal/k0s"
uc "github.com/k0sproject/k0s/pkg/autopilot/updater"
"github.com/k0sproject/k0s/pkg/build"
"github.com/k0sproject/k0s/pkg/component/status"
Expand Down Expand Up @@ -77,7 +76,7 @@ func newCronUpdater(parentCtx context.Context, updateConfig apv1beta2.UpdateConf
schedule = defaultCronSchedule
}

status, err := status.GetStatusInfo(k0s.DefaultK0sStatusSocketPath)
status, err := status.GetStatusInfo(status.DefaultSocketPath)
if err != nil {
return nil, err
}
Expand Down
14 changes: 6 additions & 8 deletions pkg/component/status/client.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build unix

// SPDX-FileCopyrightText: 2022 k0s authors
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -40,7 +38,7 @@ type ProbeStatus struct {
// GetStatus returns the status of the k0s process using the status socket
func GetStatusInfo(socketPath string) (*K0sStatus, error) {
status := &K0sStatus{}
if err := doHTTPRequestViaUnixSocket(socketPath, "status", status); err != nil {
if err := doStatusHTTPRequest(socketPath, "status", status); err != nil {
return nil, err
}
return status, nil
Expand All @@ -49,20 +47,20 @@ func GetStatusInfo(socketPath string) (*K0sStatus, error) {
// GetComponentStatus returns the per-component events and health-checks
func GetComponentStatus(socketPath string, maxCount int) (*prober.State, error) {
status := &prober.State{}
if err := doHTTPRequestViaUnixSocket(socketPath,
if err := doStatusHTTPRequest(socketPath,
fmt.Sprintf("components?maxCount=%d", maxCount),
status); err != nil {
return nil, err
}
return status, nil
}

func doHTTPRequestViaUnixSocket(socketPath string, path string, tgt any) error {
httpc := http.Client{
func doStatusHTTPRequest(socketPath string, path string, tgt any) error {
httpc := &http.Client{
Transport: &http.Transport{
DisableKeepAlives: true,
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
var d net.Dialer
return d.DialContext(ctx, "unix", socketPath)
return dialSocket(ctx, socketPath)
},
},
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/component/status/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025 k0s authors
// SPDX-License-Identifier: Apache-2.0

package status

import "github.com/k0sproject/k0s/pkg/constant"

// DefaultSocketPath is the platform-specific default socket path used by k0s
// when no explicit status socket is provided.
//
// Deprecated: This constant is defined to avoid a circular import in autopilot
// and will be refactored out.
const DefaultSocketPath = constant.StatusSocketPathDefault
33 changes: 8 additions & 25 deletions pkg/component/status/status.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build unix

// SPDX-FileCopyrightText: 2021 k0s authors
// SPDX-License-Identifier: Apache-2.0

Expand All @@ -9,9 +7,7 @@ import (
"context"
"encoding/json"
"errors"
"net"
"net/http"
"os"
"strconv"
"time"

Expand All @@ -35,7 +31,6 @@ type Status struct {
Socket string
L *logrus.Entry
httpserver http.Server
listener net.Listener
CertManager certManager
}

Expand All @@ -62,34 +57,23 @@ func (s *Status) Init(_ context.Context) error {
w.WriteHeader(http.StatusInternalServerError)
}
})
var err error
s.httpserver = http.Server{
Handler: mux,
}

removeLeftovers(s.Socket)
s.listener, err = net.Listen("unix", s.Socket)
if err != nil {
s.L.Errorf("failed to create listener %s", err)
return err
}
s.L.Infof("Listening address %s", s.Socket)

return nil
}

// removeLeftovers tries to remove leftover sockets that nothing is listening on
func removeLeftovers(socket string) {
_, err := net.Dial("unix", socket)
if err != nil {
_ = os.Remove(socket)
}
}

// Start runs the component
func (s *Status) Start(_ context.Context) error {
listener, err := newStatusListener(s.Socket)
if err != nil {
s.L.Errorf("failed to create listener %s", err)
return err
}
s.L.Infof("Listening address %s", s.Socket)
go func() {
if err := s.httpserver.Serve(s.listener); err != nil && !errors.Is(err, http.ErrServerClosed) {
if err := s.httpserver.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) {
s.L.Errorf("failed to start status server at %s: %s", s.Socket, err)
}
}()
Expand All @@ -103,8 +87,7 @@ func (s *Status) Stop() error {
if err := s.httpserver.Shutdown(ctx); err != nil && !errors.Is(err, context.Canceled) {
return err
}
// Unix socket doesn't need to be explicitly removed because it's handled
// by httpserver.Shutdown
cleanupStatusListener(s.Socket)
return nil
}

Expand Down
Loading
Loading