Skip to content

Commit

Permalink
Merge pull request #1 from ibuildthecloud/master
Browse files Browse the repository at this point in the history
Dynamically lookup k3s and Rancher versions from channel servers
  • Loading branch information
ibuildthecloud authored Jun 16, 2021
2 parents 26ef33a + 5cdadb3 commit 9eb71cf
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 26 deletions.
8 changes: 4 additions & 4 deletions cmd/rancherd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
"github.com/spf13/cobra"
)

type App struct {
type Rancherd struct {
}

func (a *App) Run(cmd *cobra.Command, args []string) error {
func (a *Rancherd) Run(cmd *cobra.Command, args []string) error {
return cmd.Help()
}

func main() {
root := cli.Command(&App{}, cobra.Command{
Long: "Bootstrappin' the whole Ranch",
root := cli.Command(&Rancherd{}, cobra.Command{
Long: "Bootstrap Rancher and k3s/rke2 on a node",
})
root.AddCommand(
bootstrap.NewBootstrap(),
Expand Down
3 changes: 2 additions & 1 deletion cmd/rancherd/probe/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (

func NewProbe() *cobra.Command {
return cli.Command(&Probe{}, cobra.Command{
Short: "Run plan probes",
Short: "Run plan probes",
Hidden: true,
})
}

Expand Down
1 change: 1 addition & 0 deletions cmd/rancherd/retry/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func NewRetry() *cobra.Command {
return cli.Command(&Retry{}, cobra.Command{
Short: "Retry command until it succeeds",
DisableFlagParsing: true,
Hidden: true,
})
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ require (
github.com/spf13/cobra v1.1.3
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
k8s.io/api v0.21.0
k8s.io/apimachinery v0.21.0
k8s.io/client-go v12.0.0+incompatible
Expand Down
31 changes: 25 additions & 6 deletions pkg/plan/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ func toJoinPlan(cfg *config.Config, dataDir string) (*applyinator.Plan, error) {
}

plan := plan{}
k8sVersion := versions.K8sVersion(cfg)
k8sVersion, err := versions.K8sVersion(cfg)
if err != nil {
return nil, err
}

if err := plan.addFile(runtime.ToFile(&cfg.RuntimeConfig, config.GetRuntime(k8sVersion), false)); err != nil {
return nil, err
Expand All @@ -67,7 +70,11 @@ func ToPlan(config *config.Config, dataDir string) (*applyinator.Plan, error) {
}

func (p *plan) addInstructions(cfg *config.Config, dataDir string) error {
k8sVersion := versions.K8sVersion(cfg)
k8sVersion, err := versions.K8sVersion(cfg)
if err != nil {
return err
}

if err := p.addInstruction(runtime.ToInstruction(cfg.RuntimeInstallerImage, cfg.SystemDefaultRegistry, k8sVersion)); err != nil {
return err
}
Expand All @@ -76,7 +83,10 @@ func (p *plan) addInstructions(cfg *config.Config, dataDir string) error {
return err
}

rancherVersion := versions.RancherVersion(cfg)
rancherVersion, err := versions.RancherVersion(cfg)
if err != nil {
return err
}
if err := p.addInstruction(rancher.ToInstruction(cfg.RancherInstallerImage, cfg.SystemDefaultRegistry, k8sVersion, rancherVersion, dataDir)); err != nil {
return err
}
Expand All @@ -102,7 +112,10 @@ func (p *plan) addInstruction(instruction *applyinator.Instruction, err error) e
}

func (p *plan) addFiles(cfg *config.Config, dataDir string) error {
k8sVersions := versions.K8sVersion(cfg)
k8sVersions, err := versions.K8sVersion(cfg)
if err != nil {
return err
}
runtimeName := config.GetRuntime(k8sVersions)

// config.yaml
Expand Down Expand Up @@ -143,13 +156,19 @@ func (p *plan) addFile(file *applyinator.File, err error) error {
}

func (p *plan) addProbesForRoles(cfg *config.Config) error {
k8sVersion := versions.K8sVersion(cfg)
k8sVersion, err := versions.K8sVersion(cfg)
if err != nil {
return err
}
p.Probes = probe.ProbesForRole(&cfg.RuntimeConfig, config.GetRuntime(k8sVersion))
return nil
}

func (p *plan) addProbes(cfg *config.Config) error {
k8sVersion := versions.K8sVersion(cfg)
k8sVersion, err := versions.K8sVersion(cfg)
if err != nil {
return err
}
p.Probes = probe.AllProbes(config.GetRuntime(k8sVersion))
return nil
}
5 changes: 4 additions & 1 deletion pkg/plan/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import (
)

func Run(ctx context.Context, cfg *config.Config, plan *applyinator.Plan, dataDir string) error {
k8sVersion := versions.K8sVersion(cfg)
k8sVersion, err := versions.K8sVersion(cfg)
if err != nil {
return err
}
runtime := config.GetRuntime(k8sVersion)

if err := writePlan(plan, dataDir); err != nil {
Expand Down
14 changes: 14 additions & 0 deletions pkg/rancherd/rancher.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/rancher/rancherd/pkg/config"
"github.com/rancher/rancherd/pkg/plan"
"github.com/rancher/rancherd/pkg/versions"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -44,6 +45,18 @@ func (r *Rancherd) execute(ctx context.Context) error {
return nil
}

k8sVersion, err := versions.K8sVersion(&cfg)
if err != nil {
return err
}

rancherVersion, err := versions.RancherVersion(&cfg)
if err != nil {
return err
}

logrus.Infof("Bootstrapping Rancher (%s/%s)", rancherVersion, k8sVersion)

nodePlan, err := plan.ToPlan(&cfg, r.cfg.DataDir)
if err != nil {
return fmt.Errorf("generating plan: %w", err)
Expand Down Expand Up @@ -105,6 +118,7 @@ func (r *Rancherd) setDone(cfg config.Config) error {

func (r *Rancherd) done() (bool, error) {
if r.cfg.Force {
_ = os.Remove(r.DoneStamp())
return false, nil
}
_, err := os.Stat(r.DoneStamp())
Expand Down
11 changes: 6 additions & 5 deletions pkg/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ func ToBootstrapFile(config *config.Config, path string) (*applyinator.File, err
nodeName = strings.Split(hostname, ".")[0]
}

var (
k8sVersion = versions.K8sVersion(config)
token = config.Token
err error
)
k8sVersion, err := versions.K8sVersion(config)
if err != nil {
return nil, err
}

token := config.Token
if token == "" {
token, err = randomtoken.Generate()
if err != nil {
Expand Down
115 changes: 106 additions & 9 deletions pkg/versions/versions.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,114 @@
package versions

import "github.com/rancher/rancherd/pkg/config"
import (
"fmt"
"net/http"
"path"
"strings"
"sync"

func K8sVersion(config *config.Config) string {
if config.KubernetesVersion == "" {
return "v1.21.1+k3s1"
"github.com/rancher/rancherd/pkg/config"
"gopkg.in/yaml.v3"
)

var (
cachedK8sVersion = map[string]string{}
cachedRancherVersion = map[string]string{}
cachedLock sync.Mutex
redirectClient = &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
)

func getVersionOrURL(urlFormat, def, version string) (_ string, isURL bool) {
if version == "" {
version = def
}

if strings.HasPrefix(version, "v") && len(strings.Split(version, ".")) > 2 {
return version, false
}

channelURL := version
if !strings.HasPrefix(channelURL, "https://") &&
!strings.HasPrefix(channelURL, "http://") {
if strings.HasSuffix(channelURL, "-head") {
return channelURL, false
}
channelURL = fmt.Sprintf(urlFormat, version)
}
return config.KubernetesVersion

return channelURL, true
}

func RancherVersion(config *config.Config) string {
if config.RancherVersion == "" {
return "master-head"
func K8sVersion(config *config.Config) (string, error) {
cachedLock.Lock()
defer cachedLock.Unlock()

cached, ok := cachedK8sVersion[config.KubernetesVersion]
if ok {
return cached, nil
}

versionOrURL, isURL := getVersionOrURL("https://update.k3s.io/v1-release/channels/%s", "testing", config.KubernetesVersion)
if !isURL {
return versionOrURL, nil
}

resp, err := redirectClient.Get(versionOrURL)
if err != nil {
return "", fmt.Errorf("getting channel version from (%s): %w", versionOrURL, err)
}
defer resp.Body.Close()

url, err := resp.Location()
if err != nil {
return "", fmt.Errorf("getting channel version URL from (%s): %w", versionOrURL, err)
}
return config.RancherVersion

versionOrURL = path.Base(url.Path)
cachedK8sVersion[config.KubernetesVersion] = versionOrURL
return versionOrURL, nil
}

func RancherVersion(config *config.Config) (string, error) {
cachedLock.Lock()
defer cachedLock.Unlock()

cached, ok := cachedRancherVersion[config.RancherVersion]
if ok {
return cached, nil
}

versionOrURL, isURL := getVersionOrURL("https://releases.rancher.com/server-charts/%s/index.yaml", "master-head", config.RancherVersion)
if !isURL {
return versionOrURL, nil
}

resp, err := http.Get(versionOrURL)
if err != nil {
return "", fmt.Errorf("getting rancher channel version from (%s): %w", versionOrURL, err)
}
defer resp.Body.Close()

index := &chartIndex{}
if err := yaml.NewDecoder(resp.Body).Decode(index); err != nil {
return "", fmt.Errorf("unmarshalling rancher channel version from (%s): %w", versionOrURL, err)
}

versions := index.Entries["rancher"]
if len(versions) == 0 {
return "", fmt.Errorf("failed to find version for rancher chart at (%s)", versionOrURL)
}

cachedRancherVersion[config.RancherVersion] = versions[0].Version
return versions[0].Version, nil
}

type chartIndex struct {
Entries map[string][]struct {
Version string `yaml:"version"`
} `yaml:"entries"`
}

0 comments on commit 9eb71cf

Please sign in to comment.