github.com/GoogleContainerTools/skaffold/v2@v2.13.2/integration/ko_test.go (about) 1 /* 2 Copyright 2021 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 integration 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 stdlog "log" 24 "net/http/httptest" 25 "path/filepath" 26 "runtime" 27 "testing" 28 29 "github.com/google/go-containerregistry/pkg/crane" 30 "github.com/google/go-containerregistry/pkg/registry" 31 "github.com/google/go-containerregistry/pkg/v1/mutate" 32 "github.com/google/go-containerregistry/pkg/v1/random" 33 34 "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/build/ko" 35 "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config" 36 "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/platform" 37 "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest" 38 ) 39 40 func TestBuildAndPushKoImageProgrammatically(t *testing.T) { 41 MarkIntegrationTest(t, CanRunWithoutGcp) 42 43 // Start a local registry server. 44 // This registry hosts the base image, and it is the target registry for the built image. 45 baseimageNamespace := "baseimage" 46 registryServer, err := registryServerWithImage(baseimageNamespace) 47 if err != nil { 48 t.Fatalf("could not create test registry server: %v", err) 49 } 50 defer registryServer.Close() 51 registryAddr := registryServer.Listener.Addr().String() 52 baseImage := fmt.Sprintf("%s/%s", registryAddr, baseimageNamespace) 53 54 // Get the directory of the basic ko sample app from the `examples` directory. 55 exampleAppDir, err := koExampleAppDir() 56 if err != nil { 57 t.Fatalf("could not get ko example app dir: %+v", err) 58 } 59 60 // Build the artifact 61 b := ko.NewArtifactBuilder(nil, true, config.RunModes.Build, nil) 62 artifact := &latest.Artifact{ 63 ArtifactType: latest.ArtifactType{ 64 KoArtifact: &latest.KoArtifact{ 65 BaseImage: baseImage, 66 }, 67 }, 68 Workspace: exampleAppDir, 69 } 70 imageName := fmt.Sprintf("%s/%s", registryAddr, "skaffold-ko") 71 _, err = b.Build(context.Background(), nil, artifact, imageName, platform.Matcher{}) 72 if err != nil { 73 t.Fatalf("b.Build(): %+v", err) 74 } 75 } 76 77 // registryServerWithImage starts a local registry and pushes a random image. 78 // Use this to speed up tests, by not having to reach out to a real registry. 79 // The registry uses a NOP logger to avoid spamming test logs. 80 // Remember to call `defer Close()` on the returned `httptest.Server`. 81 func registryServerWithImage(namespace string) (*httptest.Server, error) { 82 nopLog := stdlog.New(io.Discard, "", 0) 83 r := registry.New(registry.Logger(nopLog)) 84 s := httptest.NewServer(r) 85 imageName := fmt.Sprintf("%s/%s", s.Listener.Addr().String(), namespace) 86 image, err := random.Image(1024, 1) 87 if err != nil { 88 return nil, fmt.Errorf("random.Image(): %+v", err) 89 } 90 // ko 0.12 starts to validate image platform, the random generated image doesn't that info, we need to manually to set 91 // image platform back to the image. image.ConfigFile() is a deepCopy() method, we need to use mutate.ConfigFile() to inject 92 // the platform info. 93 configFile, _ := image.ConfigFile() 94 configFile.OS = runtime.GOOS 95 configFile.Architecture = runtime.GOARCH 96 configFile.OSVersion = runtime.Version() 97 98 image, err = mutate.ConfigFile(image, configFile) 99 if err != nil { 100 return nil, fmt.Errorf("failed to mutate image: %+v", err) 101 } 102 103 err = crane.Push(image, imageName) 104 if err != nil { 105 return nil, fmt.Errorf("crane.Push(): %+v", err) 106 } 107 return s, nil 108 } 109 110 // koExampleAppDir returns the directory path of the basic ko builder sample app. 111 func koExampleAppDir() (string, error) { 112 _, filename, _, ok := runtime.Caller(0) 113 if !ok { 114 return "", fmt.Errorf("could not get current filename") 115 } 116 basepath := filepath.Dir(filename) 117 exampleDir, err := filepath.Abs(filepath.Join(basepath, "examples", "ko")) 118 if err != nil { 119 return "", fmt.Errorf("could not get absolute path of example from basepath %q: %w", basepath, err) 120 } 121 return exampleDir, nil 122 }