Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.7.x] more ci related backports #1293

Merged
merged 4 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -113,24 +113,6 @@ jobs:
builder: gcr.io/cf-build-service-public/ci/kpack-builder
additional_pack_args: '--env BP_GIT2GO_ENABLED="true" --env BP_GIT2GO_USE_LIBSSL="true"'

build-waiter-image:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Docker Login
uses: docker/[email protected]
with:
registry: ${{ secrets.REGISTRY_HOST }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build
uses: ./.github/actions/pack-build
with:
pack_version: ${{ env.PACK_VERSION }}
tag: ${{ env.PUBLIC_IMAGE_DEV_REPO }}/build-waiter
bp_go_targets: "./cmd/build-waiter"

rebase-image:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -194,12 +176,20 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Docker Login
uses: docker/[email protected]
with:
registry: ${{ secrets.REGISTRY_HOST }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
- name: Build
run: |
trap 'echo -e "$output"' EXIT

output=$(go run ./hack/lifecycle/main.go --tag=${{ env.PUBLIC_IMAGE_DEV_REPO }}/lifecycle 2>&1)
image=$(echo "$output" | grep "saved lifecycle" | awk -F "saved lifecycle image: " '{print $2}')
mkdir images
Expand Down
11 changes: 8 additions & 3 deletions test/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import (
"os"
"strconv"
"testing"

"github.com/google/go-containerregistry/pkg/authn"
)

type config struct {
builder string
testRegistry string
imageTag string

generatedImageNames []string
}

func loadConfig(t *testing.T) config {
Expand All @@ -29,6 +29,11 @@ func loadConfig(t *testing.T) config {

func (c *config) newImageTag() string {
genTag := c.imageTag + "-" + strconv.Itoa(rand.Int())
c.generatedImageNames = append(c.generatedImageNames, genTag)
return genTag
}

type dockerCredentials map[string]authn.AuthConfig

type dockerConfigJson struct {
Auths dockerCredentials `json:"auths"`
}
91 changes: 66 additions & 25 deletions test/execute_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package test
import (
"bytes"
"context"
"encoding/json"
"fmt"
"math/rand"
"os"
Expand All @@ -14,7 +15,6 @@ import (
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/sclevine/spec"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -53,13 +53,15 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
)

var (
cfg config
clients *clients
ctx = context.Background()
cfg config
clients *clients
ctx = context.Background()
builtImages map[string]struct{}
)

it.Before(func() {
cfg = loadConfig(t)
builtImages = map[string]struct{}{}

var err error
clients, err = newClients(t)
Expand Down Expand Up @@ -92,7 +94,7 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
})

it.After(func() {
for _, tag := range cfg.generatedImageNames {
for tag := range builtImages {
deleteImageTag(t, tag)
}
})
Expand All @@ -107,18 +109,35 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
basicAuth, err := auth.Authorization()
require.NoError(t, err)

reg := cfg.testRegistry
// Handle path in registry
if strings.ContainsRune(reg, '/') {
r, err := name.NewRepository(reg, name.WeakValidation)
require.NoError(t, err)
reg = r.RegistryStr()
}

configJson := dockerConfigJson{Auths: dockerCredentials{
reg: authn.AuthConfig{
Username: basicAuth.Username,
Password: basicAuth.Password,
},
}}
dockerCfgJson, err := json.Marshal(configJson)
require.NoError(t, err)

_, err = clients.k8sClient.CoreV1().Secrets(testNamespace).Create(ctx, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: dockerSecret,
Name: dockerSecret,
Namespace: testNamespace,
Annotations: map[string]string{
"kpack.io/docker": reference.Context().RegistryStr(),
},
},
StringData: map[string]string{
"username": basicAuth.Username,
"password": basicAuth.Password,
Data: map[string][]byte{
corev1.DockerConfigJsonKey: dockerCfgJson,
},
Type: corev1.SecretTypeBasicAuth,
Type: corev1.SecretTypeDockerConfigJson,
}, metav1.CreateOptions{})
require.NoError(t, err)

Expand All @@ -131,6 +150,11 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
Name: dockerSecret,
},
},
ImagePullSecrets: []corev1.LocalObjectReference{
{
Name: dockerSecret,
},
},
}, metav1.CreateOptions{})
require.NoError(t, err)

Expand Down Expand Up @@ -384,7 +408,7 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
}, metav1.CreateOptions{})
require.NoError(t, err)

validateImageCreate(t, clients, image, expectedResources)
builtImages[validateImageCreate(t, clients, image, expectedResources)] = struct{}{}
validateRebase(t, ctx, clients, image.Name, testNamespace)
})
}
Expand All @@ -400,7 +424,7 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
},
}

generateRebuild(&ctx, t, cfg, clients, volumeCacheConfig, testNamespace, clusterBuilderName, serviceAccountName)
builtImages[generateRebuild(&ctx, t, cfg, clients, volumeCacheConfig, testNamespace, clusterBuilderName, serviceAccountName)] = struct{}{}
})

it("can trigger rebuilds with registry cache", func() {
Expand All @@ -411,11 +435,11 @@ func testCreateImage(t *testing.T, when spec.G, it spec.S) {
Tag: cacheImageTag,
},
}
generateRebuild(&ctx, t, cfg, clients, registryCacheConfig, testNamespace, clusterBuilderName, serviceAccountName)
builtImages[generateRebuild(&ctx, t, cfg, clients, registryCacheConfig, testNamespace, clusterBuilderName, serviceAccountName)] = struct{}{}
})
}

func generateRebuild(ctx *context.Context, t *testing.T, cfg config, clients *clients, cacheConfig *buildapi.ImageCacheConfig, testNamespace, clusterBuilderName, serviceAccountName string) {
func generateRebuild(ctx *context.Context, t *testing.T, cfg config, clients *clients, cacheConfig *buildapi.ImageCacheConfig, testNamespace, clusterBuilderName, serviceAccountName string) string {
expectedResources := corev1.ResourceRequirements{
Limits: corev1.ResourceList{
corev1.ResourceMemory: resource.MustParse("1G"),
Expand Down Expand Up @@ -455,7 +479,7 @@ func generateRebuild(ctx *context.Context, t *testing.T, cfg config, clients *cl
}, metav1.CreateOptions{})
require.NoError(t, err)

validateImageCreate(t, clients, image, expectedResources)
originalImageTag := validateImageCreate(t, clients, image, expectedResources)

list, err := clients.client.KpackV1alpha2().Builds(testNamespace).List(*ctx, metav1.ListOptions{
LabelSelector: fmt.Sprintf("image.kpack.io/image=%s", imageName),
Expand All @@ -475,6 +499,11 @@ func generateRebuild(ctx *context.Context, t *testing.T, cfg config, clients *cl
require.NoError(t, err)
return len(list.Items) == 2
}, 5*time.Second, 1*time.Minute)

rebuiltImageTag := validateImageCreate(t, clients, image, expectedResources)
require.Equal(t, originalImageTag, rebuiltImageTag)

return originalImageTag
}

func readNamespaceLabelsFromEnv() map[string]string {
Expand Down Expand Up @@ -514,37 +543,40 @@ func waitUntilReady(t *testing.T, ctx context.Context, clients *clients, objects
}
}

func validateImageCreate(t *testing.T, clients *clients, image *buildapi.Image, expectedResources corev1.ResourceRequirements) {
func validateImageCreate(t *testing.T, clients *clients, image *buildapi.Image, expectedResources corev1.ResourceRequirements) string {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

logTail := &bytes.Buffer{}
go func() {
err := logs.NewBuildLogsClient(clients.k8sClient).Tail(ctx, logTail, image.Name, "1", image.Namespace)
err := logs.NewBuildLogsClient(clients.k8sClient).TailImage(ctx, logTail, image.Name, image.Namespace)
require.NoError(t, err)
}()

t.Logf("Waiting for image '%s' to be created", image.Name)
waitUntilReady(t, ctx, clients, image)

registryClient := &registry.Client{}
_, _, err = registryClient.Fetch(authn.DefaultKeychain, image.Spec.Tag)
_, identifier, err := registryClient.Fetch(authn.DefaultKeychain, image.Spec.Tag)
require.NoError(t, err)

eventually(t, func() bool {
return strings.Contains(logTail.String(), "Build successful")
}, 1*time.Second, 10*time.Second)

buildList, err := clients.client.KpackV1alpha2().Builds(image.Namespace).List(ctx, metav1.ListOptions{
LabelSelector: fmt.Sprintf("image.kpack.io/image=%s", image.Name),
})
require.NoError(t, err)

podList, err := clients.k8sClient.CoreV1().Pods(image.Namespace).List(ctx, metav1.ListOptions{
LabelSelector: fmt.Sprintf("image.kpack.io/image=%s", image.Name),
})
require.NoError(t, err)

require.Len(t, podList.Items, 1)
pod := podList.Items[0]
require.Len(t, podList.Items, len(buildList.Items))

require.Equal(t, 1, len(pod.Spec.Containers))
assert.Equal(t, expectedResources, pod.Spec.Containers[0].Resources)
return identifier
}

func validateRebase(t *testing.T, ctx context.Context, clients *clients, imageName, testNamespace string) {
Expand Down Expand Up @@ -585,13 +617,22 @@ func validateRebase(t *testing.T, ctx context.Context, clients *clients, imageNa

func deleteImageTag(t *testing.T, deleteImageTag string) {
reference, err := name.ParseReference(deleteImageTag, name.WeakValidation)
require.NoError(t, err)
if err != nil {
t.Logf("error cleaning up: could not parse reference: %s", err)
return
}

authenticator, err := authn.DefaultKeychain.Resolve(reference.Context().Registry)
require.NoError(t, err)
if err != nil {
t.Logf("error cleaning up: could not resolve keychain to delete tag: %s", err)
return
}

err = remote.Delete(reference, remote.WithAuth(authenticator))
require.NoError(t, err)
if err != nil {
t.Logf("error cleaning up: could not delete reference: %s", err)
return
}
}

func deleteNamespace(t *testing.T, ctx context.Context, clients *clients, namespace string) {
Expand Down