-
Notifications
You must be signed in to change notification settings - Fork 9
/
publishimage.go
95 lines (76 loc) · 2.82 KB
/
publishimage.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package oci
import (
"context"
"namespacelabs.dev/foundation/internal/compute"
"namespacelabs.dev/foundation/schema"
"namespacelabs.dev/foundation/std/tasks"
)
type TargetRewritter interface {
CheckRewriteLocalUse(RepositoryWithAccess) *RepositoryWithAccess
}
type ImageSource interface {
GetSourceLabel() string
GetSourcePackageRef() *schema.PackageRef
}
var ConvertImagesToEstargz = false
func PublishImage(tag compute.Computable[RepositoryWithParent], image NamedImage) NamedImageID {
return MakeNamedImageID(image.Description(), &publishImage{tag: tag, label: image.Description(), image: AsResolvable(image.Image())})
}
func PublishResolvable(tag compute.Computable[RepositoryWithParent], image compute.Computable[ResolvableImage], source ImageSource) compute.Computable[ImageID] {
if ConvertImagesToEstargz {
image = &convertToEstargz{resolvable: image}
}
sourceLabel := ""
if source != nil {
if lbl := source.GetSourceLabel(); lbl != "" {
sourceLabel = lbl
} else if ref := source.GetSourcePackageRef(); ref != nil {
sourceLabel = ref.Canonical()
}
}
return &publishImage{tag: tag, image: image, sourceLabel: sourceLabel}
}
type publishImage struct {
tag compute.Computable[RepositoryWithParent]
image compute.Computable[ResolvableImage]
label string // Does not affect the output.
sourceLabel string // Does not affect the output.
compute.LocalScoped[ImageID]
}
func (pi *publishImage) Inputs() *compute.In {
return compute.Inputs().Computable("tag", pi.tag).Computable("image", pi.image)
}
func (pi *publishImage) Output() compute.Output {
return compute.Output{NotCacheable: true} // XXX capture more explicitly that there are side-effects.
}
func (pi *publishImage) Action() *tasks.ActionEvent {
action := tasks.Action("oci.publish-image")
if pi.label != "" {
action = action.Arg("image", pi.label)
}
if pi.sourceLabel != "" {
action = action.Arg("source", pi.sourceLabel)
}
return action
}
func (pi *publishImage) Compute(ctx context.Context, deps compute.Resolved) (ImageID, error) {
tag := compute.MustGetDepValue(deps, pi.tag, "tag")
tasks.Attachments(ctx).AddResult("repository", tag.Repository)
target := tag.RepositoryWithAccess
if tag.Parent != nil {
if x, ok := tag.Parent.(TargetRewritter); ok {
if newTarget := x.CheckRewriteLocalUse(target); newTarget != nil {
target = *newTarget
}
}
}
digest, err := compute.MustGetDepValue(deps, pi.image, "image").Push(ctx, target, true)
if err != nil {
return ImageID{}, err
}
// Use the original name, not the rewritten one, for readability purposes.
return ImageID{Repository: tag.Repository, Digest: digest.String()}, nil
}