Skip to content

Commit

Permalink
chore: add DOCA driver matrix validation
Browse files Browse the repository at this point in the history
Signed-off-by: Fred Rolland <[email protected]>
  • Loading branch information
rollandf committed Jan 13, 2025
1 parent 74690cd commit e5a81f9
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 8 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ jobs:
uses: actions/checkout@v4
- name: check release-build
run: make check-release-build
check-doca-drivers:
name: check doca-drivers
runs-on: ubuntu-22.04
permissions:
contents: read
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: checkout
uses: actions/checkout@v4
- name: check doca-drivers
run: make check-doca-drivers
unit-tests:
name: Unit-tests
runs-on: ubuntu-22.04
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ testbin
test
build
hack/manifests
hack/tmp
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ REPO_PATH=$(ORG_PATH)/$(PACKAGE)
CHART_PATH=$(CURDIR)/deployment/$(PACKAGE)
TOOLSDIR=$(CURDIR)/hack/tools/bin
MANIFESTDIR=$(CURDIR)/hack/manifests
HACKTMPDIR=$(CURDIR)/hack/tmp
BUILDDIR=$(CURDIR)/build/_output
GOFILES=$(shell find . -name "*.go" | grep -vE "(\/vendor\/)|(_test.go)")
TESTPKGS=./...
Expand All @@ -37,6 +38,7 @@ BUILD_VERSION := $(strip $(shell [ -d .git ] && git describe --always --tags --d
BUILD_TIMESTAMP := $(shell date -u +"%Y-%m-%dT%H:%M:%S%Z")
VCS_BRANCH := $(strip $(shell git rev-parse --abbrev-ref HEAD))
VCS_REF := $(strip $(shell [ -d .git ] && git rev-parse --short HEAD))
DOCA_DRIVER_RELEASE_URL := https://raw.githubusercontent.com/Mellanox/doca-driver-build/refs/heads/main/release_manifests/

# Docker
IMAGE_BUILDER?=docker
Expand Down Expand Up @@ -109,6 +111,9 @@ $(MANIFESTDIR):
$(BUILDDIR): ; $(info Creating build directory...)
mkdir -p $@

$(HACKTMPDIR):
@mkdir -p $@

build: generate $(BUILDDIR)/$(BINARY_NAME) ; $(info Building $(BINARY_NAME)...) @ ## Build executable file
$(info Done!)

Expand Down Expand Up @@ -356,6 +361,7 @@ clean: ; $(info Cleaning...) @ ## Cleanup everything
@rm -rf $(BUILDDIR)
@rm -rf $(TOOLSDIR)
@rm -rf $(MANIFESTDIR)
@rm -rf $(HACKTMPDIR)

.PHONY: help
help: ## Show this message
Expand Down Expand Up @@ -414,6 +420,12 @@ release-build:
cd hack && $(GO) run release.go --templateDir ./templates/crs/ --outputDir ../example/crs
cd hack && $(GO) run release.go --templateDir ./templates/values/ --outputDir ../deployment/network-operator/

.PHONY: check-doca-drivers
check-doca-drivers: $(HACKTMPDIR)
$(eval DOCAVERSION := $(shell yq '.Mofed.version' hack/release.yaml | cut -d'-' -f1))
wget $(DOCA_DRIVER_RELEASE_URL)$(DOCAVERSION)-TBD.yaml -O $(HACKTMPDIR)/doca-driver-matrix.yaml
cd hack && $(GO) run release.go --doca-driver-check --doca-driver-matrix $(HACKTMPDIR)/doca-driver-matrix.yaml

# dev environment

MINIKUBE_CLUSTER_NAME = net-op-dev
Expand Down
119 changes: 111 additions & 8 deletions hack/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (

"sigs.k8s.io/yaml"

yamlflow "gopkg.in/yaml.v3"

mellanoxv1alpha1 "github.com/Mellanox/network-operator/api/v1alpha1"

"github.com/google/go-containerregistry/pkg/authn"
Expand Down Expand Up @@ -80,6 +82,18 @@ type Release struct {
MaintenanceOperator *ReleaseImageSpec
}

type DocaDriverMatrix struct {

Check failure on line 85 in hack/release.go

View workflow job for this annotation

GitHub Actions / golangci-lint

exported: exported type DocaDriverMatrix should have comment or be unexported (revive)
Precompiled []struct {
OS string `yaml:"os"`
Arch []string `yaml:"archs,flow"`
Kernels []string `yaml:"kernels,flow"`
} `yaml:"precompiled"`
DynamicallyCompiled []struct {
OS string `yaml:"os,flow"`
Arch []string `yaml:"archs,flow"`
} `yaml:"dynamically_compiled"`
}

func readDefaults(releaseDefaults string) Release {
f, err := os.ReadFile(filepath.Clean(releaseDefaults))
if err != nil {
Expand Down Expand Up @@ -136,9 +150,82 @@ func main() {
outputDir := flag.String("outputDir", ".", "Destination directory to render templates to")
releaseDefaults := flag.String("releaseDefaults", "release.yaml", "Destination of the release defaults definition")
retrieveSha := flag.Bool("with-sha256", false, "retrieve SHA256 for container images references")
docaDriverCheck := flag.Bool("doca-driver-check", false, "Verify DOCA Driver tags")
docaDriverMatrix := flag.String("doca-driver-matrix", "tmp/doca-driver-matrix.yaml", "DOCA Driver tags matrix")
flag.Parse()
release := readDefaults(*releaseDefaults)
readEnvironmentVariables(&release)

if !*docaDriverCheck {
renderTemplates(release, templateDir, outputDir, retrieveSha)
} else {
docaDriverTagsCheck(release, docaDriverMatrix)
}
}

func docaDriverTagsCheck(release Release, docaDriverMatrix *string) {

Check failure on line 166 in hack/release.go

View workflow job for this annotation

GitHub Actions / golangci-lint

hugeParam: release is heavy (184 bytes); consider passing it by pointer (gocritic)
f, err := os.ReadFile(filepath.Clean(*docaDriverMatrix))
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
var config DocaDriverMatrix
if err := yamlflow.Unmarshal(f, &config); err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
auth, err := getAuth()
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
tags, err := resolveTags(release.Mofed.Repository, release.Mofed.Image, auth)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
if err := validateTags(config, tags, release.Mofed.Version); err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
}

func validateTags(config DocaDriverMatrix, tags []string, version string) error {
// Build expected OS-arch combinations
expectedCombinations := make(map[string]struct{})
for _, entry := range config.DynamicallyCompiled {
for _, arch := range entry.Arch {
key := fmt.Sprintf("%s-%s", entry.OS, arch)
expectedCombinations[key] = struct{}{}
}
}

// Filter tags based on version prefix
filteredTags := []string{}
for _, tag := range tags {
if strings.HasPrefix(tag, version) {
filteredTags = append(filteredTags, tag)
}
}

// Validate if each expected combination exists in the filtered tags
for combo := range expectedCombinations {
found := false
for _, tag := range filteredTags {
if strings.Contains(tag, combo) {
found = true
break
}
}
if !found {
return fmt.Errorf("missing os-arch combination: %s", combo)
}
}

return nil
}

func renderTemplates(release Release, templateDir, outputDir *string, retrieveSha *bool) {

Check failure on line 228 in hack/release.go

View workflow job for this annotation

GitHub Actions / golangci-lint

hugeParam: release is heavy (184 bytes); consider passing it by pointer (gocritic)
if *retrieveSha {
err := resolveImagesSha(&release)
if err != nil {
Expand Down Expand Up @@ -198,15 +285,23 @@ func main() {
}
}

func resolveImagesSha(release *Release) error {
func getAuth() (*authn.Basic, error) {
nvcrToken := os.Getenv("NGC_CLI_API_KEY")
if nvcrToken == "" {
return fmt.Errorf("NGC_CLI_API_KEY is unset")
return nil, fmt.Errorf("NGC_CLI_API_KEY is unset")
}
auth := &authn.Basic{
Username: "$oauthtoken",
Password: nvcrToken,
}
return auth, nil
}

func resolveImagesSha(release *Release) error {
auth, err := getAuth()
if err != nil {
return err
}
v := reflect.ValueOf(*release)
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
Expand Down Expand Up @@ -263,27 +358,35 @@ func resolveImageSha(repo, image, tag string, auth *authn.Basic) (string, error)
return digest.String(), nil
}

func resolveDocaDriversShas(repoName, imageName, ver string, auth *authn.Basic) ([]string, error) {
shaArray := make([]string, 0)
func resolveTags(repoName, imageName string, auth *authn.Basic) ([]string, error) {
tags := make([]string, 0)
image := fmt.Sprintf("%s/%s", repoName, imageName)
repo, err := containerregistryname.NewRepository(image)
if err != nil {
return shaArray, err
return tags, err
}
var tags []string
if strings.Contains(repoName, "nvstaging") {
tags, err = remote.List(repo, remote.WithAuth(auth))
if err != nil {
return shaArray, err
return tags, err
}
} else {
// Container registry might fail if providing unneeded auth
tags, err = remote.List(repo)
if err != nil {
return shaArray, err
return tags, err
}
}
sort.Strings(tags)
return tags, nil
}

func resolveDocaDriversShas(repoName, imageName, ver string, auth *authn.Basic) ([]string, error) {
shaArray := make([]string, 0)
tags, err := resolveTags(repoName, imageName, auth)
if err != nil {
return shaArray, err
}
shaSet := make(map[string]interface{})
for _, tag := range tags {
if strings.Contains(tag, ver) && (strings.Contains(tag, "rhcos") || strings.Contains(tag, "rhel")) {
Expand Down

0 comments on commit e5a81f9

Please sign in to comment.