| 1 | package installer |
| 2 | |
| 3 | import ( |
| 4 | _ "embed" |
| 5 | "errors" |
| 6 | "strings" |
| 7 | |
| 8 | "github.com/gosuda/portal-tunnel/v2/types" |
| 9 | ) |
| 10 | |
| 11 | //go:embed install.sh |
| 12 | var installShellScript string |
| 13 | |
| 14 | //go:embed install.ps1 |
| 15 | var installPowerShellScript string |
| 16 | |
| 17 | func RelayScript(portalURL string, isWindows bool) (script, filename, contentType string, err error) { |
| 18 | portalURL = strings.TrimSpace(portalURL) |
| 19 | if portalURL == "" { |
| 20 | return "", "", "", errors.New("portal url is required") |
| 21 | } |
| 22 | |
| 23 | script, filename, contentType = scriptFor(isWindows) |
| 24 | if isWindows { |
| 25 | return relayPowerShellScript(portalURL, script), filename, contentType, nil |
| 26 | } |
| 27 | return relayShellScript(portalURL, script), filename, contentType, nil |
| 28 | } |
| 29 | |
| 30 | func scriptFor(isWindows bool) (script, filename, contentType string) { |
| 31 | if isWindows { |
| 32 | return installPowerShellScript, "install.ps1", "text/plain; charset=utf-8" |
| 33 | } |
| 34 | return installShellScript, "install.sh", "text/x-shellscript" |
| 35 | } |
| 36 | |
| 37 | func AssetFilename(slug string) (string, bool) { |
| 38 | switch strings.TrimSpace(slug) { |
| 39 | case "linux-amd64", "linux-arm64", "darwin-amd64", "darwin-arm64": |
| 40 | return "portal-" + slug, true |
| 41 | case "windows-amd64", "windows-arm64": |
| 42 | return "portal-" + slug + ".exe", true |
| 43 | default: |
| 44 | return "", false |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | func relayShellScript(portalURL, script string) string { |
| 49 | overrides := strings.Join([]string{ |
| 50 | "BASE_URL=" + quoteShellValue(portalURL), |
| 51 | "RELAY_URL=" + quoteShellValue(portalURL), |
| 52 | "BIN_PATH_PREFIX=" + quoteShellValue(strings.Trim(types.PathInstallBinPrefix, "/")), |
| 53 | "", |
| 54 | }, "\n") |
| 55 | return insertAfterShebang(script, overrides) |
| 56 | } |
| 57 | |
| 58 | func relayPowerShellScript(portalURL, script string) string { |
| 59 | overrides := strings.Join([]string{ |
| 60 | "$env:BASE_URL = " + quotePowerShellValue(portalURL), |
| 61 | "$env:RELAY_URL = " + quotePowerShellValue(portalURL), |
| 62 | "$env:BIN_PATH_PREFIX = " + quotePowerShellValue(strings.Trim(types.PathInstallBinPrefix, "/")), |
| 63 | "", |
| 64 | }, "\n") |
| 65 | return overrides + script |
| 66 | } |
| 67 | |
| 68 | func insertAfterShebang(script, prefix string) string { |
| 69 | if strings.HasPrefix(script, "#!") { |
| 70 | if newline := strings.IndexByte(script, '\n'); newline >= 0 { |
| 71 | return script[:newline+1] + prefix + script[newline+1:] |
| 72 | } |
| 73 | } |
| 74 | return prefix + script |
| 75 | } |
| 76 | |
| 77 | func quoteShellValue(value string) string { |
| 78 | return "'" + strings.ReplaceAll(value, "'", `'\"'\"'`) + "'" |
| 79 | } |
| 80 | |
| 81 | func quotePowerShellValue(value string) string { |
| 82 | return "'" + strings.ReplaceAll(value, "'", "''") + "'" |
| 83 | } |