From cb0901e8e1390df03dbcead8fcf9006a10b2b916 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Wed, 20 Apr 2016 15:48:37 +0100 Subject: [PATCH] Move all the flag parsing to main.go; implement `scope help` --- docker/entrypoint.sh | 70 +++------------------ docker/run-app | 2 +- docker/run-probe | 2 +- prog/app.go | 52 +++++----------- prog/main.go | 144 +++++++++++++++++++++++++++++++++++++++---- prog/probe.go | 81 +++++++++--------------- scope | 23 ++++++- 7 files changed, 206 insertions(+), 168 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index a6e50cd906..df443d4568 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash usage() { echo "$0 --app.foo bar --probe.foo bar" @@ -6,89 +6,37 @@ usage() { } mkdir -p /var/run/weave -APP_ARGS="" -PROBE_ARGS="" + TOKEN_PROVIDED=false -if [ "$1" = version ]; then - /home/weave/scope version +if [ "$1" = "version" -o "$1" = "help" ]; then + exec -a scope /home/weave/scope --mode $1 exit 0 fi -while true; do - case "$1" in - --app.*) - if echo "$1" | grep "=" 1>/dev/null; then - ARG_NAME=$(echo "$1" | sed 's/\-\-app\.\([^=]*\)=\(.*\)/\1/') - ARG_VALUE=$(echo "$1" | sed 's/\-\-app\.\([^=]*\)=\(.*\)/\2/') - else - [ $# -gt 1 ] || usage - ARG_NAME=$(echo "$1" | sed 's/\-\-app\.//') - ARG_VALUE="$2" - shift - fi - APP_ARGS="$APP_ARGS -$ARG_NAME=$ARG_VALUE" - ;; - --debug) - APP_ARGS="$APP_ARGS -log.level=debug" - PROBE_ARGS="$PROBE_ARGS -log.level=debug" - ;; +for arg in $@; do + case "$arg" in --no-app|--probe-only) touch /etc/service/app/down ;; --no-probe|--app-only) touch /etc/service/probe/down ;; - --weave.hostname*) - if echo "$1" | grep "=" 1>/dev/null; then - ARG_VALUE=$(echo "$1" | sed 's/\-\-weave.hostname=\(.*\)/\1/') - else - [ $# -gt 1 ] || usage - ARG_VALUE="$2" - shift - fi - PROBE_ARGS="$PROBE_ARGS -weave.hostname=$ARG_VALUE" - APP_ARGS="$APP_ARGS -weave.hostname=$ARG_VALUE" - ;; - --probe.*) - if echo "$1" | grep "=" 1>/dev/null; then - ARG_NAME=$(echo "$1" | sed 's/\-\-probe\.\([^=]*\)=\(.*\)/\1/') - ARG_VALUE=$(echo "$1" | sed 's/\-\-probe\.\([^=]*\)=\(.*\)/\2/') - else - [ $# -gt 1 ] || usage - ARG_NAME=$(echo "$1" | sed 's/\-\-probe\.//') - ARG_VALUE="$2" - shift - fi - PROBE_ARGS="$PROBE_ARGS -$ARG_NAME=$ARG_VALUE" - ;; --service-token*) - if echo "$1" | grep "=" 1>/dev/null; then - ARG_VALUE=$(echo "$1" | sed 's/\-\-service-token=\(.*\)/\1/') - else - [ $# -gt 1 ] || usage - ARG_VALUE="$2" - shift - fi - PROBE_ARGS="$PROBE_ARGS -token=$ARG_VALUE" TOKEN_PROVIDED=true touch /etc/service/app/down ;; - *) - break - ;; esac - shift done -echo "$APP_ARGS" >/var/run/weave/scope-app.args -echo "$PROBE_ARGS" >/var/run/weave/scope-probe.args +echo "$@" >/var/run/weave/scope-app.args +echo "$@" >/var/run/weave/scope-probe.args # End of the command line can optionally be some # addresses of apps to connect to, for people not # using Weave DNS. We stick these in /var/run/weave/apps # for the run-probe script to pick up. -MANUAL_APPS=$@ +MANUAL_APPS="" # Implicitly target the Scope Service if a service token was provided with # no explicit manual app. diff --git a/docker/run-app b/docker/run-app index 93b0e0713c..beeb932947 100755 --- a/docker/run-app +++ b/docker/run-app @@ -1,3 +1,3 @@ #!/bin/bash -exec -a scope-app /home/weave/scope app $(cat /var/run/weave/scope-app.args) +exec -a scope-app /home/weave/scope --mode app $(cat /var/run/weave/scope-app.args) diff --git a/docker/run-probe b/docker/run-probe index 929e6d824b..c171768f70 100755 --- a/docker/run-probe +++ b/docker/run-probe @@ -1,3 +1,3 @@ #!/bin/bash -exec -a scope-probe /home/weave/scope probe $(cat /var/run/weave/scope-probe.args) $(cat /var/run/weave/apps) +exec -a scope-probe /home/weave/scope --mode probe $(cat /var/run/weave/scope-probe.args) $(cat /var/run/weave/apps) diff --git a/prog/app.go b/prog/app.go index 6fa06fb137..0fcf72c9d7 100644 --- a/prog/app.go +++ b/prog/app.go @@ -1,7 +1,6 @@ package main import ( - "flag" "fmt" "math/rand" "net/http" @@ -25,7 +24,6 @@ import ( "github.com/weaveworks/scope/common/middleware" "github.com/weaveworks/scope/common/network" "github.com/weaveworks/scope/common/weave" - "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/scope/probe/docker" ) @@ -142,50 +140,28 @@ func pipeRouterFactory(userIDer multitenant.UserIDer, pipeRouterURL, consulInf s } // Main runs the app -func appMain() { - var ( - window = flag.Duration("window", 15*time.Second, "window") - listen = flag.String("http.address", ":"+strconv.Itoa(xfer.AppPort), "webserver listen address") - logLevel = flag.String("log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic") - logPrefix = flag.String("log.prefix", "", "prefix for each log line") - logHTTP = flag.Bool("log.http", false, "Log individual HTTP requests") - - weaveAddr = flag.String("weave.addr", app.DefaultWeaveURL, "Address on which to contact WeaveDNS") - weaveHostname = flag.String("weave.hostname", app.DefaultHostname, "Hostname to advertise in WeaveDNS") - containerName = flag.String("container.name", app.DefaultContainerName, "Name of this container (to lookup container ID)") - dockerEndpoint = flag.String("docker", app.DefaultDockerEndpoint, "Location of docker endpoint (to lookup container ID)") - - collectorURL = flag.String("collector", "local", "Collector to use (local of dynamodb)") - controlRouterURL = flag.String("control.router", "local", "Control router to use (local or sqs)") - pipeRouterURL = flag.String("pipe.router", "local", "Pipe router to use (local)") - userIDHeader = flag.String("userid.header", "", "HTTP header to use as userid") - - awsCreateTables = flag.Bool("aws.create.tables", false, "Create the tables in DynamoDB") - consulInf = flag.String("consul.inf", "", "The interface who's address I should advertise myself under in consul") - ) - flag.Parse() - - setLogLevel(*logLevel) - setLogFormatter(*logPrefix) +func appMain(flags appFlags) { + setLogLevel(flags.logLevel) + setLogFormatter(flags.logPrefix) userIDer := multitenant.NoopUserIDer - if *userIDHeader != "" { - userIDer = multitenant.UserIDHeader(*userIDHeader) + if flags.userIDHeader != "" { + userIDer = multitenant.UserIDHeader(flags.userIDHeader) } - collector, err := collectorFactory(userIDer, *collectorURL, *window, *awsCreateTables) + collector, err := collectorFactory(userIDer, flags.collectorURL, flags.window, flags.awsCreateTables) if err != nil { log.Fatalf("Error creating collector: %v", err) return } - controlRouter, err := controlRouterFactory(userIDer, *controlRouterURL) + controlRouter, err := controlRouterFactory(userIDer, flags.controlRouterURL) if err != nil { log.Fatalf("Error creating control router: %v", err) return } - pipeRouter, err := pipeRouterFactory(userIDer, *pipeRouterURL, *consulInf) + pipeRouter, err := pipeRouterFactory(userIDer, flags.pipeRouterURL, flags.consulInf) if err != nil { log.Fatalf("Error creating pipe router: %v", err) return @@ -213,10 +189,10 @@ func appMain() { // If user supplied a weave router address, periodically try and register // out IP address in WeaveDNS. - if *weaveAddr != "" { + if flags.weaveAddr != "" { weave, err := newWeavePublisher( - *dockerEndpoint, *weaveAddr, - *weaveHostname, *containerName) + flags.dockerEndpoint, flags.weaveAddr, + flags.weaveHostname, flags.containerName) if err != nil { log.Println("Failed to start weave integration:", err) } else { @@ -225,12 +201,12 @@ func appMain() { } handler := router(collector, controlRouter, pipeRouter) - if *logHTTP { + if flags.logHTTP { handler = middleware.Logging.Wrap(handler) } go func() { - log.Infof("listening on %s", *listen) - log.Info(http.ListenAndServe(*listen, handler)) + log.Infof("listening on %s", flags.listen) + log.Info(http.ListenAndServe(flags.listen, handler)) }() common.SignalHandlerLoop() diff --git a/prog/main.go b/prog/main.go index e4b66c479c..2d3827ad41 100644 --- a/prog/main.go +++ b/prog/main.go @@ -1,12 +1,17 @@ package main import ( + "flag" "fmt" "os" + "strconv" "strings" + "time" log "github.com/Sirupsen/logrus" + "github.com/weaveworks/scope/app" + "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/weave/common" ) @@ -45,27 +50,142 @@ func setLogLevel(levelname string) { log.SetLevel(level) } -func usage() { - fmt.Fprintf(os.Stderr, "usage: %s (app|probe|version) args...\n", os.Args[0]) - os.Exit(1) +type flags struct { + probe probeFlags + app appFlags +} + +type probeFlags struct { + token string + httpListen string + publishInterval time.Duration + spyInterval time.Duration + spyProcs bool + procRoot string + pluginsRoot string + useConntrack bool + insecure bool + logPrefix string + logLevel string + + dockerEnabled bool + dockerInterval time.Duration + dockerBridge string + + kubernetesEnabled bool + kubernetesAPI string + kubernetesInterval time.Duration + + weaveAddr string + weaveHostname string +} + +type appFlags struct { + window time.Duration + listen string + logLevel string + logPrefix string + logHTTP bool + + weaveAddr string + weaveHostname string + containerName string + dockerEndpoint string + + collectorURL string + controlRouterURL string + pipeRouterURL string + userIDHeader string + + awsCreateTables bool + consulInf string } func main() { - if len(os.Args) < 2 { - usage() - } + var ( + flags = flags{} + mode string + debug bool + weaveHostname string + ) - module := os.Args[1] - os.Args = append([]string{os.Args[0]}, os.Args[2:]...) + // Flags that apply to both probe and app + flag.StringVar(&mode, "mode", "help", "For internal use.") + flag.BoolVar(&debug, "debug", false, "Force debug logging.") + flag.StringVar(&weaveHostname, "weave.hostname", "", "Hostname to advertise/lookup in WeaveDNS") + + // We can ignore these - we need to know how to parse them, but they are interpreted by the entrypoint script. + // They are also here so they are included in usage. + flag.Bool("no-app", false, "Don't run the app.") + flag.Bool("probe-only", false, "Only run the probe.") + flag.Bool("no-probe", false, "Don't run the probe.") + flag.Bool("app-only", false, "Only run the app") + flag.String("service-token", "", "Token to use to authenticate with scope.weave.works") + + // Probe flags + flag.StringVar(&flags.probe.token, "probe.token", "default-token", "Token to use to authenticate with scope.weave.works") + flag.StringVar(&flags.probe.httpListen, "probe.http.listen", "", "listen address for HTTP profiling and instrumentation server") + flag.DurationVar(&flags.probe.publishInterval, "probe.publish.interval", 3*time.Second, "publish (output) interval") + flag.DurationVar(&flags.probe.spyInterval, "probe.spy.interval", time.Second, "spy (scan) interval") + flag.BoolVar(&flags.probe.spyProcs, "probe.processes", true, "report processes (needs root)") + flag.StringVar(&flags.probe.procRoot, "probe.proc.root", "/proc", "location of the proc filesystem") + flag.StringVar(&flags.probe.pluginsRoot, "probe.plugins.root", "/var/run/scope/plugins", "Root directory to search for plugins") + flag.BoolVar(&flags.probe.useConntrack, "probe.conntrack", true, "also use conntrack to track connections") + flag.BoolVar(&flags.probe.insecure, "probe.insecure", false, "(SSL) explicitly allow \"insecure\" SSL connections and transfers") + flag.StringVar(&flags.probe.logPrefix, "probe.log.prefix", "", "prefix for each log line") + flag.StringVar(&flags.probe.logLevel, "probe.log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic") + flag.BoolVar(&flags.probe.dockerEnabled, "probe.docker", false, "collect Docker-related attributes for processes") + flag.DurationVar(&flags.probe.dockerInterval, "probe.docker.interval", 10*time.Second, "how often to update Docker attributes") + flag.StringVar(&flags.probe.dockerBridge, "probe.docker.bridge", "docker0", "the docker bridge name") + flag.BoolVar(&flags.probe.kubernetesEnabled, "probe.kubernetes", false, "collect kubernetes-related attributes for containers, should only be enabled on the master node") + flag.StringVar(&flags.probe.kubernetesAPI, "probe.kubernetes.api", "", "Address of kubernetes master api") + flag.DurationVar(&flags.probe.kubernetesInterval, "probe.kubernetes.interval", 10*time.Second, "how often to do a full resync of the kubernetes data") + flag.StringVar(&flags.probe.weaveAddr, "probe.weave.addr", "127.0.0.1:6784", "IP address & port of the Weave router") + flag.StringVar(&flags.probe.weaveHostname, "probe.weave.hostname", app.DefaultHostname, "Hostname to lookup in WeaveDNS") + + // App flags + flag.DurationVar(&flags.app.window, "app.window", 15*time.Second, "window") + flag.StringVar(&flags.app.listen, "app.http.address", ":"+strconv.Itoa(xfer.AppPort), "webserver listen address") + flag.StringVar(&flags.app.logLevel, "app.log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic") + flag.StringVar(&flags.app.logPrefix, "app.log.prefix", "", "prefix for each log line") + flag.BoolVar(&flags.app.logHTTP, "app.log.http", false, "Log individual HTTP requests") + + flag.StringVar(&flags.app.weaveAddr, "app.weave.addr", app.DefaultWeaveURL, "Address on which to contact WeaveDNS") + flag.StringVar(&flags.app.weaveHostname, "app.weave.hostname", app.DefaultHostname, "Hostname to advertise in WeaveDNS") + flag.StringVar(&flags.app.containerName, "app.container.name", app.DefaultContainerName, "Name of this container (to lookup container ID)") + flag.StringVar(&flags.app.dockerEndpoint, "app.docker", app.DefaultDockerEndpoint, "Location of docker endpoint (to lookup container ID)") + + flag.StringVar(&flags.app.collectorURL, "app.collector", "local", "Collector to use (local of dynamodb)") + flag.StringVar(&flags.app.controlRouterURL, "app.control.router", "local", "Control router to use (local or sqs)") + flag.StringVar(&flags.app.pipeRouterURL, "app.pipe.router", "local", "Pipe router to use (local)") + flag.StringVar(&flags.app.userIDHeader, "app.userid.header", "", "HTTP header to use as userid") + + flag.BoolVar(&flags.app.awsCreateTables, "app.aws.create.tables", false, "Create the tables in DynamoDB") + flag.StringVar(&flags.app.consulInf, "app.consul.inf", "", "The interface who's address I should advertise myself under in consul") + + flag.Parse() + + // Deal with common args + if debug { + flags.probe.logLevel = "debug" + flags.app.logLevel = "debug" + } + if weaveHostname != "" { + flags.probe.weaveHostname = weaveHostname + flags.app.weaveHostname = weaveHostname + } - switch module { + switch mode { case "app": - appMain() + appMain(flags.app) case "probe": - probeMain() + probeMain(flags.probe) case "version": fmt.Println("Weave Scope version", version) + case "help": + flag.PrintDefaults() default: - usage() + fmt.Printf("command '%s' not recognices", mode) + os.Exit(1) } } diff --git a/prog/probe.go b/prog/probe.go index 9a783455a0..3138b16b49 100644 --- a/prog/probe.go +++ b/prog/probe.go @@ -63,36 +63,9 @@ func check() { } // Main runs the probe -func probeMain() { - var ( - targets = []string{fmt.Sprintf("localhost:%d", xfer.AppPort)} - token = flag.String("token", "default-token", "probe token") - httpListen = flag.String("http.listen", "", "listen address for HTTP profiling and instrumentation server") - publishInterval = flag.Duration("publish.interval", 3*time.Second, "publish (output) interval") - spyInterval = flag.Duration("spy.interval", time.Second, "spy (scan) interval") - spyProcs = flag.Bool("processes", true, "report processes (needs root)") - procRoot = flag.String("proc.root", "/proc", "location of the proc filesystem") - pluginsRoot = flag.String("plugins.root", "/var/run/scope/plugins", "Root directory to search for plugins") - useConntrack = flag.Bool("conntrack", true, "also use conntrack to track connections") - insecure = flag.Bool("insecure", false, "(SSL) explicitly allow \"insecure\" SSL connections and transfers") - logPrefix = flag.String("log.prefix", "", "prefix for each log line") - logLevel = flag.String("log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic") - - dockerEnabled = flag.Bool("docker", false, "collect Docker-related attributes for processes") - dockerInterval = flag.Duration("docker.interval", 10*time.Second, "how often to update Docker attributes") - dockerBridge = flag.String("docker.bridge", "docker0", "the docker bridge name") - - kubernetesEnabled = flag.Bool("kubernetes", false, "collect kubernetes-related attributes for containers, should only be enabled on the master node") - kubernetesAPI = flag.String("kubernetes.api", "", "Address of kubernetes master api") - kubernetesInterval = flag.Duration("kubernetes.interval", 10*time.Second, "how often to do a full resync of the kubernetes data") - - weaveAddr = flag.String("weave.addr", "127.0.0.1:6784", "IP address & port of the Weave router") - weaveDNSTarget = flag.String("weave.hostname", fmt.Sprintf("scope.weave.local:%d", xfer.AppPort), "Hostname to lookup in weaveDNS") - ) - flag.Parse() - - setLogLevel(*logLevel) - setLogFormatter(*logPrefix) +func probeMain(flags probeFlags) { + setLogLevel(flags.logLevel) + setLogFormatter(flags.logPrefix) // Setup in memory metrics sink inm := metrics.NewInmemSink(time.Minute, 2*time.Minute) @@ -102,28 +75,30 @@ func probeMain() { defer log.Info("probe exiting") - if *spyProcs && os.Getegid() != 0 { - log.Warn("-process=true, but that requires root to find everything") + if flags.spyProcs && os.Getegid() != 0 { + log.Warn("--probe.process=true, but that requires root to find everything") } rand.Seed(time.Now().UnixNano()) - probeID := strconv.FormatInt(rand.Int63(), 16) var ( + probeID = strconv.FormatInt(rand.Int63(), 16) hostName = hostname.Get() hostID = hostName // TODO(pb): we should sanitize the hostname ) log.Infof("probe starting, version %s, ID %s", version, probeID) + log.Infof("command line: %v", os.Args) go check() + var targets = []string{fmt.Sprintf("localhost:%d", xfer.AppPort)} if len(flag.Args()) > 0 { targets = flag.Args() } log.Infof("publishing to: %s", strings.Join(targets, ", ")) probeConfig := appclient.ProbeConfig{ - Token: *token, + Token: flags.token, ProbeID: probeID, - Insecure: *insecure, + Insecure: flags.insecure, } clients := appclient.NewMultiAppClient(func(hostname, endpoint string) (appclient.AppClient, error) { return appclient.NewAppClient( @@ -136,13 +111,13 @@ func probeMain() { resolver := appclient.NewResolver(targets, net.LookupIP, clients.Set) defer resolver.Stop() - processCache := process.NewCachingWalker(process.NewWalker(*procRoot)) + processCache := process.NewCachingWalker(process.NewWalker(flags.procRoot)) scanner := procspy.NewConnectionScanner(processCache) - endpointReporter := endpoint.NewReporter(hostID, hostName, *spyProcs, *useConntrack, scanner) + endpointReporter := endpoint.NewReporter(hostID, hostName, flags.spyProcs, flags.useConntrack, scanner) defer endpointReporter.Stop() - p := probe.New(probeID, *spyInterval, *publishInterval, clients) + p := probe.New(probeID, flags.spyInterval, flags.publishInterval, clients) p.AddTicker(processCache) hostReporter := host.NewReporter(hostID, hostName, probeID, clients) defer hostReporter.Stop() @@ -153,11 +128,11 @@ func probeMain() { ) p.AddTagger(probe.NewTopologyTagger(), host.NewTagger(hostID)) - if *dockerEnabled { - if err := report.AddLocalBridge(*dockerBridge); err != nil { - log.Errorf("Docker: problem with bridge %s: %v", *dockerBridge, err) + if flags.dockerEnabled { + if err := report.AddLocalBridge(flags.dockerBridge); err != nil { + log.Errorf("Docker: problem with bridge %s: %v", flags.dockerBridge, err) } - if registry, err := docker.NewRegistry(*dockerInterval, clients, true); err == nil { + if registry, err := docker.NewRegistry(flags.dockerInterval, clients, true); err == nil { defer registry.Stop() p.AddTagger(docker.NewTagger(registry, processCache)) p.AddReporter(docker.NewReporter(registry, hostID, probeID, p)) @@ -166,8 +141,8 @@ func probeMain() { } } - if *kubernetesEnabled { - if client, err := kubernetes.NewClient(*kubernetesAPI, *kubernetesInterval); err == nil { + if flags.kubernetesEnabled { + if client, err := kubernetes.NewClient(flags.kubernetesAPI, flags.kubernetesInterval); err == nil { defer client.Stop() p.AddReporter(kubernetes.NewReporter(client)) } else { @@ -176,25 +151,25 @@ func probeMain() { } } - if *weaveAddr != "" { - client := weave.NewClient(sanitize.URL("http://", 6784, "")(*weaveAddr)) + if flags.weaveAddr != "" { + client := weave.NewClient(sanitize.URL("http://", 6784, "")(flags.weaveAddr)) weave := overlay.NewWeave(hostID, client) defer weave.Stop() p.AddTagger(weave) p.AddReporter(weave) - dockerBridgeIP, err := network.GetFirstAddressOf(*dockerBridge) + dockerBridgeIP, err := network.GetFirstAddressOf(flags.dockerBridge) if err != nil { log.Println("Error getting docker bridge ip:", err) } else { weaveDNSLookup := appclient.LookupUsing(dockerBridgeIP + ":53") - weaveResolver := appclient.NewResolver([]string{*weaveDNSTarget}, weaveDNSLookup, clients.Set) + weaveResolver := appclient.NewResolver([]string{flags.weaveHostname}, weaveDNSLookup, clients.Set) defer weaveResolver.Stop() } } pluginRegistry, err := plugins.NewRegistry( - *pluginsRoot, + flags.pluginsRoot, pluginAPIVersion, map[string]string{ "probe_id": probeID, @@ -208,11 +183,11 @@ func probeMain() { p.AddReporter(pluginRegistry) } - if *httpListen != "" { + if flags.httpListen != "" { go func() { - log.Infof("Profiling data being exported to %s", *httpListen) - log.Infof("go tool pprof http://%s/debug/pprof/{profile,heap,block}", *httpListen) - log.Infof("Profiling endpoint %s terminated: %v", *httpListen, http.ListenAndServe(*httpListen, nil)) + log.Infof("Profiling data being exported to %s", flags.httpListen) + log.Infof("go tool pprof http://%s/debug/pprof/{profile,heap,block}", flags.httpListen) + log.Infof("Profiling endpoint %s terminated: %v", flags.httpListen, http.ListenAndServe(flags.httpListen, nil)) }() } diff --git a/scope b/scope index 4e3e92af29..dbb589a28e 100755 --- a/scope +++ b/scope @@ -94,7 +94,7 @@ launch_command() { -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/scope/plugins:/var/run/scope/plugins \ -e CHECKPOINT_DISABLE \ - $WEAVESCOPE_DOCKER_ARGS $SCOPE_IMAGE --probe.docker true "$@" + $WEAVESCOPE_DOCKER_ARGS $SCOPE_IMAGE --probe.docker=true "$@" } check_docker_version @@ -105,7 +105,26 @@ case "$COMMAND" in ;; version) - docker run $SCOPE_IMAGE version + docker run --rm -e CHECKPOINT_DISABLE $SCOPE_IMAGE version + ;; + + help) + cat >&2 <&2 <