Skip to content

Commit 6c7f756

Browse files
authored
Merge pull request #809 from dgageot/guess-gcb-projectId
Try to guess GCB projectID from the image name
2 parents f614956 + f0c9659 commit 6c7f756

File tree

2 files changed

+123
-11
lines changed

2 files changed

+123
-11
lines changed

pkg/skaffold/build/container_builder.go

+48-11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/json"
2222
"fmt"
2323
"io"
24+
"strings"
2425
"time"
2526

2627
cstorage "cloud.google.com/go/storage"
@@ -30,6 +31,8 @@ import (
3031
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2"
3132
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
3233
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/version"
34+
"github.com/docker/distribution/reference"
35+
"github.com/docker/docker/registry"
3336
"github.com/pkg/errors"
3437
"github.com/sirupsen/logrus"
3538
"golang.org/x/oauth2/google"
@@ -116,13 +119,18 @@ func (cb *GoogleCloudBuilder) buildArtifact(ctx context.Context, out io.Writer,
116119
}
117120
logrus.Debugf("Build args: %s", buildArgs)
118121

119-
cbBucket := fmt.Sprintf("%s%s", cb.ProjectID, constants.GCSBucketSuffix)
120-
buildObject := fmt.Sprintf("source/%s-%s.tar.gz", cb.ProjectID, util.RandomID())
122+
projectID, err := cb.guessProjectID(artifact)
123+
if err != nil {
124+
return "", errors.Wrap(err, "getting projectID")
125+
}
126+
127+
cbBucket := fmt.Sprintf("%s%s", projectID, constants.GCSBucketSuffix)
128+
buildObject := fmt.Sprintf("source/%s-%s.tar.gz", projectID, util.RandomID())
121129

122-
if err := cb.createBucketIfNotExists(ctx, cbBucket); err != nil {
130+
if err := cb.createBucketIfNotExists(ctx, projectID, cbBucket); err != nil {
123131
return "", errors.Wrap(err, "creating bucket if not exists")
124132
}
125-
if err := cb.checkBucketProjectCorrect(ctx, cbBucket); err != nil {
133+
if err := cb.checkBucketProjectCorrect(ctx, projectID, cbBucket); err != nil {
126134
return "", errors.Wrap(err, "checking bucket is in correct project")
127135
}
128136

@@ -133,7 +141,7 @@ func (cb *GoogleCloudBuilder) buildArtifact(ctx context.Context, out io.Writer,
133141

134142
args := append([]string{"build", "--tag", artifact.ImageName, "-f", artifact.DockerArtifact.DockerfilePath}, buildArgs...)
135143
args = append(args, ".")
136-
call := cbclient.Projects.Builds.Create(cb.ProjectID, &cloudbuild.Build{
144+
call := cbclient.Projects.Builds.Create(projectID, &cloudbuild.Build{
137145
LogsBucket: cbBucket,
138146
Source: &cloudbuild.Source{
139147
StorageSource: &cloudbuild.StorageSource{
@@ -169,7 +177,7 @@ func (cb *GoogleCloudBuilder) buildArtifact(ctx context.Context, out io.Writer,
169177
watch:
170178
for {
171179
logrus.Debugf("current offset %d", offset)
172-
b, err := cbclient.Projects.Builds.Get(cb.ProjectID, remoteID).Do()
180+
b, err := cbclient.Projects.Builds.Get(projectID, remoteID).Do()
173181
if err != nil {
174182
return "", errors.Wrap(err, "getting build status")
175183
}
@@ -226,6 +234,35 @@ watch:
226234
return newTag, nil
227235
}
228236

237+
func (cb *GoogleCloudBuilder) guessProjectID(artifact *v1alpha2.Artifact) (string, error) {
238+
if cb.ProjectID != "" {
239+
return cb.ProjectID, nil
240+
}
241+
242+
ref, err := reference.ParseNormalizedNamed(artifact.ImageName)
243+
if err != nil {
244+
return "", errors.Wrap(err, "parsing image name for registry")
245+
}
246+
247+
repoInfo, err := registry.ParseRepositoryInfo(ref)
248+
if err != nil {
249+
return "", err
250+
}
251+
252+
index := repoInfo.Index
253+
if !index.Official {
254+
switch index.Name {
255+
case "gcr.io", "us.gcr.io", "eu.gcr.io", "asia.gcr.io", "staging-k8s.gcr.io":
256+
parts := strings.Split(repoInfo.Name.String(), "/")
257+
if len(parts) >= 2 {
258+
return parts[1], nil
259+
}
260+
}
261+
}
262+
263+
return "", fmt.Errorf("unable to guess GCP projectID from image name [%s]", artifact.ImageName)
264+
}
265+
229266
func getBuildID(op *cloudbuild.Operation) (string, error) {
230267
if op.Metadata == nil {
231268
return "", errors.New("missing Metadata in operation")
@@ -272,12 +309,12 @@ func (cb *GoogleCloudBuilder) getLogs(ctx context.Context, offset int64, bucket,
272309
return r, nil
273310
}
274311

275-
func (cb *GoogleCloudBuilder) checkBucketProjectCorrect(ctx context.Context, bucket string) error {
312+
func (cb *GoogleCloudBuilder) checkBucketProjectCorrect(ctx context.Context, projectID, bucket string) error {
276313
c, err := cstorage.NewClient(ctx)
277314
if err != nil {
278315
return errors.Wrap(err, "getting storage client")
279316
}
280-
it := c.Buckets(ctx, cb.ProjectID)
317+
it := c.Buckets(ctx, projectID)
281318
// Set the prefix to the bucket we're looking for to only return that bucket and buckets with that prefix
282319
// that we'll filter further later on
283320
it.Prefix = bucket
@@ -297,7 +334,7 @@ func (cb *GoogleCloudBuilder) checkBucketProjectCorrect(ctx context.Context, buc
297334

298335
}
299336

300-
func (cb *GoogleCloudBuilder) createBucketIfNotExists(ctx context.Context, bucket string) error {
337+
func (cb *GoogleCloudBuilder) createBucketIfNotExists(ctx context.Context, projectID, bucket string) error {
301338
c, err := cstorage.NewClient(ctx)
302339
if err != nil {
303340
return errors.Wrap(err, "getting storage client")
@@ -315,11 +352,11 @@ func (cb *GoogleCloudBuilder) createBucketIfNotExists(ctx context.Context, bucke
315352
return errors.Wrapf(err, "getting bucket %s", bucket)
316353
}
317354

318-
if err := c.Bucket(bucket).Create(ctx, cb.ProjectID, &cstorage.BucketAttrs{
355+
if err := c.Bucket(bucket).Create(ctx, projectID, &cstorage.BucketAttrs{
319356
Name: bucket,
320357
}); err != nil {
321358
return err
322359
}
323-
logrus.Debugf("Created bucket %s in %s", bucket, cb.ProjectID)
360+
logrus.Debugf("Created bucket %s in %s", bucket, projectID)
324361
return nil
325362
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Copyright 2018 The Skaffold Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package build
18+
19+
import (
20+
"testing"
21+
22+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2"
23+
"github.com/GoogleContainerTools/skaffold/testutil"
24+
)
25+
26+
func TestGuessProjectID(t *testing.T) {
27+
var tests = []struct {
28+
description string
29+
config *v1alpha2.GoogleCloudBuild
30+
artifact *v1alpha2.Artifact
31+
expected string
32+
shouldErr bool
33+
}{
34+
{
35+
description: "fixed projectId",
36+
config: &v1alpha2.GoogleCloudBuild{ProjectID: "fixed"},
37+
artifact: &v1alpha2.Artifact{ImageName: "any"},
38+
expected: "fixed",
39+
},
40+
{
41+
description: "gcr.io",
42+
config: &v1alpha2.GoogleCloudBuild{},
43+
artifact: &v1alpha2.Artifact{ImageName: "gcr.io/project/image"},
44+
expected: "project",
45+
},
46+
{
47+
description: "eu.gcr.io",
48+
config: &v1alpha2.GoogleCloudBuild{},
49+
artifact: &v1alpha2.Artifact{ImageName: "gcr.io/project/image"},
50+
expected: "project",
51+
},
52+
{
53+
description: "docker hub",
54+
config: &v1alpha2.GoogleCloudBuild{},
55+
artifact: &v1alpha2.Artifact{ImageName: "project/image"},
56+
shouldErr: true,
57+
},
58+
{
59+
description: "invalid GCR image",
60+
config: &v1alpha2.GoogleCloudBuild{},
61+
artifact: &v1alpha2.Artifact{ImageName: "gcr.io"},
62+
shouldErr: true,
63+
},
64+
}
65+
66+
for _, test := range tests {
67+
t.Run(test.description, func(t *testing.T) {
68+
builder := NewGoogleCloudBuilder(test.config)
69+
70+
projectID, err := builder.guessProjectID(test.artifact)
71+
72+
testutil.CheckErrorAndDeepEqual(t, test.shouldErr, err, test.expected, projectID)
73+
})
74+
}
75+
}

0 commit comments

Comments
 (0)