Skip to content

Commit

Permalink
controllers: register CmdImage on tiltfile load (#5318)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicks committed Dec 21, 2021
1 parent 2d7bd0e commit eb86c23
Show file tree
Hide file tree
Showing 11 changed files with 663 additions and 508 deletions.
13 changes: 13 additions & 0 deletions internal/controllers/apis/cmdimage/cmdimage.go
@@ -0,0 +1,13 @@
package cmdimage

import (
"fmt"

"github.com/tilt-dev/tilt/pkg/apis"
"github.com/tilt-dev/tilt/pkg/model"
)

// Generate the name for the CmdImage API object from an ImageTarget and ManifestName.
func GetName(mn model.ManifestName, id model.TargetID) string {
return apis.SanitizeName(fmt.Sprintf("%s:%s", mn.String(), id.Name))
}
38 changes: 38 additions & 0 deletions internal/controllers/core/tiltfile/api.go
Expand Up @@ -170,6 +170,7 @@ var typesWithTiltfileBuiltins = []apiset.Object{

var typesToReconcile = append([]apiset.Object{
&v1alpha1.ImageMap{},
&v1alpha1.CmdImage{},
&v1alpha1.DockerImage{},
&v1alpha1.UIResource{},
&v1alpha1.LiveUpdate{},
Expand Down Expand Up @@ -213,6 +214,7 @@ func toAPIObjects(
result.AddSetForType(&v1alpha1.ImageMap{}, toImageMapObjects(tlr, disableSources))
result.AddSetForType(&v1alpha1.LiveUpdate{}, toLiveUpdateObjects(tlr))
result.AddSetForType(&v1alpha1.DockerImage{}, toDockerImageObjects(tlr, disableSources))
result.AddSetForType(&v1alpha1.CmdImage{}, toCmdImageObjects(tlr, disableSources))

for _, obj := range typesWithTiltfileBuiltins {
result.AddSetForType(obj, tlr.ObjectSet.GetSetForType(obj))
Expand Down Expand Up @@ -440,6 +442,42 @@ func toDockerImageObjects(tlr *tiltfile.TiltfileLoadResult, disableSources disab
return result
}

// Pulls out all the CmdImage objects generated by the Tiltfile.
func toCmdImageObjects(tlr *tiltfile.TiltfileLoadResult, disableSources disableSourceMap) apiset.TypedObjectSet {
result := apiset.TypedObjectSet{}

for _, m := range tlr.Manifests {
for _, iTarget := range m.ImageTargets {
name := iTarget.CmdImageName
if name == "" {
continue
}

// Currently, if a CmdImage is in more than one manifest,
// we will create one per manifest.
//
// In the medium-term, we should try to annotate them in a way
// that allows manifests to share images.
ci := &v1alpha1.CmdImage{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Annotations: map[string]string{
v1alpha1.AnnotationManifest: m.Name.String(),
v1alpha1.AnnotationSpanID: fmt.Sprintf("cmdimage:%s", name),
},
},
Spec: iTarget.CustomBuildInfo().CmdImageSpec,
}

// TODO(nick): Add DisableSource to image builds.
//di.Spec.DisableSource = disableSources[m.Name]

result[name] = ci
}
}
return result
}

// Pulls out all the ImageMap objects generated by the Tiltfile.
func toImageMapObjects(tlr *tiltfile.TiltfileLoadResult, disableSources disableSourceMap) apiset.TypedObjectSet {
result := apiset.TypedObjectSet{}
Expand Down
29 changes: 29 additions & 0 deletions internal/controllers/core/tiltfile/api_test.go
Expand Up @@ -134,6 +134,35 @@ func TestImageMapCreate(t *testing.T) {
assert.Contains(t, di.Spec.Ref, SanchoRef.String())
}

func TestCmdImageCreate(t *testing.T) {
f := newAPIFixture(t)
target := model.MustNewImageTarget(SanchoRef).
WithBuildDetails(model.CustomBuild{
CmdImageSpec: v1alpha1.CmdImageSpec{Args: []string{"echo"}},
Deps: []string{f.Path()},
})
fe := manifestbuilder.New(f, "fe").
WithImageTarget(target).
WithK8sYAML(testyaml.SanchoYAML).
Build()
nn := types.NamespacedName{Name: "tiltfile"}
tf := &v1alpha1.Tiltfile{ObjectMeta: metav1.ObjectMeta{Name: "tiltfile"}}
err := f.updateOwnedObjects(nn, tf,
&tiltfile.TiltfileLoadResult{Manifests: []model.Manifest{fe}})
assert.NoError(t, err)

name := apis.SanitizeName(SanchoRef.String())

var im v1alpha1.ImageMap
assert.NoError(t, f.Get(types.NamespacedName{Name: name}, &im))
assert.Contains(t, im.Spec.Selector, SanchoRef.String())

ciName := apis.SanitizeName(fmt.Sprintf("fe:%s", SanchoRef.String()))
var ci v1alpha1.CmdImage
assert.NoError(t, f.Get(types.NamespacedName{Name: ciName}, &ci))
assert.Contains(t, ci.Spec.Ref, SanchoRef.String())
}

func TestAPITwoTiltfiles(t *testing.T) {
f := newAPIFixture(t)
feA := manifestbuilder.New(f, "fe-a").WithK8sYAML(testyaml.SanchoYAML).Build()
Expand Down
3 changes: 3 additions & 0 deletions internal/testutils/manifestbuilder/manifestbuilder.go
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/tilt-dev/tilt/internal/container"
"github.com/tilt-dev/tilt/internal/controllers/apis/cmdimage"
"github.com/tilt-dev/tilt/internal/controllers/apis/dockerimage"
"github.com/tilt-dev/tilt/internal/controllers/apis/liveupdate"
"github.com/tilt-dev/tilt/internal/k8s"
Expand Down Expand Up @@ -160,6 +161,8 @@ func (b ManifestBuilder) Build() model.Manifest {
for index, iTarget := range b.iTargets {
if iTarget.IsDockerBuild() {
iTarget.DockerImageName = dockerimage.GetName(b.name, iTarget.ID())
} else if iTarget.IsCustomBuild() {
iTarget.CmdImageName = cmdimage.GetName(b.name, iTarget.ID())
}

if liveupdate.IsEmptySpec(iTarget.LiveUpdateSpec) {
Expand Down
3 changes: 3 additions & 0 deletions internal/tiltfile/tiltfile_state.go
Expand Up @@ -15,6 +15,7 @@ import (
"golang.org/x/mod/semver"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/tilt-dev/tilt/internal/controllers/apis/cmdimage"
"github.com/tilt-dev/tilt/internal/controllers/apis/dockerimage"
"github.com/tilt-dev/tilt/internal/controllers/apis/liveupdate"
"github.com/tilt-dev/tilt/internal/controllers/apiset"
Expand Down Expand Up @@ -1427,6 +1428,8 @@ func (s *tiltfileState) imgTargetsForDependencyIDsHelper(mn model.ManifestName,
}
iTarget = iTarget.WithBuildDetails(model.DockerBuild{DockerImageSpec: spec})
case CustomBuild:
iTarget.CmdImageName = cmdimage.GetName(mn, iTarget.ID())

spec := v1alpha1.CmdImageSpec{
Args: image.customCommand.Argv,
Dir: image.workDir,
Expand Down
7 changes: 7 additions & 0 deletions pkg/apis/core/v1alpha1/cmdimage_types.go
Expand Up @@ -53,6 +53,9 @@ type CmdImageList struct {

// CmdImageSpec describes how the custom script builds images and where it puts them.
type CmdImageSpec struct {
// The named reference of the image.
Ref string `json:"ref" protobuf:"bytes,7,opt,name=ref"`

// Command-line arguments. Must have length at least 1.
Args []string `json:"args,omitempty" protobuf:"bytes,1,rep,name=args"`

Expand Down Expand Up @@ -98,6 +101,10 @@ type CmdImageSpec struct {
var _ resource.Object = &CmdImage{}
var _ resourcestrategy.Validater = &CmdImage{}

func (in *CmdImage) GetSpec() interface{} {
return in.Spec
}

func (in *CmdImage) GetObjectMeta() *metav1.ObjectMeta {
return &in.ObjectMeta
}
Expand Down

0 comments on commit eb86c23

Please sign in to comment.