Skip to content

Commit

Permalink
Merge branch 'main' of github.com:open-component-model/ocm into reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
hilmarf committed May 8, 2024
2 parents e73a3d7 + 7f589f7 commit 8c6b24a
Show file tree
Hide file tree
Showing 40 changed files with 831 additions and 232 deletions.
6 changes: 5 additions & 1 deletion cmds/demoplugin/accessmethods/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ func (a *AccessMethod) ComposeAccessSpecification(p ppi.Plugin, opts ppi.Config,
func (a *AccessMethod) Reader(p ppi.Plugin, spec ppi.AccessSpec, creds credentials.Credentials) (io.ReadCloser, error) {
my := spec.(*AccessSpec)

cfg, _ := p.GetConfig()
cfg, err := p.GetConfig()
if err != nil {
return nil, errors.Wrapf(err, "can't get config for access method %s", my.MediaType)
}

root := os.TempDir()
if cfg != nil && cfg.(*config.Config).AccessMethods.Path != "" {
root = cfg.(*config.Config).Uploaders.Path
Expand Down
6 changes: 5 additions & 1 deletion cmds/demoplugin/uploaders/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ func (a *Uploader) Writer(p ppi.Plugin, arttype, mediatype, hint string, repo pp
var file *os.File
var err error

cfg, _ := p.GetConfig()
cfg, err := p.GetConfig()
if err != nil {
return nil, nil, errors.Wrapf(err, "can't get config for access method %s", mediatype)
}

root := os.TempDir()
if cfg != nil && cfg.(*config.Config).Uploaders.Path != "" {
root = cfg.(*config.Config).Uploaders.Path
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package install
package common

import (
"bufio"
Expand All @@ -16,7 +16,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

func readObjects(manifestPath string) ([]*unstructured.Unstructured, error) {
func ReadObjects(manifestPath string) ([]*unstructured.Unstructured, error) {
fi, err := os.Lstat(manifestPath)
if err != nil {
return nil, err
Expand Down
103 changes: 103 additions & 0 deletions cmds/ocm/commands/controllercmds/common/fetcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package common

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
)

func getLatestVersion(ctx context.Context, url string) (string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url+"/latest", nil)
if err != nil {
return "", err
}

res, err := http.DefaultClient.Do(req)
if err != nil {
return "", fmt.Errorf("GitHub API call failed: %w", err)
}

if res.Body != nil {
defer res.Body.Close()
}

type meta struct {
Tag string `json:"tag_name"`
}
var m meta
if err := json.NewDecoder(res.Body).Decode(&m); err != nil {
return "", fmt.Errorf("decoding GitHub API response failed: %w", err)
}

return m.Tag, err
}

// existingVersion calls the GitHub API to confirm the given version does exist.
func existingVersion(ctx context.Context, url, version string) (bool, error) {
if !strings.HasPrefix(version, "v") {
version = "v" + version
}

ghURL := fmt.Sprintf(url+"/tags/%s", version)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, ghURL, nil)
if err != nil {
return false, fmt.Errorf("GitHub API call failed: %w", err)
}

res, err := http.DefaultClient.Do(req)
if err != nil {
return false, err
}

if res.Body != nil {
defer res.Body.Close()
}

switch res.StatusCode {
case http.StatusOK:
return true, nil
case http.StatusNotFound:
return false, nil
default:
return false, fmt.Errorf("GitHub API returned an unexpected status code (%d)", res.StatusCode)
}
}

func fetch(ctx context.Context, url, version, dir, filename string) error {
ghURL := fmt.Sprintf("%s/latest/download/%s", url, filename)
if strings.HasPrefix(version, "v") {
ghURL = fmt.Sprintf("%s/download/%s/%s", url, version, filename)
}

req, err := http.NewRequest(http.MethodGet, ghURL, nil)
if err != nil {
return fmt.Errorf("failed to create HTTP request for %s, error: %w", ghURL, err)
}

resp, err := http.DefaultClient.Do(req.WithContext(ctx))
if err != nil {
return fmt.Errorf("failed to download manifests.tar.gz from %s, error: %w", ghURL, err)
}
defer resp.Body.Close()

// check response
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to download %s from %s, status: %s", filename, ghURL, resp.Status)
}

wf, err := os.OpenFile(filepath.Join(dir, filename), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o777)
if err != nil {
return fmt.Errorf("failed to open temp file: %w", err)
}

if _, err := io.Copy(wf, resp.Body); err != nil {
return fmt.Errorf("failed to write to temp file: %w", err)
}

return nil
}
111 changes: 111 additions & 0 deletions cmds/ocm/commands/controllercmds/common/manifests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package common

import (
"context"
"fmt"
"os"
"path/filepath"

"github.com/fluxcd/pkg/ssa"
"github.com/open-component-model/ocm/pkg/contexts/clictx"
"github.com/open-component-model/ocm/pkg/out"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

func Install(ctx context.Context, octx clictx.Context, sm *ssa.ResourceManager, releaseURL, baseURL, manifest, filename, version string, dryRun bool) error {
objects, err := fetchObjects(ctx, octx, releaseURL, baseURL, manifest, filename, version, dryRun)
if err != nil {
return fmt.Errorf("✗ failed to construct objects to apply: %w", err)
}

// dry run was set to true, no objects are returned
if len(objects) == 0 {
return nil
}

if _, err := sm.ApplyAllStaged(context.Background(), objects, ssa.DefaultApplyOptions()); err != nil {
return fmt.Errorf("✗ failed to apply manifests: %w", err)
}

out.Outf(octx, "► waiting for ocm deployment to be ready\n")
if err = sm.Wait(objects, ssa.DefaultWaitOptions()); err != nil {
return fmt.Errorf("✗ failed to wait for objects to be ready: %w", err)
}

return nil
}

func Uninstall(ctx context.Context, octx clictx.Context, sm *ssa.ResourceManager, releaseURL, baseURL, manifest, filename, version string, dryRun bool) error {
objects, err := fetchObjects(ctx, octx, releaseURL, baseURL, manifest, filename, version, dryRun)
if err != nil {
return fmt.Errorf("✗ failed to construct objects to apply: %w", err)
}

// dry run was set to true, no objects are returned
if len(objects) == 0 {
return nil
}

if _, err := sm.DeleteAll(context.Background(), objects, ssa.DefaultDeleteOptions()); err != nil {
return fmt.Errorf("✗ failed to delete manifests: %w", err)
}

out.Outf(octx, "► waiting for ocm deployment to be deleted\n")
if err = sm.WaitForTermination(objects, ssa.DefaultWaitOptions()); err != nil {
return fmt.Errorf("✗ failed to wait for objects to be deleted: %w", err)
}

return nil
}

func fetchObjects(ctx context.Context, octx clictx.Context, releaseURL, baseURL, manifest, filename, version string, dryRun bool) ([]*unstructured.Unstructured, error) {
if version == "latest" {
latest, err := getLatestVersion(ctx, releaseURL)
if err != nil {
return nil, fmt.Errorf("✗ failed to retrieve latest version for %s: %w", manifest, err)
}
out.Outf(octx, "► got latest version %q\n", latest)
version = latest
} else {
exists, err := existingVersion(ctx, releaseURL, version)
if err != nil {
return nil, fmt.Errorf("✗ failed to check if version exists: %w", err)
}
if !exists {
return nil, fmt.Errorf("✗ version %q does not exist", version)
}
}

temp, err := os.MkdirTemp("", manifest+"-download")
if err != nil {
return nil, fmt.Errorf("✗ failed to create temp folder: %w", err)
}
defer os.RemoveAll(temp)

if err := fetch(ctx, baseURL, version, temp, filename); err != nil {
return nil, fmt.Errorf("✗ failed to download install.yaml file: %w", err)
}

path := filepath.Join(temp, filename)
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil, fmt.Errorf("✗ failed to find %s file at location: %w", filename, err)
}
out.Outf(octx, "✔ successfully fetched install file\n")
if dryRun {
content, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("✗ failed to read %s file at location: %w", filename, err)
}

out.Outf(octx, string(content))
return nil, nil
}
out.Outf(octx, "► applying to cluster...\n")

objects, err := ReadObjects(path)
if err != nil {
return nil, fmt.Errorf("✗ failed to construct objects to apply: %w", err)
}

return objects, nil
}
Loading

0 comments on commit 8c6b24a

Please sign in to comment.