diff options
Diffstat (limited to 'internal/admin/model.go')
| -rw-r--r-- | internal/admin/model.go | 102 |
1 files changed, 73 insertions, 29 deletions
diff --git a/internal/admin/model.go b/internal/admin/model.go index cf69fcd..5a7f984 100644 --- a/internal/admin/model.go +++ b/internal/admin/model.go @@ -10,9 +10,11 @@ import ( "os" "path/filepath" + "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/storage/filesystem" + "github.com/go-git/go-git/v5/storage/memory" "gopkg.in/ini.v1" @@ -28,6 +30,8 @@ const ( Admin = 2 // GitExportMagic magic file name for daemon export GitExportMagic = "git-daemon-export-ok" + // GitWebExportMagic + GitWebExportMagic = "git-web-export-ok" ) // Action composite type for modes @@ -67,22 +71,65 @@ type ServerRepos struct { BasePath string `json:"basepath"` } -func loadServerConfig(configPath string) *ServerRepos { - file, err := os.Open(configPath) +func loadFromGit(gitUrl, filePath string) ([]byte, error) { + fs := memfs.New() + storer := memory.NewStorage() + _, err := git.Clone(storer, fs, &git.CloneOptions{ + URL: gitUrl, + }) if err != nil { - log.Fatalf("Failed to open gitserver config %s", err) + // log.error + fmt.Printf("coudln't clone mgmt repo %s", err) + return []byte(""), errors.New("coudln't clone mgmt repo") + } + file, err := fs.Open(filePath) + if err != nil { + fmt.Printf("Failed to open gitserver config %s", err) + return []byte(""), errors.New("coudln't open git config file from mgmt repo") } defer file.Close() - b, err := io.ReadAll(file) + return io.ReadAll(file) +} + +func loadLocalFile(path string) ([]byte, error) { + file, err := os.Open(path) + if err != nil { + log.Printf("config file not opened %s", path) + return []byte{}, err + } + configBytes, err := io.ReadAll(file) if err != nil { - log.Fatalf("Failed to read the gitserver config %s", err) + log.Print("config file not read") + return []byte{}, err + } + return configBytes, nil +} + +func loadServerConfig(mgmtRepo bool, baseDir, configPath string) (*ServerRepos, error) { + configBytes := []byte{} + var err error + if mgmtRepo { + repoURI := filepath.Join("file:///", baseDir, "mgmt.git") + configBytes, err = loadFromGit(repoURI, configPath) + if err != nil { + // log.error + log.Print("Failed to load config file from git") + return &ServerRepos{}, err + } + } else { + configBytes, err = loadLocalFile(filepath.Join(baseDir, configPath)) + if err != nil { + // log.error + log.Print("Failed to load config file from git") + return &ServerRepos{}, err + } } config := &ServerRepos{} - err = yaml.Unmarshal(b, &config) + err = yaml.Unmarshal(configBytes, &config) if err != nil { - log.Fatalf("Failed to parse gitserver config %s", err) + return &ServerRepos{}, errors.New("Could not parse gitserver config") } - return config + return config, nil } // ServerPolicies generate casbin policies @@ -108,19 +155,20 @@ func readOnlyPaths(role, repoName string) [][]string { } } func writePaths(role, repoName string) [][]string { - return [][]string{[]string{role, fmt.Sprintf("/%s/git-recieve-pack", repoName), "POST"}} + return [][]string{[]string{role, fmt.Sprintf("/%s/git-receive-pack", repoName), "POST"}} } // Policy generate policy for repo base on mode func (p *Permission) Policy(repoName string) [][]string { policies := [][]string{} // if read mode or greater e.g. write mode + roleName := fmt.Sprintf("role:%s", p.Role) if p.Mode >= Read { - policies = append(policies, readOnlyPaths(p.Role, repoName)...) + policies = append(policies, readOnlyPaths(roleName, repoName)...) } // if write mode if p.Mode >= Write { - policies = append(policies, writePaths(p.Role, repoName)...) + policies = append(policies, writePaths(roleName, repoName)...) } return policies } @@ -145,8 +193,18 @@ func (r *GitRepo) ReconcileRepo(basePath string) { strg := filesystem.NewStorage(fs, nil) _, _ = git.Init(strg, nil) } + // set export file for git-http-backend + okExport := filepath.Join(repoBase, GitExportMagic) + _, err = os.Stat(okExport) + if errors.Is(err, fs.ErrNotExist) { + // Create web export + f, err := os.Create(okExport) + f.Close() + if err != nil { + log.Fatalf("%s coudln't be created %s", GitExportMagic, err) + } + } r.ConfigureExport(repoBase) - if r.GitWebConfig == nil { r.GitWebConfig = &GitWeb{} } @@ -155,24 +213,10 @@ func (r *GitRepo) ReconcileRepo(basePath string) { // ConfigureExport setup repo for sharing and configure web settings func (r *GitRepo) ConfigureExport(repoBase string) { - // do nothing on public repos - okExport := filepath.Join(repoBase, GitExportMagic) - _, err := os.Stat(okExport) - // Not public but the export setting is setting exists - if !r.Public && err == nil { - // delete file - os.Remove(okExport) - return - } - // Not public and the file doesn't exist - if !r.Public && errors.Is(err, fs.ErrNotExist) { - return - } - // - f, err := os.Create(okExport) - defer f.Close() + okExport := filepath.Join(repoBase, GitWebExportMagic) + _, err := os.Create(okExport) if err != nil { - log.Fatalf("git-daemon-export-ok coudln't be created %s", err) + log.Fatalf("%s coudln't be created %s", GitWebExportMagic, err) } } |