Skip to content

Commit 01217aa

Browse files
committed
/api/v1/clusters/info redirects to github releases for downloads
1 parent 56692ec commit 01217aa

File tree

11 files changed

+243
-27
lines changed

11 files changed

+243
-27
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ VERSION ?= $(shell git rev-parse --verify HEAD)
22
GOOS ?= $(shell go env | grep GOOS | cut -d'"' -f2)
33
BINARIES := apiserver kubernikus kubernikusctl wormhole
44

5-
LDFLAGS := -X github.com/sapcc/kubernikus/pkg/version.VERSION=$(VERSION)
5+
LDFLAGS := -X github.com/sapcc/kubernikus/pkg/version.GitCommit=$(VERSION)
66
GOFLAGS := -ldflags "$(LDFLAGS) -s -w"
77

88
SRCDIRS := pkg cmd

ci/task_cli.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ run:
2121
make bin/linux/kubernikusctl
2222
make bin/windows/kubernikusctl.exe
2323
upx bin/*/*
24-
git rev-parse HEAD > $BINARIES/commitish
25-
echo "1.0.0+"$(git rev-parse --short HEAD) > $BINARIES/tag
24+
SHA=$(git rev-parse HEAD)
25+
echo $SHA > $BINARIES/commitish
26+
echo "1.0.0+$SHA" > $BINARIES/tag
2627
2728
cp bin/darwin/kubernikusctl $BINARIES/kubernikusctl_darwin_amd64
2829
cp bin/linux/kubernikusctl $BINARIES/kubernikusctl_linux_amd64

pkg/api/handlers/get_cluster_info.go

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,100 @@
11
package handlers
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"net/http"
7+
"strings"
8+
"sync"
59

610
"github.com/go-openapi/runtime/middleware"
711
"github.com/sapcc/kubernikus/pkg/api"
812
"github.com/sapcc/kubernikus/pkg/api/models"
913
"github.com/sapcc/kubernikus/pkg/api/rest/operations"
14+
"github.com/sapcc/kubernikus/pkg/version"
1015
)
1116

1217
func NewGetClusterInfo(rt *api.Runtime) operations.GetClusterInfoHandler {
13-
return &getClusterInfo{rt}
18+
return &getClusterInfo{Runtime: rt, githubApiURL: "https://api.github.com"}
1419
}
1520

1621
type getClusterInfo struct {
1722
*api.Runtime
23+
links []models.Link
24+
linkMutex sync.Mutex
25+
githubApiURL string
1826
}
1927

2028
func (d *getClusterInfo) Handle(params operations.GetClusterInfoParams, principal *models.Principal) middleware.Responder {
29+
30+
links, err := d.getLinks()
31+
if err != nil {
32+
return NewErrorResponse(&operations.GetClusterInfoDefault{}, 500, err.Error())
33+
}
34+
2135
info := &models.KlusterInfo{
2236
SetupCommand: createSetupCommand(principal),
2337
Binaries: []models.Binaries{
2438
{
25-
Name: "kubernikusctl",
26-
Links: []models.Link{
27-
{
28-
Platform: "darwin",
29-
Link: "static/binaries/darwin/amd64/kubernikusctl",
30-
},
31-
{
32-
Platform: "linux",
33-
Link: "static/binaries/linux/amd64/kubernikusctl",
34-
},
35-
},
39+
Name: "kubernikusctl",
40+
Links: links,
3641
},
3742
},
3843
}
3944
return operations.NewGetClusterInfoOK().WithPayload(info)
4045
}
4146

47+
func (d *getClusterInfo) getLinks() ([]models.Link, error) {
48+
d.linkMutex.Lock()
49+
defer d.linkMutex.Unlock()
50+
if d.links != nil {
51+
return d.links, nil
52+
}
53+
54+
release := "latest"
55+
if version.GitCommit != "HEAD" {
56+
release = fmt.Sprintf("%s-%s", version.VERSION, version.GitCommit)
57+
}
58+
resp, err := http.Get(fmt.Sprintf("%s/repos/sapcc/kubernikus/releases/%s", d.githubApiURL, release))
59+
if err != nil {
60+
return nil, fmt.Errorf("Failed to fetch release %s: %s", release, err)
61+
}
62+
if resp.StatusCode >= 400 {
63+
return nil, fmt.Errorf("Failed to fetch release %s: %s", release, resp.Status)
64+
}
65+
var releaseResponse struct {
66+
Assets []struct {
67+
Name string
68+
DownloadURL string `json:"browser_download_url"`
69+
}
70+
}
71+
if err := json.NewDecoder(resp.Body).Decode(&releaseResponse); err != nil {
72+
return nil, err
73+
}
74+
links := make([]models.Link, 0, 3)
75+
for _, asset := range releaseResponse.Assets {
76+
link := models.Link{Link: asset.DownloadURL}
77+
switch {
78+
case strings.Contains(asset.Name, "darwin"):
79+
link.Platform = "darwin"
80+
case strings.Contains(asset.Name, "linux"):
81+
link.Platform = "linux"
82+
case strings.Contains(asset.Name, "windows"):
83+
link.Platform = "windows"
84+
default:
85+
//skip unknown assets
86+
continue
87+
}
88+
links = append(links, link)
89+
}
90+
if len(links) == 0 {
91+
return nil, fmt.Errorf("No downloads found for release %s", release)
92+
}
93+
d.links = links
94+
return links, nil
95+
96+
}
97+
4298
func createSetupCommand(principal *models.Principal) string {
4399
userName := principal.Name
44100
userDomainName := principal.Domain
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package handlers
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/sapcc/kubernikus/pkg/api/models"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestKubernikusctlDownloadLinks(t *testing.T) {
14+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15+
fmt.Fprintln(w, releaseResponse)
16+
}))
17+
handler := getClusterInfo{githubApiURL: server.URL}
18+
links, err := handler.getLinks()
19+
assert.NoError(t, err)
20+
expected := []models.Link{
21+
models.Link{Platform: "darwin", Link: "https://github.com/sapcc/kubernikus/releases/download/v20171115131940/kubernikusctl_darwin_amd64"},
22+
models.Link{Platform: "linux", Link: "https://github.com/sapcc/kubernikus/releases/download/v20171115131940/kubernikusctl_linux_amd64"},
23+
models.Link{Platform: "windows", Link: "https://github.com/sapcc/kubernikus/releases/download/v20171115131940/kubernikusctl_windows_amd64.exe"},
24+
}
25+
assert.Equal(t, expected, links)
26+
27+
}
28+
29+
const releaseResponse = `{
30+
"url": "https://api.github.com/repos/sapcc/kubernikus/releases/8526436",
31+
"assets_url": "https://api.github.com/repos/sapcc/kubernikus/releases/8526436/assets",
32+
"upload_url": "https://uploads.github.com/repos/sapcc/kubernikus/releases/8526436/assets{?name,label}",
33+
"html_url": "https://github.com/sapcc/kubernikus/releases/tag/v20171115131940",
34+
"id": 8526436,
35+
"tag_name": "v20171115131940",
36+
"target_commitish": "10d14aeeec3e0ae063fd7e83ae121b9a10de876f",
37+
"name": "20171115131940",
38+
"draft": false,
39+
"author": {
40+
"login": "sapcc-bot",
41+
"id": 23400221,
42+
"avatar_url": "https://avatars2.githubusercontent.com/u/23400221?v=4",
43+
"gravatar_id": "",
44+
"url": "https://api.github.com/users/sapcc-bot",
45+
"html_url": "https://github.com/sapcc-bot",
46+
"followers_url": "https://api.github.com/users/sapcc-bot/followers",
47+
"following_url": "https://api.github.com/users/sapcc-bot/following{/other_user}",
48+
"gists_url": "https://api.github.com/users/sapcc-bot/gists{/gist_id}",
49+
"starred_url": "https://api.github.com/users/sapcc-bot/starred{/owner}{/repo}",
50+
"subscriptions_url": "https://api.github.com/users/sapcc-bot/subscriptions",
51+
"organizations_url": "https://api.github.com/users/sapcc-bot/orgs",
52+
"repos_url": "https://api.github.com/users/sapcc-bot/repos",
53+
"events_url": "https://api.github.com/users/sapcc-bot/events{/privacy}",
54+
"received_events_url": "https://api.github.com/users/sapcc-bot/received_events",
55+
"type": "User",
56+
"site_admin": false
57+
},
58+
"prerelease": false,
59+
"created_at": "2017-11-15T11:43:05Z",
60+
"published_at": "2017-11-15T13:21:40Z",
61+
"assets": [
62+
{
63+
"url": "https://api.github.com/repos/sapcc/kubernikus/releases/assets/5353345",
64+
"id": 5353345,
65+
"name": "kubernikusctl_darwin_amd64",
66+
"label": "",
67+
"uploader": {
68+
"login": "sapcc-bot",
69+
"id": 23400221,
70+
"avatar_url": "https://avatars2.githubusercontent.com/u/23400221?v=4",
71+
"gravatar_id": "",
72+
"url": "https://api.github.com/users/sapcc-bot",
73+
"html_url": "https://github.com/sapcc-bot",
74+
"followers_url": "https://api.github.com/users/sapcc-bot/followers",
75+
"following_url": "https://api.github.com/users/sapcc-bot/following{/other_user}",
76+
"gists_url": "https://api.github.com/users/sapcc-bot/gists{/gist_id}",
77+
"starred_url": "https://api.github.com/users/sapcc-bot/starred{/owner}{/repo}",
78+
"subscriptions_url": "https://api.github.com/users/sapcc-bot/subscriptions",
79+
"organizations_url": "https://api.github.com/users/sapcc-bot/orgs",
80+
"repos_url": "https://api.github.com/users/sapcc-bot/repos",
81+
"events_url": "https://api.github.com/users/sapcc-bot/events{/privacy}",
82+
"received_events_url": "https://api.github.com/users/sapcc-bot/received_events",
83+
"type": "User",
84+
"site_admin": false
85+
},
86+
"content_type": "application/octet-stream",
87+
"state": "uploaded",
88+
"size": 6025872,
89+
"download_count": 2,
90+
"created_at": "2017-11-15T13:21:41Z",
91+
"updated_at": "2017-11-15T13:21:52Z",
92+
"browser_download_url": "https://github.com/sapcc/kubernikus/releases/download/v20171115131940/kubernikusctl_darwin_amd64"
93+
},
94+
{
95+
"url": "https://api.github.com/repos/sapcc/kubernikus/releases/assets/5353346",
96+
"id": 5353346,
97+
"name": "kubernikusctl_linux_amd64",
98+
"label": "",
99+
"uploader": {
100+
"login": "sapcc-bot",
101+
"id": 23400221,
102+
"avatar_url": "https://avatars2.githubusercontent.com/u/23400221?v=4",
103+
"gravatar_id": "",
104+
"url": "https://api.github.com/users/sapcc-bot",
105+
"html_url": "https://github.com/sapcc-bot",
106+
"followers_url": "https://api.github.com/users/sapcc-bot/followers",
107+
"following_url": "https://api.github.com/users/sapcc-bot/following{/other_user}",
108+
"gists_url": "https://api.github.com/users/sapcc-bot/gists{/gist_id}",
109+
"starred_url": "https://api.github.com/users/sapcc-bot/starred{/owner}{/repo}",
110+
"subscriptions_url": "https://api.github.com/users/sapcc-bot/subscriptions",
111+
"organizations_url": "https://api.github.com/users/sapcc-bot/orgs",
112+
"repos_url": "https://api.github.com/users/sapcc-bot/repos",
113+
"events_url": "https://api.github.com/users/sapcc-bot/events{/privacy}",
114+
"received_events_url": "https://api.github.com/users/sapcc-bot/received_events",
115+
"type": "User",
116+
"site_admin": false
117+
},
118+
"content_type": "application/octet-stream",
119+
"state": "uploaded",
120+
"size": 5648232,
121+
"download_count": 1,
122+
"created_at": "2017-11-15T13:21:52Z",
123+
"updated_at": "2017-11-15T13:22:17Z",
124+
"browser_download_url": "https://github.com/sapcc/kubernikus/releases/download/v20171115131940/kubernikusctl_linux_amd64"
125+
},
126+
{
127+
"url": "https://api.github.com/repos/sapcc/kubernikus/releases/assets/5353347",
128+
"id": 5353347,
129+
"name": "kubernikusctl_windows_amd64.exe",
130+
"label": "",
131+
"uploader": {
132+
"login": "sapcc-bot",
133+
"id": 23400221,
134+
"avatar_url": "https://avatars2.githubusercontent.com/u/23400221?v=4",
135+
"gravatar_id": "",
136+
"url": "https://api.github.com/users/sapcc-bot",
137+
"html_url": "https://github.com/sapcc-bot",
138+
"followers_url": "https://api.github.com/users/sapcc-bot/followers",
139+
"following_url": "https://api.github.com/users/sapcc-bot/following{/other_user}",
140+
"gists_url": "https://api.github.com/users/sapcc-bot/gists{/gist_id}",
141+
"starred_url": "https://api.github.com/users/sapcc-bot/starred{/owner}{/repo}",
142+
"subscriptions_url": "https://api.github.com/users/sapcc-bot/subscriptions",
143+
"organizations_url": "https://api.github.com/users/sapcc-bot/orgs",
144+
"repos_url": "https://api.github.com/users/sapcc-bot/repos",
145+
"events_url": "https://api.github.com/users/sapcc-bot/events{/privacy}",
146+
"received_events_url": "https://api.github.com/users/sapcc-bot/received_events",
147+
"type": "User",
148+
"site_admin": false
149+
},
150+
"content_type": "application/octet-stream",
151+
"state": "uploaded",
152+
"size": 5641216,
153+
"download_count": 1,
154+
"created_at": "2017-11-15T13:22:17Z",
155+
"updated_at": "2017-11-15T13:22:37Z",
156+
"browser_download_url": "https://github.com/sapcc/kubernikus/releases/download/v20171115131940/kubernikusctl_windows_amd64.exe"
157+
}
158+
],
159+
"tarball_url": "https://api.github.com/repos/sapcc/kubernikus/tarball/v20171115131940",
160+
"zipball_url": "https://api.github.com/repos/sapcc/kubernikus/zipball/v20171115131940",
161+
"body": ""
162+
}`

pkg/api/handlers/info.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ type info struct {
1818

1919
func (d *info) Handle(params operations.InfoParams) middleware.Responder {
2020
info := &models.Info{
21-
Version: version.VERSION,
21+
Version: version.GitCommit,
2222
}
2323
return operations.NewInfoOK().WithPayload(info)
2424
}
25-
26-

pkg/apis/kubernikus/factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (klusterFactory) KlusterFor(spec models.KlusterSpec) (*v1.Kluster, error) {
7979
}
8080

8181
if k.Status.Version == "" {
82-
k.Status.Version = version.VERSION
82+
k.Status.Version = version.GitCommit
8383
}
8484

8585
for _, nodePool := range k.Spec.NodePools {

pkg/controller/operator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func NewKubernikusOperator(options *KubernikusOperatorOptions) *KubernikusOperat
167167
}
168168

169169
func (o *KubernikusOperator) Run(stopCh <-chan struct{}, wg *sync.WaitGroup) {
170-
fmt.Printf("Welcome to Kubernikus %v\n", version.VERSION)
170+
fmt.Printf("Welcome to Kubernikus %v\n", version.GitCommit)
171171

172172
kube.WaitForServer(o.Clients.Kubernetes, stopCh)
173173

pkg/templates/ignition.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (i *ignition) GenerateNode(kluster *kubernikusv1.Kluster, secret *v1.Secret
8787
OpenstackLBSubnetID: kluster.Spec.Openstack.LBSubnetID,
8888
OpenstackRouterID: kluster.Spec.Openstack.RouterID,
8989
KubernikusImage: "sapcc/kubernikus",
90-
KubernikusImageTag: version.VERSION,
90+
KubernikusImageTag: version.GitCommit,
9191
}
9292

9393
var buffer bytes.Buffer

pkg/templates/ignition_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ func TestGenerateNode(t *testing.T) {
4242
ObjectMeta: kluster.ObjectMeta,
4343
Data: secretData,
4444
}
45-
bytes, err := Ignition.GenerateNode(&kluster, &secret)
45+
_, err := Ignition.GenerateNode(&kluster, &secret)
4646
assert.NoError(t, err)
47-
48-
fmt.Printf("bytes = %+v\n", string(bytes))
49-
5047
}

pkg/version/base.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
package version
22

3-
var VERSION = "HEAD"
3+
const VERSION = "1.0.0"
4+
5+
var GitCommit = "HEAD"

0 commit comments

Comments
 (0)