diff --git a/agent/agent_test.go b/agent/agent_test.go index ec791505ba28d..9f75f42363ea6 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -559,7 +559,7 @@ func TestAgent(t *testing.T) { DERPMap: derpMap, }, 0) defer conn.Close() - res, err := conn.Speedtest(speedtest.Upload, speedtest.MinDuration) + res, err := conn.Speedtest(speedtest.Upload, 250*time.Millisecond) require.NoError(t, err) t.Logf("%.2f MBits/s", res[len(res)-1].MBitsPerSecond()) }) diff --git a/cli/agent_test.go b/cli/agent_test.go index 39662a1cde89f..82c199cd6268f 100644 --- a/cli/agent_test.go +++ b/cli/agent_test.go @@ -47,7 +47,7 @@ func TestWorkspaceAgent(t *testing.T) { workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) - cmd, _ := clitest.New(t, "agent", "--auth", "azure-instance-identity", "--agent-url", client.URL.String(), "--wireguard=false") + cmd, _ := clitest.New(t, "agent", "--auth", "azure-instance-identity", "--agent-url", client.URL.String()) ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() errC := make(chan error) @@ -105,7 +105,7 @@ func TestWorkspaceAgent(t *testing.T) { workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) - cmd, _ := clitest.New(t, "agent", "--auth", "aws-instance-identity", "--agent-url", client.URL.String(), "--wireguard=false") + cmd, _ := clitest.New(t, "agent", "--auth", "aws-instance-identity", "--agent-url", client.URL.String()) ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() errC := make(chan error) @@ -163,7 +163,7 @@ func TestWorkspaceAgent(t *testing.T) { workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) - cmd, _ := clitest.New(t, "agent", "--auth", "google-instance-identity", "--agent-url", client.URL.String(), "--wireguard=false") + cmd, _ := clitest.New(t, "agent", "--auth", "google-instance-identity", "--agent-url", client.URL.String()) ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() errC := make(chan error) diff --git a/cli/configssh.go b/cli/configssh.go index 79eb280559697..7ebb9dddf5d8b 100644 --- a/cli/configssh.go +++ b/cli/configssh.go @@ -374,7 +374,7 @@ func configSSH() *cobra.Command { cmd.Flags().BoolVarP(&skipProxyCommand, "skip-proxy-command", "", false, "Specifies whether the ProxyCommand option should be skipped. Useful for testing.") _ = cmd.Flags().MarkHidden("skip-proxy-command") cliflag.BoolVarP(cmd.Flags(), &usePreviousOpts, "use-previous-options", "", "CODER_SSH_USE_PREVIOUS_OPTIONS", false, "Specifies whether or not to keep options from previous run of config-ssh.") - cliflag.BoolVarP(cmd.Flags(), &wireguard, "wireguard", "", "CODER_CONFIG_SSH_WIREGUARD", false, "Whether to use Wireguard for SSH tunneling.") + cliflag.BoolVarP(cmd.Flags(), &wireguard, "wireguard", "", "CODER_CONFIG_SSH_WIREGUARD", true, "Whether to use Wireguard for SSH tunneling.") _ = cmd.Flags().MarkHidden("wireguard") cliui.AllowSkipPrompt(cmd) diff --git a/cli/portforward.go b/cli/portforward.go index ac4561163f837..7828b7fe61cff 100644 --- a/cli/portforward.go +++ b/cli/portforward.go @@ -6,7 +6,6 @@ import ( "net" "os" "os/signal" - "runtime" "strconv" "strings" "sync" @@ -24,10 +23,9 @@ import ( func portForward() *cobra.Command { var ( - tcpForwards []string // : - udpForwards []string // : - unixForwards []string // : OR : - wireguard bool + tcpForwards []string // : + udpForwards []string // : + wireguard bool ) cmd := &cobra.Command{ Use: "port-forward ", @@ -43,14 +41,6 @@ func portForward() *cobra.Command { Description: "Port forward a single UDP port from port 9000 to port 9000 on your local machine", Command: "coder port-forward --udp 9000", }, - example{ - Description: "Forward a Unix socket in the workspace to a local Unix socket", - Command: "coder port-forward --unix ./local.sock:~/remote.sock", - }, - example{ - Description: "Forward a Unix socket in the workspace to a local TCP port", - Command: "coder port-forward --unix 8080:~/remote.sock", - }, example{ Description: "Port forward multiple TCP ports and a UDP port", Command: "coder port-forward --tcp 8080:8080 --tcp 9000:3000 --udp 5353:53", @@ -60,7 +50,7 @@ func portForward() *cobra.Command { ctx, cancel := context.WithCancel(cmd.Context()) defer cancel() - specs, err := parsePortForwards(tcpForwards, udpForwards, unixForwards) + specs, err := parsePortForwards(tcpForwards, udpForwards) if err != nil { return xerrors.Errorf("parse port-forward specs: %w", err) } @@ -165,8 +155,7 @@ func portForward() *cobra.Command { cmd.Flags().StringArrayVarP(&tcpForwards, "tcp", "p", []string{}, "Forward a TCP port from the workspace to the local machine") cmd.Flags().StringArrayVar(&udpForwards, "udp", []string{}, "Forward a UDP port from the workspace to the local machine. The UDP connection has TCP-like semantics to support stateful UDP protocols") - cmd.Flags().StringArrayVar(&unixForwards, "unix", []string{}, "Forward a Unix socket in the workspace to a local Unix socket or TCP port") - cmd.Flags().BoolVarP(&wireguard, "wireguard", "", false, "Specifies whether to use wireguard networking or not.") + cmd.Flags().BoolVarP(&wireguard, "wireguard", "", true, "Specifies whether to use wireguard networking or not.") _ = cmd.Flags().MarkHidden("wireguard") return cmd } @@ -198,8 +187,6 @@ func listenAndPortForward(ctx context.Context, cmd *cobra.Command, conn agent.Co IP: net.ParseIP(host), Port: portInt, }) - case "unix": - l, err = net.Listen(spec.listenNetwork, spec.listenAddress) default: return nil, xerrors.Errorf("unknown listen network %q", spec.listenNetwork) } @@ -236,14 +223,14 @@ func listenAndPortForward(ctx context.Context, cmd *cobra.Command, conn agent.Co } type portForwardSpec struct { - listenNetwork string // tcp, udp, unix + listenNetwork string // tcp, udp listenAddress string // : or path - dialNetwork string // tcp, udp, unix + dialNetwork string // tcp, udp dialAddress string // : or path } -func parsePortForwards(tcpSpecs, udpSpecs, unixSpecs []string) ([]portForwardSpec, error) { +func parsePortForwards(tcpSpecs, udpSpecs []string) ([]portForwardSpec, error) { specs := []portForwardSpec{} for _, spec := range tcpSpecs { @@ -274,29 +261,6 @@ func parsePortForwards(tcpSpecs, udpSpecs, unixSpecs []string) ([]portForwardSpe }) } - for _, specStr := range unixSpecs { - localPath, localTCP, remotePath, err := parseUnixUnix(specStr) - if err != nil { - return nil, xerrors.Errorf("failed to parse Unix port-forward specification %q: %w", specStr, err) - } - - spec := portForwardSpec{ - dialNetwork: "unix", - dialAddress: remotePath, - } - if localPath == "" { - spec.listenNetwork = "tcp" - spec.listenAddress = fmt.Sprintf("127.0.0.1:%v", localTCP) - } else { - if runtime.GOOS == "windows" { - return nil, xerrors.Errorf("Unix port-forwarding is not supported on Windows") - } - spec.listenNetwork = "unix" - spec.listenAddress = localPath - } - specs = append(specs, spec) - } - // Check for duplicate entries. locals := map[string]struct{}{} for _, spec := range specs { @@ -322,15 +286,6 @@ func parsePort(in string) (uint16, error) { return uint16(port), nil } -func parseUnixPath(in string) (string, error) { - path, err := agent.ExpandRelativeHomePath(strings.TrimSpace(in)) - if err != nil { - return "", xerrors.Errorf("tidy path %q: %w", in, err) - } - - return path, nil -} - func parsePortPort(in string) (local uint16, remote uint16, err error) { parts := strings.Split(in, ":") if len(parts) > 2 { @@ -352,37 +307,3 @@ func parsePortPort(in string) (local uint16, remote uint16, err error) { return local, remote, nil } - -func parsePortOrUnixPath(in string) (string, uint16, error) { - port, err := parsePort(in) - if err == nil { - return "", port, nil - } - - path, err := parseUnixPath(in) - if err != nil { - return "", 0, xerrors.Errorf("could not parse port or unix path %q: %w", in, err) - } - - return path, 0, nil -} - -func parseUnixUnix(in string) (string, uint16, string, error) { - parts := strings.Split(in, ":") - if len(parts) > 2 { - return "", 0, "", xerrors.Errorf("invalid port-forward specification %q", in) - } - if len(parts) == 1 { - // Duplicate the single part - parts = append(parts, parts[0]) - } - - localPath, localPort, err := parsePortOrUnixPath(parts[0]) - if err != nil { - return "", 0, "", xerrors.Errorf("parse local part of spec %q: %w", in, err) - } - - // We don't really touch the remote path at all since it gets cleaned - // up/expanded on the remote. - return localPath, localPort, parts[1], nil -} diff --git a/cli/portforward_test.go b/cli/portforward_test.go index d98fbec7920c0..df92f20177a07 100644 --- a/cli/portforward_test.go +++ b/cli/portforward_test.go @@ -6,8 +6,6 @@ import ( "fmt" "io" "net" - "path/filepath" - "runtime" "strings" "sync" "testing" @@ -58,7 +56,7 @@ func TestPortForward(t *testing.T) { // setupRemote creates a "remote" listener to emulate a service in the // workspace. setupRemote func(t *testing.T) net.Listener - // setupLocal returns an available port or Unix socket path that the + // setupLocal returns an available port that the // port-forward command will listen on "locally". Returns the address // you pass to net.Dial, and the port/path you pass to `coder // port-forward`. @@ -110,26 +108,6 @@ func TestPortForward(t *testing.T) { return l.Addr().String(), port }, }, - { - name: "Unix", - network: "unix", - flag: "--unix=%v:%v", - setupRemote: func(t *testing.T) net.Listener { - if runtime.GOOS == "windows" { - t.Skip("Unix socket forwarding isn't supported on Windows") - } - - tmpDir := t.TempDir() - l, err := net.Listen("unix", filepath.Join(tmpDir, "test.sock")) - require.NoError(t, err, "create UDP listener") - return l - }, - setupLocal: func(t *testing.T) (string, string) { - tmpDir := t.TempDir() - path := filepath.Join(tmpDir, "test.sock") - return path, path - }, - }, } // Setup agent once to be shared between test-cases (avoid expensive @@ -234,74 +212,16 @@ func TestPortForward(t *testing.T) { }) } - // Test doing a TCP -> Unix forward. - //nolint:paralleltest - t.Run("TCP2Unix", func(t *testing.T) { - var ( - // Find the TCP and Unix cases so we can use their setupLocal and - // setupRemote methods respectively. - tcpCase = cases[0] - unixCase = cases[2] - - // Setup remote Unix listener. - p1 = setupTestListener(t, unixCase.setupRemote(t)) - ) - - // Create a flag that forwards from local TCP to Unix listener 1. - // Notably this is a --unix flag. - localAddress, localFlag := tcpCase.setupLocal(t) - flag := fmt.Sprintf(unixCase.flag, localFlag, p1) - - // Launch port-forward in a goroutine so we can start dialing - // the "local" listener. - cmd, root := clitest.New(t, "port-forward", workspace.Name, flag) - clitest.SetupConfig(t, client, root) - buf := newThreadSafeBuffer() - cmd.SetOut(buf) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - errC := make(chan error) - go func() { - errC <- cmd.ExecuteContext(ctx) - }() - waitForPortForwardReady(t, buf) - - t.Parallel() // Port is reserved, enable parallel execution. - - // Open two connections simultaneously and test them out of - // sync. - d := net.Dialer{Timeout: testutil.WaitShort} - c1, err := d.DialContext(ctx, tcpCase.network, localAddress) - require.NoError(t, err, "open connection 1 to 'local' listener") - defer c1.Close() - c2, err := d.DialContext(ctx, tcpCase.network, localAddress) - require.NoError(t, err, "open connection 2 to 'local' listener") - defer c2.Close() - testDial(t, c2) - testDial(t, c1) - - cancel() - err = <-errC - require.ErrorIs(t, err, context.Canceled) - }) - - // Test doing TCP, UDP and Unix at the same time. + // Test doing TCP and UDP at the same time. //nolint:paralleltest t.Run("All", func(t *testing.T) { var ( - // These aren't fixed size because we exclude Unix on Windows. dials = []addr{} flags = []string{} ) // Start listeners and populate arrays with the cases. for _, c := range cases { - if strings.HasPrefix(c.network, "unix") && runtime.GOOS == "windows" { - // Unix isn't supported on Windows, but we can still - // test other protocols together. - continue - } - p := setupTestListener(t, c.setupRemote(t)) localAddress, localFlag := c.setupLocal(t) @@ -391,7 +311,7 @@ func runAgent(t *testing.T, client *codersdk.Client, userID uuid.UUID) ([]coders coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) // Start workspace agent in a goroutine - cmd, root := clitest.New(t, "agent", "--agent-token", agentToken, "--agent-url", client.URL.String(), "--wireguard=false") + cmd, root := clitest.New(t, "agent", "--agent-token", agentToken, "--agent-url", client.URL.String()) clitest.SetupConfig(t, client, root) errC := make(chan error) agentCtx, agentCancel := context.WithCancel(ctx) @@ -412,7 +332,7 @@ func runAgent(t *testing.T, client *codersdk.Client, userID uuid.UUID) ([]coders } // setupTestListener starts accepting connections and echoing a single packet. -// Returns the listener and the listen port or Unix path. +// Returns the listener and the listen port. func setupTestListener(t *testing.T, l net.Listener) string { t.Helper() @@ -444,11 +364,9 @@ func setupTestListener(t *testing.T, l net.Listener) string { }() addr := l.Addr().String() - if !strings.HasPrefix(l.Addr().Network(), "unix") { - _, port, err := net.SplitHostPort(addr) - require.NoErrorf(t, err, "split non-Unix listen path %q", addr) - addr = port - } + _, port, err := net.SplitHostPort(addr) + require.NoErrorf(t, err, "split listen path %q", addr) + addr = port return addr } diff --git a/cli/server.go b/cli/server.go index 925a1a619a840..90fb8700c85ba 100644 --- a/cli/server.go +++ b/cli/server.go @@ -812,7 +812,7 @@ func Server(newAPI func(*coderd.Options) *coderd.API) *cobra.Command { "Specifies an issuer URL to use for OIDC.") cliflag.StringArrayVarP(root.Flags(), &oidcScopes, "oidc-scopes", "", "CODER_OIDC_SCOPES", []string{oidc.ScopeOpenID, "profile", "email"}, "Specifies scopes to grant when authenticating with OIDC.") - cliflag.BoolVarP(root.Flags(), &tailscaleEnable, "tailscale", "", "CODER_TAILSCALE", false, + cliflag.BoolVarP(root.Flags(), &tailscaleEnable, "tailscale", "", "CODER_TAILSCALE", true, "Specifies whether Tailscale networking is used for web applications and terminals.") _ = root.Flags().MarkHidden("tailscale") enableTelemetryByDefault := !isTest() diff --git a/cli/ssh.go b/cli/ssh.go index 796c1849a3305..21ac08ed772f0 100644 --- a/cli/ssh.go +++ b/cli/ssh.go @@ -221,7 +221,7 @@ func ssh() *cobra.Command { cliflag.BoolVarP(cmd.Flags(), &forwardAgent, "forward-agent", "A", "CODER_SSH_FORWARD_AGENT", false, "Specifies whether to forward the SSH agent specified in $SSH_AUTH_SOCK") cliflag.StringVarP(cmd.Flags(), &identityAgent, "identity-agent", "", "CODER_SSH_IDENTITY_AGENT", "", "Specifies which identity agent to use (overrides $SSH_AUTH_SOCK), forward agent must also be enabled") cliflag.DurationVarP(cmd.Flags(), &wsPollInterval, "workspace-poll-interval", "", "CODER_WORKSPACE_POLL_INTERVAL", workspacePollInterval, "Specifies how often to poll for workspace automated shutdown.") - cliflag.BoolVarP(cmd.Flags(), &wireguard, "wireguard", "", "CODER_SSH_WIREGUARD", false, "Whether to use Wireguard for SSH tunneling.") + cliflag.BoolVarP(cmd.Flags(), &wireguard, "wireguard", "", "CODER_SSH_WIREGUARD", true, "Whether to use Wireguard for SSH tunneling.") _ = cmd.Flags().MarkHidden("wireguard") return cmd diff --git a/coderd/coderd.go b/coderd/coderd.go index e4fc05b21c7e7..4b7c12c893e01 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -95,6 +95,12 @@ func New(options *Options) *API { if options.APIRateLimit == 0 { options.APIRateLimit = 512 } + if options.AgentStatsRefreshInterval == 0 { + options.AgentStatsRefreshInterval = 10 * time.Minute + } + if options.MetricsCacheRefreshInterval == 0 { + options.MetricsCacheRefreshInterval = time.Hour + } if options.Authorizer == nil { var err error options.Authorizer, err = rbac.NewAuthorizer() diff --git a/go.mod b/go.mod index 13832bcfd4cf2..23576413066d0 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20220912224234-e80c replace github.com/gliderlabs/ssh => github.com/coder/ssh v0.0.0-20220811105153-fcea99919338 // Fixes a deadlock on close in devtunnel. -replace golang.zx2c4.com/wireguard => github.com/coder/wireguard-go v0.0.0-20220913030355-902de6e9b175 +replace golang.zx2c4.com/wireguard => github.com/coder/wireguard-go v0.0.0-20220913030931-b1b3bb45caf9 require ( cdr.dev/slog v1.4.2-0.20220525200111-18dce5c2cd5f diff --git a/go.sum b/go.sum index e3d95afa7bd3a..41957b92a542a 100644 --- a/go.sum +++ b/go.sum @@ -357,8 +357,8 @@ github.com/coder/ssh v0.0.0-20220811105153-fcea99919338 h1:tN5GKFT68YLVzJoA8AHui github.com/coder/ssh v0.0.0-20220811105153-fcea99919338/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914= github.com/coder/tailscale v1.1.1-0.20220912224234-e80caec6c05f h1:NN9O1Pgno2QQy+JBnZk1VQ3vyAmWaB+yEotUDEuFKm8= github.com/coder/tailscale v1.1.1-0.20220912224234-e80caec6c05f/go.mod h1:5amxy08qijEa8bcTW2SeIy4MIqcmd7LMsuOxqOlj2Ak= -github.com/coder/wireguard-go v0.0.0-20220913030355-902de6e9b175 h1:obgyZIctZKcztM+TiIBUIJkOf04L9Fg+oLb47XEGy44= -github.com/coder/wireguard-go v0.0.0-20220913030355-902de6e9b175/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg= +github.com/coder/wireguard-go v0.0.0-20220913030931-b1b3bb45caf9 h1:AeU4w8hSB+XEj3e8HjvEUTy/MWQd6tddnr9dELrRjKk= +github.com/coder/wireguard-go v0.0.0-20220913030931-b1b3bb45caf9/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=