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 }