diff --git a/pkg/skaffold/bazel/bazel_test.go b/pkg/skaffold/bazel/bazel_test.go index 0c3bbf3bc7d..73e63b2fa3b 100644 --- a/pkg/skaffold/bazel/bazel_test.go +++ b/pkg/skaffold/bazel/bazel_test.go @@ -18,8 +18,46 @@ package bazel import ( "testing" + + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" + "github.com/GoogleContainerTools/skaffold/testutil" ) +func TestGetDependenciesWithWorkspace(t *testing.T) { + defer func(c util.Command) { util.DefaultExecCommand = c }(util.DefaultExecCommand) + util.DefaultExecCommand = testutil.NewFakeCmdOut( + "bazel query kind('source file', deps('target')) union buildfiles('target') --noimplicit_deps --order_output=no", + "@ignored\n//external/ignored\n\n//:dep1\n//:dep2\n", + nil, + ) + + tmpDir, cleanup := testutil.NewTempDir(t) + defer cleanup() + tmpDir.Write("WORKSPACE", "") + + deps, err := GetDependencies(tmpDir.Root(), &v1alpha2.BazelArtifact{ + BuildTarget: "target", + }) + + testutil.CheckErrorAndDeepEqual(t, false, err, []string{"dep1", "dep2", "WORKSPACE"}, deps) +} + +func TestGetDependenciesWithoutWorkspace(t *testing.T) { + defer func(c util.Command) { util.DefaultExecCommand = c }(util.DefaultExecCommand) + util.DefaultExecCommand = testutil.NewFakeCmdOut( + "bazel query kind('source file', deps('target2')) union buildfiles('target2') --noimplicit_deps --order_output=no", + "@ignored\n//external/ignored\n\n//:dep3\n", + nil, + ) + + deps, err := GetDependencies(".", &v1alpha2.BazelArtifact{ + BuildTarget: "target2", + }) + + testutil.CheckErrorAndDeepEqual(t, false, err, []string{"dep3"}, deps) +} + func TestQuery(t *testing.T) { query := query("//:skaffold_example.tar") diff --git a/pkg/skaffold/build/local/bazel.go b/pkg/skaffold/build/local/bazel.go index e03db410d56..374d122ae02 100644 --- a/pkg/skaffold/build/local/bazel.go +++ b/pkg/skaffold/build/local/bazel.go @@ -31,7 +31,7 @@ import ( ) func (b *Builder) buildBazel(ctx context.Context, out io.Writer, workspace string, a *v1alpha2.BazelArtifact) (string, error) { - cmd := exec.Command("bazel", "build", a.BuildTarget) + cmd := exec.CommandContext(ctx, "bazel", "build", a.BuildTarget) cmd.Dir = workspace cmd.Stdout = out cmd.Stderr = out diff --git a/pkg/skaffold/build/local/docker.go b/pkg/skaffold/build/local/docker.go index 5ff2eb3ddeb..564dea1063d 100644 --- a/pkg/skaffold/build/local/docker.go +++ b/pkg/skaffold/build/local/docker.go @@ -41,7 +41,7 @@ func (b *Builder) buildDocker(ctx context.Context, out io.Writer, workspace stri args := []string{"build", workspace, "--file", dockerfilePath, "-t", initialTag} args = append(args, docker.GetBuildArgs(a)...) - cmd := exec.Command("docker", args...) + cmd := exec.CommandContext(ctx, "docker", args...) if b.cfg.UseBuildkit { cmd.Env = append(os.Environ(), "DOCKER_BUILDKIT=1") } diff --git a/pkg/skaffold/deploy/helm.go b/pkg/skaffold/deploy/helm.go index 622f7770da1..3ed226e4f24 100644 --- a/pkg/skaffold/deploy/helm.go +++ b/pkg/skaffold/deploy/helm.go @@ -65,7 +65,7 @@ func (h *HelmDeployer) Labels() map[string]string { func (h *HelmDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact) ([]Artifact, error) { deployResults := []Artifact{} for _, r := range h.Releases { - results, err := h.deployRelease(out, r, builds) + results, err := h.deployRelease(ctx, out, r, builds) if err != nil { releaseName, _ := evaluateReleaseName(r.Name) return deployResults, errors.Wrapf(err, "deploying %s", releaseName) @@ -92,7 +92,7 @@ func (h *HelmDeployer) Dependencies() ([]string, error) { // Cleanup deletes what was deployed by calling Deploy. func (h *HelmDeployer) Cleanup(ctx context.Context, out io.Writer) error { for _, r := range h.Releases { - if err := h.deleteRelease(out, r); err != nil { + if err := h.deleteRelease(ctx, out, r); err != nil { releaseName, _ := evaluateReleaseName(r.Name) return errors.Wrapf(err, "deploying %s", releaseName) } @@ -100,24 +100,24 @@ func (h *HelmDeployer) Cleanup(ctx context.Context, out io.Writer) error { return nil } -func (h *HelmDeployer) helm(out io.Writer, arg ...string) error { +func (h *HelmDeployer) helm(ctx context.Context, out io.Writer, arg ...string) error { args := append([]string{"--kube-context", h.kubeContext}, arg...) - cmd := exec.Command("helm", args...) + cmd := exec.CommandContext(ctx, "helm", args...) cmd.Stdout = out cmd.Stderr = out return util.RunCmd(cmd) } -func (h *HelmDeployer) deployRelease(out io.Writer, r v1alpha2.HelmRelease, builds []build.Artifact) ([]Artifact, error) { +func (h *HelmDeployer) deployRelease(ctx context.Context, out io.Writer, r v1alpha2.HelmRelease, builds []build.Artifact) ([]Artifact, error) { isInstalled := true releaseName, err := evaluateReleaseName(r.Name) if err != nil { return nil, errors.Wrap(err, "cannot parse the release name template") } - if err := h.helm(out, "get", releaseName); err != nil { + if err := h.helm(ctx, out, "get", releaseName); err != nil { color.Red.Fprintf(out, "Helm release %s not installed. Installing...\n", releaseName) isInstalled = false } @@ -140,7 +140,7 @@ func (h *HelmDeployer) deployRelease(out io.Writer, r v1alpha2.HelmRelease, buil // First build dependencies. logrus.Infof("Building helm dependencies...") - if err := h.helm(out, "dep", "build", r.ChartPath); err != nil { + if err := h.helm(ctx, out, "dep", "build", r.ChartPath); err != nil { return nil, errors.Wrap(err, "building helm dependencies") } @@ -164,7 +164,7 @@ func (h *HelmDeployer) deployRelease(out io.Writer, r v1alpha2.HelmRelease, buil } args = append(args, r.ChartPath) } else { - chartPath, err := h.packageChart(r) + chartPath, err := h.packageChart(ctx, r) if err != nil { return nil, errors.WithMessage(err, "cannot package chart") } @@ -240,8 +240,8 @@ func (h *HelmDeployer) deployRelease(out io.Writer, r v1alpha2.HelmRelease, buil } args = append(args, setOpts...) - helmErr := h.helm(out, args...) - return h.getDeployResults(ns, releaseName), helmErr + helmErr := h.helm(ctx, out, args...) + return h.getDeployResults(ctx, ns, releaseName), helmErr } // imageName if the given string includes a fully qualified docker image name then lets trim just the tag part out @@ -260,7 +260,7 @@ func extractTag(imageName string) string { // packageChart packages the chart and returns path to the chart archive file. // If this function returns an error, it will always be wrapped. -func (h *HelmDeployer) packageChart(r v1alpha2.HelmRelease) (string, error) { +func (h *HelmDeployer) packageChart(ctx context.Context, r v1alpha2.HelmRelease) (string, error) { tmp := os.TempDir() packageArgs := []string{"package", r.ChartPath, "--destination", tmp} if r.Packaged.Version != "" { @@ -279,7 +279,7 @@ func (h *HelmDeployer) packageChart(r v1alpha2.HelmRelease) (string, error) { } buf := &bytes.Buffer{} - err := h.helm(buf, packageArgs...) + err := h.helm(ctx, buf, packageArgs...) output := strings.TrimSpace(buf.String()) if err != nil { return "", errors.Wrapf(err, "package chart into a .tgz archive (%s)", output) @@ -293,9 +293,9 @@ func (h *HelmDeployer) packageChart(r v1alpha2.HelmRelease) (string, error) { return filepath.Join(tmp, fpath), nil } -func (h *HelmDeployer) getReleaseInfo(release string) (*bufio.Reader, error) { +func (h *HelmDeployer) getReleaseInfo(ctx context.Context, release string) (*bufio.Reader, error) { var releaseInfo bytes.Buffer - if err := h.helm(&releaseInfo, "get", release); err != nil { + if err := h.helm(ctx, &releaseInfo, "get", release); err != nil { return nil, fmt.Errorf("error retrieving helm deployment info: %s", releaseInfo.String()) } return bufio.NewReader(&releaseInfo), nil @@ -304,8 +304,8 @@ func (h *HelmDeployer) getReleaseInfo(release string) (*bufio.Reader, error) { // Retrieve info about all releases using helm get // Skaffold labels will be applied to each deployed k8s object // Since helm isn't always consistent with retrieving results, don't return errors here -func (h *HelmDeployer) getDeployResults(namespace string, release string) []Artifact { - b, err := h.getReleaseInfo(release) +func (h *HelmDeployer) getDeployResults(ctx context.Context, namespace string, release string) []Artifact { + b, err := h.getReleaseInfo(ctx, release) if err != nil { logrus.Warnf(err.Error()) return nil @@ -313,13 +313,13 @@ func (h *HelmDeployer) getDeployResults(namespace string, release string) []Arti return parseReleaseInfo(namespace, b) } -func (h *HelmDeployer) deleteRelease(out io.Writer, r v1alpha2.HelmRelease) error { +func (h *HelmDeployer) deleteRelease(ctx context.Context, out io.Writer, r v1alpha2.HelmRelease) error { releaseName, err := evaluateReleaseName(r.Name) if err != nil { return errors.Wrap(err, "cannot parse the release name template") } - if err := h.helm(out, "delete", releaseName, "--purge"); err != nil { + if err := h.helm(ctx, out, "delete", releaseName, "--purge"); err != nil { logrus.Debugf("deleting release %s: %v\n", releaseName, err) } diff --git a/pkg/skaffold/deploy/kubectl.go b/pkg/skaffold/deploy/kubectl.go index 3479af07972..48d316c15d8 100644 --- a/pkg/skaffold/deploy/kubectl.go +++ b/pkg/skaffold/deploy/kubectl.go @@ -64,7 +64,7 @@ func (k *KubectlDeployer) Labels() map[string]string { // Deploy templates the provided manifests with a simple `find and replace` and // runs `kubectl apply` on those manifests func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact) ([]Artifact, error) { - manifests, err := k.readManifests() + manifests, err := k.readManifests(ctx) if err != nil { return nil, errors.Wrap(err, "reading manifests") } @@ -78,7 +78,7 @@ func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []bu return nil, errors.Wrap(err, "replacing images in manifests") } - updated, err := k.kubectl.Apply(out, manifests) + updated, err := k.kubectl.Apply(ctx, out, manifests) if err != nil { return nil, errors.Wrap(err, "apply") } @@ -88,12 +88,12 @@ func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []bu // Cleanup deletes what was deployed by calling Deploy. func (k *KubectlDeployer) Cleanup(ctx context.Context, out io.Writer) error { - manifests, err := k.readManifests() + manifests, err := k.readManifests(ctx) if err != nil { return errors.Wrap(err, "reading manifests") } - if err := k.kubectl.Detete(out, manifests); err != nil { + if err := k.kubectl.Detete(ctx, out, manifests); err != nil { return errors.Wrap(err, "delete") } @@ -135,7 +135,7 @@ func parseManifestsForDeploys(manifests kubectl.ManifestList) ([]Artifact, error } // readManifests reads the manifests to deploy/delete. -func (k *KubectlDeployer) readManifests() (kubectl.ManifestList, error) { +func (k *KubectlDeployer) readManifests(ctx context.Context) (kubectl.ManifestList, error) { files, err := k.manifestFiles(k.Manifests) if err != nil { return nil, errors.Wrap(err, "expanding user manifest list") @@ -152,7 +152,7 @@ func (k *KubectlDeployer) readManifests() (kubectl.ManifestList, error) { } for _, m := range k.RemoteManifests { - manifest, err := k.readRemoteManifest(m) + manifest, err := k.readRemoteManifest(ctx, m) if err != nil { return nil, errors.Wrap(err, "get remote manifests") } @@ -165,7 +165,7 @@ func (k *KubectlDeployer) readManifests() (kubectl.ManifestList, error) { return manifests, nil } -func (k *KubectlDeployer) readRemoteManifest(name string) ([]byte, error) { +func (k *KubectlDeployer) readRemoteManifest(ctx context.Context, name string) ([]byte, error) { var args []string if parts := strings.Split(name, ":"); len(parts) > 1 { args = append(args, "--namespace", parts[0]) @@ -174,7 +174,7 @@ func (k *KubectlDeployer) readRemoteManifest(name string) ([]byte, error) { args = append(args, name, "-o", "yaml") var manifest bytes.Buffer - err := k.kubectl.Run(nil, &manifest, "get", nil, args...) + err := k.kubectl.Run(ctx, nil, &manifest, "get", nil, args...) if err != nil { return nil, errors.Wrap(err, "getting manifest") } diff --git a/pkg/skaffold/deploy/kubectl/cli.go b/pkg/skaffold/deploy/kubectl/cli.go index e534f7efb77..87ad6a92be6 100644 --- a/pkg/skaffold/deploy/kubectl/cli.go +++ b/pkg/skaffold/deploy/kubectl/cli.go @@ -17,6 +17,7 @@ limitations under the License. package kubectl import ( + "context" "io" "os/exec" @@ -36,8 +37,8 @@ type CLI struct { } // Detete runs `kubectl delete` on a list of manifests. -func (c *CLI) Detete(out io.Writer, manifests ManifestList) error { - if err := c.Run(manifests.Reader(), out, "delete", c.Flags.Delete, "--ignore-not-found=true", "-f", "-"); err != nil { +func (c *CLI) Detete(ctx context.Context, out io.Writer, manifests ManifestList) error { + if err := c.Run(ctx, manifests.Reader(), out, "delete", c.Flags.Delete, "--ignore-not-found=true", "-f", "-"); err != nil { return errors.Wrap(err, "kubectl delete") } @@ -45,7 +46,7 @@ func (c *CLI) Detete(out io.Writer, manifests ManifestList) error { } // Apply runs `kubectl apply` on a list of manifests. -func (c *CLI) Apply(out io.Writer, manifests ManifestList) (ManifestList, error) { +func (c *CLI) Apply(ctx context.Context, out io.Writer, manifests ManifestList) (ManifestList, error) { // Only redeploy modified or new manifests // TODO(dgageot): should we delete a manifest that was deployed and is not anymore? updated := c.previousApply.Diff(manifests) @@ -55,7 +56,7 @@ func (c *CLI) Apply(out io.Writer, manifests ManifestList) (ManifestList, error) return nil, nil } - if err := c.Run(manifests.Reader(), out, "apply", c.Flags.Apply, "-f", "-"); err != nil { + if err := c.Run(ctx, manifests.Reader(), out, "apply", c.Flags.Apply, "-f", "-"); err != nil { return nil, errors.Wrap(err, "kubectl apply") } @@ -63,7 +64,7 @@ func (c *CLI) Apply(out io.Writer, manifests ManifestList) (ManifestList, error) } // Run shells out kubectl CLI. -func (c *CLI) Run(in io.Reader, out io.Writer, command string, commandFlags []string, arg ...string) error { +func (c *CLI) Run(ctx context.Context, in io.Reader, out io.Writer, command string, commandFlags []string, arg ...string) error { args := []string{"--context", c.KubeContext} if c.Namespace != "" { args = append(args, "--namespace", c.Namespace) @@ -73,7 +74,7 @@ func (c *CLI) Run(in io.Reader, out io.Writer, command string, commandFlags []st args = append(args, commandFlags...) args = append(args, arg...) - cmd := exec.Command("kubectl", args...) + cmd := exec.CommandContext(ctx, "kubectl", args...) cmd.Stdin = in cmd.Stdout = out cmd.Stderr = out diff --git a/pkg/skaffold/deploy/kustomize.go b/pkg/skaffold/deploy/kustomize.go index 24277f72670..77e7b48ff87 100644 --- a/pkg/skaffold/deploy/kustomize.go +++ b/pkg/skaffold/deploy/kustomize.go @@ -53,7 +53,7 @@ func (k *KustomizeDeployer) Labels() map[string]string { } func (k *KustomizeDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact) ([]Artifact, error) { - manifests, err := k.readManifests() + manifests, err := k.readManifests(ctx) if err != nil { return nil, errors.Wrap(err, "reading manifests") } @@ -67,7 +67,7 @@ func (k *KustomizeDeployer) Deploy(ctx context.Context, out io.Writer, builds [] return nil, errors.Wrap(err, "replacing images in manifests") } - updated, err := k.kubectl.Apply(out, manifests) + updated, err := k.kubectl.Apply(ctx, out, manifests) if err != nil { return nil, errors.Wrap(err, "apply") } @@ -76,12 +76,12 @@ func (k *KustomizeDeployer) Deploy(ctx context.Context, out io.Writer, builds [] } func (k *KustomizeDeployer) Cleanup(ctx context.Context, out io.Writer) error { - manifests, err := k.readManifests() + manifests, err := k.readManifests(ctx) if err != nil { return errors.Wrap(err, "reading manifests") } - if err := k.kubectl.Detete(out, manifests); err != nil { + if err := k.kubectl.Detete(ctx, out, manifests); err != nil { return errors.Wrap(err, "delete") } @@ -93,8 +93,8 @@ func (k *KustomizeDeployer) Dependencies() ([]string, error) { return []string{k.KustomizePath}, nil } -func (k *KustomizeDeployer) readManifests() (kubectl.ManifestList, error) { - cmd := exec.Command("kustomize", "build", k.KustomizePath) +func (k *KustomizeDeployer) readManifests(ctx context.Context) (kubectl.ManifestList, error) { + cmd := exec.CommandContext(ctx, "kustomize", "build", k.KustomizePath) out, err := util.RunCmdOut(cmd) if err != nil { return nil, errors.Wrap(err, "kustomize build") diff --git a/pkg/skaffold/kubernetes/colorpicker.go b/pkg/skaffold/kubernetes/colorpicker.go index 561390887a1..2ec6e354e8b 100644 --- a/pkg/skaffold/kubernetes/colorpicker.go +++ b/pkg/skaffold/kubernetes/colorpicker.go @@ -49,7 +49,7 @@ type colorPicker struct { imageColors map[string]color.Color } -// NewColorPicker creates a new ColorPicker. For each artfact, a color will be selected +// NewColorPicker creates a new ColorPicker. For each artifact, a color will be selected // sequentially from `colorCodes`. If all colors are used, the first color will be used // again. The formatter for the associated color will then be returned by `Pick` each // time it is called for the artifact and can be used to write to out in that color. diff --git a/pkg/skaffold/kubernetes/wait.go b/pkg/skaffold/kubernetes/wait.go index f17000b5f66..82e9f888651 100644 --- a/pkg/skaffold/kubernetes/wait.go +++ b/pkg/skaffold/kubernetes/wait.go @@ -27,14 +27,11 @@ import ( apierrs "k8s.io/apimachinery/pkg/api/errors" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/tools/cache" ) func WaitForPodReady(pods corev1.PodInterface, podName string) error { @@ -97,119 +94,6 @@ func WaitForPodComplete(pods corev1.PodInterface, podName string, timeout time.D }) } -type PodStore struct { - cache.Store - stopCh chan struct{} - Reflector *cache.Reflector -} - -func (s *PodStore) List() []*v1.Pod { - objects := s.Store.List() - pods := make([]*v1.Pod, 0) - for _, o := range objects { - pods = append(pods, o.(*v1.Pod)) - } - return pods -} - -func (s *PodStore) Stop() { - close(s.stopCh) -} - -func NewPodStore(c kubernetes.Interface, namespace string, label fmt.Stringer, field fmt.Stringer) *PodStore { - lw := &cache.ListWatch{ - ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { - options.LabelSelector = label.String() - options.FieldSelector = field.String() - obj, err := c.CoreV1().Pods(namespace).List(options) - return runtime.Object(obj), err - }, - WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { - options.LabelSelector = label.String() - options.FieldSelector = field.String() - return c.CoreV1().Pods(namespace).Watch(options) - }, - } - store := cache.NewStore(cache.MetaNamespaceKeyFunc) - stopCh := make(chan struct{}) - reflector := cache.NewReflector(lw, &v1.Pod{}, store, 0) - go reflector.Run(stopCh) - return &PodStore{Store: store, stopCh: stopCh, Reflector: reflector} -} - -func StartPods(c kubernetes.Interface, namespace string, pod v1.Pod, waitForRunning bool) error { - pod.ObjectMeta.Labels["name"] = pod.Name - if waitForRunning { - label := labels.SelectorFromSet(labels.Set(map[string]string{"name": pod.Name})) - err := WaitForPodsWithLabelRunning(c, namespace, label) - if err != nil { - return fmt.Errorf("Error waiting for pod %s to be running: %v", pod.Name, err) - } - } - return nil -} - -// WaitForPodsWithLabelRunning waits up to 10 minutes for all matching pods to become Running and at least one -// matching pod exists. -func WaitForPodsWithLabelRunning(c kubernetes.Interface, ns string, label labels.Selector) error { - lastKnownPodNumber := -1 - return wait.PollImmediate(500*time.Millisecond, time.Minute*10, func() (bool, error) { - listOpts := meta_v1.ListOptions{LabelSelector: label.String()} - pods, err := c.CoreV1().Pods(ns).List(listOpts) - if err != nil { - glog.Infof("error getting Pods with label selector %q [%v]\n", label.String(), err) - return false, nil - } - - if lastKnownPodNumber != len(pods.Items) { - glog.Infof("Found %d Pods for label selector %s\n", len(pods.Items), label.String()) - lastKnownPodNumber = len(pods.Items) - } - - if len(pods.Items) == 0 { - return false, nil - } - - for _, pod := range pods.Items { - if pod.Status.Phase != v1.PodRunning { - return false, nil - } - } - - return true, nil - }) -} - -// WaitForRCToStabilize waits till the RC has a matching generation/replica count between spec and status. -func WaitForRCToStabilize(c kubernetes.Interface, ns, name string, timeout time.Duration) error { - options := meta_v1.ListOptions{FieldSelector: fields.Set{ - "metadata.name": name, - "metadata.namespace": ns, - }.AsSelector().String()} - w, err := c.CoreV1().ReplicationControllers(ns).Watch(options) - if err != nil { - return err - } - _, err = watch.Until(timeout, w, func(event watch.Event) (bool, error) { - switch event.Type { - case watch.Deleted: - return false, apierrs.NewNotFound(schema.GroupResource{Resource: "replicationcontrollers"}, "") - } - switch rc := event.Object.(type) { - case *v1.ReplicationController: - if rc.Name == name && rc.Namespace == ns && - rc.Generation <= rc.Status.ObservedGeneration && - *(rc.Spec.Replicas) == rc.Status.Replicas { - return true, nil - } - glog.Infof("Waiting for rc %s to stabilize, generation %v observed generation %v spec.replicas %d status.replicas %d", - name, rc.Generation, rc.Status.ObservedGeneration, *(rc.Spec.Replicas), rc.Status.Replicas) - } - return false, nil - }) - return err -} - // WaitForDeploymentToStabilize waits till the Deployment has a matching generation/replica count between spec and status. func WaitForDeploymentToStabilize(c kubernetes.Interface, ns, name string, timeout time.Duration) error { options := meta_v1.ListOptions{FieldSelector: fields.Set{ @@ -239,59 +123,3 @@ func WaitForDeploymentToStabilize(c kubernetes.Interface, ns, name string, timeo }) return err } - -// WaitForService waits until the service appears (exist == true), or disappears (exist == false) -func WaitForService(c kubernetes.Interface, namespace, name string, exist bool, interval, timeout time.Duration) error { - err := wait.PollImmediate(interval, timeout, func() (bool, error) { - _, err := c.CoreV1().Services(namespace).Get(name, meta_v1.GetOptions{}) - switch { - case err == nil: - glog.Infof("Service %s in namespace %s found.", name, namespace) - return exist, nil - case apierrs.IsNotFound(err): - glog.Infof("Service %s in namespace %s disappeared.", name, namespace) - return !exist, nil - case !IsRetryableAPIError(err): - glog.Infof("Non-retryable failure while getting service.") - return false, err - default: - glog.Infof("Get service %s in namespace %s failed: %v", name, namespace, err) - return false, nil - } - }) - if err != nil { - stateMsg := map[bool]string{true: "to appear", false: "to disappear"} - return fmt.Errorf("error waiting for service %s/%s %s: %v", namespace, name, stateMsg[exist], err) - } - return nil -} - -//WaitForServiceEndpointsNum waits until the amount of endpoints that implement service to expectNum. -func WaitForServiceEndpointsNum(c kubernetes.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error { - return wait.Poll(interval, timeout, func() (bool, error) { - glog.Infof("Waiting for amount of service:%s endpoints to be %d", serviceName, expectNum) - list, err := c.CoreV1().Endpoints(namespace).List(meta_v1.ListOptions{}) - if err != nil { - return false, err - } - - for _, e := range list.Items { - if e.Name == serviceName && countEndpointsNum(&e) == expectNum { - return true, nil - } - } - return false, nil - }) -} - -func countEndpointsNum(e *v1.Endpoints) int { - num := 0 - for _, sub := range e.Subsets { - num += len(sub.Addresses) - } - return num -} - -func IsRetryableAPIError(err error) bool { - return apierrs.IsTimeout(err) || apierrs.IsServerTimeout(err) || apierrs.IsTooManyRequests(err) || apierrs.IsInternalError(err) -} diff --git a/pkg/skaffold/runner/changes.go b/pkg/skaffold/runner/changes.go index 67711d811d3..caf8cbd6887 100644 --- a/pkg/skaffold/runner/changes.go +++ b/pkg/skaffold/runner/changes.go @@ -21,17 +21,17 @@ import ( ) type changes struct { - diryArtifacts []*v1alpha2.Artifact - needsRedeploy bool - needsReload bool + dirtyArtifacts []*v1alpha2.Artifact + needsRedeploy bool + needsReload bool } func (c *changes) Add(a *v1alpha2.Artifact) { - c.diryArtifacts = append(c.diryArtifacts, a) + c.dirtyArtifacts = append(c.dirtyArtifacts, a) } func (c *changes) reset() { - c.diryArtifacts = nil + c.dirtyArtifacts = nil c.needsRedeploy = false c.needsReload = false } diff --git a/pkg/skaffold/runner/runner.go b/pkg/skaffold/runner/runner.go index ba94c8509b6..374bdef81e7 100644 --- a/pkg/skaffold/runner/runner.go +++ b/pkg/skaffold/runner/runner.go @@ -192,8 +192,8 @@ func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*v1 switch { case changed.needsReload: err = ErrorConfigurationChanged - case len(changed.diryArtifacts) > 0: - err = r.buildAndDeploy(ctx, out, changed.diryArtifacts, imageList) + case len(changed.dirtyArtifacts) > 0: + err = r.buildAndDeploy(ctx, out, changed.dirtyArtifacts, imageList) case changed.needsRedeploy: if _, err := r.Deploy(ctx, out, r.builds); err != nil { logrus.Warnln("Skipping Deploy due to error:", err) diff --git a/pkg/skaffold/update/update.go b/pkg/skaffold/update/update.go index afaf9e7e79a..cca69eb9913 100644 --- a/pkg/skaffold/update/update.go +++ b/pkg/skaffold/update/update.go @@ -18,7 +18,6 @@ package update import ( "context" - "fmt" "io/ioutil" "net/http" "os" @@ -30,6 +29,8 @@ import ( "github.com/pkg/errors" ) +const latestVersionURL = "https://storage.googleapis.com/skaffold/releases/latest/VERSION" + // IsUpdateCheckEnabled returns whether or not the update check is enabled // It is true by default, but setting it to any other value than true will disable the check func IsUpdateCheckEnabled() bool { @@ -37,15 +38,11 @@ func IsUpdateCheckEnabled() bool { if version.Get().GitTreeState == "dirty" { return false } + v := os.Getenv(constants.UpdateCheckEnvironmentVariable) - if v == "" || strings.ToLower(v) == "true" { - return true - } - return false + return v == "" || strings.ToLower(v) == "true" } -var latestVersionURL = fmt.Sprintf("https://storage.googleapis.com/skaffold/releases/latest/VERSION") - // GetLatestVersion uses a VERSION file stored on GCS to determine the latest released version of skaffold func GetLatestVersion(ctx context.Context) (semver.Version, error) { resp, err := http.Get(latestVersionURL) diff --git a/pkg/skaffold/util/util.go b/pkg/skaffold/util/util.go index 50d420ebcfb..d87a2bc360e 100644 --- a/pkg/skaffold/util/util.go +++ b/pkg/skaffold/util/util.go @@ -63,21 +63,6 @@ func StrSliceContains(sl []string, s string) bool { return false } -func UniqueStrSlice(values []string) []string { - var unique []string - - m := make(map[string]bool) - for _, value := range values { - m[value] = true - } - for value := range m { - unique = append(unique, value) - } - - sort.Strings(unique) - return unique -} - // ExpandPathsGlob expands paths according to filepath.Glob patterns // Returns a list of unique files that match the glob patterns passed in. func ExpandPathsGlob(workingDir string, paths []string) ([]string, error) { diff --git a/testutil/util.go b/testutil/util.go index 5b93652c4b8..295b5d8bbc6 100644 --- a/testutil/util.go +++ b/testutil/util.go @@ -43,6 +43,7 @@ func (f FakeReaderCloser) Close() error { return nil } func (f FakeReaderCloser) Read([]byte) (int, error) { return 0, f.Err } func CheckErrorAndDeepEqual(t *testing.T, shouldErr bool, err error, expected, actual interface{}) { + t.Helper() if err := checkErr(shouldErr, err); err != nil { t.Error(err) return @@ -54,6 +55,7 @@ func CheckErrorAndDeepEqual(t *testing.T, shouldErr bool, err error, expected, a } func CheckErrorAndTypeEquality(t *testing.T, shouldErr bool, err error, expected, actual interface{}) { + t.Helper() if err := checkErr(shouldErr, err); err != nil { t.Error(err) return @@ -68,6 +70,7 @@ func CheckErrorAndTypeEquality(t *testing.T, shouldErr bool, err error, expected } func CheckError(t *testing.T, shouldErr bool, err error) { + t.Helper() if err := checkErr(shouldErr, err); err != nil { t.Error(err) }