Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: SovereignCloudStack/csctl
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.4
Choose a base ref
...
head repository: SovereignCloudStack/csctl
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.0.5
Choose a head ref
  • 4 commits
  • 6 files changed
  • 3 contributors

Commits on Sep 16, 2024

  1. fix(publish): use release directory name for the tag

    Signed-off-by: Jan Schoone <6106846+jschoone@users.noreply.github.com>
    jschoone committed Sep 16, 2024
    Copy the full SHA
    fe7c931 View commit details

Commits on Sep 26, 2024

  1. 🐛 assets are uploaded to oci registry with every publish (#158)

    * added: gitignore IDE specific files
    
    Signed-off-by: Danny Eiselt <eiselt@b1-systems.de>
    
    * added: check if hash release exists in OCI and reject push
    
    Signed-off-by: Danny Eiselt <eiselt@b1-systems.de>
    
    ---------
    
    Signed-off-by: Danny Eiselt <eiselt@b1-systems.de>
    DEiselt authored Sep 26, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    67ba98a View commit details

Commits on Oct 21, 2024

  1. 🌱 Update Github Actions group to v2.0.2

    | datasource  | package                   | from    | to     |
    | ----------- | ------------------------- | ------- | ------ |
    | github-tags | lycheeverse/lychee-action | v1.10.0 | v2.0.2 |
    cluster-stack-bot[bot] authored and jschoone committed Oct 21, 2024
    Copy the full SHA
    8b5d6b4 View commit details

Commits on Oct 23, 2024

  1. feat(create): Support OCI remote and deduplicate code (#162)

    added: allow switch for assetclient in create command
    added: `--publish` flag for create command
    removed: unused code changes from last commit
    changed: moved `pushReleaseAssets` function to `create.go`
    removed: publish command and `publish.go` file
    changed: help text format
    chore: go mod tidy
    chore(create): reactivate validateHash
    fix: make linter happy
    
    Signed-off-by: Danny Eiselt <eiselt@b1-systems.de>
    Co-authored-by: Jan Schoone <6106846+jschoone@users.noreply.github.com>
    DEiselt and jschoone authored Oct 23, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    5bf6153 View commit details
Showing with 96 additions and 385 deletions.
  1. +1 −1 .github/workflows/schedule-link-checker.yml
  2. +1 −0 .gitignore
  3. +1 −1 go.mod
  4. +93 −7 pkg/cmd/create.go
  5. +0 −375 pkg/cmd/publish.go
  6. +0 −1 pkg/cmd/root.go
2 changes: 1 addition & 1 deletion .github/workflows/schedule-link-checker.yml
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ jobs:
private_key: ${{ secrets.SCS_APP_PRIVATE_KEY }}

- name: Link Checker
uses: lycheeverse/lychee-action@2b973e86fc7b1f6b36a93795fe2c9c6ae1118621 # v1.10.0
uses: lycheeverse/lychee-action@7cd0af4c74a61395d455af97419279d86aafaede # v2.0.2
id: lychee
env:
GITHUB_TOKEN: "${{ steps.generate-token.outputs.token }}"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -24,3 +24,4 @@ releases/
.release
.envrc
dist/
.idea/
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@ require (
golang.org/x/mod v0.16.0
golang.org/x/oauth2 v0.18.0
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.14.4
oras.land/oras-go/v2 v2.5.0
@@ -142,6 +141,7 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/api v0.29.0 // indirect
k8s.io/apiextensions-apiserver v0.29.0 // indirect
k8s.io/apimachinery v0.29.0 // indirect
100 changes: 93 additions & 7 deletions pkg/cmd/create.go
Original file line number Diff line number Diff line change
@@ -23,7 +23,9 @@ import (
"os"
"path/filepath"

"github.com/SovereignCloudStack/csctl/pkg/assetsclient"
"github.com/SovereignCloudStack/csctl/pkg/assetsclient/github"
"github.com/SovereignCloudStack/csctl/pkg/assetsclient/oci"
"github.com/SovereignCloudStack/csctl/pkg/clusterstack"
"github.com/SovereignCloudStack/csctl/pkg/hash"
"github.com/SovereignCloudStack/csctl/pkg/providerplugin"
@@ -47,7 +49,9 @@ var (
note - Hash mode takes the last hash of the git commit.`
example = `csctl create tests/cluster-stacks/docker/ferrol -m hash (for hash mode)
csctl create tests/cluster-stacks/docker/ferrol -m hash --github-release github-release/ (for stable mode)`
csctl create tests/cluster-stacks/docker/ferrol -m hash github-release/ (for stable mode)
csctl create --publish --remote oci tests/cluster-stacks/docker/ferrol (publish to OCI repository)`
)

var (
@@ -57,6 +61,8 @@ var (
clusterStackVersion string
clusterAddonVersion string
nodeImageVersion string
remote string
publish bool
)

// CreateOptions contains config for creating a release.
@@ -69,6 +75,7 @@ type CreateOptions struct {
CurrentReleaseHash hash.ReleaseHash
LatestReleaseHash hash.ReleaseHash
NodeImageRegistry string
releaseName string
}

// createCmd represents the create command.
@@ -88,6 +95,8 @@ func init() {
createCmd.Flags().StringVar(&clusterStackVersion, "cluster-stack-version", "", "It is used to specify the semver version for the cluster stack in the custom mode")
createCmd.Flags().StringVar(&clusterAddonVersion, "cluster-addon-version", "", "It is used to specify the semver version for the cluster addon in the custom mode")
createCmd.Flags().StringVar(&nodeImageVersion, "node-image-version", "", "It is used to specify the semver version for the node images in the custom mode")
createCmd.Flags().StringVar(&remote, "remote", "github", "Which remote repository to use and thus which credentials are required. Currently supported are 'github' and 'oci'.")
createCmd.Flags().BoolVar(&publish, "publish", false, "Publish release after creation is done. This is only implemented for OCI currently.")
}

// GetCreateOptions create a Create Option for create command.
@@ -129,12 +138,22 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti
case stableMode:
createOption.Metadata = &clusterstack.MetaData{}

gc, err := github.NewFactory().NewClient(ctx)
var remoteFactory assetsclient.Factory

// using switch here in case more will be added in the future (aws?)
switch remote {
case "github":
remoteFactory = github.NewFactory()
case "oci":
remoteFactory = oci.NewFactory()
}

ac, err := remoteFactory.NewClient(ctx)
if err != nil {
return nil, fmt.Errorf("failed to create new github client: %w", err)
return nil, fmt.Errorf("failed to create new asset client: %w", err)
}

latestRepoRelease, err := getLatestReleaseFromRemoteRepository(ctx, mode, config, gc)
latestRepoRelease, err := getLatestReleaseFromRemoteRepository(ctx, mode, config, ac)
if err != nil {
return nil, fmt.Errorf("failed to get latest release form remote repository: %w", err)
}
@@ -147,7 +166,7 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti
createOption.Metadata.Versions.Components.ClusterAddon = "v1"
createOption.Metadata.Versions.Components.NodeImage = "v1"
} else {
if err := downloadReleaseAssets(ctx, latestRepoRelease, "./.tmp/release/", gc); err != nil {
if err := downloadReleaseAssets(ctx, latestRepoRelease, "./.tmp/release/", ac); err != nil {
return nil, fmt.Errorf("failed to download release asset: %w", err)
}

@@ -185,6 +204,12 @@ func GetCreateOptions(ctx context.Context, clusterStackPath string) (*CreateOpti
if err != nil {
return nil, fmt.Errorf("failed to get cluster stack release directory name: %w", err)
}

createOption.releaseName, err = clusterstack.GetClusterStackReleaseDirectoryName(createOption.Metadata, createOption.Config)
if err != nil {
return nil, fmt.Errorf("failed to get cluster stack release name: %w", err)
}

// Release directory name `release/docker-ferrol-1-27-v1`
createOption.ClusterStackReleaseDir = filepath.Join(outputDirectory, releaseDirName)

@@ -215,7 +240,7 @@ func createAction(cmd *cobra.Command, args []string) error {
return fmt.Errorf("failed to validate with latest release hash: %w", err)
}

if err := createOpts.generateRelease(); err != nil {
if err := createOpts.generateRelease(cmd.Context()); err != nil {
return fmt.Errorf("failed to generate release: %w", err)
}
fmt.Printf("Created %s\n", createOpts.ClusterStackReleaseDir)
@@ -234,7 +259,7 @@ func (c *CreateOptions) validateHash() error {
return nil
}

func (c *CreateOptions) generateRelease() error {
func (c *CreateOptions) generateRelease(ctx context.Context) error {
if err := os.MkdirAll(c.ClusterStackReleaseDir, os.ModePerm); err != nil {
return fmt.Errorf("failed to create output directory: %w", err)
}
@@ -323,6 +348,32 @@ func (c *CreateOptions) generateRelease() error {
if err != nil {
return fmt.Errorf("providerplugin.CreateNodeImages() failed: %w", err)
}

if publish {
if remote != "oci" {
return fmt.Errorf("not pushing assets. --publish is only implemented for remote OCI")
}

ociClient, err := oci.NewClient()
if err != nil {
return fmt.Errorf("failed to create new oci client: %w", err)
}

var hashAnnotation string
if len(c.CurrentReleaseHash.ClusterStack) >= 7 {
hashAnnotation = c.CurrentReleaseHash.ClusterStack[:7]
}

annotations := map[string]string{
"kubernetesVersion": c.Metadata.Versions.Kubernetes,
"hash": hashAnnotation,
}

if err := pushReleaseAssets(ctx, ociClient, c.ClusterStackReleaseDir, c.releaseName, annotations); err != nil {
return fmt.Errorf("failed to push release assets to the oci registry: %w", err)
}
}

return nil
}

@@ -382,3 +433,38 @@ func cleanTmpDirectory() error {

return nil
}

func pushReleaseAssets(ctx context.Context, pusher assetsclient.Pusher, clusterStackReleasePath, releaseName string, annotations map[string]string) error {
releaseAssets := []assetsclient.ReleaseAsset{}

ociclient, err := oci.NewClient()
if err != nil {
return fmt.Errorf("error creating oci client: %w", err)
}

if ociclient.FoundRelease(ctx, releaseName) {
fmt.Printf("release tag \"%s\" found in oci registry. aborting push\n", releaseName)
return nil
}

files, err := os.ReadDir(clusterStackReleasePath)
if err != nil {
return fmt.Errorf("failed to read directory %s: %w", clusterStackReleasePath, err)
}

for _, file := range files {
if file.Type().IsRegular() {
releaseAssets = append(releaseAssets, assetsclient.ReleaseAsset{
FileName: file.Name(),
MediaType: getMediaType(file.Name()),
})
}
}

if err := pusher.PushReleaseAssets(ctx, releaseAssets, releaseName, clusterStackReleasePath, clusterStackArtifactType, annotations); err != nil {
return fmt.Errorf("failed to push release assets to oci registry: %w", err)
}

fmt.Printf("successfully pushed clusterstack release: %s:%s \n", ociclient.Repository.Reference.String(), releaseName)
return nil
}
Loading