-
Notifications
You must be signed in to change notification settings - Fork 212
Create base #1
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| vendor |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| FROM codercom/ubuntu-dev-go | ||
|
|
||
| LABEL project_root "~/go/src/go.coder.com" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # sshcode | ||
|
|
||
| `sshcode` is a CLI to automatically install and run [code-server](https://github.com/codercom/code-server) over SSH. | ||
|
|
||
|  | ||
|
|
||
| ## Install | ||
|
|
||
| Chrome is recommended. | ||
|
|
||
| ```bash | ||
| go get go.coder.com/sshcode | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```bash | ||
| sshcode [email protected] | ||
| # Starts code-server on dev.kwc.io and opens in a new browser window. | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| module go.coder.com/sshcode | ||
|
|
||
| go 1.12 | ||
|
|
||
| require ( | ||
| go.coder.com/flog v0.0.0-20190129195112-eaed154a0db8 | ||
| golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be // indirect | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= | ||
| github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | ||
| github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= | ||
| github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||
| github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= | ||
| github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | ||
| go.coder.com/flog v0.0.0-20190129195112-eaed154a0db8 h1:PtQ3moPi4EAz3cyQhkUs1IGIXa2QgJpP60yMjOdu0kk= | ||
| go.coder.com/flog v0.0.0-20190129195112-eaed154a0db8/go.mod h1:83JsYgXYv0EOaXjIMnaZ1Fl6ddNB3fJnDZ/8845mUJ8= | ||
| golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be h1:mI+jhqkn68ybP0ORJqunXn+fq+Eeb4hHKqLQcFICjAc= | ||
| golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "flag" | ||
| "fmt" | ||
| "net" | ||
| "net/http" | ||
| "os" | ||
| "os/exec" | ||
| "strconv" | ||
| "time" | ||
|
|
||
| "go.coder.com/flog" | ||
| ) | ||
|
|
||
| func main() { | ||
| flag.Usage = func() { | ||
| fmt.Printf(`Usage: %v HOST [SSH ARGS...] | ||
|
|
||
| Start code-server over SSH. | ||
| More info: https://github.com/codercom/sshcode | ||
| `, os.Args[0]) | ||
| } | ||
|
|
||
| flag.Parse() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a blocker but in the future, you don't need the flag library, you have no flags. You can directly use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nvm, flag automatically gives you a |
||
| host := flag.Arg(0) | ||
|
|
||
| if host == "" { | ||
| // If no host is specified output the usage. | ||
| flag.Usage() | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| flog.Info("ensuring code-server is updated...") | ||
|
|
||
| // Downloads the latest code-server and allows it to be executed. | ||
| sshCmd := exec.Command("ssh", | ||
| "-tt", | ||
kylecarbs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| host, | ||
| `/bin/bash -c 'set -euxo pipefail || exit 1 | ||
| mkdir -p ~/bin | ||
| wget -q https://codesrv-ci.cdr.sh/latest-linux -O ~/bin/code-server | ||
| chmod +x ~/bin/code-server | ||
| '`, | ||
| ) | ||
| output, err := sshCmd.CombinedOutput() | ||
| if err != nil { | ||
| flog.Fatal("failed to update code-server: %v: %s", err, output) | ||
| } | ||
|
|
||
| flog.Info("starting code-server...") | ||
| localPort, err := scanAvailablePort() | ||
| if err != nil { | ||
| flog.Fatal("failed to scan available port: %v", err) | ||
| } | ||
|
|
||
| // Starts code-server and forwards the remote port. | ||
| sshCmd = exec.Command("ssh", | ||
| "-tt", | ||
| "-q", | ||
| "-L", | ||
| localPort+":localhost:"+localPort, | ||
| host, | ||
| "~/bin/code-server --host 127.0.0.1 --allow-http --no-auth --port="+localPort, | ||
| ) | ||
| sshCmd.Stdout = os.Stdout | ||
| sshCmd.Stderr = os.Stderr | ||
| err = sshCmd.Start() | ||
| if err != nil { | ||
| flog.Fatal("failed to start code-server: %v", err) | ||
| } | ||
|
|
||
| url := "http://127.0.0.1:" + localPort | ||
| ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) | ||
| defer cancel() | ||
| for { | ||
kylecarbs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if ctx.Err() != nil { | ||
| flog.Fatal("code-server didn't start in time %v", ctx.Err()) | ||
| } | ||
| // Waits for code-server to be available before opening the browser. | ||
| r, _ := http.NewRequest("GET", url, nil) | ||
| r = r.WithContext(ctx) | ||
| resp, err := http.DefaultClient.Do(r) | ||
| if err != nil { | ||
| continue | ||
| } | ||
| resp.Body.Close() | ||
| break | ||
| } | ||
|
|
||
| openBrowser(url) | ||
| sshCmd.Wait() | ||
| } | ||
|
|
||
| func openBrowser(url string) { | ||
| var openCmd *exec.Cmd | ||
| if commandExists("google-chrome") { | ||
| openCmd = exec.Command("google-chrome", "--app="+url, "--disable-extensions", "--disable-plugins") | ||
| } else if commandExists("firefox") { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I take it back. If neither of these exist, this program will panic.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| openCmd = exec.Command("firefox", "--url="+url, "-safe-mode") | ||
| } else { | ||
| flog.Info("unable to find a browser to open: sshcode only supports firefox and chrome") | ||
|
|
||
| return | ||
| } | ||
|
|
||
| err := openCmd.Start() | ||
| if err != nil { | ||
| flog.Fatal("failed to open browser: %v", err) | ||
| } | ||
| } | ||
|
|
||
| // Checks if a command exists locally. | ||
| func commandExists(name string) bool { | ||
| _, err := exec.LookPath(name) | ||
| return err == nil | ||
| } | ||
|
|
||
| // scanAvailablePort scans 1024-4096 until an available port is found. | ||
| func scanAvailablePort() (string, error) { | ||
| for port := 1024; port < 4096; port++ { | ||
| l, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) | ||
| if err != nil { | ||
| // If we have an error the port is taken. | ||
| port++ | ||
| continue | ||
| } | ||
| _ = l.Close() | ||
|
|
||
| return strconv.Itoa(port), nil | ||
| } | ||
|
|
||
| return "", errors.New("no ports available") | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.