blob: 0a58be2edcd0276871f5ad87a1782b4077d97e49 [file] [log] [blame]
giolekva8aa73e82022-07-09 11:34:39 +04001package main
2
3import (
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +04004 "net"
giolekva8aa73e82022-07-09 11:34:39 +04005 "os"
giolekva8aa73e82022-07-09 11:34:39 +04006
7 "github.com/giolekva/pcloud/core/installer"
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +04008 "github.com/go-git/go-billy/v5/memfs"
9 "github.com/go-git/go-git/v5"
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040010 gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
11 "github.com/go-git/go-git/v5/storage/memory"
giolekva8aa73e82022-07-09 11:34:39 +040012 "github.com/spf13/cobra"
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040013 "golang.org/x/crypto/ssh"
giolekva8aa73e82022-07-09 11:34:39 +040014)
15
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040016const appDirName = "apps"
17
giolekva8aa73e82022-07-09 11:34:39 +040018var installFlags struct {
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040019 sshKey string
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040020 appName string
21 repoAddr string
giolekva8aa73e82022-07-09 11:34:39 +040022}
23
24func installCmd() *cobra.Command {
25 cmd := &cobra.Command{
26 Use: "install",
27 RunE: installCmdRun,
28 }
29 cmd.Flags().StringVar(
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040030 &installFlags.sshKey,
31 "ssh-key",
32 "",
33 "",
34 )
35 cmd.Flags().StringVar(
giolekva8aa73e82022-07-09 11:34:39 +040036 &installFlags.appName,
37 "app",
38 "",
39 "",
40 )
41 cmd.Flags().StringVar(
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040042 &installFlags.repoAddr,
43 "repo-addr",
giolekva8aa73e82022-07-09 11:34:39 +040044 "",
45 "",
46 )
47 return cmd
48}
49
50func installCmdRun(cmd *cobra.Command, args []string) error {
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040051 sshKey, err := os.ReadFile(installFlags.sshKey)
52 if err != nil {
53 return err
giolekva8aa73e82022-07-09 11:34:39 +040054 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040055 signer, err := ssh.ParsePrivateKey(sshKey)
56 if err != nil {
57 return err
58 }
59 repo, err := cloneRepo(installFlags.repoAddr, signer)
60 if err != nil {
61 return err
62 }
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040063 m, err := installer.NewAppManager(
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040064 repo,
65 signer,
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040066 )
67 if err != nil {
68 return err
69 }
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040070 appRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
71 app, err := appRepo.Find(installFlags.appName)
giolekva8aa73e82022-07-09 11:34:39 +040072 if err != nil {
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040073 return err
giolekva8aa73e82022-07-09 11:34:39 +040074 }
Giorgi Lekveishvilibd6be7f2023-05-26 15:51:28 +040075 return m.Install(*app)
giolekva8aa73e82022-07-09 11:34:39 +040076}
Giorgi Lekveishvili23ef7f82023-05-26 11:57:48 +040077
78func cloneRepo(address string, signer ssh.Signer) (*git.Repository, error) {
79 return git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
80 URL: address,
81 Auth: auth(signer),
82 RemoteName: "origin",
83 InsecureSkipTLS: true,
84 })
85}
86
87func auth(signer ssh.Signer) *gitssh.PublicKeys {
88 return &gitssh.PublicKeys{
89 Signer: signer,
90 HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
91 HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
92 // TODO(giolekva): verify server public key
93 // fmt.Printf("## %s || %s -- \n", serverPubKey, ssh.MarshalAuthorizedKey(key))
94 return nil
95 },
96 },
97 }
98}