Skip to content
This repository was archived by the owner on Feb 5, 2020. It is now read-only.
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ docker run \
-v /etc/kubernetes:/etc/kubernetes \
-v /var/run/dbus:/var/run/dbus \
-v /usr/share/coreos/os-release:/usr/share/coreos/os-release \
-v /usr/lib/os-release:/usr/lib/os-release \
quay.io/casey_callendrello/torcx-tectonic-bootstrap-amd64 \
--verbose=debug
```
Expand Down
109 changes: 101 additions & 8 deletions internal/kube_version.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package internal

import (
"io/ioutil"
"bufio"
"fmt"
"os"
"strings"

"github.com/Sirupsen/logrus"
"github.com/pkg/errors"
Expand All @@ -10,8 +13,69 @@ import (
"k8s.io/client-go/tools/clientcmd"
)

// KubeVersion connects to the APIServer and determines the kubernetes version
const (
// installerEnvPath is the env file written by tectonic-installer
installerEnvPath = "/etc/kubernetes/installer/kubelet.env"
// envVersionKey is the key for the version flag
envVersionKey = "KUBELET_IMAGE_TAG"
// kubeletEnvPath is the env file sourced by `kubelet.service`
kubeletEnvPath = "/etc/kubernetes/kubelet.env"
)

// WriteKubeletEnv writes the `kubelet.env` file
func (a *App) WriteKubeletEnv(destPath string, k8sVersion string) error {
// This reverse charset constraints in docker tags (for the hyperkube image)
kubeletVersion := strings.Replace(k8sVersion, "+", "_", -1)

flags, err := readEnvFile(installerEnvPath)
if err != nil {
return nil
}

dstFp, err := os.Create(destPath)
if err != nil {
return nil
}
defer dstFp.Close()

for k, v := range flags {
if k == envVersionKey && kubeletVersion != "" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to add the versionKey if its not present in the file?

@lucab lucab Aug 11, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmh, an emergency fallback would not hurt.

After some more thinking, I prefer to let the kubelet service fail to start in such cases. Otherwise debugging what's wrong here can be quite hard.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's reasonable.

v = kubeletVersion
}
fmt.Fprintf(dstFp, "%s=%s\n", k, v)
}

return nil
}

// GetKubeVersion retrieves kubernetes version querying several sources:
// 1. a custom/forced version string
// 2. GitVersion of the remote API-server `/version`
// 3. hyperkube version (from its container tag)
func (a *App) GetKubeVersion() (string, error) {
if a.Conf.ForceKubeVersion != "" {
return a.Conf.ForceKubeVersion, nil
}

apiVersion, apiErr := a.versionFromAPIServer()
if apiErr == nil {
return apiVersion, nil
}
logrus.Debug("failed attempt to determine Kubernetes APIServer version: ", apiErr)

pathVersion, pathErr := a.versionFromPath(installerEnvPath, envVersionKey)
if pathErr == nil {
// This accomodates for charset constraints in docker tags (for the hyperkube image)
version := strings.Replace(pathVersion, "_", "+", -1)
return version, nil
}
logrus.Debug("failed attempt to determine Kubernetes installer version: ", pathErr)

return "", errors.New("unable to determine cluster version")
}

// versionFromAPIServer connects to the APIServer and determines the kubernetes version
func (a *App) versionFromAPIServer() (string, error) {
logrus.Info("Determining kubernetes version")
config, err := clientcmd.BuildConfigFromFlags("", a.Conf.Kubeconfig)
if err != nil {
Expand All @@ -30,13 +94,42 @@ func (a *App) GetKubeVersion() (string, error) {
logrus.Debug("Got kubernetes version ", version.GitVersion)

return version.GitVersion, nil
}

// versionFromPath reads Kubernetes version from a file
func (a *App) versionFromPath(path string, envKey string) (string, error) {
flags, err := readEnvFile(path)
if err != nil {
return "", err
}

version, ok := flags[envKey]
if ok && version != "" {
return version, nil
}

return "", errors.Errorf("no %q flag found in %q", envKey, path)
}

// WriteKubeVersion writes the kube version file.
// This should be done when everything has been successfully installed,
// so that the kubelet will start on boot.
func (a *App) WriteKubeVersion(version string) error {
// XXX Do same formatting as the old unit file
return ioutil.WriteFile(a.Conf.KubeVersionPath, []byte(version), 0644)
// readEnvFile reads a systemd env file and returns a map with
// the environment flags.
func readEnvFile(envPath string) (map[string]string, error) {
env := make(map[string]string)

fp, err := os.Open(envPath)
if err != nil {
return env, err
}
defer fp.Close()

sc := bufio.NewScanner(fp)
for sc.Scan() {
line := sc.Text()
tokens := strings.SplitN(line, "=", 2)
if len(tokens) == 2 {
env[tokens[0]] = strings.Trim(tokens[1], `"`)
}
}

return env, nil
}
18 changes: 6 additions & 12 deletions internal/torcx.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,11 @@ func (a *App) Run() error {
return err
}

var k8sVersion string
if a.Conf.ForceKubeVersion != "" {
k8sVersion = a.Conf.ForceKubeVersion
} else {
var err error
k8sVersion, err = a.GetKubeVersion()
if err != nil {
return err
}
k8sVersion, err := a.GetKubeVersion()
if err != nil {
return err
}
logrus.Infof("running on Kubernetes version %q", k8sVersion)

dockerVersion, err := DockerVersionFor(k8sVersion)
if err != nil {
Expand All @@ -118,12 +113,11 @@ func (a *App) Run() error {
return err
}

// Writing the kubeversion file will block our systemd unit from running
// so it's how we mark completion
err = a.WriteKubeVersion(k8sVersion)
err = a.WriteKubeletEnv(kubeletEnvPath, k8sVersion)
if err != nil {
return err
}

return nil
}

Expand Down