| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| 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 kyle@dev.kwc.io | ||
| # 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() | ||
|
Comment thread
Copy link
Copy Markdown
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityNot a blocker but in the future, you don't need the flag library, you have no flags. You can directly use os.Args.
Sorry, something went wrong.
kylecarbs reacted with thumbs up emoji
All reactions
Copy link
Copy Markdown
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityNvm, flag automatically gives you a -h flag which is nice. So this is the way to go.
Sorry, something went wrong.
kylecarbs reacted with thumbs up emoji
All reactions
|
||
| 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", | ||
|
Comment thread
kylecarbs marked this conversation as 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 { | ||
|
Comment thread
kylecarbs marked this conversation as 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") { | ||
|
Comment thread
Copy link
Copy Markdown
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI take it back. If neither of these exist, this program will panic.
Sorry, something went wrong.
kylecarbs reacted with thumbs up emoji
All reactions
Copy link
Copy Markdown
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Sorry, something went wrong.
All reactions
|
||
| 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") | ||
| } | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.