Skip to content
Closed
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
24 changes: 22 additions & 2 deletions pkg/oci/pusher.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package oci

import (
"context"
"errors"
"fmt"
"net/http"
"os"
Expand All @@ -12,8 +13,10 @@ import (
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/layout"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
progress "github.com/schollz/progressbar/v3"

fn "knative.dev/func/pkg/functions"
Expand Down Expand Up @@ -181,13 +184,30 @@ func getBuildDir(f fn.Function) (string, error) {
func (p *Pusher) writeIndex(ctx context.Context, ref name.Reference, ii v1.ImageIndex, creds Credentials) error {
oo := []remote.Option{
remote.WithContext(ctx),
remote.WithProgress(p.updates),
remote.WithTransport(p.transport),
}

if !p.Anonymous {
oo = append(oo, remote.WithAuth(creds))
}

return remote.WriteIndex(ref, ii, oo...)
// Ensure the repository exists. Some registries (notably
// OpenShift's internal registry) return HTTP 500 for manifest
// HEAD requests by digest when the repository doesn't exist yet.
// WriteIndex checks child manifests by digest, so the repository
// must exist beforehand. A HEAD by tag returns a proper 404, so
// use that to detect the missing repository and create it by
// pushing an empty image. The tag is overwritten by the index.
if _, err := remote.Head(ref, oo...); err != nil {
var terr *transport.Error
if errors.As(err, &terr) && terr.StatusCode == http.StatusNotFound {
if err := remote.Write(ref, empty.Image, oo...); err != nil {
return fmt.Errorf("cannot create repo: %w", err)
}
} else {
return fmt.Errorf("cannot check repo existence: %w", err)
}
}

return remote.WriteIndex(ref, ii, append(oo, remote.WithProgress(p.updates))...)
}
Loading