Skip to content

Commit e292969

Browse files
feat(*): switch to using controller-sdk-go for controller interactions (#402)
1 parent 9629215 commit e292969

18 files changed

Lines changed: 191 additions & 466 deletions

glide.lock

Lines changed: 34 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ import:
4141
version: 8e7dc108ab3a1ab6ce6d922bbaff5657b88e8e49
4242
repo: https://github.com/spf13/pflag
4343
vcs: git
44+
- package: github.com/deis/controller-sdk-go
45+
version: 1c9d1c9821ed4984babf7136f1de46ac1698590a

pkg/controller/utils.go

Lines changed: 19 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,48 @@
11
package controller
22

33
import (
4-
"crypto/md5"
5-
"encoding/hex"
6-
"encoding/json"
74
"fmt"
8-
"net/http"
95
"os"
10-
"strings"
116

127
"github.com/deis/builder/pkg/conf"
13-
"golang.org/x/crypto/ssh"
8+
deis "github.com/deis/controller-sdk-go"
9+
"github.com/deis/pkg/log"
1410
)
1511

1612
const (
1713
hostEnvName = "DEIS_CONTROLLER_SERVICE_HOST"
1814
portEnvName = "DEIS_CONTROLLER_SERVICE_PORT"
1915
)
2016

21-
// UserInfo represents the required information from a user to make a push and interact with the
22-
// controller
23-
type UserInfo struct {
24-
Username string
25-
Key string
26-
Fingerprint string
27-
Apps []string
28-
}
29-
30-
// URLStr returns the url of the controller with the given path prepended.
31-
func URLStr(additionalPath ...string) (string, error) {
17+
// New creates a new SDK client configured as the builder.
18+
func New() (*deis.Client, error) {
3219
host := os.Getenv(hostEnvName)
3320
port := os.Getenv(portEnvName)
3421

35-
if host == "" {
36-
return "", fmt.Errorf("missing required '%v' environment variable", hostEnvName)
37-
}
38-
39-
if port == "" {
40-
return "", fmt.Errorf("missing required '%v' environment variable", portEnvName)
41-
}
42-
43-
return fmt.Sprintf("http://%s:%s/%s", host, port, strings.Join(additionalPath, "/")), nil
44-
}
45-
46-
// fingerprint generates a colon-separated fingerprint string from a public key.
47-
func fingerprint(key ssh.PublicKey) string {
48-
hash := md5.Sum(key.Marshal())
49-
buf := make([]byte, hex.EncodedLen(len(hash)))
50-
hex.Encode(buf, hash[:])
51-
// We need this in colon notation:
52-
fp := make([]byte, len(buf)+15)
53-
54-
i, j := 0, 0
55-
for ; i < len(buf); i++ {
56-
if i > 0 && i%2 == 0 {
57-
fp[j] = ':'
58-
j++
59-
}
60-
fp[j] = buf[i]
61-
j++
62-
}
63-
return string(fp)
64-
}
65-
66-
// UserInfoFromKey makes a request to the controller to get the user info from they given key.
67-
func UserInfoFromKey(key ssh.PublicKey) (*UserInfo, error) {
68-
fp := fingerprint(key)
69-
url, err := URLStr("v2", "hooks", "key", fp)
70-
if err != nil {
71-
return nil, err
72-
}
73-
74-
req, err := http.NewRequest("GET", url, nil)
22+
client, err := deis.New(true, fmt.Sprintf("http://%s:%s/", host, port), "")
7523
if err != nil {
76-
return nil, err
24+
return client, err
7725
}
26+
client.UserAgent = "deis-builder"
7827

7928
builderKey, err := conf.GetBuilderKey()
8029
if err != nil {
81-
return nil, err
30+
return client, err
8231
}
32+
client.HooksToken = builderKey
8333

84-
req.Header.Add("Content-Type", "application/json")
85-
req.Header.Add("Accept", "application/json")
86-
req.Header.Add("User-Agent", "deis-builder")
87-
req.Header.Add("X-Deis-Builder-Auth", builderKey)
34+
return client, nil
35+
}
8836

89-
res, err := http.DefaultClient.Do(req)
90-
if err != nil {
91-
return nil, err
92-
}
93-
defer res.Body.Close()
37+
// CheckAPICompat checks for API compatibility errors and warns about them.
38+
func CheckAPICompat(c *deis.Client, err error) error {
39+
if err == deis.ErrAPIMismatch {
40+
log.Info("WARNING: SDK and Controller API versions do not match. SDK: %s Controller: %s",
41+
deis.APIVersion, c.ControllerAPIVersion)
9442

95-
if res.StatusCode != 200 {
96-
return nil, fmt.Errorf("user has no permissions to push in application")
43+
// API mismatch isn't fatal, so after warning continue on.
44+
return nil
9745
}
9846

99-
ret := &UserInfo{}
100-
if err := json.NewDecoder(res.Body).Decode(ret); err != nil {
101-
return nil, err
102-
}
103-
ret.Fingerprint = fp
104-
return ret, nil
47+
return err
10548
}

pkg/gitreceive/build.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ import (
1111
"path/filepath"
1212
"strings"
1313

14-
"github.com/deis/builder/pkg"
14+
"github.com/deis/builder/pkg/controller"
1515
"github.com/deis/builder/pkg/git"
1616
"github.com/deis/builder/pkg/k8s"
1717
"github.com/deis/builder/pkg/storage"
1818
"github.com/deis/builder/pkg/sys"
19+
"github.com/deis/controller-sdk-go"
20+
deisAPI "github.com/deis/controller-sdk-go/api"
21+
"github.com/deis/controller-sdk-go/hooks"
1922
"github.com/deis/pkg/log"
2023
"github.com/docker/distribution/context"
2124
storagedriver "github.com/docker/distribution/registry/storage/driver"
@@ -44,6 +47,7 @@ func run(cmd *exec.Cmd) error {
4447
}
4548

4649
func build(
50+
client *deis.Client,
4751
conf *Config,
4852
storageDriver storagedriver.StorageDriver,
4953
kubeClient *client.Client,
@@ -91,11 +95,12 @@ func build(
9195
slugBuilderInfo := NewSlugBuilderInfo(slugName)
9296

9397
// Get the application config from the controller, so we can check for a custom buildpack URL
94-
appConf, err := getAppConfig(conf, builderKey, conf.Username, appName)
95-
if err != nil {
96-
return fmt.Errorf("getting app config for %s (%s)", appName, err)
98+
appConf, err := hooks.GetAppConfig(client, conf.Username, appName)
99+
if controller.CheckAPICompat(client, err) != nil {
100+
return err
97101
}
98-
log.Debug("got the following config back for app %s: %+v", appName, *appConf)
102+
103+
log.Debug("got the following config back for app %s: %+v", appName, appConf)
99104
var buildPackURL string
100105
if buildPackURLInterface, ok := appConf.Values["BUILDPACK_URL"]; ok {
101106
if bpStr, ok := buildPackURLInterface.(string); ok {
@@ -252,26 +257,24 @@ func build(
252257
}
253258
log.Debug("Done")
254259

255-
procType := pkg.ProcessType{}
260+
procType := deisAPI.ProcessType{}
256261
if procType, err = getProcFile(storageDriver, tmpDir, slugBuilderInfo.AbsoluteProcfileKey(), bType); err != nil {
257262
return err
258263
}
259264

260265
log.Info("Build complete.")
261266

262-
buildHook := createBuildHook(slugBuilderInfo, gitSha, conf.Username, appName, image, procType, usingDockerfile)
263267
quit := progress("...", conf.SessionIdleInterval())
264268
log.Info("Launching App...")
265-
buildHookResp, err := publishRelease(conf, builderKey, buildHook)
269+
if !usingDockerfile {
270+
image = slugBuilderInfo.AbsoluteSlugObjectKey()
271+
}
272+
release, err := hooks.CreateBuild(client, conf.Username, conf.App(), image, gitSha.Short(), procType, usingDockerfile)
266273
quit <- true
267274
<-quit
268-
if err != nil {
275+
if controller.CheckAPICompat(client, err) != nil {
269276
return fmt.Errorf("publishing release (%s)", err)
270277
}
271-
release, ok := buildHookResp.Release["version"]
272-
if !ok {
273-
return fmt.Errorf("No release returned from Deis controller")
274-
}
275278

276279
log.Info("Done, %s:v%d deployed to Deis\n", appName, release)
277280
log.Info("Use 'deis open' to view this application in your browser\n")
@@ -294,8 +297,8 @@ func prettyPrintJSON(data interface{}) (string, error) {
294297
return string(formatted.Bytes()), nil
295298
}
296299

297-
func getProcFile(getter storage.ObjectGetter, dirName, procfileKey string, bType buildType) (pkg.ProcessType, error) {
298-
procType := pkg.ProcessType{}
300+
func getProcFile(getter storage.ObjectGetter, dirName, procfileKey string, bType buildType) (deisAPI.ProcessType, error) {
301+
procType := deisAPI.ProcessType{}
299302
if _, err := os.Stat(fmt.Sprintf("%s/Procfile", dirName)); err == nil {
300303
rawProcFile, err := ioutil.ReadFile(fmt.Sprintf("%s/Procfile", dirName))
301304
if err != nil {

pkg/gitreceive/build_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"testing"
99

1010
"github.com/arschles/assert"
11-
"github.com/deis/builder/pkg"
1211
"github.com/deis/builder/pkg/storage"
12+
"github.com/deis/controller-sdk-go/api"
1313
"github.com/docker/distribution/context"
1414
"gopkg.in/yaml.v2"
1515
)
@@ -35,7 +35,7 @@ func TestGetProcFileFromRepoSuccess(t *testing.T) {
3535
}()
3636
getter := &storage.FakeObjectGetter{}
3737
procType, err := getProcFile(getter, tmpDir, objKey, buildTypeProcfile)
38-
actualData := pkg.ProcessType{}
38+
actualData := api.ProcessType{}
3939
yaml.Unmarshal(data, &actualData)
4040
assert.NoErr(t, err)
4141
assert.Equal(t, procType, actualData, "data")
@@ -70,7 +70,7 @@ func TestGetProcFileFromServerSuccess(t *testing.T) {
7070
}
7171

7272
procType, err := getProcFile(getter, "", objKey, buildTypeProcfile)
73-
actualData := pkg.ProcessType{}
73+
actualData := api.ProcessType{}
7474
yaml.Unmarshal(data, &actualData)
7575
assert.NoErr(t, err)
7676
assert.Equal(t, procType, actualData, "data")

pkg/gitreceive/constants.go

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)