Browse Source

Make program name a variable to be changed at compile time

pull/1770/head
Darren Shepherd 5 years ago
parent
commit
7e59c0801e
  1. 7
      cmd/k3s/main.go
  2. 21
      pkg/agent/config/config.go
  3. 3
      pkg/agent/containerd/containerd.go
  4. 3
      pkg/agent/flannel/setup.go
  5. 7
      pkg/agent/loadbalancer/loadbalancer.go
  6. 9
      pkg/agent/run.go
  7. 3
      pkg/agent/tunnel/tunnel.go
  8. 3
      pkg/cli/agent/agent.go
  9. 17
      pkg/cli/cmds/agent.go
  10. 3
      pkg/cli/cmds/log.go
  11. 2
      pkg/cli/cmds/root.go
  12. 37
      pkg/cli/cmds/server.go
  13. 5
      pkg/cli/server/server.go
  14. 5
      pkg/cloudprovider/cloudprovider.go
  15. 11
      pkg/cloudprovider/instances.go
  16. 7
      pkg/cluster/https.go
  17. 5
      pkg/cluster/join.go
  18. 22
      pkg/daemons/control/server.go
  19. 11
      pkg/datadir/datadir.go
  20. 12
      pkg/dqlite/controller/client/controller.go
  21. 22
      pkg/nodeconfig/nodeconfig.go
  22. 15
      pkg/nodeconfig/nodeconfig_test.go
  23. 34
      pkg/server/router.go
  24. 7
      pkg/server/server.go
  25. 14
      pkg/servicelb/controller.go
  26. 8
      pkg/version/version.go

7
cmd/k3s/main.go

@ -13,6 +13,7 @@ import (
"github.com/rancher/k3s/pkg/data"
"github.com/rancher/k3s/pkg/datadir"
"github.com/rancher/k3s/pkg/untar"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@ -24,8 +25,8 @@ func main() {
app := cmds.NewApp()
app.Commands = []cli.Command{
cmds.NewServerCommand(wrap("k3s-server", os.Args)),
cmds.NewAgentCommand(wrap("k3s-agent", os.Args)),
cmds.NewServerCommand(wrap(version.Program+"-server", os.Args)),
cmds.NewAgentCommand(wrap(version.Program+"-agent", os.Args)),
cmds.NewKubectlCommand(externalCLIAction("kubectl")),
cmds.NewCRICTL(externalCLIAction("crictl")),
cmds.NewCtrCommand(externalCLIAction("ctr")),
@ -88,7 +89,7 @@ func stageAndRun(dataDir string, cmd string, args []string) error {
if err := os.Setenv("PATH", filepath.Join(dir, "bin")+":"+os.Getenv("PATH")+":"+filepath.Join(dir, "bin/aux")); err != nil {
return err
}
if err := os.Setenv("K3S_DATA_DIR", dir); err != nil {
if err := os.Setenv(version.ProgramUpper+"_DATA_DIR", dir); err != nil {
return err
}

21
pkg/agent/config/config.go

@ -25,6 +25,7 @@ import (
"github.com/rancher/k3s/pkg/clientaccess"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/daemons/control"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/net"
@ -73,12 +74,12 @@ func getNodeNamedCrt(nodeName, nodePasswordFile string) HTTPRequester {
req.SetBasicAuth(username, password)
}
req.Header.Set("K3s-Node-Name", nodeName)
req.Header.Set(version.Program+"-Node-Name", nodeName)
nodePassword, err := ensureNodePassword(nodePasswordFile)
if err != nil {
return nil, err
}
req.Header.Set("K3s-Node-Password", nodePassword)
req.Header.Set(version.Program+"-Node-Password", nodePassword)
resp, err := client.Do(req)
if err != nil {
@ -142,7 +143,7 @@ func upgradeOldNodePasswordPath(oldNodePasswordFile, newNodePasswordFile string)
}
func getServingCert(nodeName, servingCertFile, servingKeyFile, nodePasswordFile string, info *clientaccess.Info) (*tls.Certificate, error) {
servingCert, err := Request("/v1-k3s/serving-kubelet.crt", info, getNodeNamedCrt(nodeName, nodePasswordFile))
servingCert, err := Request("/v1-"+version.Program+"/serving-kubelet.crt", info, getNodeNamedCrt(nodeName, nodePasswordFile))
if err != nil {
return nil, err
}
@ -166,7 +167,7 @@ func getServingCert(nodeName, servingCertFile, servingKeyFile, nodePasswordFile
func getHostFile(filename, keyFile string, info *clientaccess.Info) error {
basename := filepath.Base(filename)
fileBytes, err := clientaccess.Get("/v1-k3s/"+basename, info)
fileBytes, err := clientaccess.Get("/v1-"+version.Program+"/"+basename, info)
if err != nil {
return err
}
@ -206,7 +207,7 @@ func splitCertKeyPEM(bytes []byte) (certPem []byte, keyPem []byte) {
func getNodeNamedHostFile(filename, keyFile, nodeName, nodePasswordFile string, info *clientaccess.Info) error {
basename := filepath.Base(filename)
fileBytes, err := Request("/v1-k3s/"+basename, info, getNodeNamedCrt(nodeName, nodePasswordFile))
fileBytes, err := Request("/v1-"+version.Program+"/"+basename, info, getNodeNamedCrt(nodeName, nodePasswordFile))
if err != nil {
return err
}
@ -282,7 +283,7 @@ func locateOrGenerateResolvConf(envInfo *cmds.Agent) string {
}
}
tmpConf := filepath.Join(os.TempDir(), "k3s-resolv.conf")
tmpConf := filepath.Join(os.TempDir(), version.Program+"-resolv.conf")
if err := ioutil.WriteFile(tmpConf, []byte("nameserver 8.8.8.8\n"), 0444); err != nil {
logrus.Error(err)
return ""
@ -385,13 +386,13 @@ func get(envInfo *cmds.Agent, proxy proxy.Proxy) (*config.Node, error) {
return nil, err
}
clientK3sControllerCert := filepath.Join(envInfo.DataDir, "client-k3s-controller.crt")
clientK3sControllerKey := filepath.Join(envInfo.DataDir, "client-k3s-controller.key")
clientK3sControllerCert := filepath.Join(envInfo.DataDir, "client-"+version.Program+"-controller.crt")
clientK3sControllerKey := filepath.Join(envInfo.DataDir, "client-"+version.Program+"-controller.key")
if err := getHostFile(clientK3sControllerCert, clientK3sControllerKey, info); err != nil {
return nil, err
}
kubeconfigK3sController := filepath.Join(envInfo.DataDir, "k3scontroller.kubeconfig")
kubeconfigK3sController := filepath.Join(envInfo.DataDir, version.Program+"controller.kubeconfig")
if err := control.KubeConfig(kubeconfigK3sController, proxy.APIServerURL(), serverCAFile, clientK3sControllerCert, clientK3sControllerKey); err != nil {
return nil, err
}
@ -488,7 +489,7 @@ func get(envInfo *cmds.Agent, proxy proxy.Proxy) (*config.Node, error) {
}
func getConfig(info *clientaccess.Info) (*config.Control, error) {
data, err := clientaccess.Get("/v1-k3s/config", info)
data, err := clientaccess.Get("/v1-"+version.Program+"/config", info)
if err != nil {
return nil, err
}

3
pkg/agent/containerd/containerd.go

@ -20,6 +20,7 @@ import (
"github.com/rancher/k3s/pkg/agent/templates"
util2 "github.com/rancher/k3s/pkg/agent/util"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
yaml "gopkg.in/yaml.v2"
@ -233,7 +234,7 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error {
containerdConfig.SELinuxEnabled = selEnabled
}
if containerdConfig.SELinuxEnabled && !selConfigured {
logrus.Warnf("SELinux is enabled for k3s but process is not running in context '%s', k3s-selinux policy may need to be applied", SELinuxContextType)
logrus.Warnf("SELinux is enabled for "+version.Program+" but process is not running in context '%s', "+version.Program+"-selinux policy may need to be applied", SELinuxContextType)
}
containerdTemplateBytes, err := ioutil.ReadFile(cfg.Containerd.Template)

3
pkg/agent/flannel/setup.go

@ -10,6 +10,7 @@ import (
"github.com/rancher/k3s/pkg/agent/util"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
@ -142,7 +143,7 @@ func createFlannelConf(nodeConfig *config.Node) error {
func setupStrongSwan(nodeConfig *config.Node) error {
// if data dir env is not set point to root
dataDir := os.Getenv("K3S_DATA_DIR")
dataDir := os.Getenv(version.ProgramUpper + "_DATA_DIR")
if dataDir == "" {
dataDir = "/"
}

7
pkg/agent/loadbalancer/loadbalancer.go

@ -8,6 +8,7 @@ import (
"sync"
"github.com/google/tcpproxy"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
)
@ -27,9 +28,9 @@ type LoadBalancer struct {
nextServerIndex int
}
const (
SupervisorServiceName = "k3s-agent-load-balancer"
APIServerServiceName = "k3s-api-server-agent-load-balancer"
var (
SupervisorServiceName = version.Program + "-agent-load-balancer"
APIServerServiceName = version.Program + "-api-server-agent-load-balancer"
)
func New(dataDir, serviceName, serverURL string) (_lb *LoadBalancer, _err error) {

9
pkg/agent/run.go

@ -23,6 +23,7 @@ import (
daemonconfig "github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/nodeconfig"
"github.com/rancher/k3s/pkg/rootless"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -32,10 +33,10 @@ import (
"k8s.io/client-go/tools/clientcmd"
)
const (
InternalIPLabel = "k3s.io/internal-ip"
ExternalIPLabel = "k3s.io/external-ip"
HostnameLabel = "k3s.io/hostname"
var (
InternalIPLabel = version.Program + ".io/internal-ip"
ExternalIPLabel = version.Program + ".io/external-ip"
HostnameLabel = version.Program + ".io/hostname"
)
func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {

3
pkg/agent/tunnel/tunnel.go

@ -13,6 +13,7 @@ import (
"github.com/gorilla/websocket"
"github.com/rancher/k3s/pkg/agent/proxy"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/remotedialer"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
@ -159,7 +160,7 @@ func Setup(ctx context.Context, config *config.Node, proxy proxy.Proxy) error {
}
func connect(rootCtx context.Context, waitGroup *sync.WaitGroup, address string, tlsConfig *tls.Config) context.CancelFunc {
wsURL := fmt.Sprintf("wss://%s/v1-k3s/connect", address)
wsURL := fmt.Sprintf("wss://%s/v1-"+version.Program+"/connect", address)
ws := &websocket.Dialer{
TLSClientConfig: tlsConfig,
}

3
pkg/cli/agent/agent.go

@ -11,6 +11,7 @@ import (
"github.com/rancher/k3s/pkg/datadir"
"github.com/rancher/k3s/pkg/netutil"
"github.com/rancher/k3s/pkg/token"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/wrangler/pkg/signals"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -48,7 +49,7 @@ func Run(ctx *cli.Context) error {
cmds.AgentConfig.NodeIP = netutil.GetIPFromInterface(cmds.AgentConfig.FlannelIface)
}
logrus.Infof("Starting k3s agent %s", ctx.App.Version)
logrus.Infof("Starting "+version.Program+" agent %s", ctx.App.Version)
dataDir, err := datadir.LocalHome(cmds.AgentConfig.DataDir, cmds.AgentConfig.Rootless)
if err != nil {

17
pkg/cli/cmds/agent.go

@ -4,6 +4,7 @@ import (
"os"
"path/filepath"
"github.com/rancher/k3s/pkg/version"
"github.com/urfave/cli"
)
@ -57,7 +58,7 @@ var (
NodeNameFlag = cli.StringFlag{
Name: "node-name",
Usage: "(agent/node) Node name",
EnvVar: "K3S_NODE_NAME",
EnvVar: version.ProgramUpper + "_NODE_NAME",
Destination: &AgentConfig.NodeName,
}
WithNodeIDFlag = cli.BoolFlag{
@ -79,7 +80,7 @@ var (
Name: "private-registry",
Usage: "(agent/runtime) Private registry configuration file",
Destination: &AgentConfig.PrivateRegistry,
Value: "/etc/rancher/k3s/registries.yaml",
Value: "/etc/rancher/" + version.Program + "/registries.yaml",
}
PauseImageFlag = cli.StringFlag{
Name: "pause-image",
@ -105,7 +106,7 @@ var (
ResolvConfFlag = cli.StringFlag{
Name: "resolv-conf",
Usage: "(agent/networking) Kubelet resolv.conf file",
EnvVar: "K3S_RESOLV_CONF",
EnvVar: version.ProgramUpper + "_RESOLV_CONF",
Destination: &AgentConfig.ResolvConf,
}
ExtraKubeletArgs = cli.StringSliceFlag{
@ -150,26 +151,26 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command {
cli.StringFlag{
Name: "token,t",
Usage: "(cluster) Token to use for authentication",
EnvVar: "K3S_TOKEN",
EnvVar: version.ProgramUpper + "_TOKEN",
Destination: &AgentConfig.Token,
},
cli.StringFlag{
Name: "token-file",
Usage: "(cluster) Token file to use for authentication",
EnvVar: "K3S_TOKEN_FILE",
EnvVar: version.ProgramUpper + "_TOKEN_FILE",
Destination: &AgentConfig.TokenFile,
},
cli.StringFlag{
Name: "server,s",
Usage: "(cluster) Server to connect to",
EnvVar: "K3S_URL",
EnvVar: version.ProgramUpper + "_URL",
Destination: &AgentConfig.ServerURL,
},
cli.StringFlag{
Name: "data-dir,d",
Usage: "(agent/data) Folder to hold state",
Destination: &AgentConfig.DataDir,
Value: "/var/lib/rancher/k3s",
Value: "/var/lib/rancher/" + version.Program + "",
},
NodeNameFlag,
WithNodeIDFlag,
@ -200,7 +201,7 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command {
Name: "cluster-secret",
Usage: "(deprecated) use --token",
Destination: &AgentConfig.ClusterSecret,
EnvVar: "K3S_CLUSTER_SECRET",
EnvVar: version.ProgramUpper + "_CLUSTER_SECRET",
},
},
}

3
pkg/cli/cmds/log.go

@ -11,6 +11,7 @@ import (
"github.com/docker/docker/pkg/reexec"
"github.com/natefinch/lumberjack"
"github.com/rancher/k3s/pkg/version"
"github.com/urfave/cli"
)
@ -90,7 +91,7 @@ func runWithLogging() error {
l = io.MultiWriter(l, os.Stderr)
}
args := append([]string{"k3s"}, os.Args[1:]...)
args := append([]string{version.Program}, os.Args[1:]...)
cmd := reexec.Command(args...)
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "_K3S_LOG_REEXEC_=true")

2
pkg/cli/cmds/root.go

@ -33,7 +33,7 @@ func NewApp() *cli.App {
Name: "debug",
Usage: "Turn on debug logs",
Destination: &Debug,
EnvVar: "K3S_DEBUG",
EnvVar: version.ProgramUpper + "_DEBUG",
},
}

37
pkg/cli/cmds/server.go

@ -1,6 +1,7 @@
package cmds
import (
"github.com/rancher/k3s/pkg/version"
"github.com/urfave/cli"
)
@ -69,7 +70,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
AlsoLogToStderr,
cli.StringFlag{
Name: "bind-address",
Usage: "(listener) k3s bind address (default: 0.0.0.0)",
Usage: "(listener) " + version.Program + " bind address (default: 0.0.0.0)",
Destination: &ServerConfig.BindAddress,
},
cli.IntFlag{
@ -95,7 +96,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
},
cli.StringFlag{
Name: "data-dir,d",
Usage: "(data) Folder to hold state default /var/lib/rancher/k3s or ${HOME}/.rancher/k3s if not root",
Usage: "(data) Folder to hold state default /var/lib/rancher/" + version.Program + " or ${HOME}/.rancher/" + version.Program + " if not root",
Destination: &ServerConfig.DataDir,
},
cli.StringFlag{
@ -132,25 +133,25 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
Name: "token,t",
Usage: "(cluster) Shared secret used to join a server or agent to a cluster",
Destination: &ServerConfig.Token,
EnvVar: "K3S_TOKEN",
EnvVar: version.ProgramUpper + "_TOKEN",
},
cli.StringFlag{
Name: "token-file",
Usage: "(cluster) File containing the cluster-secret/token",
Destination: &ServerConfig.TokenFile,
EnvVar: "K3S_TOKEN_FILE",
EnvVar: version.ProgramUpper + "_TOKEN_FILE",
},
cli.StringFlag{
Name: "write-kubeconfig,o",
Usage: "(client) Write kubeconfig for admin client to this file",
Destination: &ServerConfig.KubeConfigOutput,
EnvVar: "K3S_KUBECONFIG_OUTPUT",
EnvVar: version.ProgramUpper + "_KUBECONFIG_OUTPUT",
},
cli.StringFlag{
Name: "write-kubeconfig-mode",
Usage: "(client) Write kubeconfig with this mode",
Destination: &ServerConfig.KubeConfigMode,
EnvVar: "K3S_KUBECONFIG_MODE",
EnvVar: version.ProgramUpper + "_KUBECONFIG_MODE",
},
cli.StringSliceFlag{
Name: "kube-apiserver-arg",
@ -176,25 +177,25 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
Name: "datastore-endpoint",
Usage: "(db) Specify etcd, Mysql, Postgres, or Sqlite (default) data source name",
Destination: &ServerConfig.DatastoreEndpoint,
EnvVar: "K3S_DATASTORE_ENDPOINT",
EnvVar: version.ProgramUpper + "_DATASTORE_ENDPOINT",
},
cli.StringFlag{
Name: "datastore-cafile",
Usage: "(db) TLS Certificate Authority file used to secure datastore backend communication",
Destination: &ServerConfig.DatastoreCAFile,
EnvVar: "K3S_DATASTORE_CAFILE",
EnvVar: version.ProgramUpper + "_DATASTORE_CAFILE",
},
cli.StringFlag{
Name: "datastore-certfile",
Usage: "(db) TLS certification file used to secure datastore backend communication",
Destination: &ServerConfig.DatastoreCertFile,
EnvVar: "K3S_DATASTORE_CERTFILE",
EnvVar: version.ProgramUpper + "_DATASTORE_CERTFILE",
},
cli.StringFlag{
Name: "datastore-keyfile",
Usage: "(db) TLS key file used to secure datastore backend communication",
Destination: &ServerConfig.DatastoreKeyFile,
EnvVar: "K3S_DATASTORE_KEYFILE",
EnvVar: version.ProgramUpper + "_DATASTORE_KEYFILE",
},
cli.StringFlag{
Name: "default-local-storage-path",
@ -212,7 +213,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
},
cli.BoolFlag{
Name: "disable-cloud-controller",
Usage: "(components) Disable k3s default cloud controller manager",
Usage: "(components) Disable " + version.Program + " default cloud controller manager",
Destination: &ServerConfig.DisableCCM,
},
cli.BoolFlag{
@ -222,7 +223,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
},
cli.BoolFlag{
Name: "disable-network-policy",
Usage: "(components) Disable k3s default network policy controller",
Usage: "(components) Disable " + version.Program + " default network policy controller",
Destination: &ServerConfig.DisableNPC,
},
NodeNameFlag,
@ -250,32 +251,32 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
Name: "agent-token",
Usage: "(experimental/cluster) Shared secret used to join agents to the cluster, but not servers",
Destination: &ServerConfig.AgentToken,
EnvVar: "K3S_AGENT_TOKEN",
EnvVar: version.ProgramUpper + "_AGENT_TOKEN",
},
cli.StringFlag{
Name: "agent-token-file",
Usage: "(experimental/cluster) File containing the agent secret",
Destination: &ServerConfig.AgentTokenFile,
EnvVar: "K3S_AGENT_TOKEN_FILE",
EnvVar: version.ProgramUpper + "_AGENT_TOKEN_FILE",
},
cli.StringFlag{
Name: "server,s",
Usage: "(experimental/cluster) Server to connect to, used to join a cluster",
EnvVar: "K3S_URL",
EnvVar: version.ProgramUpper + "_URL",
Destination: &ServerConfig.ServerURL,
},
cli.BoolFlag{
Name: "cluster-init",
Hidden: hideDqlite,
Usage: "(experimental/cluster) Initialize new cluster master",
EnvVar: "K3S_CLUSTER_INIT",
EnvVar: version.ProgramUpper + "_CLUSTER_INIT",
Destination: &ServerConfig.ClusterInit,
},
cli.BoolFlag{
Name: "cluster-reset",
Hidden: hideDqlite,
Usage: "(experimental/cluster) Forget all peers and become a single cluster new cluster master",
EnvVar: "K3S_CLUSTER_RESET",
EnvVar: version.ProgramUpper + "_CLUSTER_RESET",
Destination: &ServerConfig.ClusterReset,
},
cli.BoolFlag{
@ -295,7 +296,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
Name: "cluster-secret",
Usage: "(deprecated) use --token",
Destination: &ServerConfig.ClusterSecret,
EnvVar: "K3S_CLUSTER_SECRET",
EnvVar: version.ProgramUpper + "_CLUSTER_SECRET",
},
cli.BoolFlag{
Name: "disable-agent",

5
pkg/cli/server/server.go

@ -17,6 +17,7 @@ import (
"github.com/rancher/k3s/pkg/rootless"
"github.com/rancher/k3s/pkg/server"
"github.com/rancher/k3s/pkg/token"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/wrangler/pkg/signals"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -209,7 +210,7 @@ func run(app *cli.Context, cfg *cmds.Server) error {
return errors.Wrapf(err, "Invalid TLS Cipher Suites %s: %v", TLSCipherSuites, err)
}
logrus.Info("Starting k3s ", app.App.Version)
logrus.Info("Starting "+version.Program+" ", app.App.Version)
notifySocket := os.Getenv("NOTIFY_SOCKET")
os.Unsetenv("NOTIFY_SOCKET")
@ -220,7 +221,7 @@ func run(app *cli.Context, cfg *cmds.Server) error {
go func() {
<-serverConfig.ControlConfig.Runtime.APIServerReady
logrus.Info("k3s is up and running")
logrus.Info("" + version.Program + " is up and running")
if notifySocket != "" {
os.Setenv("NOTIFY_SOCKET", notifySocket)
systemd.SdNotify(true, "READY=1\n")

5
pkg/cloudprovider/cloudprovider.go

@ -4,6 +4,7 @@ import (
"context"
"io"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/wrangler-api/pkg/generated/controllers/core"
coreclient "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
"github.com/rancher/wrangler/pkg/start"
@ -15,7 +16,7 @@ type k3s struct {
}
func init() {
cloudprovider.RegisterCloudProvider("k3s", func(config io.Reader) (cloudprovider.Interface, error) {
cloudprovider.RegisterCloudProvider(version.Program, func(config io.Reader) (cloudprovider.Interface, error) {
return &k3s{}, nil
})
}
@ -49,7 +50,7 @@ func (k *k3s) Routes() (cloudprovider.Routes, bool) {
}
func (k *k3s) ProviderName() string {
return "k3s"
return version.Program
}
func (k *k3s) HasClusterID() bool {

11
pkg/cloudprovider/instances.go

@ -4,16 +4,17 @@ import (
"context"
"fmt"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
cloudprovider "k8s.io/cloud-provider"
)
const (
InternalIPLabel = "k3s.io/internal-ip"
ExternalIPLabel = "k3s.io/external-ip"
HostnameLabel = "k3s.io/hostname"
var (
InternalIPLabel = version.Program + ".io/internal-ip"
ExternalIPLabel = version.Program + ".io/external-ip"
HostnameLabel = version.Program + ".io/hostname"
)
func (k *k3s) AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error {
@ -45,7 +46,7 @@ func (k *k3s) InstanceType(ctx context.Context, name types.NodeName) (string, er
if err != nil {
return "", err
}
return "k3s", nil
return version.Program, nil
}
func (k *k3s) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) {

7
pkg/cluster/https.go

@ -13,6 +13,7 @@ import (
"github.com/rancher/dynamiclistener/storage/kubernetes"
"github.com/rancher/dynamiclistener/storage/memory"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/wrangler-api/pkg/generated/controllers/core"
"github.com/sirupsen/logrus"
)
@ -30,8 +31,8 @@ func (c *Cluster) newListener(ctx context.Context) (net.Listener, http.Handler,
storage := tlsStorage(ctx, c.config.DataDir, c.runtime)
return dynamiclistener.NewListener(tcp, storage, cert, key, dynamiclistener.Config{
CN: "k3s",
Organization: []string{"k3s"},
CN: version.Program,
Organization: []string{version.Program},
TLSConfig: tls.Config{
ClientAuth: tls.RequestClientCert,
MinVersion: c.config.TLSMinVersion,
@ -79,5 +80,5 @@ func tlsStorage(ctx context.Context, dataDir string, runtime *config.ControlRunt
cache := memory.NewBacked(fileStorage)
return kubernetes.New(ctx, func() *core.Factory {
return runtime.Core
}, "kube-system", "k3s-serving", cache)
}, "kube-system", ""+version.Program+"-serving", cache)
}

5
pkg/cluster/join.go

@ -9,6 +9,7 @@ import (
"github.com/rancher/k3s/pkg/bootstrap"
"github.com/rancher/k3s/pkg/clientaccess"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
)
@ -44,7 +45,7 @@ func (c *Cluster) shouldJoin() (bool, error) {
}
if dqlite && c.config.Token == "" {
return false, fmt.Errorf("K3S_TOKEN is required to join a cluster")
return false, fmt.Errorf(version.ProgramUpper + "_TOKEN is required to join a cluster")
}
return true, nil
@ -79,7 +80,7 @@ func (c *Cluster) httpJoin() error {
}
c.clientAccessInfo = info
content, err := clientaccess.Get("/v1-k3s/server-bootstrap", info)
content, err := clientaccess.Get("/v1-"+version.Program+"/server-bootstrap", info)
if err != nil {
return err
}

22
pkg/daemons/control/server.go

@ -27,6 +27,7 @@ import (
"github.com/rancher/k3s/pkg/daemons/executor"
"github.com/rancher/k3s/pkg/passwd"
"github.com/rancher/k3s/pkg/token"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/wrangler-api/pkg/generated/controllers/rbac"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -186,7 +187,7 @@ func apiServer(ctx context.Context, cfg *config.Control, runtime *config.Control
argsMap["tls-cert-file"] = runtime.ServingKubeAPICert
argsMap["tls-private-key-file"] = runtime.ServingKubeAPIKey
argsMap["service-account-key-file"] = runtime.ServiceKey
argsMap["service-account-issuer"] = "k3s"
argsMap["service-account-issuer"] = version.Program
argsMap["api-audiences"] = "unknown"
argsMap["basic-auth-file"] = runtime.PasswdFile
argsMap["kubelet-certificate-authority"] = runtime.ServerCA
@ -290,8 +291,8 @@ func prepare(ctx context.Context, config *config.Control, runtime *config.Contro
runtime.ClientKubeAPIKey = filepath.Join(config.DataDir, "tls", "client-kube-apiserver.key")
runtime.ClientKubeProxyCert = filepath.Join(config.DataDir, "tls", "client-kube-proxy.crt")
runtime.ClientKubeProxyKey = filepath.Join(config.DataDir, "tls", "client-kube-proxy.key")
runtime.ClientK3sControllerCert = filepath.Join(config.DataDir, "tls", "client-k3s-controller.crt")
runtime.ClientK3sControllerKey = filepath.Join(config.DataDir, "tls", "client-k3s-controller.key")
runtime.ClientK3sControllerCert = filepath.Join(config.DataDir, "tls", "client-"+version.Program+"-controller.crt")
runtime.ClientK3sControllerKey = filepath.Join(config.DataDir, "tls", "client-"+version.Program+"-controller.key")
runtime.ServingKubeAPICert = filepath.Join(config.DataDir, "tls", "serving-kube-apiserver.crt")
runtime.ServingKubeAPIKey = filepath.Join(config.DataDir, "tls", "serving-kube-apiserver.key")
@ -382,7 +383,7 @@ func migratePassword(p *passwd.Passwd) error {
server, _ := p.Pass("server")
node, _ := p.Pass("node")
if server == "" && node != "" {
return p.EnsureUser("server", "k3s:server", node)
return p.EnsureUser("server", version.Program+":server", node)
}
return nil
}
@ -433,11 +434,11 @@ func genUsers(config *config.Control, runtime *config.ControlRuntime) error {
nodePass := getNodePass(config, serverPass)
if err := passwd.EnsureUser("node", "k3s:agent", nodePass); err != nil {
if err := passwd.EnsureUser("node", version.Program+":agent", nodePass); err != nil {
return err
}
if err := passwd.EnsureUser("server", "k3s:server", serverPass); err != nil {
if err := passwd.EnsureUser("server", version.Program+":server", serverPass); err != nil {
return err
}
@ -466,7 +467,7 @@ func getSigningCertFactory(regen bool, altNames *certutil.AltNames, extKeyUsage
}
func genClientCerts(config *config.Control, runtime *config.ControlRuntime) error {
regen, err := createSigningCertKey("k3s-client", runtime.ClientCA, runtime.ClientCAKey)
regen, err := createSigningCertKey(version.Program+"-client", runtime.ClientCA, runtime.ClientCAKey)
if err != nil {
return err
}
@ -519,6 +520,7 @@ func genClientCerts(config *config.Control, runtime *config.ControlRuntime) erro
if _, err = factory("system:kube-proxy", nil, runtime.ClientKubeProxyCert, runtime.ClientKubeProxyKey); err != nil {
return err
}
// this must be hardcoded to k3s-controller because it's hard coded in the rolebindings.yaml
if _, err = factory("system:k3s-controller", nil, runtime.ClientK3sControllerCert, runtime.ClientK3sControllerKey); err != nil {
return err
}
@ -554,7 +556,7 @@ func createServerSigningCertKey(config *config.Control, runtime *config.ControlR
}
return true, nil
}
return createSigningCertKey("k3s-server", runtime.ServerCA, runtime.ServerCAKey)
return createSigningCertKey(version.Program+"-server", runtime.ServerCA, runtime.ServerCAKey)
}
func genServerCerts(config *config.Control, runtime *config.ControlRuntime) error {
@ -586,7 +588,7 @@ func genServerCerts(config *config.Control, runtime *config.ControlRuntime) erro
}
func genRequestHeaderCerts(config *config.Control, runtime *config.ControlRuntime) error {
regen, err := createSigningCertKey("k3s-request-header", runtime.RequestHeaderCA, runtime.RequestHeaderCAKey)
regen, err := createSigningCertKey(version.Program+"-request-header", runtime.RequestHeaderCA, runtime.RequestHeaderCAKey)
if err != nil {
return err
}
@ -783,7 +785,7 @@ func cloudControllerManager(ctx context.Context, cfg *config.Control, runtime *c
"cluster-cidr": cfg.ClusterIPRange.String(),
"bind-address": localhostIP.String(),
"secure-port": "0",
"cloud-provider": "k3s",
"cloud-provider": version.Program,
"allow-untagged-cloud": "true",
"node-status-update-frequency": "1m",
}

11
pkg/datadir/datadir.go

@ -5,14 +5,15 @@ import (
"path/filepath"
"github.com/pkg/errors"
"github.com/rancher/k3s/pkg/version"
"github.com/rancher/wrangler/pkg/resolvehome"
)
const (
DefaultDataDir = "/var/lib/rancher/k3s"
DefaultHomeDataDir = "${HOME}/.rancher/k3s"
HomeConfig = "${HOME}/.kube/k3s.yaml"
GlobalConfig = "/etc/rancher/k3s/k3s.yaml"
var (
DefaultDataDir = "/var/lib/rancher/" + version.Program
DefaultHomeDataDir = "${HOME}/.rancher/" + version.Program
HomeConfig = "${HOME}/.kube/" + version.Program + ".yaml"
GlobalConfig = "/etc/rancher/" + version.Program + "/" + version.Program + ".yaml"
)
func Resolve(dataDir string) (string, error) {

12
pkg/dqlite/controller/client/controller.go

@ -7,17 +7,21 @@ import (
"github.com/canonical/go-dqlite/client"
"github.com/canonical/go-dqlite/driver"
"github.com/rancher/k3s/pkg/version"
controllerv1 "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
var (
nodeID = "cluster." + version.Program + ".cattle.io/node-id"
nodeAddress = "cluster." + version.Program + ".cattle.io/node-address"
)
const (
allKey = "_all_"
nodeID = "cluster.k3s.cattle.io/node-id"
nodeAddress = "cluster.k3s.cattle.io/node-address"
master = "node-role.kubernetes.io/master"
allKey = "_all_"
master = "node-role.kubernetes.io/master"
)
func Register(ctx context.Context, nodeName string, nodeInfo client.NodeInfo,

22
pkg/nodeconfig/nodeconfig.go

@ -9,14 +9,18 @@ import (
"strings"
"github.com/pkg/errors"
"github.com/rancher/k3s/pkg/version"
corev1 "k8s.io/api/core/v1"
)
var (
NodeArgsAnnotation = version.Program + ".io/node-args"
NodeEnvAnnotation = version.Program + ".io/node-env"
NodeConfigHashAnnotation = version.Program + ".io/node-config-hash"
)
const (
NodeArgsAnnotation = "k3s.io/node-args"
NodeEnvAnnotation = "k3s.io/node-env"
NodeConfigHashAnnotation = "k3s.io/node-config-hash"
OmittedValue = "********"
OmittedValue = "********"
)
func getNodeArgs() (string, error) {
@ -47,7 +51,7 @@ func getNodeEnv() (string, error) {
k3sEnv := make(map[string]string)
for _, v := range os.Environ() {
keyValue := strings.SplitN(v, "=", 2)
if strings.HasPrefix(keyValue[0], "K3S_") {
if strings.HasPrefix(keyValue[0], version.ProgramUpper+"_") {
k3sEnv[keyValue[0]] = keyValue[1]
}
}
@ -93,10 +97,10 @@ func SetNodeConfigAnnotations(node *corev1.Node) (bool, error) {
func isSecret(key string) bool {
secretData := []string{
"K3S_TOKEN",
"K3S_DATASTORE_ENDPOINT",
"K3S_AGENT_TOKEN",
"K3S_CLUSTER_SECRET",
version.ProgramUpper + "_TOKEN",
version.ProgramUpper + "_DATASTORE_ENDPOINT",
version.ProgramUpper + "_AGENT_TOKEN",
version.ProgramUpper + "_CLUSTER_SECRET",
"--token",
"-t",
"--agent-token",

15
pkg/nodeconfig/nodeconfig_test.go

@ -4,6 +4,7 @@ import (
"os"
"testing"
"github.com/rancher/k3s/pkg/version"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@ -27,7 +28,7 @@ var FakeNodeWithAnnotation = &corev1.Node{
Name: "fakeNode-with-annotation",
Annotations: map[string]string{
NodeArgsAnnotation: `["server","--no-flannel"]`,
NodeEnvAnnotation: `{"K3S_NODE_NAME":"fakeNode-with-annotation"}`,
NodeEnvAnnotation: `{"` + version.ProgramUpper + `_NODE_NAME":"fakeNode-with-annotation"}`,
NodeConfigHashAnnotation: "LNQOAOIMOQIBRMEMACW7LYHXUNPZADF6RFGOSPIHJCOS47UVUJAA====",
},
},
@ -40,8 +41,8 @@ func assertEqual(t *testing.T, a interface{}, b interface{}) {
}
func TestSetEmptyNodeConfigAnnotations(t *testing.T) {
os.Args = []string{"k3s", "server", "--no-flannel"}
os.Setenv("K3S_NODE_NAME", "fakeNode-no-annotation")
os.Args = []string{version.Program, "server", "--no-flannel"}
os.Setenv(version.ProgramUpper+"_NODE_NAME", "fakeNode-no-annotation")
nodeUpdated, err := SetNodeConfigAnnotations(FakeNodeWithNoAnnotation)
if err != nil {
t.Fatalf("Failed to set node config annotation: %v", err)
@ -52,7 +53,7 @@ func TestSetEmptyNodeConfigAnnotations(t *testing.T) {
actualArgs := FakeNodeWithNoAnnotation.Annotations[NodeArgsAnnotation]
assertEqual(t, expectedArgs, actualArgs)
expectedEnv := `{"K3S_NODE_NAME":"fakeNode-no-annotation"}`
expectedEnv := `{"` + version.ProgramUpper + `_NODE_NAME":"fakeNode-no-annotation"}`
actualEnv := FakeNodeWithNoAnnotation.Annotations[NodeEnvAnnotation]
assertEqual(t, expectedEnv, actualEnv)
@ -63,8 +64,8 @@ func TestSetEmptyNodeConfigAnnotations(t *testing.T) {
func TestSetExistingNodeConfigAnnotations(t *testing.T) {
// adding same config
os.Args = []string{"k3s", "server", "--no-flannel"}
os.Setenv("K3S_NODE_NAME", "fakeNode-with-annotation")
os.Args = []string{version.Program, "server", "--no-flannel"}
os.Setenv(version.ProgramUpper+"_NODE_NAME", "fakeNode-with-annotation")
nodeUpdated, err := SetNodeConfigAnnotations(FakeNodeWithAnnotation)
if err != nil {
t.Fatalf("Failed to set node config annotation: %v", err)
@ -73,7 +74,7 @@ func TestSetExistingNodeConfigAnnotations(t *testing.T) {
}
func TestSetArgsWithEqual(t *testing.T) {
os.Args = []string{"k3s", "server", "--no-flannel", "--write-kubeconfig-mode=777"}
os.Args = []string{version.Program, "server", "--no-flannel", "--write-kubeconfig-mode=777"}
os.Setenv("K3S_NODE_NAME", "fakeNode-with-no-annotation")
nodeUpdated, err := SetNodeConfigAnnotations(FakeNodeWithNoAnnotation)
if err != nil {

34
pkg/server/router.go

@ -17,6 +17,7 @@ import (
"github.com/rancher/k3s/pkg/bootstrap"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/k3s/pkg/passwd"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/json"
)
@ -26,28 +27,29 @@ const (
)
func router(serverConfig *config.Control, tunnel http.Handler, ca []byte) http.Handler {
prefix := "/v1-" + version.Program
authed := mux.NewRouter()
authed.Use(authMiddleware(serverConfig, "k3s:agent"))
authed.Use(authMiddleware(serverConfig, version.Program+":agent"))
authed.NotFoundHandler = serverConfig.Runtime.Handler
authed.Path("/v1-k3s/serving-kubelet.crt").Handler(servingKubeletCert(serverConfig, serverConfig.Runtime.ServingKubeletKey))
authed.Path("/v1-k3s/client-kubelet.crt").Handler(clientKubeletCert(serverConfig, serverConfig.Runtime.ClientKubeletKey))
authed.Path("/v1-k3s/client-kube-proxy.crt").Handler(fileHandler(serverConfig.Runtime.ClientKubeProxyCert, serverConfig.Runtime.ClientKubeProxyKey))
authed.Path("/v1-k3s/client-k3s-controller.crt").Handler(fileHandler(serverConfig.Runtime.ClientK3sControllerCert, serverConfig.Runtime.ClientK3sControllerKey))
authed.Path("/v1-k3s/client-ca.crt").Handler(fileHandler(serverConfig.Runtime.ClientCA))
authed.Path("/v1-k3s/server-ca.crt").Handler(fileHandler(serverConfig.Runtime.ServerCA))
authed.Path("/v1-k3s/config").Handler(configHandler(serverConfig))
authed.Path(prefix + "/serving-kubelet.crt").Handler(servingKubeletCert(serverConfig, serverConfig.Runtime.ServingKubeletKey))
authed.Path(prefix + "/client-kubelet.crt").Handler(clientKubeletCert(serverConfig, serverConfig.Runtime.ClientKubeletKey))
authed.Path(prefix + "/client-kube-proxy.crt").Handler(fileHandler(serverConfig.Runtime.ClientKubeProxyCert, serverConfig.Runtime.ClientKubeProxyKey))
authed.Path(prefix + "/client-" + version.Program + "-controller.crt").Handler(fileHandler(serverConfig.Runtime.ClientK3sControllerCert, serverConfig.Runtime.ClientK3sControllerKey))
authed.Path(prefix + "/client-ca.crt").Handler(fileHandler(serverConfig.Runtime.ClientCA))
authed.Path(prefix + "/server-ca.crt").Handler(fileHandler(serverConfig.Runtime.ServerCA))
authed.Path(prefix + "/config").Handler(configHandler(serverConfig))
nodeAuthed := mux.NewRouter()
nodeAuthed.Use(authMiddleware(serverConfig, "system:nodes"))
nodeAuthed.Path("/v1-k3s/connect").Handler(tunnel)
nodeAuthed.Path(prefix + "/connect").Handler(tunnel)
nodeAuthed.NotFoundHandler = authed
serverAuthed := mux.NewRouter()
serverAuthed.Use(authMiddleware(serverConfig, "k3s:server"))
serverAuthed.Use(authMiddleware(serverConfig, version.Program+":server"))
serverAuthed.NotFoundHandler = nodeAuthed
serverAuthed.Path("/db/info").Handler(nodeAuthed)
if serverConfig.Runtime.HTTPBootstrap {
serverAuthed.Path("/v1-k3s/server-bootstrap").Handler(bootstrap.Handler(&serverConfig.Runtime.ControlRuntimeBootstrap))
serverAuthed.Path(prefix + "/server-bootstrap").Handler(bootstrap.Handler(&serverConfig.Runtime.ControlRuntimeBootstrap))
}
staticDir := filepath.Join(serverConfig.DataDir, "static")
@ -68,17 +70,17 @@ func cacerts(ca []byte) http.Handler {
}
func getNodeInfo(req *http.Request) (string, string, error) {
nodeNames := req.Header["K3s-Node-Name"]
if len(nodeNames) != 1 || nodeNames[0] == "" {
nodeName := req.Header.Get(version.Program + "-Node-Name")
if nodeName == "" {
return "", "", errors.New("node name not set")
}
nodePasswords := req.Header["K3s-Node-Password"]
if len(nodePasswords) != 1 || nodePasswords[0] == "" {
nodePassword := req.Header.Get(version.Program + "-Node-Password")
if nodePassword == "" {
return "", "", errors.New("node password not set")
}
return strings.ToLower(nodeNames[0]), nodePasswords[0], nil
return strings.ToLower(nodeName), nodePassword, nil
}
func getCACertAndKeys(caCertFile, caKeyFile, signingKeyFile string) ([]*x509.Certificate, crypto.Signer, crypto.Signer, error) {

7
pkg/server/server.go

@ -25,6 +25,7 @@ import (
"github.com/rancher/k3s/pkg/servicelb"
"github.com/rancher/k3s/pkg/static"
"github.com/rancher/k3s/pkg/util"
"github.com/rancher/k3s/pkg/version"
v1 "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
"github.com/rancher/wrangler/pkg/leader"
"github.com/rancher/wrangler/pkg/resolvehome"
@ -138,7 +139,7 @@ func runControllers(ctx context.Context, config *Config) error {
logrus.Fatal("controllers exited")
}()
} else {
go leader.RunOrDie(ctx, "", "k3s", sc.K8s, start)
go leader.RunOrDie(ctx, "", version.Program, sc.K8s, start)
}
return nil
@ -256,7 +257,7 @@ func writeKubeConfig(certs string, config *Config) error {
kubeConfig, err := HomeKubeConfig(true, config.Rootless)
def := true
if err != nil {
kubeConfig = filepath.Join(config.ControlConfig.DataDir, "kubeconfig-k3s.yaml")
kubeConfig = filepath.Join(config.ControlConfig.DataDir, "kubeconfig-"+version.Program+".yaml")
def = false
}
kubeConfigSymlink := kubeConfig
@ -333,7 +334,7 @@ func printToken(httpsPort int, advertiseIP, prefix, cmd string) {
ip = hostIP.String()
}
logrus.Infof("%s k3s %s -s https://%s:%d -t ${NODE_TOKEN}", prefix, cmd, ip, httpsPort)
logrus.Infof("%s %s %s -s https://%s:%d -t ${NODE_TOKEN}", prefix, version.Program, cmd, ip, httpsPort)
}
func FormatToken(token string, certFile string) (string, error) {

14
pkg/servicelb/controller.go

@ -6,6 +6,7 @@ import (
"sort"
"strconv"
"github.com/rancher/k3s/pkg/version"
appclient "github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1"
coreclient "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
"github.com/rancher/wrangler/pkg/apply"
@ -26,12 +27,15 @@ import (
coregetter "k8s.io/client-go/kubernetes/typed/core/v1"
)
var (
svcNameLabel = "svccontroller." + version.Program + ".cattle.io/svcname"
daemonsetNodeLabel = "svccontroller." + version.Program + ".cattle.io/enablelb"
nodeSelectorLabel = "svccontroller." + version.Program + ".cattle.io/nodeselector"
)
const (
image = "rancher/klipper-lb:v0.1.2"
svcNameLabel = "svccontroller.k3s.cattle.io/svcname"
daemonsetNodeLabel = "svccontroller.k3s.cattle.io/enablelb"
nodeSelectorLabel = "svccontroller.k3s.cattle.io/nodeselector"
Ready = condition.Cond("Ready")
image = "rancher/klipper-lb:v0.1.2"
Ready = condition.Cond("Ready")
)
var (

8
pkg/version/version.go

@ -1,6 +1,10 @@
package version
import "strings"
var (
Version = "dev"
GitCommit = "HEAD"
Program = "k3s"
ProgramUpper = strings.ToUpper("k3s")
Version = "dev"
GitCommit = "HEAD"
)

Loading…
Cancel
Save