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