blob: 10d74aea637ee07f6597129bb3da57017057288f [file] [log] [blame]
gio0eaf2712024-04-14 13:08:46 +04001package main
2
3import (
4 "encoding/json"
5 "flag"
6 "fmt"
7 "net"
8 "os"
9
10 "golang.org/x/crypto/ssh"
11
12 "github.com/go-git/go-billy/v5/osfs"
13 "github.com/go-git/go-git/v5"
14 gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
15 "github.com/go-git/go-git/v5/storage/memory"
16)
17
18var port = flag.Int("port", 3000, "Port to listen on")
19var repoAddr = flag.String("repo-addr", "", "Git repository address")
20var sshKey = flag.String("ssh-key", "", "Private SSH key to access Git repository")
21var appDir = flag.String("app-dir", "", "Path to store application repository locally")
22var runCfg = flag.String("run-cfg", "", "Run configuration")
23var manager = flag.String("manager", "", "Address of the manager")
24
25type Command struct {
26 Bin string `json:"bin"`
27 Args []string `json:"args"`
gio1364e432024-06-29 11:39:18 +040028 Env []string `json:"env"`
gio0eaf2712024-04-14 13:08:46 +040029}
30
31func CloneRepository(addr string, signer ssh.Signer, path string) error {
giof5ffedb2024-06-19 14:14:43 +040032 c, err := git.Clone(memory.NewStorage(), osfs.New(path, osfs.WithBoundOS()), &git.CloneOptions{
gio0eaf2712024-04-14 13:08:46 +040033 URL: addr,
34 Auth: &gitssh.PublicKeys{
35 User: "git",
36 Signer: signer,
37 HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
38 HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
39 // TODO(giolekva): verify server public key
40 fmt.Printf("--- %+v\n", ssh.MarshalAuthorizedKey(key))
41 return nil
42 },
43 },
44 },
giof5ffedb2024-06-19 14:14:43 +040045 RemoteName: "origin",
46 ReferenceName: "refs/heads/master",
47 SingleBranch: true,
48 Depth: 1,
49 InsecureSkipTLS: true,
50 Progress: os.Stdout,
gio0eaf2712024-04-14 13:08:46 +040051 })
giof5ffedb2024-06-19 14:14:43 +040052 if err != nil {
53 return err
54 }
55 wt, err := c.Worktree()
56 if err != nil {
57 return err
58 }
59 sb, err := wt.Submodules()
60 if err != nil {
61 return err
62 }
63 if err := sb.Init(); err != nil {
64 return err
65 }
66 if err := sb.Update(&git.SubmoduleUpdateOptions{
67 Depth: 1,
68 }); err != nil {
69 return err
70 }
gio0eaf2712024-04-14 13:08:46 +040071 return err
72}
73
74func main() {
75 flag.Parse()
76 self, ok := os.LookupEnv("SELF_IP")
77 if !ok {
78 panic("no SELF_IP")
79 }
80 key, err := os.ReadFile(*sshKey)
81 if err != nil {
82 panic(err)
83 }
84 signer, err := ssh.ParsePrivateKey(key)
85 if err != nil {
86 panic(err)
87 }
88 if err := CloneRepository(*repoAddr, signer, *appDir); err != nil {
89 panic(err)
90 }
91 r, err := os.Open(*runCfg)
92 if err != nil {
93 panic(err)
94 }
95 defer r.Close()
96 var cmds []Command
97 if err := json.NewDecoder(r).Decode(&cmds); err != nil {
98 panic(err)
99 }
100 s := NewServer(*port, *repoAddr, signer, *appDir, cmds, self, *manager)
101 s.Start()
102}