blob: dce8ffed1d4115becc1182ae81af7a1f4a344da1 [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")
gio266c04f2024-07-03 14:18:45 +040019var appId = flag.String("app-id", "", "Application ID")
gio0eaf2712024-04-14 13:08:46 +040020var repoAddr = flag.String("repo-addr", "", "Git repository address")
21var sshKey = flag.String("ssh-key", "", "Private SSH key to access Git repository")
22var appDir = flag.String("app-dir", "", "Path to store application repository locally")
23var runCfg = flag.String("run-cfg", "", "Run configuration")
24var manager = flag.String("manager", "", "Address of the manager")
25
26type Command struct {
27 Bin string `json:"bin"`
28 Args []string `json:"args"`
gio1364e432024-06-29 11:39:18 +040029 Env []string `json:"env"`
gio0eaf2712024-04-14 13:08:46 +040030}
31
32func CloneRepository(addr string, signer ssh.Signer, path string) error {
giof5ffedb2024-06-19 14:14:43 +040033 c, err := git.Clone(memory.NewStorage(), osfs.New(path, osfs.WithBoundOS()), &git.CloneOptions{
gio0eaf2712024-04-14 13:08:46 +040034 URL: addr,
35 Auth: &gitssh.PublicKeys{
36 User: "git",
37 Signer: signer,
38 HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
39 HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
40 // TODO(giolekva): verify server public key
41 fmt.Printf("--- %+v\n", ssh.MarshalAuthorizedKey(key))
42 return nil
43 },
44 },
45 },
giof5ffedb2024-06-19 14:14:43 +040046 RemoteName: "origin",
47 ReferenceName: "refs/heads/master",
48 SingleBranch: true,
49 Depth: 1,
50 InsecureSkipTLS: true,
51 Progress: os.Stdout,
gio0eaf2712024-04-14 13:08:46 +040052 })
giof5ffedb2024-06-19 14:14:43 +040053 if err != nil {
54 return err
55 }
56 wt, err := c.Worktree()
57 if err != nil {
58 return err
59 }
60 sb, err := wt.Submodules()
61 if err != nil {
62 return err
63 }
64 if err := sb.Init(); err != nil {
65 return err
66 }
67 if err := sb.Update(&git.SubmoduleUpdateOptions{
68 Depth: 1,
69 }); err != nil {
70 return err
71 }
gio0eaf2712024-04-14 13:08:46 +040072 return err
73}
74
75func main() {
76 flag.Parse()
77 self, ok := os.LookupEnv("SELF_IP")
78 if !ok {
79 panic("no SELF_IP")
80 }
81 key, err := os.ReadFile(*sshKey)
82 if err != nil {
83 panic(err)
84 }
85 signer, err := ssh.ParsePrivateKey(key)
86 if err != nil {
87 panic(err)
88 }
89 if err := CloneRepository(*repoAddr, signer, *appDir); err != nil {
90 panic(err)
91 }
92 r, err := os.Open(*runCfg)
93 if err != nil {
94 panic(err)
95 }
96 defer r.Close()
97 var cmds []Command
98 if err := json.NewDecoder(r).Decode(&cmds); err != nil {
99 panic(err)
100 }
gio266c04f2024-07-03 14:18:45 +0400101 s := NewServer(*port, *appId, *repoAddr, signer, *appDir, cmds, self, *manager)
gio0eaf2712024-04-14 13:08:46 +0400102 s.Start()
103}