Skip to content

Commit 4875b97

Browse files
committed
Merge pull request #223 from arschles/gcs-compat
fix(pkg/gitreceive): replace the AWS SDK with minio-go
2 parents a22473d + 7a62c76 commit 4875b97

19 files changed

Lines changed: 554 additions & 161 deletions

glide.lock

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

glide.yaml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import:
1111
- package: github.com/Masterminds/cookoo
1212
version: 110a04ff7dc3e7c9b86c1a2413906a16a2bb65cb
1313
subpackages:
14-
- /log
15-
- /safely
16-
- /fmt
14+
- log
15+
- safely
16+
- fmt
1717
- package: golang.org/x/crypto
1818
version: f7445b17d61953e333441674c2d11e91ae4559d3
1919
subpackages:
20-
- /ssh
20+
- ssh
2121
- package: gopkg.in/yaml.v2
2222
version: eca94c41d994ae2215d455ce578ae6e2dc6ee516
2323
- package: github.com/pborman/uuid
@@ -28,13 +28,8 @@ import:
2828
- log
2929
- package: github.com/codegangsta/cli
3030
version: a65b733b303f0055f8d324d805f393cd3e7a7904
31-
- package: github.com/aws/aws-sdk-go
32-
version: 87b1e60a50b09e4812dee560b33a238f67305804
33-
subpackages:
34-
- aws
35-
- aws/session
36-
- service/s3
3731
- package: k8s.io/kubernetes
3832
version: ~1.1
3933
- package: github.com/arschles/assert
4034
version: 6882f85ccdc7c1822b146d1a6b0c2c48f91b5140
35+
- package: github.com/minio/minio-go

pkg/gitreceive/build.go

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

14-
"github.com/aws/aws-sdk-go/service/s3"
1514
"github.com/deis/builder/pkg"
1615
"github.com/deis/builder/pkg/gitreceive/git"
1716
"github.com/deis/builder/pkg/gitreceive/storage"
@@ -21,7 +20,6 @@ import (
2120

2221
"k8s.io/kubernetes/pkg/api"
2322
client "k8s.io/kubernetes/pkg/client/unversioned"
24-
"k8s.io/kubernetes/pkg/util/wait"
2523
)
2624

2725
// repoCmd returns exec.Command(first, others...) with its current working directory repoDir
@@ -42,7 +40,7 @@ func run(cmd *exec.Cmd) error {
4240
return cmd.Run()
4341
}
4442

45-
func build(conf *Config, s3Client *s3.S3, kubeClient *client.Client, fs sys.FS, env sys.Env, builderKey, rawGitSha string) error {
43+
func build(conf *Config, s3Client *storage.Client, kubeClient *client.Client, fs sys.FS, env sys.Env, builderKey, rawGitSha string) error {
4644
repo := conf.Repository
4745
gitSha, err := git.NewSha(rawGitSha)
4846
if err != nil {
@@ -121,7 +119,7 @@ func build(conf *Config, s3Client *s3.S3, kubeClient *client.Client, fs sys.FS,
121119
return fmt.Errorf("opening %s for read (%s)", appTgz, err)
122120
}
123121

124-
log.Debug("Uploading tar to %s/%s/%s", s3Client.Endpoint, conf.Bucket, slugBuilderInfo.TarKey())
122+
log.Debug("Uploading tar to %s/%s/%s", s3Client.Endpoint.FullURL(), conf.Bucket, slugBuilderInfo.TarKey())
125123
if err := storage.UploadObject(s3Client, conf.Bucket, slugBuilderInfo.TarKey(), appTgzReader); err != nil {
126124
return fmt.Errorf("uploading %s to %s/%s (%v)", absAppTgz, conf.Bucket, slugBuilderInfo.TarKey(), err)
127125
}
@@ -193,11 +191,20 @@ func build(conf *Config, s3Client *s3.S3, kubeClient *client.Client, fs sys.FS,
193191
}
194192
log.Debug("size of streamed logs %v", size)
195193

194+
log.Debug(
195+
"Waiting for the %s/%s pod to end. Checking every %s for %s",
196+
newPod.Namespace,
197+
newPod.Name,
198+
conf.BuilderPodTickDuration(),
199+
conf.BuilderPodWaitDuration(),
200+
)
196201
// check the state and exit code of the build pod.
197202
// if the code is not 0 return error
198203
if err := waitForPodEnd(kubeClient, newPod.Namespace, newPod.Name, conf.BuilderPodTickDuration(), conf.BuilderPodWaitDuration()); err != nil {
199204
return fmt.Errorf("error getting builder pod status (%s)", err)
200205
}
206+
log.Debug("Done")
207+
log.Debug("Checking for builder pod exit code")
201208
buildPod, err := kubeClient.Pods(newPod.Namespace).Get(newPod.Name)
202209
if err != nil {
203210
return fmt.Errorf("error getting builder pod status (%s)", err)
@@ -209,37 +216,30 @@ func build(conf *Config, s3Client *s3.S3, kubeClient *client.Client, fs sys.FS,
209216
return fmt.Errorf("Build pod exited with code %d, stopping build.", state.ExitCode)
210217
}
211218
}
212-
219+
log.Debug("Done")
220+
221+
log.Debug(
222+
"Polling the S3 server every %s for %s for the resultant slug at %s/%s",
223+
conf.ObjectStorageTickDuration(),
224+
conf.ObjectStorageWaitDuration(),
225+
conf.Bucket,
226+
slugBuilderInfo.AbsoluteSlugObjectKey(),
227+
)
213228
// poll the s3 server to ensure the slug exists
214-
err = wait.PollImmediate(conf.ObjectStorageTickDuration(), conf.ObjectStorageWaitDuration(), func() (bool, error) {
215-
exists, err := storage.ObjectExists(s3Client, conf.Bucket, slugBuilderInfo.PushKey())
216-
if err != nil {
217-
return false, fmt.Errorf("Checking if object %s/%s exists (%s)", conf.Bucket, slugBuilderInfo.PushKey(), err)
218-
}
219-
return exists, nil
220-
})
221-
222-
if err != nil {
223-
return fmt.Errorf("Timed out waiting for object in storage. Aborting build...")
229+
if err := storage.WaitForObject(
230+
s3Client,
231+
conf.Bucket,
232+
slugBuilderInfo.AbsoluteSlugObjectKey(),
233+
conf.ObjectStorageTickDuration(),
234+
conf.ObjectStorageWaitDuration(),
235+
); err != nil {
236+
return fmt.Errorf("Timed out waiting for object in storage, aborting build (%s)", err)
224237
}
225238
log.Info("Build complete.")
226239
log.Info("Launching app.")
227240
log.Info("Launching...")
228241

229-
buildHook := &pkg.BuildHook{
230-
Sha: gitSha.Short(),
231-
ReceiveUser: conf.Username,
232-
ReceiveRepo: appName,
233-
Image: appName,
234-
Procfile: procType,
235-
}
236-
if !usingDockerfile {
237-
buildHook.Dockerfile = ""
238-
// need this to tell the controller what URL to give the slug runner
239-
buildHook.Image = slugBuilderInfo.PushURL() + "/slug.tgz"
240-
} else {
241-
buildHook.Dockerfile = "true"
242-
}
242+
buildHook := createBuildHook(slugBuilderInfo, gitSha, conf.Username, appName, procType, usingDockerfile)
243243
buildHookResp, err := publishRelease(conf, builderKey, buildHook)
244244
if err != nil {
245245
return fmt.Errorf("publishing release (%s)", err)

pkg/gitreceive/controller.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"strings"
1010

1111
"github.com/deis/builder/pkg"
12+
"github.com/deis/builder/pkg/gitreceive/git"
13+
"github.com/deis/builder/pkg/gitreceive/storage"
1214
"github.com/deis/pkg/log"
1315
)
1416

@@ -148,3 +150,28 @@ func receive(conf *Config, builderKey, gitSha string) error {
148150
}
149151
return nil
150152
}
153+
154+
func createBuildHook(
155+
slugBuilderInfo *storage.SlugBuilderInfo,
156+
gitSha *git.SHA,
157+
username,
158+
appName string,
159+
procType pkg.ProcessType,
160+
usingDockerfile bool,
161+
) *pkg.BuildHook {
162+
ret := &pkg.BuildHook{
163+
Sha: gitSha.Short(),
164+
ReceiveUser: username,
165+
ReceiveRepo: appName,
166+
Image: appName,
167+
Procfile: procType,
168+
}
169+
if !usingDockerfile {
170+
ret.Dockerfile = ""
171+
// need this to tell the controller what URL to give the slug runner
172+
ret.Image = slugBuilderInfo.AbsoluteSlugURL()
173+
} else {
174+
ret.Dockerfile = "true"
175+
}
176+
return ret
177+
}

pkg/gitreceive/controller_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package gitreceive
2+
3+
import (
4+
"testing"
5+
6+
"github.com/arschles/assert"
7+
"github.com/deis/builder/pkg"
8+
"github.com/deis/builder/pkg/gitreceive/git"
9+
"github.com/deis/builder/pkg/gitreceive/storage"
10+
)
11+
12+
const (
13+
rawSha = "c3b4e4ba8b7267226ff02ad07a3a2cca9c9237de"
14+
bucket = "git"
15+
appName = "myapp"
16+
slugName = "myslug"
17+
username = "myuser"
18+
)
19+
20+
func TestCreateBuildHook(t *testing.T) {
21+
procType := pkg.ProcessType(make(map[string]string))
22+
sha, err := git.NewSha(rawSha)
23+
assert.NoErr(t, err)
24+
endpoint := &storage.Endpoint{URLStr: "s3.amazonaws.com", Secure: false}
25+
slugBuilderInfo := storage.NewSlugBuilderInfo(endpoint, bucket, appName, slugName, sha)
26+
hookUsingDockerfile := createBuildHook(slugBuilderInfo, sha, username, appName, procType, true)
27+
assert.Equal(t, hookUsingDockerfile.Sha, sha.Short(), "git sha")
28+
assert.Equal(t, hookUsingDockerfile.ReceiveUser, username, "username")
29+
assert.Equal(t, hookUsingDockerfile.ReceiveRepo, appName, "username")
30+
assert.Equal(t, hookUsingDockerfile.Image, appName, "image")
31+
assert.Equal(t, hookUsingDockerfile.Procfile, procType, "procfile")
32+
assert.Equal(t, hookUsingDockerfile.Dockerfile, "true", "dockerfile field")
33+
34+
hookNoDockerfile := createBuildHook(slugBuilderInfo, sha, username, appName, procType, false)
35+
assert.Equal(t, hookNoDockerfile.Sha, sha.Short(), "git sha")
36+
assert.Equal(t, hookNoDockerfile.ReceiveUser, username, "username")
37+
assert.Equal(t, hookNoDockerfile.ReceiveRepo, appName, "username")
38+
assert.Equal(t, hookNoDockerfile.Image, slugBuilderInfo.AbsoluteSlugURL(), "image")
39+
assert.Equal(t, hookNoDockerfile.Procfile, procType, "procfile")
40+
assert.Equal(t, hookNoDockerfile.Dockerfile, "", "dockerfile field")
41+
42+
}

pkg/gitreceive/storage/auth.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"os"
66
"strings"
77

8-
"github.com/aws/aws-sdk-go/aws/credentials"
98
"github.com/deis/builder/pkg/sys"
109
)
1110

@@ -17,18 +16,27 @@ const (
1716
var (
1817
errMissingKey = fmt.Errorf("missing %s", accessKeyIDFile)
1918
errMissingSecret = fmt.Errorf("missing %s", accessSecretKeyFile)
20-
emptyAuth = credentials.AnonymousCredentials
19+
emptyCreds = creds{}
2120
)
2221

22+
type creds struct {
23+
accessKeyID string
24+
accessKeySecret string
25+
}
26+
27+
func (c *creds) isZero() bool {
28+
return c.accessKeyID == "" && c.accessKeySecret == ""
29+
}
30+
2331
// getAuth gets storage credentials from accessKeyIDFile and accessSecretKeyFile.
2432
// if a key exists but not a secret, or vice-versa, returns an error.
2533
// if both don't exist returns emptyAuth.
2634
// otherwise returns a valid auth
27-
func getAuth(fs sys.FS) (*credentials.Credentials, error) {
35+
func getAuth(fs sys.FS) (*creds, error) {
2836
accessKeyIDBytes, accessKeyErr := fs.ReadFile(accessKeyIDFile)
2937
accessSecretKeyBytes, accessSecretKeyErr := fs.ReadFile(accessSecretKeyFile)
3038
if accessKeyErr == os.ErrNotExist && accessSecretKeyErr == os.ErrNotExist {
31-
return emptyAuth, nil
39+
return &emptyCreds, nil
3240
}
3341
if accessKeyErr != nil && accessSecretKeyErr == nil {
3442
return nil, errMissingKey
@@ -39,18 +47,17 @@ func getAuth(fs sys.FS) (*credentials.Credentials, error) {
3947

4048
id := strings.TrimSpace(string(accessKeyIDBytes))
4149
secret := strings.TrimSpace(string(accessSecretKeyBytes))
42-
return credentials.NewStaticCredentials(id, secret, ""), nil
50+
return &creds{accessKeyID: id, accessKeySecret: secret}, nil
4351
}
4452

4553
// CredsOK checks if the required credentials to make a request exist
4654
func CredsOK(fs sys.FS) bool {
47-
cred, err := getAuth(fs)
55+
creds, err := getAuth(fs)
4856
if err != nil {
4957
return false
5058
}
5159

52-
auth, _ := cred.Get()
53-
if auth.AccessKeyID == "" && auth.SecretAccessKey == "" {
60+
if creds.accessKeyID == "" && creds.accessKeySecret == "" {
5461
return false
5562
}
5663

0 commit comments

Comments
 (0)