github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/subtool/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/Cloud-Foundations/Dominator/lib/constants"
    10  	"github.com/Cloud-Foundations/Dominator/lib/flags/commands"
    11  	"github.com/Cloud-Foundations/Dominator/lib/flags/loadflags"
    12  	"github.com/Cloud-Foundations/Dominator/lib/flagutil"
    13  	"github.com/Cloud-Foundations/Dominator/lib/log"
    14  	"github.com/Cloud-Foundations/Dominator/lib/log/cmdlogger"
    15  	"github.com/Cloud-Foundations/Dominator/lib/log/debuglogger"
    16  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    17  	"github.com/Cloud-Foundations/Dominator/lib/srpc/setupclient"
    18  )
    19  
    20  var (
    21  	computedFilesRoot = flag.String("computedFilesRoot", "",
    22  		"Name of directory tree containing computed files")
    23  	connectTimeout = flag.Duration("connectTimeout", 15*time.Second,
    24  		"connection timeout")
    25  	cpuPercent = flag.Uint("cpuPercent", 0,
    26  		"CPU speed as percentage of capacity (default 50)")
    27  	debug             = flag.Bool("debug", false, "Enable debug mode")
    28  	deleteBeforeFetch = flag.Bool("deleteBeforeFetch", false,
    29  		"If true, delete prior to Fetch rather than during Update")
    30  	file = flag.String("file", "",
    31  		"Name of file to write encoded data to")
    32  	forceDisruption = flag.Bool("forceDisruption", false,
    33  		"If true, force an upgrade regardless of DisruptionManager state")
    34  	forceImageChange = flag.Bool("forceImageChange", false,
    35  		"If true, force an upgrade even if changing the image")
    36  	filterFile = flag.String("filterFile", "",
    37  		"Replacement filter file to apply when pushing image")
    38  	imageServerHostname = flag.String("imageServerHostname", "localhost",
    39  		"Hostname of image server")
    40  	imageServerPortNum = flag.Uint("imageServerPortNum",
    41  		constants.ImageServerPortNumber,
    42  		"Port number of image server")
    43  	interval = flag.Uint("interval", 1,
    44  		"Seconds to sleep between Polls")
    45  	lockDuration = flag.Duration("lockDuration", 15*time.Second,
    46  		"Time to lock client from mutations by other clients")
    47  	networkSpeedPercent = flag.Uint("networkSpeedPercent",
    48  		constants.DefaultNetworkSpeedPercent,
    49  		"Network speed as percentage of capacity")
    50  	newConnection = flag.Bool("newConnection", false,
    51  		"If true, (re)open a connection for each Poll")
    52  	numPolls = flag.Int("numPolls", 1,
    53  		"The number of polls to run (infinite: < 0)")
    54  	objectServerHostname = flag.String("objectServerHostname", "localhost",
    55  		"Hostname of image server")
    56  	objectServerPortNum = flag.Uint("objectServerPortNum",
    57  		constants.ImageServerPortNumber,
    58  		"Port number of image server")
    59  	scanExcludeList  flagutil.StringList = constants.ScanExcludeList
    60  	scanSpeedPercent                     = flag.Uint("scanSpeedPercent",
    61  		constants.DefaultScanSpeedPercent,
    62  		"Scan speed as percentage of capacity")
    63  	shortPoll = flag.Bool("shortPoll", false,
    64  		"If true, perform a short poll which does not request image or object data")
    65  	showTimes = flag.Bool("showTimes", false,
    66  		"If true, show time taken for some operations")
    67  	subHostname = flag.String("subHostname", "localhost", "Hostname of sub")
    68  	subPortNum  = flag.Uint("subPortNum", constants.SubPortNumber,
    69  		"Port number of sub")
    70  	timeout = flag.Duration("timeout", 15*time.Minute,
    71  		"timeout for long operations")
    72  	triggersFile = flag.String("triggersFile", "",
    73  		"Replacement triggers file to apply when pushing image")
    74  	triggersString = flag.String("triggersString", "",
    75  		"Replacement triggers string to apply when pushing image (ignored if triggersFile is set)")
    76  	wait = flag.Uint("wait", 0, "Seconds to sleep after last Poll")
    77  
    78  	logger      *debuglogger.Logger
    79  	timeoutTime time.Time
    80  )
    81  
    82  func init() {
    83  	flag.Var(&scanExcludeList, "scanExcludeList",
    84  		"Comma separated list of patterns to exclude from scanning")
    85  }
    86  
    87  func printUsage() {
    88  	w := flag.CommandLine.Output()
    89  	fmt.Fprintln(w,
    90  		"Usage: subtool [flags...] fetch|get-config|poll|set-config")
    91  	fmt.Fprintln(w, "Common flags:")
    92  	flag.PrintDefaults()
    93  	fmt.Fprintln(w, "Commands:")
    94  	commands.PrintCommands(w, subcommands)
    95  }
    96  
    97  func getSubClient(logger log.DebugLogger) *srpc.Client {
    98  	clientName := fmt.Sprintf("%s:%d", *subHostname, *subPortNum)
    99  	client, err := srpc.DialHTTP("tcp", clientName, *connectTimeout)
   100  	if err != nil {
   101  		logger.Fatalf("Error dialing %s: %s\n", clientName, err)
   102  	}
   103  	return client
   104  }
   105  
   106  func getSubClientRetry(logger log.DebugLogger) *srpc.Client {
   107  	clientName := fmt.Sprintf("%s:%d", *subHostname, *subPortNum)
   108  	var client *srpc.Client
   109  	var err error
   110  	for time.Now().Before(timeoutTime) {
   111  		client, err = srpc.DialHTTP("tcp", clientName, time.Second*5)
   112  		if err == nil {
   113  			return client
   114  		}
   115  		if err == srpc.ErrorMissingCertificate ||
   116  			err == srpc.ErrorBadCertificate ||
   117  			err == srpc.ErrorAccessToMethodDenied {
   118  			// Never going to happen. Bail out.
   119  			logger.Fatalf("Error dialing %s: %s\n", clientName, err)
   120  		}
   121  	}
   122  	logger.Fatalf("Error dialing %s: %s\n", clientName, err)
   123  	return nil
   124  }
   125  
   126  var subcommands = []commands.Command{
   127  	{"boost-cpu-limit", "", 0, 0, boostCpuLimitSubcommand},
   128  	{"cleanup", "", 0, 0, cleanupSubcommand},
   129  	{"delete", "pathname...", 1, 1, deleteSubcommand},
   130  	{"fetch", "hashesFile", 1, 1, fetchSubcommand},
   131  	{"fetch-image", "image", 1, 1, fetchImageSubcommand},
   132  	{"get-config", "", 0, 0, getConfigSubcommand},
   133  	{"get-file", "remoteFile localFile", 2, 2, getFileSubcommand},
   134  	{"list-missing-objects", "image", 1, 1, listMissingObjectsSubcommand},
   135  	{"poll", "", 0, 0, pollSubcommand},
   136  	{"push-file", "source dest", 2, 2, pushFileSubcommand},
   137  	{"push-image", "image", 1, 1, pushImageSubcommand},
   138  	{"push-missing-objects", "image", 1, 1, pushMissingObjectsSubcommand},
   139  	{"restart-service", "name", 1, 1, restartServiceSubcommand},
   140  	{"set-config", "", 0, 0, setConfigSubcommand},
   141  	{"show-update-request", "image", 1, 1, showUpdateRequestSubcommand},
   142  	{"wait-for-image", "image", 1, 1, waitForImageSubcommand},
   143  }
   144  
   145  func doMain() int {
   146  	if err := loadflags.LoadForCli("subtool"); err != nil {
   147  		fmt.Fprintln(os.Stderr, err)
   148  		return 1
   149  	}
   150  	flag.Usage = printUsage
   151  	flag.Parse()
   152  	if flag.NArg() < 1 {
   153  		printUsage()
   154  		return 2
   155  	}
   156  	logger = cmdlogger.New()
   157  	srpc.SetDefaultLogger(logger)
   158  	if *triggersFile != "" && *triggersString != "" {
   159  		logger.Fatalln(os.Stderr,
   160  			"Cannot specify both -triggersFile and -triggersString")
   161  	}
   162  	if err := setupclient.SetupTls(true); err != nil {
   163  		logger.Fatalln(os.Stderr, err)
   164  	}
   165  	timeoutTime = time.Now().Add(*timeout)
   166  	return commands.RunCommands(subcommands, printUsage, logger)
   167  }
   168  
   169  func main() {
   170  	os.Exit(doMain())
   171  }