Path: blob/main/dev/preview/previewctl/cmd/install_context.go
2500 views
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package cmd56import (7"context"8"fmt"9"io/fs"10"os"11"time"1213"github.com/cockroachdb/errors"14"github.com/sirupsen/logrus"15"github.com/spf13/cobra"16"k8s.io/client-go/util/homedir"1718"github.com/gitpod-io/gitpod/previewctl/pkg/preview"19)2021type installContextCmdOpts struct {22logger *logrus.Logger2324watch bool25timeout time.Duration26kubeConfigSavePath string27sshPrivateKeyPath string28}2930func newInstallContextCmd(logger *logrus.Logger) *cobra.Command {31ctx := context.Background()3233opts := installContextCmdOpts{34logger: logger,35}3637// Used to ensure that we only install contexts38var lastSuccessfulPreviewEnvironment *preview.Config = nil3940install := func(retry bool, timeout time.Duration) error {41name, err := preview.GetName(branch)42if err != nil {43return err44}4546if hasAccess(ctx, logger, name) {47opts.logger.Debugf("Access to [%s] already configured and connections can be established", name)48return nil49}5051p, err := preview.New(branch, logger)52if err != nil {53return err54}5556if lastSuccessfulPreviewEnvironment != nil && lastSuccessfulPreviewEnvironment.Same(p) {57logger.Infof("The preview envrionment hasn't changed")58return nil59}6061err = p.InstallContext(ctx, &preview.InstallCtxOpts{62Retry: retry,63RetryTimeout: opts.timeout,64KubeSavePath: opts.kubeConfigSavePath,65SSHPrivateKeyPath: opts.sshPrivateKeyPath,66})6768if err == nil {69lastSuccessfulPreviewEnvironment = p70}7172return err73}7475cmd := &cobra.Command{76Use: "install-context",77Short: "Installs the kubectl context of a preview environment.",78PreRunE: func(cmd *cobra.Command, args []string) error {79if _, err := os.Stat(opts.sshPrivateKeyPath); errors.Is(err, fs.ErrNotExist) {80err := preview.GenerateSSHPrivateKey(opts.sshPrivateKeyPath)81if err != nil {82return err83}84}8586opts.kubeConfigSavePath = getKubeConfigPath()87return nil88},89RunE: func(cmd *cobra.Command, args []string) error {90if opts.watch {91for range time.Tick(15 * time.Second) {92// We're using a short timeout here to handle the scenario where someone switches93// to a branch that doesn't have a preview environment. In that case the default94// timeout would mean that we would block for 10 minutes, potentially missing95// if the user changes to a new branch that does that a preview.96err := install(true, 30*time.Second)97if err != nil {98logger.WithFields(logrus.Fields{"err": err}).Info("Failed to install context. Trying again soon.")99}100}101}102103return install(true, opts.timeout)104},105}106107cmd.Flags().BoolVar(&opts.watch, "watch", false, "If watch is enabled, previewctl will keep trying to install the kube-context every 15 seconds, even when successful.")108cmd.Flags().DurationVarP(&opts.timeout, "timeout", "t", 10*time.Minute, "Timeout before considering the installation failed. It will retry installing the context until successful or the timeout is reached")109cmd.PersistentFlags().StringVar(&opts.sshPrivateKeyPath, "private-key-path", fmt.Sprintf("%s/.ssh/vm_ed25519", homedir.HomeDir()), "path to the private key used to authenticate with the VM")110111return cmd112}113114115