mirror of
https://github.com/kairos-io/provider-rke2.git
synced 2025-09-25 12:16:55 +00:00
PE-5129 PE-5115 feat: support custom cluster root path and cluster reset event (#71)
* feat: support custom cluster root path Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com> * chore(dep): bump yaml from v2 to v3 Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com> * ci: update gcr push token Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com> * support cluster reset event Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com> * fix: use ubuntu-22.04 as runner Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com> --------- Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com>
This commit is contained in:
4
.github/workflows/provider-packaging.yaml
vendored
4
.github/workflows/provider-packaging.yaml
vendored
@@ -11,7 +11,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
version: "latest"
|
version: "latest"
|
||||||
- run: earthly --ci +lint
|
- run: earthly --ci +lint
|
||||||
build-provider-package:
|
build-provider-package:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
|
2
.github/workflows/pull_request.yaml
vendored
2
.github/workflows/pull_request.yaml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
version: "latest"
|
version: "latest"
|
||||||
- run: earthly --ci +lint
|
- run: earthly --ci +lint
|
||||||
build-provider-package:
|
build-provider-package:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
|
@@ -3,6 +3,11 @@
|
|||||||
# You can by pass commit hooks with:
|
# You can by pass commit hooks with:
|
||||||
# git commit -n
|
# git commit -n
|
||||||
repos:
|
repos:
|
||||||
|
- repo: https://github.com/compilerla/conventional-pre-commit
|
||||||
|
rev: v2.4.0
|
||||||
|
hooks:
|
||||||
|
- id: conventional-pre-commit
|
||||||
|
stages: [commit-msg]
|
||||||
- repo: https://github.com/tekwizely/pre-commit-golang
|
- repo: https://github.com/tekwizely/pre-commit-golang
|
||||||
rev: v1.0.0-rc.1
|
rev: v1.0.0-rc.1
|
||||||
hooks:
|
hooks:
|
||||||
|
@@ -5,8 +5,8 @@ ARG BASE_IMAGE=quay.io/kairos/core-opensuse-leap:v2.4.3
|
|||||||
ARG IMAGE_REPOSITORY=quay.io/kairos
|
ARG IMAGE_REPOSITORY=quay.io/kairos
|
||||||
|
|
||||||
ARG LUET_VERSION=0.35.1
|
ARG LUET_VERSION=0.35.1
|
||||||
ARG GOLINT_VERSION=v1.56.2
|
ARG GOLINT_VERSION=v1.61.0
|
||||||
ARG GOLANG_VERSION=1.22
|
ARG GOLANG_VERSION=1.23
|
||||||
|
|
||||||
ARG RKE2_VERSION=latest
|
ARG RKE2_VERSION=latest
|
||||||
ARG BASE_IMAGE_NAME=$(echo $BASE_IMAGE | grep -o [^/]*: | rev | cut -c2- | rev)
|
ARG BASE_IMAGE_NAME=$(echo $BASE_IMAGE | grep -o [^/]*: | rev | cut -c2- | rev)
|
||||||
@@ -55,7 +55,7 @@ VERSION:
|
|||||||
|
|
||||||
COPY . ./
|
COPY . ./
|
||||||
|
|
||||||
RUN echo $(git describe --exact-match --tags || echo "v0.0.0-$(git log --oneline -n 1 | cut -d" " -f1)") > VERSION
|
RUN echo $(git describe --exact-match --tags || echo "v0.0.0-$(git rev-parse --short=8 HEAD)") > VERSION
|
||||||
|
|
||||||
SAVE ARTIFACT VERSION VERSION
|
SAVE ARTIFACT VERSION VERSION
|
||||||
|
|
||||||
|
11
go.mod
11
go.mod
@@ -1,12 +1,12 @@
|
|||||||
module github.com/c3os-io/c3os/provider-rke2
|
module github.com/c3os-io/c3os/provider-rke2
|
||||||
|
|
||||||
go 1.22.5
|
go 1.23.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/kairos-io/kairos-sdk v0.4.2
|
github.com/kairos-io/kairos-sdk v0.5.0
|
||||||
github.com/mudler/yip v1.9.4
|
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5
|
||||||
|
github.com/mudler/yip v1.10.0
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.4.0
|
||||||
)
|
)
|
||||||
@@ -20,7 +20,6 @@ require (
|
|||||||
github.com/itchyny/gojq v0.12.16 // indirect
|
github.com/itchyny/gojq v0.12.16 // indirect
|
||||||
github.com/itchyny/timefmt-go v0.1.6 // indirect
|
github.com/itchyny/timefmt-go v0.1.6 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 // indirect
|
|
||||||
github.com/nxadm/tail v1.4.8 // indirect
|
github.com/nxadm/tail v1.4.8 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||||
@@ -28,5 +27,5 @@ require (
|
|||||||
github.com/twpayne/go-vfs/v4 v4.3.0 // indirect
|
github.com/twpayne/go-vfs/v4 v4.3.0 // indirect
|
||||||
golang.org/x/sys v0.24.0 // indirect
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
12
go.sum
12
go.sum
@@ -40,8 +40,8 @@ github.com/itchyny/gojq v0.12.16 h1:yLfgLxhIr/6sJNVmYfQjTIv0jGctu6/DgDoivmxTr7g=
|
|||||||
github.com/itchyny/gojq v0.12.16/go.mod h1:6abHbdC2uB9ogMS38XsErnfqJ94UlngIJGlRAIj4jTM=
|
github.com/itchyny/gojq v0.12.16/go.mod h1:6abHbdC2uB9ogMS38XsErnfqJ94UlngIJGlRAIj4jTM=
|
||||||
github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q=
|
github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q=
|
||||||
github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg=
|
github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg=
|
||||||
github.com/kairos-io/kairos-sdk v0.4.2 h1:tq0a6R9qSotatFt20q/+oIHJSN+XTQWji4XgHk5Vvlw=
|
github.com/kairos-io/kairos-sdk v0.5.0 h1:CtYz2WXe5huKkjPSro2J1kiLVjDr6T9909uckK17Bqw=
|
||||||
github.com/kairos-io/kairos-sdk v0.4.2/go.mod h1:1x8VaVt1ppXxQUlNyDRksoDglR423hxfEtjx6qWDO7w=
|
github.com/kairos-io/kairos-sdk v0.5.0/go.mod h1:RO5ad3gCd2O2zJE5mEnPHLUy/+fRKKQL4fe7xV6FtyA=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
@@ -51,8 +51,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mVt7lh9glAryzQblMsbJYU2VnrdZ8yHlTs=
|
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5 h1:FaZD86+A9mVt7lh9glAryzQblMsbJYU2VnrdZ8yHlTs=
|
||||||
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI=
|
github.com/mudler/go-pluggable v0.0.0-20230126220627-7710299a0ae5/go.mod h1:WmKcT8ONmhDQIqQ+HxU+tkGWjzBEyY/KFO8LTGCu4AI=
|
||||||
github.com/mudler/yip v1.9.4 h1:yaiPKWG5kt/DTNCf7ZGfyWdb1j5c06zYqWF3F+SVKsE=
|
github.com/mudler/yip v1.10.0 h1:MwEIySEfSRRwTUz2BmQQpRn6+M7jqVGf/OldsepBvz0=
|
||||||
github.com/mudler/yip v1.9.4/go.mod h1:nqf8JFCq7a7rIkm7cSs+SOc8QbiyvVJ/xLbUw4GgzFs=
|
github.com/mudler/yip v1.10.0/go.mod h1:gwH7iGcr1Jimox2xKtN2AprEO00GzY7smvuycqCL7+Y=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
@@ -127,8 +127,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
|
|||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=
|
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
@@ -136,7 +134,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
|
||||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||||
|
219
main.go
219
main.go
@@ -1,226 +1,21 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"github.com/c3os-io/c3os/provider-rke2/pkg/provider"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/kairos-io/kairos-sdk/clusterplugin"
|
"github.com/kairos-io/kairos-sdk/clusterplugin"
|
||||||
yip "github.com/mudler/yip/pkg/schema"
|
"github.com/mudler/go-pluggable"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
kyaml "sigs.k8s.io/yaml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
configurationPath = "/etc/rancher/rke2/config.d"
|
|
||||||
containerdEnvConfigPath = "/etc/default"
|
|
||||||
|
|
||||||
serverSystemName = "rke2-server"
|
|
||||||
agentSystemName = "rke2-agent"
|
|
||||||
K8SNoProxy = ".svc,.svc.cluster,.svc.cluster.local"
|
|
||||||
localImagesPath = "/opt/content/images"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RKE2Config struct {
|
|
||||||
Token string `yaml:"token"`
|
|
||||||
Server string `yaml:"server"`
|
|
||||||
TLSSan []string `yaml:"tls-san"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func clusterProvider(cluster clusterplugin.Cluster) yip.YipConfig {
|
|
||||||
|
|
||||||
var importStage yip.Stage
|
|
||||||
rke2Config := RKE2Config{
|
|
||||||
Token: cluster.ClusterToken,
|
|
||||||
// RKE2 server listens on 9345 for node registration https://docs.rke2.io/install/quickstart/#3-configure-the-rke2-agent-service
|
|
||||||
Server: fmt.Sprintf("https://%s:9345", cluster.ControlPlaneHost),
|
|
||||||
TLSSan: []string{
|
|
||||||
cluster.ControlPlaneHost,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if cluster.Role == clusterplugin.RoleInit {
|
|
||||||
rke2Config.Server = ""
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
systemName := serverSystemName
|
|
||||||
if cluster.Role == clusterplugin.RoleWorker {
|
|
||||||
systemName = agentSystemName
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure we always have a valid user config
|
|
||||||
if cluster.Options == "" {
|
|
||||||
cluster.Options = "{}"
|
|
||||||
}
|
|
||||||
|
|
||||||
var providerConfig bytes.Buffer
|
|
||||||
_ = yaml.NewEncoder(&providerConfig).Encode(&rke2Config)
|
|
||||||
|
|
||||||
userOptions, _ := kyaml.YAMLToJSON([]byte(cluster.Options))
|
|
||||||
options, _ := kyaml.YAMLToJSON(providerConfig.Bytes())
|
|
||||||
|
|
||||||
proxyValues := proxyEnv(userOptions, cluster.Env)
|
|
||||||
|
|
||||||
files := []yip.File{
|
|
||||||
{
|
|
||||||
Path: filepath.Join(configurationPath, "90_userdata.yaml"),
|
|
||||||
Permissions: 0400,
|
|
||||||
Content: string(userOptions),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Path: filepath.Join(configurationPath, "99_userdata.yaml"),
|
|
||||||
Permissions: 0400,
|
|
||||||
Content: string(options),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(proxyValues) > 0 {
|
|
||||||
files = append(files, yip.File{
|
|
||||||
Path: filepath.Join(containerdEnvConfigPath, systemName),
|
|
||||||
Permissions: 0400,
|
|
||||||
Content: proxyValues,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
stages := []yip.Stage{
|
|
||||||
{
|
|
||||||
Name: "Install RKE2 Configuration Files",
|
|
||||||
Files: files,
|
|
||||||
|
|
||||||
Commands: []string{
|
|
||||||
fmt.Sprintf("jq -s 'def flatten: reduce .[] as $i([]; if $i | type == \"array\" then . + ($i | flatten) else . + [$i] end); [.[] | to_entries] | flatten | reduce .[] as $dot ({}; .[$dot.key] += $dot.value)' %s/*.yaml > /etc/rancher/rke2/config.yaml", configurationPath),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if cluster.ImportLocalImages {
|
|
||||||
if cluster.LocalImagesPath == "" {
|
|
||||||
cluster.LocalImagesPath = localImagesPath
|
|
||||||
}
|
|
||||||
|
|
||||||
importStage = yip.Stage{
|
|
||||||
Commands: []string{
|
|
||||||
fmt.Sprintf("/bin/sh /opt/rke2/scripts/import.sh %s > /var/log/import.log", cluster.LocalImagesPath),
|
|
||||||
},
|
|
||||||
If: fmt.Sprintf("[ -d %s ]", cluster.LocalImagesPath),
|
|
||||||
}
|
|
||||||
stages = append(stages, importStage)
|
|
||||||
}
|
|
||||||
|
|
||||||
stages = append(stages,
|
|
||||||
yip.Stage{
|
|
||||||
Name: "Waiting to finish extracting content",
|
|
||||||
Commands: []string{
|
|
||||||
"sleep 120",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
yip.Stage{
|
|
||||||
Name: "Enable Systemd Services",
|
|
||||||
Commands: []string{
|
|
||||||
fmt.Sprintf("systemctl enable %s", systemName),
|
|
||||||
fmt.Sprintf("systemctl restart %s", systemName),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
cfg := yip.YipConfig{
|
|
||||||
Name: "RKE2 Kairos Cluster Provider",
|
|
||||||
Stages: map[string][]yip.Stage{
|
|
||||||
"boot.before": stages,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
func proxyEnv(userOptions []byte, proxyMap map[string]string) string {
|
|
||||||
var proxy []string
|
|
||||||
var noProxy string
|
|
||||||
var isProxyConfigured bool
|
|
||||||
|
|
||||||
httpProxy := proxyMap["HTTP_PROXY"]
|
|
||||||
httpsProxy := proxyMap["HTTPS_PROXY"]
|
|
||||||
userNoProxy := proxyMap["NO_PROXY"]
|
|
||||||
defaultNoProxy := getDefaultNoProxy(userOptions)
|
|
||||||
|
|
||||||
if len(httpProxy) > 0 {
|
|
||||||
proxy = append(proxy, fmt.Sprintf("HTTP_PROXY=%s", httpProxy))
|
|
||||||
proxy = append(proxy, fmt.Sprintf("CONTAINERD_HTTP_PROXY=%s", httpProxy))
|
|
||||||
isProxyConfigured = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(httpsProxy) > 0 {
|
|
||||||
proxy = append(proxy, fmt.Sprintf("HTTPS_PROXY=%s", httpsProxy))
|
|
||||||
proxy = append(proxy, fmt.Sprintf("CONTAINERD_HTTPS_PROXY=%s", httpsProxy))
|
|
||||||
isProxyConfigured = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if isProxyConfigured {
|
|
||||||
noProxy = defaultNoProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(userNoProxy) > 0 {
|
|
||||||
noProxy = noProxy + "," + userNoProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(noProxy) > 0 {
|
|
||||||
proxy = append(proxy, fmt.Sprintf("NO_PROXY=%s", noProxy))
|
|
||||||
proxy = append(proxy, fmt.Sprintf("CONTAINERD_NO_PROXY=%s", noProxy))
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(proxy, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getDefaultNoProxy(userOptions []byte) string {
|
|
||||||
|
|
||||||
var noProxy string
|
|
||||||
|
|
||||||
data := make(map[string]interface{})
|
|
||||||
err := json.Unmarshal(userOptions, &data)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("error while unmarshalling user options", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if data != nil {
|
|
||||||
clusterCIDR := data["cluster-cidr"].(string)
|
|
||||||
serviceCIDR := data["service-cidr"].(string)
|
|
||||||
|
|
||||||
if len(clusterCIDR) > 0 {
|
|
||||||
noProxy = noProxy + "," + clusterCIDR
|
|
||||||
}
|
|
||||||
if len(serviceCIDR) > 0 {
|
|
||||||
noProxy = noProxy + "," + serviceCIDR
|
|
||||||
}
|
|
||||||
noProxy = noProxy + "," + getNodeCIDR() + "," + K8SNoProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
return noProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNodeCIDR() string {
|
|
||||||
addrs, _ := net.InterfaceAddrs()
|
|
||||||
var result string
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
|
||||||
if ipnet.IP.To4() != nil {
|
|
||||||
result = addr.String()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
plugin := clusterplugin.ClusterPlugin{
|
plugin := clusterplugin.ClusterPlugin{
|
||||||
Provider: clusterProvider,
|
Provider: provider.ClusterProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := plugin.Run(); err != nil {
|
if err := plugin.Run(pluggable.FactoryPlugin{
|
||||||
|
EventType: clusterplugin.EventClusterReset,
|
||||||
|
PluginHandler: provider.HandleClusterReset,
|
||||||
|
}); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
pkg/constants/constants.go
Normal file
16
pkg/constants/constants.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
ConfigurationPath = "/etc/rancher/rke2/config.d"
|
||||||
|
ContainerdEnvConfigPath = "/etc/default"
|
||||||
|
|
||||||
|
ServerSystemName = "rke2-server"
|
||||||
|
AgentSystemName = "rke2-agent"
|
||||||
|
K8SNoProxy = ".svc,.svc.cluster,.svc.cluster.local"
|
||||||
|
LocalImagesPath = "/opt/content/images"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClusterRootPath = "cluster_root_path"
|
||||||
|
RunSystemdSystemDir = "/run/systemd/system"
|
||||||
|
)
|
206
pkg/provider/provider.go
Normal file
206
pkg/provider/provider.go
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
"github.com/c3os-io/c3os/provider-rke2/pkg/constants"
|
||||||
|
"github.com/c3os-io/c3os/provider-rke2/pkg/types"
|
||||||
|
"github.com/kairos-io/kairos-sdk/clusterplugin"
|
||||||
|
yip "github.com/mudler/yip/pkg/schema"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
kyaml "sigs.k8s.io/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ClusterProvider(cluster clusterplugin.Cluster) yip.YipConfig {
|
||||||
|
var stages []yip.Stage
|
||||||
|
clusterRootPath := getClusterRootPath(cluster)
|
||||||
|
|
||||||
|
rke2Config := types.RKE2Config{
|
||||||
|
Token: cluster.ClusterToken,
|
||||||
|
// RKE2 server listens on 9345 for node registration https://docs.rke2.io/install/quickstart/#3-configure-the-rke2-agent-service
|
||||||
|
Server: fmt.Sprintf("https://%s:9345", cluster.ControlPlaneHost),
|
||||||
|
TLSSan: []string{
|
||||||
|
cluster.ControlPlaneHost,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if cluster.Role == clusterplugin.RoleInit {
|
||||||
|
rke2Config.Server = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
systemName := constants.ServerSystemName
|
||||||
|
if cluster.Role == clusterplugin.RoleWorker {
|
||||||
|
systemName = constants.AgentSystemName
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure we always have a valid user config
|
||||||
|
if cluster.Options == "" {
|
||||||
|
cluster.Options = "{}"
|
||||||
|
}
|
||||||
|
|
||||||
|
var providerConfig bytes.Buffer
|
||||||
|
_ = yaml.NewEncoder(&providerConfig).Encode(&rke2Config)
|
||||||
|
|
||||||
|
userOptions, _ := kyaml.YAMLToJSON([]byte(cluster.Options))
|
||||||
|
options, _ := kyaml.YAMLToJSON(providerConfig.Bytes())
|
||||||
|
|
||||||
|
proxyValues := proxyEnv(userOptions, cluster.Env)
|
||||||
|
|
||||||
|
files := []yip.File{
|
||||||
|
{
|
||||||
|
Path: filepath.Join(constants.ConfigurationPath, "90_userdata.yaml"),
|
||||||
|
Permissions: 0400,
|
||||||
|
Content: string(userOptions),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: filepath.Join(constants.ConfigurationPath, "99_userdata.yaml"),
|
||||||
|
Permissions: 0400,
|
||||||
|
Content: string(options),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(proxyValues) > 0 {
|
||||||
|
files = append(files, yip.File{
|
||||||
|
Path: filepath.Join(constants.ContainerdEnvConfigPath, systemName),
|
||||||
|
Permissions: 0400,
|
||||||
|
Content: proxyValues,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
stages = append(stages, yip.Stage{
|
||||||
|
Name: "Install RKE2 Configuration Files",
|
||||||
|
Files: files,
|
||||||
|
|
||||||
|
Commands: []string{
|
||||||
|
fmt.Sprintf("jq -s 'def flatten: reduce .[] as $i([]; if $i | type == \"array\" then . + ($i | flatten) else . + [$i] end); [.[] | to_entries] | flatten | reduce .[] as $dot ({}; .[$dot.key] += $dot.value)' %s/*.yaml > /etc/rancher/rke2/config.yaml", constants.ConfigurationPath),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if cluster.ImportLocalImages {
|
||||||
|
if cluster.LocalImagesPath == "" {
|
||||||
|
cluster.LocalImagesPath = constants.LocalImagesPath
|
||||||
|
}
|
||||||
|
|
||||||
|
importStage := yip.Stage{
|
||||||
|
Commands: []string{
|
||||||
|
fmt.Sprintf("/bin/sh %s/opt/rke2/scripts/import.sh %s > /var/log/import.log", clusterRootPath, cluster.LocalImagesPath),
|
||||||
|
},
|
||||||
|
If: fmt.Sprintf("[ -d %s ]", cluster.LocalImagesPath),
|
||||||
|
}
|
||||||
|
stages = append(stages, importStage)
|
||||||
|
}
|
||||||
|
|
||||||
|
stages = append(stages,
|
||||||
|
yip.Stage{
|
||||||
|
Name: "Waiting to finish extracting content",
|
||||||
|
Commands: []string{
|
||||||
|
"sleep 120",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yip.Stage{
|
||||||
|
Name: "Enable Systemd Services",
|
||||||
|
Commands: []string{
|
||||||
|
fmt.Sprintf("systemctl enable %s", systemName),
|
||||||
|
fmt.Sprintf("systemctl restart %s", systemName),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
cfg := yip.YipConfig{
|
||||||
|
Name: "RKE2 Kairos Cluster Provider",
|
||||||
|
Stages: map[string][]yip.Stage{
|
||||||
|
"boot.before": stages,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func proxyEnv(userOptions []byte, proxyMap map[string]string) string {
|
||||||
|
var proxy []string
|
||||||
|
var noProxy string
|
||||||
|
var isProxyConfigured bool
|
||||||
|
|
||||||
|
httpProxy := proxyMap["HTTP_PROXY"]
|
||||||
|
httpsProxy := proxyMap["HTTPS_PROXY"]
|
||||||
|
userNoProxy := proxyMap["NO_PROXY"]
|
||||||
|
defaultNoProxy := getDefaultNoProxy(userOptions)
|
||||||
|
|
||||||
|
if len(httpProxy) > 0 {
|
||||||
|
proxy = append(proxy, fmt.Sprintf("HTTP_PROXY=%s", httpProxy))
|
||||||
|
proxy = append(proxy, fmt.Sprintf("CONTAINERD_HTTP_PROXY=%s", httpProxy))
|
||||||
|
isProxyConfigured = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(httpsProxy) > 0 {
|
||||||
|
proxy = append(proxy, fmt.Sprintf("HTTPS_PROXY=%s", httpsProxy))
|
||||||
|
proxy = append(proxy, fmt.Sprintf("CONTAINERD_HTTPS_PROXY=%s", httpsProxy))
|
||||||
|
isProxyConfigured = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if isProxyConfigured {
|
||||||
|
noProxy = defaultNoProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(userNoProxy) > 0 {
|
||||||
|
noProxy = noProxy + "," + userNoProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(noProxy) > 0 {
|
||||||
|
proxy = append(proxy, fmt.Sprintf("NO_PROXY=%s", noProxy))
|
||||||
|
proxy = append(proxy, fmt.Sprintf("CONTAINERD_NO_PROXY=%s", noProxy))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(proxy, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDefaultNoProxy(userOptions []byte) string {
|
||||||
|
|
||||||
|
var noProxy string
|
||||||
|
|
||||||
|
data := make(map[string]interface{})
|
||||||
|
err := json.Unmarshal(userOptions, &data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error while unmarshalling user options", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data != nil {
|
||||||
|
clusterCIDR := data["cluster-cidr"].(string)
|
||||||
|
serviceCIDR := data["service-cidr"].(string)
|
||||||
|
|
||||||
|
if len(clusterCIDR) > 0 {
|
||||||
|
noProxy = noProxy + "," + clusterCIDR
|
||||||
|
}
|
||||||
|
if len(serviceCIDR) > 0 {
|
||||||
|
noProxy = noProxy + "," + serviceCIDR
|
||||||
|
}
|
||||||
|
noProxy = noProxy + "," + getNodeCIDR() + "," + constants.K8SNoProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
return noProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNodeCIDR() string {
|
||||||
|
addrs, _ := net.InterfaceAddrs()
|
||||||
|
var result string
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||||
|
if ipnet.IP.To4() != nil {
|
||||||
|
result = addr.String()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func getClusterRootPath(cluster clusterplugin.Cluster) string {
|
||||||
|
return cluster.ProviderOptions[constants.ClusterRootPath]
|
||||||
|
}
|
44
pkg/provider/reset.go
Normal file
44
pkg/provider/reset.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/kairos-io/kairos-sdk/bus"
|
||||||
|
"github.com/kairos-io/kairos-sdk/clusterplugin"
|
||||||
|
"github.com/mudler/go-pluggable"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HandleClusterReset(event *pluggable.Event) pluggable.EventResponse {
|
||||||
|
var payload bus.EventPayload
|
||||||
|
var config clusterplugin.Config
|
||||||
|
var response pluggable.EventResponse
|
||||||
|
|
||||||
|
// parse the boot payload
|
||||||
|
if err := json.Unmarshal([]byte(event.Data), &payload); err != nil {
|
||||||
|
response.Error = fmt.Sprintf("failed to parse boot event: %s", err.Error())
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse config from boot payload
|
||||||
|
if err := yaml.Unmarshal([]byte(payload.Config), &config); err != nil {
|
||||||
|
response.Error = fmt.Sprintf("failed to parse config from boot event: %s", err.Error())
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Cluster == nil {
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterRootPath := getClusterRootPath(*config.Cluster)
|
||||||
|
cmd := exec.Command("/bin/sh", "-c", filepath.Join(clusterRootPath, "/opt/rke2/scripts", "rke2-uninstall.sh"))
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
response.Error = fmt.Sprintf("failed to reset cluster: %s", string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
7
pkg/types/mount.go
Normal file
7
pkg/types/mount.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
type MountPoint struct {
|
||||||
|
Name string
|
||||||
|
Source string
|
||||||
|
Target string
|
||||||
|
}
|
7
pkg/types/rke2.go
Normal file
7
pkg/types/rke2.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
type RKE2Config struct {
|
||||||
|
Token string `yaml:"token"`
|
||||||
|
Server string `yaml:"server"`
|
||||||
|
TLSSan []string `yaml:"tls-san"`
|
||||||
|
}
|
Reference in New Issue
Block a user