github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/cmd/roachprod/vm/local/local.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package local
    12  
    13  import (
    14  	"fmt"
    15  	"os"
    16  	"path/filepath"
    17  	"text/tabwriter"
    18  	"time"
    19  
    20  	"github.com/cockroachdb/cockroach/pkg/cmd/roachprod/config"
    21  	"github.com/cockroachdb/cockroach/pkg/cmd/roachprod/install"
    22  	"github.com/cockroachdb/cockroach/pkg/cmd/roachprod/vm"
    23  	"github.com/cockroachdb/cockroach/pkg/util/timeutil"
    24  	"github.com/cockroachdb/errors"
    25  	"github.com/spf13/pflag"
    26  )
    27  
    28  // ProviderName is config.Local.
    29  const ProviderName = config.Local
    30  
    31  func init() {
    32  	vm.Providers[ProviderName] = &Provider{}
    33  }
    34  
    35  // A Provider is used to create stub VM objects.
    36  type Provider struct{}
    37  
    38  // No-op implementation of ProviderFlags
    39  type emptyFlags struct{}
    40  
    41  // ConfigureCreateFlags is part of ProviderFlags.  This implementation is a no-op.
    42  func (o *emptyFlags) ConfigureCreateFlags(flags *pflag.FlagSet) {
    43  }
    44  
    45  // ConfigureClusterFlags is part of ProviderFlags.  This implementation is a no-op.
    46  func (o *emptyFlags) ConfigureClusterFlags(*pflag.FlagSet, vm.MultipleProjectsOption) {
    47  }
    48  
    49  // CleanSSH is part of the vm.Provider interface.  This implementation is a no-op.
    50  func (p *Provider) CleanSSH() error {
    51  	return nil
    52  }
    53  
    54  // ConfigSSH is part of the vm.Provider interface.  This implementation is a no-op.
    55  func (p *Provider) ConfigSSH() error {
    56  	return nil
    57  }
    58  
    59  // Create just creates fake host-info entries in the local filesystem
    60  func (p *Provider) Create(names []string, opts vm.CreateOpts) error {
    61  	path := filepath.Join(os.ExpandEnv(config.DefaultHostDir), config.Local)
    62  	file, err := os.Create(path)
    63  	if err != nil {
    64  		return errors.Wrapf(err, "problem creating file %s", path)
    65  	}
    66  	defer file.Close()
    67  
    68  	// Align columns left and separate with at least two spaces.
    69  	tw := tabwriter.NewWriter(file, 0, 8, 2, ' ', 0)
    70  	if _, err := tw.Write([]byte("# user@host\tlocality\n")); err != nil {
    71  		return err
    72  	}
    73  	for i := 0; i < len(names); i++ {
    74  		if _, err := tw.Write([]byte(fmt.Sprintf(
    75  			"%s@%s\t%s\n", config.OSUser.Username, "127.0.0.1", "region=local,zone=local"))); err != nil {
    76  			return err
    77  		}
    78  	}
    79  	if err := tw.Flush(); err != nil {
    80  		return errors.Wrapf(err, "problem writing file %s", path)
    81  	}
    82  	return nil
    83  }
    84  
    85  // Delete is part of the vm.Provider interface. This implementation is a no-op.
    86  func (p *Provider) Delete(vms vm.List) error {
    87  	return nil
    88  }
    89  
    90  // Extend is part of the vm.Provider interface.  This implementation returns an error.
    91  func (p *Provider) Extend(vms vm.List, lifetime time.Duration) error {
    92  	return errors.New("local clusters have unlimited lifetime")
    93  }
    94  
    95  // FindActiveAccount is part of the vm.Provider interface. This implementation is a no-op.
    96  func (p *Provider) FindActiveAccount() (string, error) {
    97  	return "", nil
    98  }
    99  
   100  // Flags is part of the vm.Provider interface. This implementation is a no-op.
   101  func (p *Provider) Flags() vm.ProviderFlags {
   102  	return &emptyFlags{}
   103  }
   104  
   105  // List constructs N-many localhost VM instances, using SyncedCluster as a way to remember
   106  // how many nodes we should have
   107  func (p *Provider) List() (ret vm.List, _ error) {
   108  	if sc, ok := install.Clusters[ProviderName]; ok {
   109  		now := timeutil.Now()
   110  		for range sc.VMs {
   111  			ret = append(ret, vm.VM{
   112  				Name:        "localhost",
   113  				CreatedAt:   now,
   114  				Lifetime:    time.Hour,
   115  				PrivateIP:   "127.0.0.1",
   116  				Provider:    ProviderName,
   117  				ProviderID:  ProviderName,
   118  				PublicIP:    "127.0.0.1",
   119  				RemoteUser:  config.OSUser.Username,
   120  				VPC:         ProviderName,
   121  				MachineType: ProviderName,
   122  				Zone:        ProviderName,
   123  			})
   124  		}
   125  	}
   126  	return
   127  }
   128  
   129  // Name returns the name of the Provider, which will also surface in VM.Provider
   130  func (p *Provider) Name() string {
   131  	return ProviderName
   132  }
   133  
   134  // Active is part of the vm.Provider interface.
   135  func (p *Provider) Active() bool {
   136  	return true
   137  }