github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/controllers/core/dockerimage/imagemap.go (about)

     1  package dockerimage
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/distribution/reference"
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  	"k8s.io/apimachinery/pkg/types"
    10  
    11  	"github.com/tilt-dev/tilt/internal/container"
    12  	"github.com/tilt-dev/tilt/internal/docker"
    13  	"github.com/tilt-dev/tilt/internal/store"
    14  	"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
    15  	"github.com/tilt-dev/tilt/pkg/model"
    16  )
    17  
    18  // A helper function for updating the imagemap
    19  // from dockerimage.Reconciler and cmdimage.Reconciler.
    20  // This is mainly for easing the transition to reconcilers.
    21  func UpdateImageMap(
    22  	ctx context.Context,
    23  	docker docker.Client,
    24  	iTarget model.ImageTarget,
    25  	cluster *v1alpha1.Cluster,
    26  	imageMaps map[types.NamespacedName]*v1alpha1.ImageMap,
    27  	startTime *metav1.MicroTime,
    28  	taggedRefs container.TaggedRefs,
    29  ) (store.ImageBuildResult, error) {
    30  	result := store.NewImageBuildResult(iTarget.ID(), taggedRefs.LocalRef, taggedRefs.ClusterRef)
    31  	if isDockerCompose(cluster) {
    32  		imgRefs, err := iTarget.Refs(cluster)
    33  		if err != nil {
    34  			return store.ImageBuildResult{}, fmt.Errorf("determining refs: %v", err)
    35  		}
    36  		ref, err := tagWithExpected(ctx, docker, taggedRefs.LocalRef, imgRefs.ConfigurationRef)
    37  		if err != nil {
    38  			return store.ImageBuildResult{}, err
    39  		}
    40  
    41  		result = store.NewImageBuildResultSingleRef(iTarget.ID(), ref)
    42  	}
    43  
    44  	result.ImageMapStatus.BuildStartTime = startTime
    45  	nn := types.NamespacedName{Name: iTarget.ImageMapName()}
    46  	im, ok := imageMaps[nn]
    47  	if !ok {
    48  		return store.ImageBuildResult{}, fmt.Errorf("apiserver missing ImageMap: %s", iTarget.ID().Name)
    49  	}
    50  	im.Status = result.ImageMapStatus
    51  	return result, nil
    52  }
    53  
    54  // tagWithExpected tags the given ref as whatever Docker Compose expects, i.e. as
    55  // the `image` value given in docker-compose.yaml. (If DC yaml specifies an image
    56  // with a tag, use that name + tag; otherwise, tag as latest.)
    57  func tagWithExpected(
    58  	ctx context.Context,
    59  	dCli docker.Client,
    60  	ref reference.NamedTagged,
    61  	expected container.RefSelector) (reference.NamedTagged, error) {
    62  	dCli = dCli.ForOrchestrator(model.OrchestratorDC)
    63  
    64  	var tagAs reference.NamedTagged
    65  	expectedNt, err := container.ParseNamedTagged(expected.String())
    66  	if err == nil {
    67  		// expected ref already includes a tag, so just tag the image as that
    68  		tagAs = expectedNt
    69  	} else {
    70  		// expected ref is just a name, so tag it as `latest` b/c that's what Docker Compose wants
    71  		tagAs, err = reference.WithTag(ref, docker.TagLatest)
    72  		if err != nil {
    73  			return nil, err
    74  		}
    75  	}
    76  
    77  	err = dCli.ImageTag(ctx, ref.String(), tagAs.String())
    78  	return tagAs, err
    79  }
    80  
    81  func isDockerCompose(cluster *v1alpha1.Cluster) bool {
    82  	return cluster != nil &&
    83  		cluster.Spec.Connection != nil &&
    84  		cluster.Spec.Connection.Docker != nil
    85  }