github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/runner/v1/deploy.go (about)

     1  /*
     2  Copyright 2019 The Skaffold Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v1
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"io"
    23  	"time"
    24  
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
    26  	deployutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/util"
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/event"
    28  	eventV2 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event/v2"
    29  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
    30  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/instrumentation"
    31  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/output"
    32  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log"
    33  )
    34  
    35  // DeployAndLog deploys a list of already built artifacts and optionally show the logs.
    36  func (r *SkaffoldRunner) DeployAndLog(ctx context.Context, out io.Writer, artifacts []graph.Artifact) error {
    37  	defer r.deployer.GetLogger().Stop()
    38  
    39  	// Logs should be retrieved up to just before the deploy
    40  	r.deployer.GetLogger().SetSince(time.Now())
    41  	// First deploy
    42  	if err := r.Deploy(ctx, out, artifacts); err != nil {
    43  		return err
    44  	}
    45  
    46  	defer r.deployer.GetAccessor().Stop()
    47  
    48  	if err := r.deployer.GetAccessor().Start(ctx, out); err != nil {
    49  		log.Entry(ctx).Warn("Error starting port forwarding:", err)
    50  	}
    51  
    52  	// Start printing the logs after deploy is finished
    53  	if err := r.deployer.GetLogger().Start(ctx, out); err != nil {
    54  		return fmt.Errorf("starting logger: %w", err)
    55  	}
    56  
    57  	if r.runCtx.Tail() || r.runCtx.PortForward() {
    58  		output.Yellow.Fprintln(out, "Press Ctrl+C to exit")
    59  		<-ctx.Done()
    60  	}
    61  
    62  	return nil
    63  }
    64  
    65  func (r *SkaffoldRunner) Deploy(ctx context.Context, out io.Writer, artifacts []graph.Artifact) error {
    66  	if r.runCtx.RenderOnly() {
    67  		return r.Render(ctx, out, artifacts, false, r.runCtx.RenderOutput())
    68  	}
    69  	defer r.deployer.GetStatusMonitor().Reset()
    70  
    71  	out, ctx = output.WithEventContext(ctx, out, constants.Deploy, constants.SubtaskIDNone)
    72  
    73  	output.Default.Fprintln(out, "Tags used in deployment:")
    74  
    75  	for _, artifact := range artifacts {
    76  		output.Default.Fprintf(out, " - %s -> ", artifact.ImageName)
    77  		fmt.Fprintln(out, artifact.Tag)
    78  	}
    79  
    80  	var localImages []graph.Artifact
    81  	for _, a := range artifacts {
    82  		if isLocal, err := r.isLocalImage(a.ImageName); err != nil {
    83  			return err
    84  		} else if isLocal {
    85  			localImages = append(localImages, a)
    86  		}
    87  	}
    88  
    89  	if len(localImages) > 0 {
    90  		log.Entry(ctx).Debug(`Local images can't be referenced by digest.
    91  They are tagged and referenced by a unique, local only, tag instead.
    92  See https://skaffold.dev/docs/pipeline-stages/taggers/#how-tagging-works`)
    93  	}
    94  
    95  	deployOut, postDeployFn, err := deployutil.WithLogFile(time.Now().Format(deployutil.TimeFormat)+".log", out, r.runCtx.Muted())
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	event.DeployInProgress()
   101  	eventV2.TaskInProgress(constants.Deploy, "Deploy to cluster")
   102  	ctx, endTrace := instrumentation.StartTrace(ctx, "Deploy_Deploying")
   103  	defer endTrace()
   104  
   105  	// we only want to register images that are local AND were built by this runner OR forced to load via flag
   106  	var localAndBuiltImages []graph.Artifact
   107  	for _, image := range localImages {
   108  		if r.runCtx.ForceLoadImages() || r.wasBuilt(image.Tag) {
   109  			localAndBuiltImages = append(localAndBuiltImages, image)
   110  		}
   111  	}
   112  
   113  	r.deployer.RegisterLocalImages(localAndBuiltImages)
   114  	err = r.deployer.Deploy(ctx, deployOut, artifacts)
   115  	r.hasDeployed = true // set even if deploy may have failed, because we want to cleanup any partially created resources
   116  	postDeployFn()
   117  	if err != nil {
   118  		event.DeployFailed(err)
   119  		eventV2.TaskFailed(constants.Deploy, err)
   120  		endTrace(instrumentation.TraceEndError(err))
   121  		return err
   122  	}
   123  
   124  	statusCheckOut, postStatusCheckFn, err := deployutil.WithStatusCheckLogFile(time.Now().Format(deployutil.TimeFormat)+".log", out, r.runCtx.Muted())
   125  	defer postStatusCheckFn()
   126  	if err != nil {
   127  		endTrace(instrumentation.TraceEndError(err))
   128  		return err
   129  	}
   130  
   131  	event.DeployComplete()
   132  	if !r.runCtx.Opts.IterativeStatusCheck {
   133  		// run final aggregated status check only if iterative status check is turned off.
   134  		if err = r.deployer.GetStatusMonitor().Check(ctx, statusCheckOut); err != nil {
   135  			eventV2.TaskFailed(constants.Deploy, err)
   136  			return err
   137  		}
   138  	}
   139  	eventV2.TaskSucceeded(constants.Deploy)
   140  	return nil
   141  }
   142  
   143  func (r *SkaffoldRunner) wasBuilt(tag string) bool {
   144  	for _, built := range r.Builds {
   145  		if built.Tag == tag {
   146  			return true
   147  		}
   148  	}
   149  	return false
   150  }