Skip to content

Commit 4750231

Browse files
committed
Download and extract artifact
1 parent 84b3a66 commit 4750231

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

controllers/gitrepository_watcher.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ package controllers
1818

1919
import (
2020
"context"
21+
"fmt"
22+
"io/ioutil"
23+
"net/http"
24+
"os"
2125
"strings"
2226
"time"
2327

@@ -27,6 +31,7 @@ import (
2731
"sigs.k8s.io/controller-runtime/pkg/client"
2832

2933
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
34+
"github.com/stefanprodan/source-watcher/pkg/untar"
3035
)
3136

3237
// GitRepositoryWatcher watches GitRepository objects for revision changes
@@ -40,9 +45,11 @@ type GitRepositoryWatcher struct {
4045
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=gitrepositories/status,verbs=get
4146

4247
func (r *GitRepositoryWatcher) Reconcile(req ctrl.Request) (ctrl.Result, error) {
48+
// set timeout for the reconciliation
4349
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
4450
defer cancel()
4551

52+
// get source object
4653
var repository sourcev1.GitRepository
4754
if err := r.Get(ctx, req.NamespacedName, &repository); err != nil {
4855
return ctrl.Result{}, client.IgnoreNotFound(err)
@@ -51,6 +58,32 @@ func (r *GitRepositoryWatcher) Reconcile(req ctrl.Request) (ctrl.Result, error)
5158
log := r.Log.WithValues(strings.ToLower(repository.Kind), req.NamespacedName)
5259
log.Info("New revision detected", "revision", repository.Status.Artifact.Revision)
5360

61+
// create tmp dir
62+
tmpDir, err := ioutil.TempDir("", repository.Name)
63+
if err != nil {
64+
return ctrl.Result{}, fmt.Errorf("failed to create temp dir, error: %w", err)
65+
}
66+
defer os.RemoveAll(tmpDir)
67+
68+
// download and extract artifact
69+
summary, err := r.fetchArtifact(ctx, repository, tmpDir)
70+
if err != nil {
71+
log.Error(err, "unable to fetch artifact")
72+
return ctrl.Result{}, err
73+
}
74+
log.Info(summary)
75+
76+
// list artifact content
77+
files, err := ioutil.ReadDir(tmpDir)
78+
if err != nil {
79+
return ctrl.Result{}, fmt.Errorf("faild to list files, error: %w", err)
80+
}
81+
82+
// do something with the artifact content
83+
for _, f := range files {
84+
log.Info("Processing " + f.Name())
85+
}
86+
5487
return ctrl.Result{}, nil
5588
}
5689

@@ -60,3 +93,43 @@ func (r *GitRepositoryWatcher) SetupWithManager(mgr ctrl.Manager) error {
6093
WithEventFilter(GitRepositoryRevisionChangePredicate{}).
6194
Complete(r)
6295
}
96+
97+
func (r *GitRepositoryWatcher) fetchArtifact(ctx context.Context, repository sourcev1.GitRepository, dir string) (string, error) {
98+
if repository.Status.Artifact == nil {
99+
return "", fmt.Errorf("respository %s does not containt an artifact", repository.Name)
100+
}
101+
102+
url := repository.Status.Artifact.URL
103+
104+
// for local run:
105+
// kubectl -n gitops-system port-forward svc/source-controller 8080:80
106+
// export SOURCE_HOST=localhost:8080
107+
if hostname := os.Getenv("SOURCE_HOST"); hostname != "" {
108+
url = fmt.Sprintf("http://%s/gitrepository/%s/%s/latest.tar.gz", hostname, repository.Namespace, repository.Name)
109+
}
110+
111+
// download the tarball
112+
req, err := http.NewRequest("GET", url, nil)
113+
if err != nil {
114+
return "", fmt.Errorf("failed to create HTTP request, error: %w", err)
115+
}
116+
117+
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
118+
if err != nil {
119+
return "", fmt.Errorf("failed to download artifact from %s, error: %w", url, err)
120+
}
121+
defer resp.Body.Close()
122+
123+
// check response
124+
if resp.StatusCode != http.StatusOK {
125+
return "", fmt.Errorf("faild to download artifact, status: %s", resp.Status)
126+
}
127+
128+
// extract
129+
summary, err := untar.Untar(resp.Body, dir)
130+
if err != nil {
131+
return "", fmt.Errorf("faild to untar artifact, error: %w", err)
132+
}
133+
134+
return summary, nil
135+
}

0 commit comments

Comments
 (0)