mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-04 15:35:38 +00:00
cmd/tailscale/cli: remove special-casing of JS/WASM
We're no longer compiling the entire CLI for WASM, so we can remove some wrapper functions and GOOS checks. Effectively reverts75de4e9cc2
.5df7ac70d6
,eda647cb47
and other changes. Fixes #5146 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This commit is contained in:
parent
5d0e3d379c
commit
db9962d63b
@ -7,6 +7,7 @@
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/peterbourgon/ff/v3/ffcli"
|
"github.com/peterbourgon/ff/v3/ffcli"
|
||||||
)
|
)
|
||||||
@ -31,6 +32,6 @@ func runBugReport(ctx context.Context, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
outln(logMarker)
|
fmt.Println(logMarker)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
ShortHelp: "get TLS certs",
|
ShortHelp: "get TLS certs",
|
||||||
ShortUsage: "cert [flags] <domain>",
|
ShortUsage: "cert [flags] <domain>",
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("cert")
|
fs := flag.NewFlagSet("cert", flag.ExitOnError)
|
||||||
fs.StringVar(&certArgs.certFile, "cert-file", "", "output cert file or \"-\" for stdout; defaults to DOMAIN.crt if --cert-file and --key-file are both unset")
|
fs.StringVar(&certArgs.certFile, "cert-file", "", "output cert file or \"-\" for stdout; defaults to DOMAIN.crt if --cert-file and --key-file are both unset")
|
||||||
fs.StringVar(&certArgs.keyFile, "key-file", "", "output cert file or \"-\" for stdout; defaults to DOMAIN.key if --cert-file and --key-file are both unset")
|
fs.StringVar(&certArgs.keyFile, "key-file", "", "output cert file or \"-\" for stdout; defaults to DOMAIN.key if --cert-file and --key-file are both unset")
|
||||||
fs.BoolVar(&certArgs.serve, "serve-demo", false, "if true, serve on port :443 using the cert as a demo, instead of writing out the files to disk")
|
fs.BoolVar(&certArgs.serve, "serve-demo", false, "if true, serve on port :443 using the cert as a demo, instead of writing out the files to disk")
|
||||||
@ -79,7 +79,7 @@ func runCert(ctx context.Context, args []string) error {
|
|||||||
domain := args[0]
|
domain := args[0]
|
||||||
|
|
||||||
printf := func(format string, a ...any) {
|
printf := func(format string, a ...any) {
|
||||||
printf(format, a...)
|
fmt.Printf(format, a...)
|
||||||
}
|
}
|
||||||
if certArgs.certFile == "-" || certArgs.keyFile == "-" {
|
if certArgs.certFile == "-" || certArgs.keyFile == "-" {
|
||||||
printf = log.Printf
|
printf = log.Printf
|
||||||
@ -138,7 +138,7 @@ func runCert(ctx context.Context, args []string) error {
|
|||||||
|
|
||||||
func writeIfChanged(filename string, contents []byte, mode os.FileMode) (changed bool, err error) {
|
func writeIfChanged(filename string, contents []byte, mode os.FileMode) (changed bool, err error) {
|
||||||
if filename == "-" {
|
if filename == "-" {
|
||||||
Stdout.Write(contents)
|
os.Stdout.Write(contents)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if old, err := os.ReadFile(filename); err == nil && bytes.Equal(contents, old) {
|
if old, err := os.ReadFile(filename); err == nil && bytes.Equal(contents, old) {
|
||||||
|
@ -33,22 +33,6 @@
|
|||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Stderr io.Writer = os.Stderr
|
|
||||||
var Stdout io.Writer = os.Stdout
|
|
||||||
|
|
||||||
func printf(format string, a ...any) {
|
|
||||||
fmt.Fprintf(Stdout, format, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// outln is like fmt.Println in the common case, except when Stdout is
|
|
||||||
// changed (as in js/wasm).
|
|
||||||
//
|
|
||||||
// It's not named println because that looks like the Go built-in
|
|
||||||
// which goes to stderr and formats slightly differently.
|
|
||||||
func outln(a ...any) {
|
|
||||||
fmt.Fprintln(Stdout, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActLikeCLI reports whether a GUI application should act like the
|
// ActLikeCLI reports whether a GUI application should act like the
|
||||||
// CLI based on os.Args, GOOS, the context the process is running in
|
// CLI based on os.Args, GOOS, the context the process is running in
|
||||||
// (pty, parent PID), etc.
|
// (pty, parent PID), etc.
|
||||||
@ -95,16 +79,6 @@ func ActLikeCLI() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFlagSet(name string) *flag.FlagSet {
|
|
||||||
onError := flag.ExitOnError
|
|
||||||
if runtime.GOOS == "js" {
|
|
||||||
onError = flag.ContinueOnError
|
|
||||||
}
|
|
||||||
fs := flag.NewFlagSet(name, onError)
|
|
||||||
fs.SetOutput(Stderr)
|
|
||||||
return fs
|
|
||||||
}
|
|
||||||
|
|
||||||
// CleanUpArgs rewrites command line arguments for simplicity and backwards compatibility.
|
// CleanUpArgs rewrites command line arguments for simplicity and backwards compatibility.
|
||||||
// In particular, it rewrites --authkey to --auth-key.
|
// In particular, it rewrites --authkey to --auth-key.
|
||||||
func CleanUpArgs(args []string) []string {
|
func CleanUpArgs(args []string) []string {
|
||||||
@ -138,11 +112,11 @@ func Run(args []string) (err error) {
|
|||||||
var warnOnce sync.Once
|
var warnOnce sync.Once
|
||||||
tailscale.SetVersionMismatchHandler(func(clientVer, serverVer string) {
|
tailscale.SetVersionMismatchHandler(func(clientVer, serverVer string) {
|
||||||
warnOnce.Do(func() {
|
warnOnce.Do(func() {
|
||||||
fmt.Fprintf(Stderr, "Warning: client version %q != tailscaled server version %q\n", clientVer, serverVer)
|
fmt.Fprintf(os.Stderr, "Warning: client version %q != tailscaled server version %q\n", clientVer, serverVer)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
rootfs := newFlagSet("tailscale")
|
rootfs := flag.NewFlagSet("tailscale", flag.ExitOnError)
|
||||||
rootfs.StringVar(&rootArgs.socket, "socket", paths.DefaultTailscaledSocket(), "path to tailscaled's unix socket")
|
rootfs.StringVar(&rootArgs.socket, "socket", paths.DefaultTailscaledSocket(), "path to tailscaled's unix socket")
|
||||||
|
|
||||||
rootCmd := &ffcli.Command{
|
rootCmd := &ffcli.Command{
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
See: https://tailscale.com/kb/1152/synology-outbound/
|
See: https://tailscale.com/kb/1152/synology-outbound/
|
||||||
`),
|
`),
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("configure-host")
|
fs := flag.NewFlagSet("configure-host", flag.ExitOnError)
|
||||||
return fs
|
return fs
|
||||||
})(),
|
})(),
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
Exec: runDebug,
|
Exec: runDebug,
|
||||||
LongHelp: `"tailscale debug" contains misc debug facilities; it is not a stable interface.`,
|
LongHelp: `"tailscale debug" contains misc debug facilities; it is not a stable interface.`,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("debug")
|
fs := flag.NewFlagSet("debug", flag.ExitOnError)
|
||||||
fs.StringVar(&debugArgs.file, "file", "", "get, delete:NAME, or NAME")
|
fs.StringVar(&debugArgs.file, "file", "", "get, delete:NAME, or NAME")
|
||||||
fs.StringVar(&debugArgs.cpuFile, "cpu-profile", "", "if non-empty, grab a CPU profile for --profile-sec seconds and write it to this file; - for stdout")
|
fs.StringVar(&debugArgs.cpuFile, "cpu-profile", "", "if non-empty, grab a CPU profile for --profile-sec seconds and write it to this file; - for stdout")
|
||||||
fs.StringVar(&debugArgs.memFile, "mem-profile", "", "if non-empty, grab a memory profile and write it to this file; - for stdout")
|
fs.StringVar(&debugArgs.memFile, "mem-profile", "", "if non-empty, grab a memory profile and write it to this file; - for stdout")
|
||||||
@ -63,7 +63,7 @@
|
|||||||
Exec: runDaemonMetrics,
|
Exec: runDaemonMetrics,
|
||||||
ShortHelp: "print tailscaled's metrics",
|
ShortHelp: "print tailscaled's metrics",
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("metrics")
|
fs := flag.NewFlagSet("metrics", flag.ExitOnError)
|
||||||
fs.BoolVar(&metricsArgs.watch, "watch", false, "print JSON dump of delta values")
|
fs.BoolVar(&metricsArgs.watch, "watch", false, "print JSON dump of delta values")
|
||||||
return fs
|
return fs
|
||||||
})(),
|
})(),
|
||||||
@ -103,7 +103,7 @@
|
|||||||
Exec: runPrefs,
|
Exec: runPrefs,
|
||||||
ShortHelp: "print prefs",
|
ShortHelp: "print prefs",
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("prefs")
|
fs := flag.NewFlagSet("prefs", flag.ExitOnError)
|
||||||
fs.BoolVar(&prefsArgs.pretty, "pretty", false, "If true, pretty-print output")
|
fs.BoolVar(&prefsArgs.pretty, "pretty", false, "If true, pretty-print output")
|
||||||
return fs
|
return fs
|
||||||
})(),
|
})(),
|
||||||
@ -113,7 +113,7 @@
|
|||||||
Exec: runWatchIPN,
|
Exec: runWatchIPN,
|
||||||
ShortHelp: "subscribe to IPN message bus",
|
ShortHelp: "subscribe to IPN message bus",
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("watch-ipn")
|
fs := flag.NewFlagSet("watch-ipn", flag.ExitOnError)
|
||||||
fs.BoolVar(&watchIPNArgs.netmap, "netmap", true, "include netmap in messages")
|
fs.BoolVar(&watchIPNArgs.netmap, "netmap", true, "include netmap in messages")
|
||||||
return fs
|
return fs
|
||||||
})(),
|
})(),
|
||||||
@ -128,7 +128,7 @@
|
|||||||
Exec: runTS2021,
|
Exec: runTS2021,
|
||||||
ShortHelp: "debug ts2021 protocol connectivity",
|
ShortHelp: "debug ts2021 protocol connectivity",
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("ts2021")
|
fs := flag.NewFlagSet("ts2021", flag.ExitOnError)
|
||||||
fs.StringVar(&ts2021Args.host, "host", "controlplane.tailscale.com", "hostname of control plane")
|
fs.StringVar(&ts2021Args.host, "host", "controlplane.tailscale.com", "hostname of control plane")
|
||||||
fs.IntVar(&ts2021Args.version, "version", int(tailcfg.CurrentCapabilityVersion), "protocol version")
|
fs.IntVar(&ts2021Args.version, "version", int(tailcfg.CurrentCapabilityVersion), "protocol version")
|
||||||
return fs
|
return fs
|
||||||
@ -146,7 +146,7 @@
|
|||||||
|
|
||||||
func writeProfile(dst string, v []byte) error {
|
func writeProfile(dst string, v []byte) error {
|
||||||
if dst == "-" {
|
if dst == "-" {
|
||||||
_, err := Stdout.Write(v)
|
_, err := os.Stdout.Write(v)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.WriteFile(dst, v, 0600)
|
return os.WriteFile(dst, v, 0600)
|
||||||
@ -198,7 +198,7 @@ func runDebug(ctx context.Context, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fatalf("%v\n", err)
|
fatalf("%v\n", err)
|
||||||
}
|
}
|
||||||
e := json.NewEncoder(Stdout)
|
e := json.NewEncoder(os.Stdout)
|
||||||
e.SetIndent("", "\t")
|
e.SetIndent("", "\t")
|
||||||
e.Encode(wfs)
|
e.Encode(wfs)
|
||||||
return nil
|
return nil
|
||||||
@ -212,7 +212,7 @@ func runDebug(ctx context.Context, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("Size: %v\n", size)
|
log.Printf("Size: %v\n", size)
|
||||||
io.Copy(Stdout, rc)
|
io.Copy(os.Stdout, rc)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if usedFlag {
|
if usedFlag {
|
||||||
@ -226,14 +226,14 @@ func runDebug(ctx context.Context, args []string) error {
|
|||||||
func runLocalCreds(ctx context.Context, args []string) error {
|
func runLocalCreds(ctx context.Context, args []string) error {
|
||||||
port, token, err := safesocket.LocalTCPPortAndToken()
|
port, token, err := safesocket.LocalTCPPortAndToken()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
printf("curl -u:%s http://localhost:%d/localapi/v0/status\n", token, port)
|
fmt.Printf("curl -u:%s http://localhost:%d/localapi/v0/status\n", token, port)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
printf("curl http://localhost:%v/localapi/v0/status\n", safesocket.WindowsLocalPort)
|
fmt.Printf("curl http://localhost:%v/localapi/v0/status\n", safesocket.WindowsLocalPort)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
printf("curl --unix-socket %s http://foo/localapi/v0/status\n", paths.DefaultTailscaledSocket())
|
fmt.Printf("curl --unix-socket %s http://foo/localapi/v0/status\n", paths.DefaultTailscaledSocket())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,10 +247,10 @@ func runPrefs(ctx context.Context, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if prefsArgs.pretty {
|
if prefsArgs.pretty {
|
||||||
outln(prefs.Pretty())
|
fmt.Println(prefs.Pretty())
|
||||||
} else {
|
} else {
|
||||||
j, _ := json.MarshalIndent(prefs, "", "\t")
|
j, _ := json.MarshalIndent(prefs, "", "\t")
|
||||||
outln(string(j))
|
fmt.Println(string(j))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -268,7 +268,7 @@ func runWatchIPN(ctx context.Context, args []string) error {
|
|||||||
n.NetMap = nil
|
n.NetMap = nil
|
||||||
}
|
}
|
||||||
j, _ := json.MarshalIndent(n, "", "\t")
|
j, _ := json.MarshalIndent(n, "", "\t")
|
||||||
printf("%s\n", j)
|
fmt.Printf("%s\n", j)
|
||||||
})
|
})
|
||||||
bc.RequestEngineStatus()
|
bc.RequestEngineStatus()
|
||||||
pump(ctx, bc, c)
|
pump(ctx, bc, c)
|
||||||
@ -282,7 +282,7 @@ func runDERPMap(ctx context.Context, args []string) error {
|
|||||||
"failed to get local derp map, instead `curl %s/derpmap/default`: %w", ipn.DefaultControlURL, err,
|
"failed to get local derp map, instead `curl %s/derpmap/default`: %w", ipn.DefaultControlURL, err,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
enc := json.NewEncoder(Stdout)
|
enc := json.NewEncoder(os.Stdout)
|
||||||
enc.SetIndent("", "\t")
|
enc.SetIndent("", "\t")
|
||||||
enc.Encode(dm)
|
enc.Encode(dm)
|
||||||
return nil
|
return nil
|
||||||
@ -299,7 +299,7 @@ func localAPIAction(action string) func(context.Context, []string) error {
|
|||||||
|
|
||||||
func runEnv(ctx context.Context, args []string) error {
|
func runEnv(ctx context.Context, args []string) error {
|
||||||
for _, e := range os.Environ() {
|
for _, e := range os.Environ() {
|
||||||
outln(e)
|
fmt.Println(e)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@ func runDaemonGoroutines(ctx context.Context, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
Stdout.Write(goroutines)
|
os.Stdout.Write(goroutines)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ func runDaemonMetrics(ctx context.Context, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !metricsArgs.watch {
|
if !metricsArgs.watch {
|
||||||
Stdout.Write(out)
|
os.Stdout.Write(out)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
bs := bufio.NewScanner(bytes.NewReader(out))
|
bs := bufio.NewScanner(bytes.NewReader(out))
|
||||||
@ -391,9 +391,9 @@ type change struct {
|
|||||||
if len(changes) > 0 {
|
if len(changes) > 0 {
|
||||||
format := fmt.Sprintf("%%-%ds %%+5d => %%v\n", maxNameLen)
|
format := fmt.Sprintf("%%-%ds %%+5d => %%v\n", maxNameLen)
|
||||||
for _, c := range changes {
|
for _, c := range changes {
|
||||||
fmt.Fprintf(Stdout, format, c.name, c.to-c.from, c.to)
|
fmt.Fprintf(os.Stdout, format, c.name, c.to-c.from, c.to)
|
||||||
}
|
}
|
||||||
io.WriteString(Stdout, "\n")
|
io.WriteString(os.Stdout, "\n")
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/peterbourgon/ff/v3/ffcli"
|
"github.com/peterbourgon/ff/v3/ffcli"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
@ -23,7 +24,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newDownFlagSet() *flag.FlagSet {
|
func newDownFlagSet() *flag.FlagSet {
|
||||||
downf := newFlagSet("down")
|
downf := flag.NewFlagSet("down", flag.ExitOnError)
|
||||||
registerAcceptRiskFlag(downf)
|
registerAcceptRiskFlag(downf)
|
||||||
return downf
|
return downf
|
||||||
}
|
}
|
||||||
@ -44,7 +45,7 @@ func runDown(ctx context.Context, args []string) error {
|
|||||||
return fmt.Errorf("error fetching current status: %w", err)
|
return fmt.Errorf("error fetching current status: %w", err)
|
||||||
}
|
}
|
||||||
if st.BackendState == "Stopped" {
|
if st.BackendState == "Stopped" {
|
||||||
fmt.Fprintf(Stderr, "Tailscale was already stopped.\n")
|
fmt.Fprintf(os.Stderr, "Tailscale was already stopped.\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, err = localClient.EditPrefs(ctx, &ipn.MaskedPrefs{
|
_, err = localClient.EditPrefs(ctx, &ipn.MaskedPrefs{
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
ShortHelp: "Copy file(s) to a host",
|
ShortHelp: "Copy file(s) to a host",
|
||||||
Exec: runCp,
|
Exec: runCp,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("cp")
|
fs := flag.NewFlagSet("cp", flag.ExitOnError)
|
||||||
fs.StringVar(&cpArgs.name, "name", "", "alternate filename to use, especially useful when <file> is \"-\" (stdin)")
|
fs.StringVar(&cpArgs.name, "name", "", "alternate filename to use, especially useful when <file> is \"-\" (stdin)")
|
||||||
fs.BoolVar(&cpArgs.verbose, "verbose", false, "verbose output")
|
fs.BoolVar(&cpArgs.verbose, "verbose", false, "verbose output")
|
||||||
fs.BoolVar(&cpArgs.targets, "targets", false, "list possible file cp targets")
|
fs.BoolVar(&cpArgs.targets, "targets", false, "list possible file cp targets")
|
||||||
@ -100,7 +100,7 @@ func runCp(ctx context.Context, args []string) error {
|
|||||||
return fmt.Errorf("can't send to %s: %v", target, err)
|
return fmt.Errorf("can't send to %s: %v", target, err)
|
||||||
}
|
}
|
||||||
if isOffline {
|
if isOffline {
|
||||||
fmt.Fprintf(Stderr, "# warning: %s is offline\n", target)
|
fmt.Fprintf(os.Stderr, "# warning: %s is offline\n", target)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(files) > 1 {
|
if len(files) > 1 {
|
||||||
@ -281,7 +281,7 @@ func runCpTargets(ctx context.Context, args []string) error {
|
|||||||
if detail != "" {
|
if detail != "" {
|
||||||
detail = "\t" + detail
|
detail = "\t" + detail
|
||||||
}
|
}
|
||||||
printf("%s\t%s%s\n", n.Addresses[0].Addr(), n.ComputedName, detail)
|
fmt.Printf("%s\t%s%s\n", n.Addresses[0].Addr(), n.ComputedName, detail)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ func (v *onConflict) Set(s string) error {
|
|||||||
ShortHelp: "Move files out of the Tailscale file inbox",
|
ShortHelp: "Move files out of the Tailscale file inbox",
|
||||||
Exec: runFileGet,
|
Exec: runFileGet,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("get")
|
fs := flag.NewFlagSet("get", flag.ExitOnError)
|
||||||
fs.BoolVar(&getArgs.wait, "wait", false, "wait for a file to arrive if inbox is empty")
|
fs.BoolVar(&getArgs.wait, "wait", false, "wait for a file to arrive if inbox is empty")
|
||||||
fs.BoolVar(&getArgs.loop, "loop", false, "run get in a loop, receiving files as they come in")
|
fs.BoolVar(&getArgs.loop, "loop", false, "run get in a loop, receiving files as they come in")
|
||||||
fs.BoolVar(&getArgs.verbose, "verbose", false, "verbose output")
|
fs.BoolVar(&getArgs.verbose, "verbose", false, "verbose output")
|
||||||
@ -415,7 +415,7 @@ func runFileGetOneBatch(ctx context.Context, dir string) []error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if getArgs.verbose {
|
if getArgs.verbose {
|
||||||
printf("waiting for file...")
|
fmt.Printf("waiting for file...")
|
||||||
}
|
}
|
||||||
if err := waitForFile(ctx); err != nil {
|
if err := waitForFile(ctx); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
@ -436,7 +436,7 @@ func runFileGetOneBatch(ctx context.Context, dir string) []error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if getArgs.verbose {
|
if getArgs.verbose {
|
||||||
printf("wrote %v as %v (%d bytes)\n", wf.Name, writtenFile, size)
|
fmt.Printf("wrote %v as %v (%d bytes)\n", wf.Name, writtenFile, size)
|
||||||
}
|
}
|
||||||
if err = localClient.DeleteWaitingFile(ctx, wf.Name); err != nil {
|
if err = localClient.DeleteWaitingFile(ctx, wf.Name); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("deleting %q from inbox: %v", wf.Name, err))
|
errs = append(errs, fmt.Errorf("deleting %q from inbox: %v", wf.Name, err))
|
||||||
@ -448,7 +448,7 @@ func runFileGetOneBatch(ctx context.Context, dir string) []error {
|
|||||||
// persistently stuck files are basically an error
|
// persistently stuck files are basically an error
|
||||||
errs = append(errs, fmt.Errorf("moved %d/%d files", deleted, len(wfs)))
|
errs = append(errs, fmt.Errorf("moved %d/%d files", deleted, len(wfs)))
|
||||||
} else if getArgs.verbose {
|
} else if getArgs.verbose {
|
||||||
printf("moved %d/%d files\n", deleted, len(wfs))
|
fmt.Printf("moved %d/%d files\n", deleted, len(wfs))
|
||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
@ -471,7 +471,7 @@ func runFileGet(ctx context.Context, args []string) error {
|
|||||||
for {
|
for {
|
||||||
errs := runFileGetOneBatch(ctx, dir)
|
errs := runFileGetOneBatch(ctx, dir)
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
outln(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
// It's possible whatever caused the error(s) (e.g. conflicting target file,
|
// It's possible whatever caused the error(s) (e.g. conflicting target file,
|
||||||
@ -493,7 +493,7 @@ func runFileGet(ctx context.Context, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, err := range errs[:len(errs)-1] {
|
for _, err := range errs[:len(errs)-1] {
|
||||||
outln(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
return errs[len(errs)-1]
|
return errs[len(errs)-1]
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
LongHelp: "Show Tailscale IP addresses for peer. Peer defaults to the current machine.",
|
LongHelp: "Show Tailscale IP addresses for peer. Peer defaults to the current machine.",
|
||||||
Exec: runIP,
|
Exec: runIP,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("ip")
|
fs := flag.NewFlagSet("ip", flag.ExitOnError)
|
||||||
fs.BoolVar(&ipArgs.want1, "1", false, "only print one IP address")
|
fs.BoolVar(&ipArgs.want1, "1", false, "only print one IP address")
|
||||||
fs.BoolVar(&ipArgs.want4, "4", false, "only print IPv4 address")
|
fs.BoolVar(&ipArgs.want4, "4", false, "only print IPv4 address")
|
||||||
fs.BoolVar(&ipArgs.want6, "6", false, "only print IPv6 address")
|
fs.BoolVar(&ipArgs.want6, "6", false, "only print IPv6 address")
|
||||||
@ -85,7 +85,7 @@ func runIP(ctx context.Context, args []string) error {
|
|||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
if ip.Is4() && v4 || ip.Is6() && v6 {
|
if ip.Is4() && v4 || ip.Is6() && v6 {
|
||||||
match = true
|
match = true
|
||||||
outln(ip)
|
fmt.Println(ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
|
@ -29,7 +29,7 @@ func runNC(ctx context.Context, args []string) error {
|
|||||||
}
|
}
|
||||||
description, ok := isRunningOrStarting(st)
|
description, ok := isRunningOrStarting(st)
|
||||||
if !ok {
|
if !ok {
|
||||||
printf("%s\n", description)
|
fmt.Printf("%s\n", description)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -32,7 +33,7 @@
|
|||||||
ShortHelp: "Print an analysis of local network conditions",
|
ShortHelp: "Print an analysis of local network conditions",
|
||||||
Exec: runNetcheck,
|
Exec: runNetcheck,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("netcheck")
|
fs := flag.NewFlagSet("netcheck", flag.ExitOnError)
|
||||||
fs.StringVar(&netcheckArgs.format, "format", "", `output format; empty (for human-readable), "json" or "json-line"`)
|
fs.StringVar(&netcheckArgs.format, "format", "", `output format; empty (for human-readable), "json" or "json-line"`)
|
||||||
fs.DurationVar(&netcheckArgs.every, "every", 0, "if non-zero, do an incremental report with the given frequency")
|
fs.DurationVar(&netcheckArgs.every, "every", 0, "if non-zero, do an incremental report with the given frequency")
|
||||||
fs.BoolVar(&netcheckArgs.verbose, "verbose", false, "verbose logs")
|
fs.BoolVar(&netcheckArgs.verbose, "verbose", false, "verbose logs")
|
||||||
@ -59,7 +60,7 @@ func runNetcheck(ctx context.Context, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(netcheckArgs.format, "json") {
|
if strings.HasPrefix(netcheckArgs.format, "json") {
|
||||||
fmt.Fprintln(Stderr, "# Warning: this JSON format is not yet considered a stable interface")
|
fmt.Fprintln(os.Stderr, "# Warning: this JSON format is not yet considered a stable interface")
|
||||||
}
|
}
|
||||||
|
|
||||||
dm, err := localClient.CurrentDERPMap(ctx)
|
dm, err := localClient.CurrentDERPMap(ctx)
|
||||||
@ -111,38 +112,38 @@ func printReport(dm *tailcfg.DERPMap, report *netcheck.Report) error {
|
|||||||
}
|
}
|
||||||
if j != nil {
|
if j != nil {
|
||||||
j = append(j, '\n')
|
j = append(j, '\n')
|
||||||
Stdout.Write(j)
|
os.Stdout.Write(j)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nReport:\n")
|
fmt.Printf("\nReport:\n")
|
||||||
printf("\t* UDP: %v\n", report.UDP)
|
fmt.Printf("\t* UDP: %v\n", report.UDP)
|
||||||
if report.GlobalV4 != "" {
|
if report.GlobalV4 != "" {
|
||||||
printf("\t* IPv4: yes, %v\n", report.GlobalV4)
|
fmt.Printf("\t* IPv4: yes, %v\n", report.GlobalV4)
|
||||||
} else {
|
} else {
|
||||||
printf("\t* IPv4: (no addr found)\n")
|
fmt.Printf("\t* IPv4: (no addr found)\n")
|
||||||
}
|
}
|
||||||
if report.GlobalV6 != "" {
|
if report.GlobalV6 != "" {
|
||||||
printf("\t* IPv6: yes, %v\n", report.GlobalV6)
|
fmt.Printf("\t* IPv6: yes, %v\n", report.GlobalV6)
|
||||||
} else if report.IPv6 {
|
} else if report.IPv6 {
|
||||||
printf("\t* IPv6: (no addr found)\n")
|
fmt.Printf("\t* IPv6: (no addr found)\n")
|
||||||
} else if report.OSHasIPv6 {
|
} else if report.OSHasIPv6 {
|
||||||
printf("\t* IPv6: no, but OS has support\n")
|
fmt.Printf("\t* IPv6: no, but OS has support\n")
|
||||||
} else {
|
} else {
|
||||||
printf("\t* IPv6: no, unavailable in OS\n")
|
fmt.Printf("\t* IPv6: no, unavailable in OS\n")
|
||||||
}
|
}
|
||||||
printf("\t* MappingVariesByDestIP: %v\n", report.MappingVariesByDestIP)
|
fmt.Printf("\t* MappingVariesByDestIP: %v\n", report.MappingVariesByDestIP)
|
||||||
printf("\t* HairPinning: %v\n", report.HairPinning)
|
fmt.Printf("\t* HairPinning: %v\n", report.HairPinning)
|
||||||
printf("\t* PortMapping: %v\n", portMapping(report))
|
fmt.Printf("\t* PortMapping: %v\n", portMapping(report))
|
||||||
|
|
||||||
// When DERP latency checking failed,
|
// When DERP latency checking failed,
|
||||||
// magicsock will try to pick the DERP server that
|
// magicsock will try to pick the DERP server that
|
||||||
// most of your other nodes are also using
|
// most of your other nodes are also using
|
||||||
if len(report.RegionLatency) == 0 {
|
if len(report.RegionLatency) == 0 {
|
||||||
printf("\t* Nearest DERP: unknown (no response to latency probes)\n")
|
fmt.Printf("\t* Nearest DERP: unknown (no response to latency probes)\n")
|
||||||
} else {
|
} else {
|
||||||
printf("\t* Nearest DERP: %v\n", dm.Regions[report.PreferredDERP].RegionName)
|
fmt.Printf("\t* Nearest DERP: %v\n", dm.Regions[report.PreferredDERP].RegionName)
|
||||||
printf("\t* DERP latency:\n")
|
fmt.Printf("\t* DERP latency:\n")
|
||||||
var rids []int
|
var rids []int
|
||||||
for rid := range dm.Regions {
|
for rid := range dm.Regions {
|
||||||
rids = append(rids, rid)
|
rids = append(rids, rid)
|
||||||
@ -169,7 +170,7 @@ func printReport(dm *tailcfg.DERPMap, report *netcheck.Report) error {
|
|||||||
if netcheckArgs.verbose {
|
if netcheckArgs.verbose {
|
||||||
derpNum = fmt.Sprintf("derp%d, ", rid)
|
derpNum = fmt.Sprintf("derp%d, ", rid)
|
||||||
}
|
}
|
||||||
printf("\t\t- %3s: %-7s (%s%s)\n", r.RegionCode, latency, derpNum, r.RegionName)
|
fmt.Printf("\t\t- %3s: %-7s (%s%s)\n", r.RegionCode, latency, derpNum, r.RegionName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
`),
|
`),
|
||||||
Exec: runPing,
|
Exec: runPing,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("ping")
|
fs := flag.NewFlagSet("ping", flag.ExitOnError)
|
||||||
fs.BoolVar(&pingArgs.verbose, "verbose", false, "verbose output")
|
fs.BoolVar(&pingArgs.verbose, "verbose", false, "verbose output")
|
||||||
fs.BoolVar(&pingArgs.untilDirect, "until-direct", true, "stop once a direct path is established")
|
fs.BoolVar(&pingArgs.untilDirect, "until-direct", true, "stop once a direct path is established")
|
||||||
fs.BoolVar(&pingArgs.tsmp, "tsmp", false, "do a TSMP-level ping (through WireGuard, but not either host OS stack)")
|
fs.BoolVar(&pingArgs.tsmp, "tsmp", false, "do a TSMP-level ping (through WireGuard, but not either host OS stack)")
|
||||||
@ -88,7 +88,7 @@ func runPing(ctx context.Context, args []string) error {
|
|||||||
}
|
}
|
||||||
description, ok := isRunningOrStarting(st)
|
description, ok := isRunningOrStarting(st)
|
||||||
if !ok {
|
if !ok {
|
||||||
printf("%s\n", description)
|
fmt.Printf("%s\n", description)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ func runPing(ctx context.Context, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if self {
|
if self {
|
||||||
printf("%v is local Tailscale IP\n", ip)
|
fmt.Printf("%v is local Tailscale IP\n", ip)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func runPing(ctx context.Context, args []string) error {
|
|||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, context.DeadlineExceeded) {
|
if errors.Is(err, context.DeadlineExceeded) {
|
||||||
printf("ping %q timed out\n", ip)
|
fmt.Printf("ping %q timed out\n", ip)
|
||||||
if n == pingArgs.num {
|
if n == pingArgs.num {
|
||||||
if !anyPong {
|
if !anyPong {
|
||||||
return errors.New("no reply")
|
return errors.New("no reply")
|
||||||
@ -133,7 +133,7 @@ func runPing(ctx context.Context, args []string) error {
|
|||||||
}
|
}
|
||||||
if pr.Err != "" {
|
if pr.Err != "" {
|
||||||
if pr.IsLocalIP {
|
if pr.IsLocalIP {
|
||||||
outln(pr.Err)
|
fmt.Println(pr.Err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New(pr.Err)
|
return errors.New(pr.Err)
|
||||||
@ -149,7 +149,7 @@ func runPing(ctx context.Context, args []string) error {
|
|||||||
via = string(pingType())
|
via = string(pingType())
|
||||||
}
|
}
|
||||||
if pingArgs.peerAPI {
|
if pingArgs.peerAPI {
|
||||||
printf("hit peerapi of %s (%s) at %s in %s\n", pr.NodeIP, pr.NodeName, pr.PeerAPIURL, latency)
|
fmt.Printf("hit peerapi of %s (%s) at %s in %s\n", pr.NodeIP, pr.NodeName, pr.PeerAPIURL, latency)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
anyPong = true
|
anyPong = true
|
||||||
@ -157,7 +157,7 @@ func runPing(ctx context.Context, args []string) error {
|
|||||||
if pr.PeerAPIPort != 0 {
|
if pr.PeerAPIPort != 0 {
|
||||||
extra = fmt.Sprintf(", %d", pr.PeerAPIPort)
|
extra = fmt.Sprintf(", %d", pr.PeerAPIPort)
|
||||||
}
|
}
|
||||||
printf("pong from %s (%s%s) via %v in %v\n", pr.NodeName, pr.NodeIP, extra, via, latency)
|
fmt.Printf("pong from %s (%s%s) via %v in %v\n", pr.NodeName, pr.NodeIP, extra, via, latency)
|
||||||
if pingArgs.tsmp || pingArgs.icmp {
|
if pingArgs.tsmp || pingArgs.icmp {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build !js && !windows
|
//go:build !windows
|
||||||
// +build !js,!windows
|
// +build !windows
|
||||||
|
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func findSSH() (string, error) {
|
|
||||||
return "", errors.New("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func execSSH(ssh string, argv []string) error {
|
|
||||||
return errors.New("Not implemented")
|
|
||||||
}
|
|
@ -46,7 +46,7 @@
|
|||||||
`),
|
`),
|
||||||
Exec: runStatus,
|
Exec: runStatus,
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("status")
|
fs := flag.NewFlagSet("status", flag.ExitOnError)
|
||||||
fs.BoolVar(&statusArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)")
|
fs.BoolVar(&statusArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)")
|
||||||
fs.BoolVar(&statusArgs.web, "web", false, "run webserver with HTML showing status")
|
fs.BoolVar(&statusArgs.web, "web", false, "run webserver with HTML showing status")
|
||||||
fs.BoolVar(&statusArgs.active, "active", false, "filter output to only peers with active sessions (not applicable to web mode)")
|
fs.BoolVar(&statusArgs.active, "active", false, "filter output to only peers with active sessions (not applicable to web mode)")
|
||||||
@ -92,7 +92,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printf("%s", j)
|
fmt.Printf("%s", j)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if statusArgs.web {
|
if statusArgs.web {
|
||||||
@ -101,7 +101,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
statusURL := interfaces.HTTPOfListener(ln)
|
statusURL := interfaces.HTTPOfListener(ln)
|
||||||
printf("Serving Tailscale status at %v ...\n", statusURL)
|
fmt.Printf("Serving Tailscale status at %v ...\n", statusURL)
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
ln.Close()
|
ln.Close()
|
||||||
@ -131,16 +131,16 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
// print health check information prior to checking LocalBackend state as
|
// print health check information prior to checking LocalBackend state as
|
||||||
// it may provide an explanation to the user if we choose to exit early
|
// it may provide an explanation to the user if we choose to exit early
|
||||||
if len(st.Health) > 0 {
|
if len(st.Health) > 0 {
|
||||||
printf("# Health check:\n")
|
fmt.Printf("# Health check:\n")
|
||||||
for _, m := range st.Health {
|
for _, m := range st.Health {
|
||||||
printf("# - %s\n", m)
|
fmt.Printf("# - %s\n", m)
|
||||||
}
|
}
|
||||||
outln()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
description, ok := isRunningOrStarting(st)
|
description, ok := isRunningOrStarting(st)
|
||||||
if !ok {
|
if !ok {
|
||||||
outln(description)
|
fmt.Println(description)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
printPS(ps)
|
printPS(ps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stdout.Write(buf.Bytes())
|
os.Stdout.Write(buf.Bytes())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ func acceptRouteDefault(goos string) bool {
|
|||||||
func inTest() bool { return flag.Lookup("test.v") != nil }
|
func inTest() bool { return flag.Lookup("test.v") != nil }
|
||||||
|
|
||||||
func newUpFlagSet(goos string, upArgs *upArgsT) *flag.FlagSet {
|
func newUpFlagSet(goos string, upArgs *upArgsT) *flag.FlagSet {
|
||||||
upf := newFlagSet("up")
|
upf := flag.NewFlagSet("up", flag.ExitOnError)
|
||||||
|
|
||||||
upf.BoolVar(&upArgs.qr, "qr", false, "show QR code for login URLs")
|
upf.BoolVar(&upArgs.qr, "qr", false, "show QR code for login URLs")
|
||||||
upf.BoolVar(&upArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)")
|
upf.BoolVar(&upArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)")
|
||||||
@ -195,7 +195,7 @@ type upOutputJSON struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func warnf(format string, args ...any) {
|
func warnf(format string, args ...any) {
|
||||||
printf("Warning: "+format+"\n", args...)
|
fmt.Printf("Warning: "+format+"\n", args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -538,7 +538,7 @@ func runUp(ctx context.Context, args []string) (retErr error) {
|
|||||||
if env.upArgs.json {
|
if env.upArgs.json {
|
||||||
printUpDoneJSON(ipn.NeedsMachineAuth, "")
|
printUpDoneJSON(ipn.NeedsMachineAuth, "")
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(Stderr, "\nTo authorize your machine, visit (as admin):\n\n\t%s\n\n", prefs.AdminPageURL())
|
fmt.Fprintf(os.Stderr, "\nTo authorize your machine, visit (as admin):\n\n\t%s\n\n", prefs.AdminPageURL())
|
||||||
}
|
}
|
||||||
case ipn.Running:
|
case ipn.Running:
|
||||||
// Done full authentication process
|
// Done full authentication process
|
||||||
@ -546,7 +546,7 @@ func runUp(ctx context.Context, args []string) (retErr error) {
|
|||||||
printUpDoneJSON(ipn.Running, "")
|
printUpDoneJSON(ipn.Running, "")
|
||||||
} else if printed {
|
} else if printed {
|
||||||
// Only need to print an update if we printed the "please click" message earlier.
|
// Only need to print an update if we printed the "please click" message earlier.
|
||||||
fmt.Fprintf(Stderr, "Success.\n")
|
fmt.Fprintf(os.Stderr, "Success.\n")
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case running <- true:
|
case running <- true:
|
||||||
@ -575,13 +575,13 @@ func runUp(ctx context.Context, args []string) (retErr error) {
|
|||||||
fmt.Println(string(data))
|
fmt.Println(string(data))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(Stderr, "\nTo authenticate, visit:\n\n\t%s\n\n", *url)
|
fmt.Fprintf(os.Stderr, "\nTo authenticate, visit:\n\n\t%s\n\n", *url)
|
||||||
if upArgs.qr {
|
if upArgs.qr {
|
||||||
q, err := qrcode.New(*url, qrcode.Medium)
|
q, err := qrcode.New(*url, qrcode.Medium)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("QR code error: %v", err)
|
log.Printf("QR code error: %v", err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(Stderr, "%s\n", q.ToString(false))
|
fmt.Fprintf(os.Stderr, "%s\n", q.ToString(false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,12 +695,12 @@ func checkSSHUpWarnings(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(st.Health) == 1 && strings.Contains(st.Health[0], "SSH") {
|
if len(st.Health) == 1 && strings.Contains(st.Health[0], "SSH") {
|
||||||
printf("%s\n", st.Health[0])
|
fmt.Printf("%s\n", st.Health[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
printf("# Health check:\n")
|
fmt.Printf("# Health check:\n")
|
||||||
for _, m := range st.Health {
|
for _, m := range st.Health {
|
||||||
printf(" - %s\n", m)
|
fmt.Printf(" - %s\n", m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
ShortUsage: "version [flags]",
|
ShortUsage: "version [flags]",
|
||||||
ShortHelp: "Print Tailscale version",
|
ShortHelp: "Print Tailscale version",
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
fs := newFlagSet("version")
|
fs := flag.NewFlagSet("version", flag.ExitOnError)
|
||||||
fs.BoolVar(&versionArgs.daemon, "daemon", false, "also print local node's daemon version")
|
fs.BoolVar(&versionArgs.daemon, "daemon", false, "also print local node's daemon version")
|
||||||
return fs
|
return fs
|
||||||
})(),
|
})(),
|
||||||
@ -34,16 +34,16 @@ func runVersion(ctx context.Context, args []string) error {
|
|||||||
return fmt.Errorf("too many non-flag arguments: %q", args)
|
return fmt.Errorf("too many non-flag arguments: %q", args)
|
||||||
}
|
}
|
||||||
if !versionArgs.daemon {
|
if !versionArgs.daemon {
|
||||||
outln(version.String())
|
fmt.Println(version.String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Client: %s\n", version.String())
|
fmt.Printf("Client: %s\n", version.String())
|
||||||
|
|
||||||
st, err := localClient.StatusWithoutPeers(ctx)
|
st, err := localClient.StatusWithoutPeers(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printf("Daemon: %s\n", st.Version)
|
fmt.Printf("Daemon: %s\n", st.Version)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ type tmplData struct {
|
|||||||
`),
|
`),
|
||||||
|
|
||||||
FlagSet: (func() *flag.FlagSet {
|
FlagSet: (func() *flag.FlagSet {
|
||||||
webf := newFlagSet("web")
|
webf := flag.NewFlagSet("web", flag.ExitOnError)
|
||||||
webf.StringVar(&webArgs.listen, "listen", "localhost:8088", "listen address; use port 0 for automatic")
|
webf.StringVar(&webArgs.listen, "listen", "localhost:8088", "listen address; use port 0 for automatic")
|
||||||
webf.BoolVar(&webArgs.cgi, "cgi", false, "run as CGI script")
|
webf.BoolVar(&webArgs.cgi, "cgi", false, "run as CGI script")
|
||||||
return webf
|
return webf
|
||||||
|
@ -274,13 +274,6 @@ func ipnServerOpts() (o ipnserver.Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch goos {
|
switch goos {
|
||||||
case "js":
|
|
||||||
// The js/wasm client has no state storage so for now
|
|
||||||
// treat all interactive logins as ephemeral.
|
|
||||||
// TODO(bradfitz): if we start using browser LocalStorage
|
|
||||||
// or something, then rethink this.
|
|
||||||
o.LoginFlags = controlclient.LoginEphemeral
|
|
||||||
fallthrough
|
|
||||||
default:
|
default:
|
||||||
o.SurviveDisconnects = true
|
o.SurviveDisconnects = true
|
||||||
o.AutostartStateKey = ipn.GlobalDaemonStateKey
|
o.AutostartStateKey = ipn.GlobalDaemonStateKey
|
||||||
|
Loading…
Reference in New Issue
Block a user