add config for snap (#191)

* add config for snap

* place holder

* fix build

* fit 7.2

* fix lint

* no empty
This commit is contained in:
Boshi Lian 2023-08-13 07:07:28 -07:00 committed by GitHub
parent 19a6a0c9eb
commit 502249d275
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 264 additions and 7 deletions

View file

@ -73,14 +73,9 @@ jobs:
cache: true
- name: Setup Snap
env:
SNAP_SECRET: ${{ secrets.snap }}
run: |
set -e
sudo snap install snapcraft --classic
echo $SNAP_SECRET | base64 -d > /tmp/secret
snap run snapcraft login --with /tmp/secret
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
@ -91,6 +86,7 @@ jobs:
env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SKIP_PUSH: ${{ github.event_name != 'release' }}
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
- name: Upload binaries to release
env:

1
.gitignore vendored
View file

@ -21,3 +21,4 @@ vendor/
go.work
dist/
cmd/sshpiperd/snap/launcher/configentry.txt

View file

@ -19,6 +19,18 @@ builds:
binary: sshpiperd
ldflags:
- -X main.mainver={{.Version}}
- id: snaplauncher
env:
- CGO_ENABLED=0
goos:
- linux
main: ./cmd/sshpiperd/snap/launcher
binary: snap/launcher
hooks:
pre: go generate ./cmd/sshpiperd/snap/launcher
goarch:
- amd64
- arm64
- id: plugin_workingdir
env:
- CGO_ENABLED=0
@ -221,7 +233,11 @@ release:
snapcrafts:
- builds:
- sshpiperd
- snaplauncher
- plugin_workingdir
- plugin_yaml
- plugin_fixed
- plugin_failtoban
name: sshpiperd
name_template: "sshpiperd_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
summary: The missing reverse proxy for ssh scp
@ -236,6 +252,14 @@ snapcrafts:
license: MIT
apps:
sshpiperd:
command: sshpiperd --server-key $SNAP_COMMON/ssh_host_ed25519_key --server-key-generate-mode notexist $SNAP/workingdir --root $SNAP_COMMON/workingdir
command: launcher
plugs: [network-bind]
daemon: simple
daemon: simple
extra_files:
- source: cmd/sshpiperd/snap/hooks/configure
destination: meta/hooks/configure
mode: 0755
hooks:
configure:
# plugin: dump
# source: cmd/sshpiperd/snap/hooks

View file

@ -0,0 +1,72 @@
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"log"
"os"
"strings"
)
func main() {
configs := map[string]string{
"sshpiperd": "../../main.go",
"workingdir": "../../../../plugin/workingdir/main.go",
"yaml": "../../../../plugin/yaml/main.go",
"fixed": "../../../../plugin/fixed/main.go",
"failtoban": "../../../../plugin/failtoban/main.go",
}
for k, v := range configs {
extractFlags(k, v)
}
}
func extractFlags(namespace, filePath string) {
file, err := os.Open(filePath)
if err != nil {
log.Fatal(err)
}
defer file.Close()
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, filePath, file, parser.AllErrors)
if err != nil {
log.Fatal(err)
}
ast.Inspect(node, func(n ast.Node) bool {
if cl, ok := n.(*ast.CompositeLit); ok {
if t, ok := cl.Type.(*ast.SelectorExpr); ok {
o, ok := t.X.(*ast.Ident)
if !ok {
return true
}
if o.Name != "cli" {
return true
}
if !strings.HasSuffix(t.Sel.Name, "Flag") {
return true
}
for _, v := range cl.Elts {
if kv, ok := v.(*ast.KeyValueExpr); ok {
if kv.Key.(*ast.Ident).Name == "Name" {
fmt.Println(namespace + "." + strings.Trim(kv.Value.(*ast.BasicLit).Value, " \""))
}
}
}
}
}
return true
})
}

4
cmd/sshpiperd/snap/hooks/configure vendored Normal file
View file

@ -0,0 +1,4 @@
#!/bin/sh
set -e
$SNAP/launcher generate

View file

@ -0,0 +1,2 @@
//go:generate sh -c "go run ../configgen/main.go > configentry.txt"
package main

View file

View file

@ -0,0 +1,158 @@
package main
import (
"embed"
"encoding/json"
"log"
"os"
"os/exec"
"path"
"strings"
)
//go:embed all:*.txt
var configentry embed.FS
func main() {
bindir := os.Getenv("SNAP")
datadir := os.Getenv("SNAP_DATA")
flags := map[string][][]string{}
configfile := path.Join(datadir, "flags.json")
if len(os.Args) > 1 && os.Args[1] == "generate" {
flags = loadFromSnapctl()
cache, _ := json.Marshal(flags)
if err := os.WriteFile(configfile, cache, 0600); err != nil {
log.Fatal(err)
}
return
}
cache, _ := os.ReadFile(configfile)
_ = json.Unmarshal(cache, &flags)
cmd := exec.Command(path.Join(bindir, "sshpiperd"))
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
for _, flag := range flags["sshpiperd"] {
cmd.Args = append(cmd.Args, "--"+flag[0], flag[1])
}
for _, plugin := range flags["sshpiperd.plugins"][0] {
cmd.Args = append(cmd.Args, path.Join(bindir, plugin))
for _, flag := range flags[plugin] {
cmd.Args = append(cmd.Args, "--"+flag[0], flag[1])
}
cmd.Args = append(cmd.Args, "--")
}
log.Println("starting sshpiperd with args:", cmd)
_ = cmd.Run()
}
func loadFromSnapctl() map[string][][]string {
commondir := os.Getenv("SNAP_COMMON")
flags := map[string][][]string{}
data, err := configentry.ReadFile("configentry.txt")
if err != nil {
log.Fatal(err)
}
for _, line := range strings.Split(string(data), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
v, err := get(line)
if err != nil {
log.Fatal(err)
}
if v == "" {
continue
}
parts := strings.Split(line, ".")
ns := parts[0]
flag := parts[1]
flags[ns] = append(flags[ns], []string{flag, v})
}
// known defaults
{
v, _ := get("sshpiperd.plugins")
if v == "" {
v = "workingdir"
}
var plugins []string
for _, str := range strings.Split(v, " ") {
str = strings.TrimSpace(str)
if str != "" {
plugins = append(plugins, str)
}
}
flags["sshpiperd.plugins"] = [][]string{plugins}
}
// {
// v, _ := get("sshpiperd.typescript-log-dir")
// if v == "" {
// v = "screenrecord"
// dir := path.Join(commondir, v)
// _ = os.MkdirAll(dir, 0700)
// flags["sshpiperd"] = append(flags["sshpiperd"], []string{"typescript-log-dir", dir})
// }
// }
{
v, _ := get("sshpiperd.server-key-generate-mode")
if v == "" {
v = "notexist"
flags["sshpiperd"] = append(flags["sshpiperd"], []string{"server-key-generate-mode", v})
}
}
{
v, _ := get("sshpiperd.server-key")
if v == "" {
v = "ssh_host_ed25519_key"
file := path.Join(commondir, v)
flags["sshpiperd"] = append(flags["sshpiperd"], []string{"server-key", file})
}
}
{
v, _ := get("workingdir.root")
if v == "" {
v = "workingdir"
dir := path.Join(commondir, v)
_ = os.MkdirAll(dir, 0700)
flags["workingdir"] = append(flags["workingdir"], []string{"root", dir})
}
}
return flags
}
func get(key string) (string, error) {
cmd := exec.Command("snapctl", "get", key)
output, err := cmd.Output()
if err != nil {
return "", err
}
value := string(output)
return strings.TrimSpace(value), nil
}