Skip to content

Commit 9eb71cf

Browse files
Merge pull request #1 from ibuildthecloud/master
Dynamically lookup k3s and Rancher versions from channel servers
2 parents 26ef33a + 5cdadb3 commit 9eb71cf

File tree

9 files changed

+163
-26
lines changed

9 files changed

+163
-26
lines changed

cmd/rancherd/main.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ import (
1010
"github.com/spf13/cobra"
1111
)
1212

13-
type App struct {
13+
type Rancherd struct {
1414
}
1515

16-
func (a *App) Run(cmd *cobra.Command, args []string) error {
16+
func (a *Rancherd) Run(cmd *cobra.Command, args []string) error {
1717
return cmd.Help()
1818
}
1919

2020
func main() {
21-
root := cli.Command(&App{}, cobra.Command{
22-
Long: "Bootstrappin' the whole Ranch",
21+
root := cli.Command(&Rancherd{}, cobra.Command{
22+
Long: "Bootstrap Rancher and k3s/rke2 on a node",
2323
})
2424
root.AddCommand(
2525
bootstrap.NewBootstrap(),

cmd/rancherd/probe/probe.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import (
1111

1212
func NewProbe() *cobra.Command {
1313
return cli.Command(&Probe{}, cobra.Command{
14-
Short: "Run plan probes",
14+
Short: "Run plan probes",
15+
Hidden: true,
1516
})
1617
}
1718

cmd/rancherd/retry/retry.go

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ func NewRetry() *cobra.Command {
1212
return cli.Command(&Retry{}, cobra.Command{
1313
Short: "Retry command until it succeeds",
1414
DisableFlagParsing: true,
15+
Hidden: true,
1516
})
1617
}
1718

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ require (
4141
github.com/spf13/cobra v1.1.3
4242
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
4343
gopkg.in/yaml.v2 v2.4.0
44+
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
4445
k8s.io/api v0.21.0
4546
k8s.io/apimachinery v0.21.0
4647
k8s.io/client-go v12.0.0+incompatible

pkg/plan/bootstrap.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ func toJoinPlan(cfg *config.Config, dataDir string) (*applyinator.Plan, error) {
4242
}
4343

4444
plan := plan{}
45-
k8sVersion := versions.K8sVersion(cfg)
45+
k8sVersion, err := versions.K8sVersion(cfg)
46+
if err != nil {
47+
return nil, err
48+
}
4649

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

6972
func (p *plan) addInstructions(cfg *config.Config, dataDir string) error {
70-
k8sVersion := versions.K8sVersion(cfg)
73+
k8sVersion, err := versions.K8sVersion(cfg)
74+
if err != nil {
75+
return err
76+
}
77+
7178
if err := p.addInstruction(runtime.ToInstruction(cfg.RuntimeInstallerImage, cfg.SystemDefaultRegistry, k8sVersion)); err != nil {
7279
return err
7380
}
@@ -76,7 +83,10 @@ func (p *plan) addInstructions(cfg *config.Config, dataDir string) error {
7683
return err
7784
}
7885

79-
rancherVersion := versions.RancherVersion(cfg)
86+
rancherVersion, err := versions.RancherVersion(cfg)
87+
if err != nil {
88+
return err
89+
}
8090
if err := p.addInstruction(rancher.ToInstruction(cfg.RancherInstallerImage, cfg.SystemDefaultRegistry, k8sVersion, rancherVersion, dataDir)); err != nil {
8191
return err
8292
}
@@ -102,7 +112,10 @@ func (p *plan) addInstruction(instruction *applyinator.Instruction, err error) e
102112
}
103113

104114
func (p *plan) addFiles(cfg *config.Config, dataDir string) error {
105-
k8sVersions := versions.K8sVersion(cfg)
115+
k8sVersions, err := versions.K8sVersion(cfg)
116+
if err != nil {
117+
return err
118+
}
106119
runtimeName := config.GetRuntime(k8sVersions)
107120

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

145158
func (p *plan) addProbesForRoles(cfg *config.Config) error {
146-
k8sVersion := versions.K8sVersion(cfg)
159+
k8sVersion, err := versions.K8sVersion(cfg)
160+
if err != nil {
161+
return err
162+
}
147163
p.Probes = probe.ProbesForRole(&cfg.RuntimeConfig, config.GetRuntime(k8sVersion))
148164
return nil
149165
}
150166

151167
func (p *plan) addProbes(cfg *config.Config) error {
152-
k8sVersion := versions.K8sVersion(cfg)
168+
k8sVersion, err := versions.K8sVersion(cfg)
169+
if err != nil {
170+
return err
171+
}
153172
p.Probes = probe.AllProbes(config.GetRuntime(k8sVersion))
154173
return nil
155174
}

pkg/plan/run.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ import (
1818
)
1919

2020
func Run(ctx context.Context, cfg *config.Config, plan *applyinator.Plan, dataDir string) error {
21-
k8sVersion := versions.K8sVersion(cfg)
21+
k8sVersion, err := versions.K8sVersion(cfg)
22+
if err != nil {
23+
return err
24+
}
2225
runtime := config.GetRuntime(k8sVersion)
2326

2427
if err := writePlan(plan, dataDir); err != nil {

pkg/rancherd/rancher.go

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/rancher/rancherd/pkg/config"
1111
"github.com/rancher/rancherd/pkg/plan"
12+
"github.com/rancher/rancherd/pkg/versions"
1213
"github.com/sirupsen/logrus"
1314
"sigs.k8s.io/yaml"
1415
)
@@ -44,6 +45,18 @@ func (r *Rancherd) execute(ctx context.Context) error {
4445
return nil
4546
}
4647

48+
k8sVersion, err := versions.K8sVersion(&cfg)
49+
if err != nil {
50+
return err
51+
}
52+
53+
rancherVersion, err := versions.RancherVersion(&cfg)
54+
if err != nil {
55+
return err
56+
}
57+
58+
logrus.Infof("Bootstrapping Rancher (%s/%s)", rancherVersion, k8sVersion)
59+
4760
nodePlan, err := plan.ToPlan(&cfg, r.cfg.DataDir)
4861
if err != nil {
4962
return fmt.Errorf("generating plan: %w", err)
@@ -105,6 +118,7 @@ func (r *Rancherd) setDone(cfg config.Config) error {
105118

106119
func (r *Rancherd) done() (bool, error) {
107120
if r.cfg.Force {
121+
_ = os.Remove(r.DoneStamp())
108122
return false, nil
109123
}
110124
_, err := os.Stat(r.DoneStamp())

pkg/resources/resources.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ func ToBootstrapFile(config *config.Config, path string) (*applyinator.File, err
2929
nodeName = strings.Split(hostname, ".")[0]
3030
}
3131

32-
var (
33-
k8sVersion = versions.K8sVersion(config)
34-
token = config.Token
35-
err error
36-
)
32+
k8sVersion, err := versions.K8sVersion(config)
33+
if err != nil {
34+
return nil, err
35+
}
36+
37+
token := config.Token
3738
if token == "" {
3839
token, err = randomtoken.Generate()
3940
if err != nil {

pkg/versions/versions.go

+106-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,114 @@
11
package versions
22

3-
import "github.com/rancher/rancherd/pkg/config"
3+
import (
4+
"fmt"
5+
"net/http"
6+
"path"
7+
"strings"
8+
"sync"
49

5-
func K8sVersion(config *config.Config) string {
6-
if config.KubernetesVersion == "" {
7-
return "v1.21.1+k3s1"
10+
"github.com/rancher/rancherd/pkg/config"
11+
"gopkg.in/yaml.v3"
12+
)
13+
14+
var (
15+
cachedK8sVersion = map[string]string{}
16+
cachedRancherVersion = map[string]string{}
17+
cachedLock sync.Mutex
18+
redirectClient = &http.Client{
19+
CheckRedirect: func(req *http.Request, via []*http.Request) error {
20+
return http.ErrUseLastResponse
21+
},
22+
}
23+
)
24+
25+
func getVersionOrURL(urlFormat, def, version string) (_ string, isURL bool) {
26+
if version == "" {
27+
version = def
28+
}
29+
30+
if strings.HasPrefix(version, "v") && len(strings.Split(version, ".")) > 2 {
31+
return version, false
32+
}
33+
34+
channelURL := version
35+
if !strings.HasPrefix(channelURL, "https://") &&
36+
!strings.HasPrefix(channelURL, "http://") {
37+
if strings.HasSuffix(channelURL, "-head") {
38+
return channelURL, false
39+
}
40+
channelURL = fmt.Sprintf(urlFormat, version)
841
}
9-
return config.KubernetesVersion
42+
43+
return channelURL, true
1044
}
1145

12-
func RancherVersion(config *config.Config) string {
13-
if config.RancherVersion == "" {
14-
return "master-head"
46+
func K8sVersion(config *config.Config) (string, error) {
47+
cachedLock.Lock()
48+
defer cachedLock.Unlock()
49+
50+
cached, ok := cachedK8sVersion[config.KubernetesVersion]
51+
if ok {
52+
return cached, nil
53+
}
54+
55+
versionOrURL, isURL := getVersionOrURL("https://update.k3s.io/v1-release/channels/%s", "testing", config.KubernetesVersion)
56+
if !isURL {
57+
return versionOrURL, nil
58+
}
59+
60+
resp, err := redirectClient.Get(versionOrURL)
61+
if err != nil {
62+
return "", fmt.Errorf("getting channel version from (%s): %w", versionOrURL, err)
63+
}
64+
defer resp.Body.Close()
65+
66+
url, err := resp.Location()
67+
if err != nil {
68+
return "", fmt.Errorf("getting channel version URL from (%s): %w", versionOrURL, err)
1569
}
16-
return config.RancherVersion
70+
71+
versionOrURL = path.Base(url.Path)
72+
cachedK8sVersion[config.KubernetesVersion] = versionOrURL
73+
return versionOrURL, nil
74+
}
75+
76+
func RancherVersion(config *config.Config) (string, error) {
77+
cachedLock.Lock()
78+
defer cachedLock.Unlock()
79+
80+
cached, ok := cachedRancherVersion[config.RancherVersion]
81+
if ok {
82+
return cached, nil
83+
}
84+
85+
versionOrURL, isURL := getVersionOrURL("https://releases.rancher.com/server-charts/%s/index.yaml", "master-head", config.RancherVersion)
86+
if !isURL {
87+
return versionOrURL, nil
88+
}
89+
90+
resp, err := http.Get(versionOrURL)
91+
if err != nil {
92+
return "", fmt.Errorf("getting rancher channel version from (%s): %w", versionOrURL, err)
93+
}
94+
defer resp.Body.Close()
95+
96+
index := &chartIndex{}
97+
if err := yaml.NewDecoder(resp.Body).Decode(index); err != nil {
98+
return "", fmt.Errorf("unmarshalling rancher channel version from (%s): %w", versionOrURL, err)
99+
}
100+
101+
versions := index.Entries["rancher"]
102+
if len(versions) == 0 {
103+
return "", fmt.Errorf("failed to find version for rancher chart at (%s)", versionOrURL)
104+
}
105+
106+
cachedRancherVersion[config.RancherVersion] = versions[0].Version
107+
return versions[0].Version, nil
108+
}
109+
110+
type chartIndex struct {
111+
Entries map[string][]struct {
112+
Version string `yaml:"version"`
113+
} `yaml:"entries"`
17114
}

0 commit comments

Comments
 (0)