diff --git a/.github/workflows/compatibility.yaml b/.github/workflows/compatibility.yaml new file mode 100644 index 0000000000..a759791ccf --- /dev/null +++ b/.github/workflows/compatibility.yaml @@ -0,0 +1,27 @@ +name: Matrix compatibility + +on: + release: + types: [created] + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + go-unit-test: + name: Generate the compatibility matrix + runs-on: ubuntu-22.04 + steps: + - name: Set up Go 1.21 + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: false + - name: Check out code into the Go module directory + uses: actions/checkout@v4 + - name: run compat + run: go run hack/compat-matrix/main.go validate docs/pages/deploying-vclusters/compat-matrix.mdx diff --git a/Justfile b/Justfile index d100edbb17..b17cac5c68 100644 --- a/Justfile +++ b/Justfile @@ -126,3 +126,9 @@ cli version="0.0.0" *ARGS="": # Version the docs for the given version docs-version id="pro" version="1.0.0": yarn docusaurus docs:version {{version}} + +generate-compatibility: + go run hack/compat-matrix/main.go generate docs/pages/deploying-vclusters/compat-matrix.mdx + +validate-compat-matrix: + go run hack/compat-matrix/main.go validate docs/pages/deploying-vclusters/compat-matrix.mdx diff --git a/docs/pages/deploying-vclusters/compat-matrix.mdx b/docs/pages/deploying-vclusters/compat-matrix.mdx new file mode 100644 index 0000000000..430044f73d --- /dev/null +++ b/docs/pages/deploying-vclusters/compat-matrix.mdx @@ -0,0 +1,85 @@ +--- +title: Compatibility Matrix +sidebar_label: Compatibility Matrix +--- + +## Compatibility Matrix for k3s distro + +The following table provides a compatibility matrix of which k8s version are supported aginst which vcluster distro versions: + +| | V1.29.0-K3S1 | V1.28.5-K3S1 | V1.27.9-K3S1 | V1.26.12-K3S1 | +|------|--------------------|--------------------|--------------------|--------------------| +| 1.29 | :white_check_mark: | :ok: | :ok: | :ok: | +| 1.28 | :ok: | :white_check_mark: | :ok: | :ok: | +| 1.27 | :ok: | :ok: | :white_check_mark: | :ok: | +| 1.26 | :ok: | :ok: | :ok: | :white_check_mark: | + + +Legend: + +:warning: : known issue + +:white_check_mark: : recommended + +:ok: : likely compatible + +## Compatibility Matrix for k8s distro + +The following table provides a compatibility matrix of which k8s version are supported aginst which vcluster distro versions: + +| | V1.29.0 | V1.28.4 | V1.27.8 | V1.26.11 | +|------|--------------------|--------------------|--------------------|--------------------| +| 1.29 | :white_check_mark: | :ok: | :ok: | :ok: | +| 1.28 | :ok: | :white_check_mark: | :ok: | :ok: | +| 1.27 | :ok: | :ok: | :white_check_mark: | :ok: | +| 1.26 | :ok: | :ok: | :ok: | :white_check_mark: | + + +Legend: + +:warning: : known issue + +:white_check_mark: : recommended + +:ok: : likely compatible + +## Compatibility Matrix for k0s distro + +The following table provides a compatibility matrix of which k8s version are supported aginst which vcluster distro versions: + +| | V1.29.1-K0S 0 | V1.28.2-K0S 0 | V1.27.6-K0S 0 | V1.26.9-K0S 0 | +|------|--------------------|--------------------|--------------------|--------------------| +| 1.29 | :white_check_mark: | :ok: | :ok: | :ok: | +| 1.28 | :ok: | :white_check_mark: | :ok: | :ok: | +| 1.27 | :ok: | :ok: | :white_check_mark: | :ok: | +| 1.26 | :ok: | :ok: | :ok: | :white_check_mark: | + + +Legend: + +:warning: : known issue + +:white_check_mark: : recommended + +:ok: : likely compatible + +## Compatibility Matrix for eks distro + +The following table provides a compatibility matrix of which k8s version are supported aginst which vcluster distro versions: + +| | V1.28.2-EKS-1-28-6 | V1.27.6-EKS-1-27-13 | V1.26.9-EKS-1-26-19 | V1.25.14-EKS-1-25-23 | +|------|--------------------|---------------------|---------------------|----------------------| +| 1.28 | :white_check_mark: | :ok: | :ok: | :ok: | +| 1.27 | :ok: | :white_check_mark: | :ok: | :ok: | +| 1.26 | :ok: | :ok: | :white_check_mark: | :ok: | +| 1.25 | :ok: | :ok: | :ok: | :white_check_mark: | + + +Legend: + +:warning: : known issue + +:white_check_mark: : recommended + +:ok: : likely compatible + diff --git a/docs/pages/deploying-vclusters/supported-distros.mdx b/docs/pages/deploying-vclusters/supported-distros.mdx index 25069863b7..09779ab8ea 100644 --- a/docs/pages/deploying-vclusters/supported-distros.mdx +++ b/docs/pages/deploying-vclusters/supported-distros.mdx @@ -114,27 +114,3 @@ For multi binary distributions, vCluster can even create those with a pre-instal In general, if you need vCluster to support another Kubernetes distribution, we are always happy to help you or accept a pull request in our GitHub repository. - - -## Compatibility Matrix - -The following table provides a compatibility matrix of which k8s version are supported aginst which vcluster distro versions: - -| Vcluster Distro | k8s Host version | Distro Version | -| --------------- | ---------------- | -------------------- | -| eks | 1.28 | v1.28.2-eks-1-28-6 | -| | 1.27 | v1.27.6-eks-1-27-13 | -| | 1.26 | v1.26.9-eks-1-26-19 | -| | 1.25 | v1.25.14-eks-1-25-23 | -| k0s | 1.28 | v1.28.2-k0s.0 | -| | 1.26 | v1.26.9-k0s.0 | -| | 1.27 | v1.27.6-k0s.0 | -| | 1.25 | v1.25.14-k0s.0 | -| k3s | 1.28 | v1.28.2-k3s1 | -| | 1.27 | v1.27.6-k3s1 | -| | 1.26 | v1.26.9-k3s1 | -| | 1.25 | v1.25.14-k3s1 | -| k8s | 1.28 | v1.28.2 | -| | 1.27 | v1.27.6 | -| | 1.26 | v1.26.9 | -| | 1.25 | v1.25.14 | diff --git a/docs/sidebars.js b/docs/sidebars.js index 303b5ad19e..413b0309c6 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -148,7 +148,7 @@ module.exports = { type: "category", label: "Kubernetes Distros", collapsed: true, - items: ["deploying-vclusters/supported-distros"], + items: ["deploying-vclusters/supported-distros", "deploying-vclusters/compat-matrix"], }, { type: "category", diff --git a/go.mod b/go.mod index 21d4aba185..2ce1c04bca 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/moby/locker v1.0.1 github.com/moby/term v0.5.0 + github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/ginkgo/v2 v2.14.0 github.com/onsi/gomega v1.30.0 github.com/pkg/errors v0.9.1 @@ -92,7 +93,6 @@ require ( github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/oklog/run v1.0.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/otiai10/copy v1.11.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/hack/compat-matrix/main.go b/hack/compat-matrix/main.go new file mode 100644 index 0000000000..e5ef4a59e8 --- /dev/null +++ b/hack/compat-matrix/main.go @@ -0,0 +1,188 @@ +package main + +import ( + "bytes" + _ "embed" + "fmt" + "os" + "slices" + "strings" + + "github.com/olekukonko/tablewriter" + "gopkg.in/yaml.v2" + + "github.com/loft-sh/vcluster-values/values" + "golang.org/x/exp/maps" +) + +const header = `--- +title: Compatibility Matrix +sidebar_label: Compatibility Matrix +--- + +` + +//go:embed matrix-template.tmpl +var templateString string + +type issueList map[string]string + +type KnownIssues struct { + K3s map[string]issueList + K0s map[string]issueList + K8s map[string]issueList + Eks map[string]issueList +} + +func main() { + if len(os.Args) != 3 { + os.Stderr.WriteString("usage: compat-matrix generate/validate outputfile") + os.Exit(1) + } + knowIssuesBytes, err := os.ReadFile("known_issues.yaml") + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Exit(1) + } + issues := KnownIssues{} + err = yaml.UnmarshalStrict(knowIssuesBytes, &issues) + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Exit(1) + } + + renderedBytes := &bytes.Buffer{} + renderedBytes.WriteString(header) + for _, v := range []string{"k3s", "k8s", "k0s", "eks"} { + var versionMap map[string]string + switch v { + case "k3s": + versionMap = values.K3SVersionMap + case "k8s": + versionMap = values.K8SAPIVersionMap + case "k0s": + versionMap = values.K0SVersionMap + case "eks": + versionMap = values.EKSAPIVersionMap + } + buff := updateTableWithDistro(v, versionMap, issues) + renderedBytes.WriteString(fmt.Sprintf(templateString, v, buff.String())) + renderedBytes.WriteString(createKnownIssue(issues.K3s)) + buff.Reset() + } + + switch os.Args[1] { + case "generate": + err = os.WriteFile(os.Args[2], renderedBytes.Bytes(), 0644) + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Exit(1) + } + case "validate": + currentFile, err := os.ReadFile(os.Args[2]) + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Exit(1) + } + if !slices.Equal(currentFile, renderedBytes.Bytes()) { + os.Stderr.WriteString("compatibility matrix is not up to date, please update it by running `just validate-compat-matrix`") + os.Exit(1) + } + } +} + +func updateTableWithDistro(distroName string, versionMap map[string]string, knownIssues KnownIssues) *bytes.Buffer { + hostVersions := maps.Keys(versionMap) + vclusterAPIs := maps.Values(versionMap) + slices.Sort(hostVersions) + slices.Reverse(hostVersions) + slices.Sort(vclusterAPIs) + slices.Reverse(vclusterAPIs) + + buff := &bytes.Buffer{} + table := tablewriter.NewWriter(buff) + for i, v := range vclusterAPIs { + vclusterAPIs[i] = removeRegistry(v) + } + table.SetHeader(append([]string{""}, vclusterAPIs...)) + + var issues map[string]issueList + switch distroName { + case "k3s": + issues = knownIssues.K3s + case "k0s": + issues = knownIssues.K0s + case "k8s": + issues = knownIssues.K8s + case "eks": + issues = knownIssues.Eks + } + + for hostVersion, issueList := range issues { + for vclusterAPI, issueDesc := range issueList { + issues[hostVersion][removeRegistry(vclusterAPI)] = issueDesc + if removeRegistry(vclusterAPI) != vclusterAPI { + // avoids removing valid entries + delete(issues[hostVersion], vclusterAPI) + } + } + } + + for i, v := range hostVersions { + table.Append(createLine(v, issues[v], vclusterAPIs, i)) + } + + table.SetAlignment(tablewriter.ALIGN_LEFT) + table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) + table.SetCenterSeparator("|") + table.Render() + + return buff +} + +func createKnownIssue(issues map[string]issueList) string { + if len(issues) == 0 { + return "" + } + keys := maps.Keys(issues) + slices.Sort(keys) + buff := &bytes.Buffer{} + table := tablewriter.NewWriter(buff) + table.SetHeader([]string{"vCluster Distro Version", "Host K8s Version", "Known Issues"}) + + for _, hostVersion := range keys { + for vclusterVersion, issue := range issues[hostVersion] { + table.Append([]string{vclusterVersion, hostVersion, issue}) + } + } + table.Render() + if buff.Len() > 0 { + buff.WriteString("\n") + } + return buff.String() +} + +func createLine(version string, list issueList, vclusterAPIVersion []string, lineNumber int) []string { + line := make([]string, 1, len(vclusterAPIVersion)+1) + line[0] = version + for i, v := range vclusterAPIVersion { + char := "" + if list[v] != "" { + char = ":warning" + } else if i == lineNumber { + char = ":white_check_mark:" + } else { + char = ":ok:" + } + line = append(line, char) + } + return line +} + +func removeRegistry(vclusterAPIVersion string) string { + lastColon := strings.LastIndex(vclusterAPIVersion, ":") + if lastColon == -1 { + return vclusterAPIVersion + } + return vclusterAPIVersion[lastColon+1:] +} diff --git a/hack/compat-matrix/matrix-template.tmpl b/hack/compat-matrix/matrix-template.tmpl new file mode 100644 index 0000000000..38746bfbfc --- /dev/null +++ b/hack/compat-matrix/matrix-template.tmpl @@ -0,0 +1,14 @@ +## Compatibility Matrix for %s distro + +The following table provides a compatibility matrix of which k8s version are supported aginst which vcluster distro versions: + +%s + +Legend: + +:warning: : known issue + +:white_check_mark: : recommended + +:ok: : likely compatible + diff --git a/known_issues.yaml b/known_issues.yaml new file mode 100644 index 0000000000..68c19acd0f --- /dev/null +++ b/known_issues.yaml @@ -0,0 +1,5 @@ +#k3s: +# 1.29: +# rancher/k3s:v1.27.9-k3s1: there is some issue there +# 1.28: +# rancher/k3s:v1.27.9-k3s1: there is some issue there diff --git a/vendor/modules.txt b/vendor/modules.txt index 2c0ed8db24..2a0aa92e24 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -185,6 +185,8 @@ github.com/go-openapi/strfmt # github.com/go-openapi/swag v0.22.7 ## explicit; go 1.19 github.com/go-openapi/swag +# github.com/go-spectest/markdown v0.0.7 +## explicit; go 1.18 # github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 ## explicit; go 1.13 github.com/go-task/slim-sprig @@ -323,6 +325,8 @@ github.com/json-iterator/go # github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 ## explicit github.com/k0kubun/go-ansi +# github.com/karrick/godirwalk v1.17.0 +## explicit; go 1.13 # github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 ## explicit github.com/kballard/go-shellquote