2020-12-26 19:36:09 +00:00
|
|
|
package main
|
|
|
|
|
2020-12-27 03:30:19 +00:00
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
2020-12-29 02:37:18 +00:00
|
|
|
"net/url"
|
2020-12-27 03:30:19 +00:00
|
|
|
"os"
|
2020-12-30 23:00:37 +00:00
|
|
|
"path/filepath"
|
2021-08-13 17:40:26 +00:00
|
|
|
"strings"
|
2020-12-27 03:30:19 +00:00
|
|
|
|
2020-12-27 07:23:00 +00:00
|
|
|
"github.com/badjware/gitlabfs/fs"
|
2020-12-29 02:37:18 +00:00
|
|
|
"github.com/badjware/gitlabfs/git"
|
2020-12-27 03:30:19 +00:00
|
|
|
"github.com/badjware/gitlabfs/gitlab"
|
2020-12-30 23:00:37 +00:00
|
|
|
"gopkg.in/yaml.v2"
|
2020-12-27 03:30:19 +00:00
|
|
|
)
|
2020-12-26 19:36:09 +00:00
|
|
|
|
2020-12-30 23:00:37 +00:00
|
|
|
type (
|
|
|
|
Config struct {
|
|
|
|
FS FSConfig `yaml:"fs,omitempty"`
|
|
|
|
Gitlab GitlabConfig `yaml:"gitlab,omitempty"`
|
|
|
|
Git GitConfig `yaml:"git,omitempty"`
|
|
|
|
}
|
|
|
|
FSConfig struct {
|
2021-08-13 17:40:26 +00:00
|
|
|
Mountpoint string `yaml:"mountpoint,omitempty"`
|
|
|
|
MountOptions string `yaml:"mountoptions,omitempty"`
|
2020-12-30 23:00:37 +00:00
|
|
|
}
|
|
|
|
GitlabConfig struct {
|
|
|
|
URL string `yaml:"url,omitempty"`
|
|
|
|
Token string `yaml:"token,omitempty"`
|
|
|
|
GroupIDs []int `yaml:"group_ids,omitempty"`
|
|
|
|
UserIDs []int `yaml:"user_ids,omitempty"`
|
|
|
|
IncludeCurrentUser bool `yaml:"include_current_user,omitempty"`
|
|
|
|
}
|
|
|
|
GitConfig struct {
|
2020-12-31 02:18:18 +00:00
|
|
|
CloneLocation string `yaml:"clone_location,omitempty"`
|
|
|
|
Remote string `yaml:"remote,omitempty"`
|
|
|
|
PullMethod string `yaml:"pull_method,omitempty"`
|
|
|
|
OnClone string `yaml:"on_clone,omitempty"`
|
|
|
|
AutoPull bool `yaml:"auto_pull,omitempty"`
|
|
|
|
Depth int `yaml:"depth,omitempty"`
|
2022-03-03 22:47:36 +00:00
|
|
|
QueueSize int `yaml:"queue_size,omitempty"`
|
|
|
|
QueueWorkerCount int `yaml:"worker_count,omitempty"`
|
2020-12-30 23:00:37 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
func loadConfig(configPath string) (*Config, error) {
|
|
|
|
// defaults
|
|
|
|
dataHome := os.Getenv("XDG_DATA_HOME")
|
|
|
|
if dataHome == "" {
|
|
|
|
dataHome = filepath.Join(os.Getenv("HOME"), ".local/share")
|
|
|
|
}
|
|
|
|
defaultCloneLocation := filepath.Join(dataHome, "gitlabfs")
|
|
|
|
|
|
|
|
config := &Config{
|
|
|
|
FS: FSConfig{
|
2021-08-13 17:40:26 +00:00
|
|
|
Mountpoint: "",
|
|
|
|
MountOptions: "nodev,nosuid",
|
2020-12-30 23:00:37 +00:00
|
|
|
},
|
|
|
|
Gitlab: GitlabConfig{
|
|
|
|
URL: "https://gitlab.com",
|
|
|
|
Token: "",
|
|
|
|
GroupIDs: []int{9970},
|
|
|
|
UserIDs: []int{},
|
|
|
|
IncludeCurrentUser: true,
|
|
|
|
},
|
|
|
|
Git: GitConfig{
|
2020-12-31 02:18:18 +00:00
|
|
|
CloneLocation: defaultCloneLocation,
|
|
|
|
Remote: "origin",
|
|
|
|
PullMethod: "http",
|
|
|
|
OnClone: "init",
|
|
|
|
AutoPull: false,
|
|
|
|
Depth: 0,
|
2022-03-03 22:47:36 +00:00
|
|
|
QueueSize: 200,
|
|
|
|
QueueWorkerCount: 5,
|
2020-12-30 23:00:37 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if configPath != "" {
|
|
|
|
f, err := os.Open(configPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open config file: %v", err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
d := yaml.NewDecoder(f)
|
|
|
|
if err := d.Decode(config); err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to parse config file: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeGitlabConfig(config *Config) (*gitlab.GitlabClientParam, error) {
|
|
|
|
// parse pull_method
|
|
|
|
if config.Git.PullMethod != gitlab.PullMethodHTTP && config.Git.PullMethod != gitlab.PullMethodSSH {
|
|
|
|
return nil, fmt.Errorf("pull_method must be either \"%v\" or \"%v\"", gitlab.PullMethodHTTP, gitlab.PullMethodSSH)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &gitlab.GitlabClientParam{
|
2021-03-24 02:18:48 +00:00
|
|
|
PullMethod: config.Git.PullMethod,
|
|
|
|
IncludeCurrentUser: config.Gitlab.IncludeCurrentUser && config.Gitlab.Token != "",
|
2020-12-30 23:00:37 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeGitConfig(config *Config) (*git.GitClientParam, error) {
|
|
|
|
// Parse the gilab url
|
|
|
|
parsedGitlabURL, err := url.Parse(config.Gitlab.URL)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse on_clone
|
2021-03-03 05:24:27 +00:00
|
|
|
cloneMethod := 0
|
|
|
|
if config.Git.OnClone == "init" {
|
|
|
|
cloneMethod = git.CloneInit
|
|
|
|
} else if config.Git.OnClone == "clone" {
|
|
|
|
cloneMethod = git.CloneClone
|
2020-12-30 23:00:37 +00:00
|
|
|
} else {
|
2021-03-03 05:24:27 +00:00
|
|
|
return nil, fmt.Errorf("on_clone must be either \"init\" or \"clone\"")
|
2020-12-30 23:00:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &git.GitClientParam{
|
2020-12-31 02:18:18 +00:00
|
|
|
CloneLocation: config.Git.CloneLocation,
|
|
|
|
RemoteName: config.Git.Remote,
|
|
|
|
RemoteURL: parsedGitlabURL,
|
2021-03-03 05:24:27 +00:00
|
|
|
CloneMethod: cloneMethod,
|
2020-12-31 02:18:18 +00:00
|
|
|
AutoPull: config.Git.AutoPull,
|
|
|
|
PullDepth: config.Git.Depth,
|
2022-03-03 22:47:36 +00:00
|
|
|
QueueSize: config.Git.QueueSize,
|
|
|
|
QueueWorkerCount: config.Git.QueueWorkerCount,
|
2020-12-30 23:00:37 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-12-26 19:36:09 +00:00
|
|
|
func main() {
|
2021-08-13 17:40:26 +00:00
|
|
|
configPath := flag.String("config", "", "The config file")
|
|
|
|
mountoptionsFlag := flag.String("o", "", "Filesystem mount options. See mount.fuse(8)")
|
|
|
|
debug := flag.Bool("debug", false, "Enable debug logging")
|
|
|
|
|
|
|
|
flag.Usage = func() {
|
|
|
|
fmt.Println("USAGE:")
|
|
|
|
fmt.Printf(" %s MOUNTPOINT\n\n", os.Args[0])
|
|
|
|
fmt.Println("OPTIONS:")
|
|
|
|
flag.PrintDefaults()
|
|
|
|
}
|
2020-12-27 03:30:19 +00:00
|
|
|
flag.Parse()
|
2020-12-30 23:00:37 +00:00
|
|
|
|
|
|
|
config, err := loadConfig(*configPath)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Configure mountpoint
|
|
|
|
mountpoint := config.FS.Mountpoint
|
|
|
|
if flag.NArg() == 1 {
|
|
|
|
mountpoint = flag.Arg(0)
|
|
|
|
}
|
|
|
|
if mountpoint == "" {
|
2021-08-13 17:40:26 +00:00
|
|
|
fmt.Println("Mountpoint is not configured in config file and missing from command-line arguments")
|
|
|
|
flag.Usage()
|
2020-12-27 07:23:00 +00:00
|
|
|
os.Exit(2)
|
2020-12-27 03:30:19 +00:00
|
|
|
}
|
2020-12-30 23:00:37 +00:00
|
|
|
|
2021-08-13 17:40:26 +00:00
|
|
|
// Configure mountoptions
|
|
|
|
mountoptions := config.FS.MountOptions
|
|
|
|
if *mountoptionsFlag != "" {
|
|
|
|
mountoptions = *mountoptionsFlag
|
|
|
|
}
|
|
|
|
parsedMountoptions := make([]string, 0)
|
|
|
|
if mountoptions != "" {
|
|
|
|
parsedMountoptions = strings.Split(mountoptions, ",")
|
|
|
|
}
|
|
|
|
|
2020-12-30 23:00:37 +00:00
|
|
|
// Create the git client
|
|
|
|
gitClientParam, err := makeGitConfig(config)
|
2020-12-29 02:37:18 +00:00
|
|
|
if err != nil {
|
2020-12-30 23:00:37 +00:00
|
|
|
fmt.Println(err)
|
2020-12-29 02:37:18 +00:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
2020-12-30 23:00:37 +00:00
|
|
|
gitClient, _ := git.NewClient(*gitClientParam)
|
2020-12-27 03:30:19 +00:00
|
|
|
|
2020-12-29 02:37:18 +00:00
|
|
|
// Create the gitlab client
|
2020-12-30 23:00:37 +00:00
|
|
|
gitlabClientParam, err := makeGitlabConfig(config)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
2020-12-29 02:37:18 +00:00
|
|
|
}
|
2020-12-30 23:00:37 +00:00
|
|
|
gitlabClient, _ := gitlab.NewClient(config.Gitlab.URL, config.Gitlab.Token, *gitlabClientParam)
|
2020-12-27 07:23:00 +00:00
|
|
|
|
2020-12-29 02:37:18 +00:00
|
|
|
// Start the filesystem
|
2021-03-03 05:25:49 +00:00
|
|
|
err = fs.Start(
|
2020-12-30 23:00:37 +00:00
|
|
|
mountpoint,
|
2021-08-13 17:40:26 +00:00
|
|
|
parsedMountoptions,
|
|
|
|
&fs.FSParam{Git: gitClient, Gitlab: gitlabClient, RootGroupIds: config.Gitlab.GroupIDs, UserIds: config.Gitlab.UserIDs},
|
2020-12-30 23:00:37 +00:00
|
|
|
*debug,
|
|
|
|
)
|
2021-03-03 05:25:49 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2020-12-26 19:36:09 +00:00
|
|
|
}
|