Compare commits
2 Commits
e26f0ae865
...
0a50158239
Author | SHA1 | Date |
---|---|---|
Massaki Archambault | 0a50158239 | |
Massaki Archambault | a4ed751abd |
|
@ -14,6 +14,12 @@ gitlab:
|
||||||
# Default to anonymous (only public projects will be visible).
|
# Default to anonymous (only public projects will be visible).
|
||||||
#token:
|
#token:
|
||||||
|
|
||||||
|
# Must be set to either "http" or "ssh".
|
||||||
|
# The protocol to configure the git remote on.
|
||||||
|
# "http" may not work on private repos unless a credential manager is configured
|
||||||
|
# If possible, prefer "ssh" over "http"
|
||||||
|
pull_method: http
|
||||||
|
|
||||||
# A list of the group ids to expose their projects in the filesystem.
|
# A list of the group ids to expose their projects in the filesystem.
|
||||||
group_ids:
|
group_ids:
|
||||||
- 9970 # gitlab-org
|
- 9970 # gitlab-org
|
||||||
|
@ -32,12 +38,6 @@ git:
|
||||||
# The name of the remote in the local clone.
|
# The name of the remote in the local clone.
|
||||||
remote: origin
|
remote: origin
|
||||||
|
|
||||||
# Must be set to either "http" or "ssh".
|
|
||||||
# The protocol to configure the git remote on.
|
|
||||||
# "http" may not work on private repos unless a credential manager is configured
|
|
||||||
# If possible, prefer "ssh" over "http"
|
|
||||||
pull_method: http
|
|
||||||
|
|
||||||
# Must be set to either "init", or "clone".
|
# Must be set to either "init", or "clone".
|
||||||
# If set to "init", the local copy will be initialized with `git init` and the remote is configured manually. The git server is nerver queried. (fast)
|
# If set to "init", the local copy will be initialized with `git init` and the remote is configured manually. The git server is nerver queried. (fast)
|
||||||
# If set to "clone", the local copy will be initialized with `git clone`. (slow)
|
# If set to "clone", the local copy will be initialized with `git clone`. (slow)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
fs:
|
||||||
|
mountpoint: /tmp/gitlabfs/test/mnt
|
||||||
|
mountoptions: nodev
|
||||||
|
|
||||||
|
gitlab:
|
||||||
|
url: https://example.com
|
||||||
|
token: "12345"
|
||||||
|
group_ids:
|
||||||
|
- 123
|
||||||
|
user_ids:
|
||||||
|
- 456
|
||||||
|
include_current_user: true
|
||||||
|
pull_method: ssh
|
||||||
|
|
||||||
|
git:
|
||||||
|
clone_location: /tmp/gitlabfs/test/clone
|
||||||
|
remote: origin
|
||||||
|
on_clone: clone
|
||||||
|
auto_pull: false
|
||||||
|
depth: 0
|
||||||
|
queue_size: 100
|
||||||
|
worker_count: 1
|
|
@ -0,0 +1,89 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/badjware/gitlabfs/git"
|
||||||
|
"github.com/badjware/gitlabfs/platforms/gitlab"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Config struct {
|
||||||
|
FS FSConfig `yaml:"fs,omitempty"`
|
||||||
|
Gitlab gitlab.GitlabClientConfig `yaml:"gitlab,omitempty"`
|
||||||
|
Git git.GitClientParam `yaml:"git,omitempty"`
|
||||||
|
}
|
||||||
|
FSConfig struct {
|
||||||
|
Mountpoint string `yaml:"mountpoint,omitempty"`
|
||||||
|
MountOptions string `yaml:"mountoptions,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
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{
|
||||||
|
Mountpoint: "",
|
||||||
|
MountOptions: "nodev,nosuid",
|
||||||
|
},
|
||||||
|
Gitlab: gitlab.GitlabClientConfig{
|
||||||
|
URL: "https://gitlab.com",
|
||||||
|
Token: "",
|
||||||
|
PullMethod: "http",
|
||||||
|
GroupIDs: []int{9970},
|
||||||
|
UserIDs: []int{},
|
||||||
|
IncludeCurrentUser: true,
|
||||||
|
},
|
||||||
|
Git: git.GitClientParam{
|
||||||
|
CloneLocation: defaultCloneLocation,
|
||||||
|
Remote: "origin",
|
||||||
|
OnClone: "init",
|
||||||
|
AutoPull: false,
|
||||||
|
Depth: 0,
|
||||||
|
QueueSize: 200,
|
||||||
|
QueueWorkerCount: 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
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 MakeGitConfig(config *Config) (*git.GitClientParam, error) {
|
||||||
|
// parse on_clone
|
||||||
|
if config.Git.OnClone != "init" && config.Git.OnClone != "clone" {
|
||||||
|
return nil, fmt.Errorf("on_clone must be either \"init\" or \"clone\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config.Git, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeGitlabConfig(config *Config) (*gitlab.GitlabClientConfig, error) {
|
||||||
|
// parse pull_method
|
||||||
|
if config.Gitlab.PullMethod != gitlab.PullMethodHTTP && config.Gitlab.PullMethod != gitlab.PullMethodSSH {
|
||||||
|
return nil, fmt.Errorf("pull_method must be either \"%v\" or \"%v\"", gitlab.PullMethodHTTP, gitlab.PullMethodSSH)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config.Gitlab, nil
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
package config_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/badjware/gitlabfs/config"
|
||||||
|
"github.com/badjware/gitlabfs/git"
|
||||||
|
"github.com/badjware/gitlabfs/platforms/gitlab"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoadConfig(t *testing.T) {
|
||||||
|
tests := map[string]struct {
|
||||||
|
input string
|
||||||
|
expected *config.Config
|
||||||
|
}{
|
||||||
|
"LoadConfig": {
|
||||||
|
input: "config.test.yaml",
|
||||||
|
expected: &config.Config{
|
||||||
|
FS: config.FSConfig{
|
||||||
|
Mountpoint: "/tmp/gitlabfs/test/mnt",
|
||||||
|
MountOptions: "nodev",
|
||||||
|
},
|
||||||
|
Gitlab: gitlab.GitlabClientConfig{
|
||||||
|
URL: "https://example.com",
|
||||||
|
Token: "12345",
|
||||||
|
PullMethod: "ssh",
|
||||||
|
GroupIDs: []int{123},
|
||||||
|
UserIDs: []int{456},
|
||||||
|
IncludeCurrentUser: true,
|
||||||
|
},
|
||||||
|
Git: git.GitClientParam{
|
||||||
|
CloneLocation: "/tmp/gitlabfs/test/clone",
|
||||||
|
Remote: "origin",
|
||||||
|
OnClone: "clone",
|
||||||
|
AutoPull: false,
|
||||||
|
Depth: 0,
|
||||||
|
QueueSize: 100,
|
||||||
|
QueueWorkerCount: 1,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
got, err := config.LoadConfig(test.input)
|
||||||
|
expected := test.expected
|
||||||
|
if !reflect.DeepEqual(got, expected) {
|
||||||
|
t.Fatalf("LoadConfig(%v) returned %v; expected %v; error: %v", test.input, got, expected, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMakeGitConfig(t *testing.T) {
|
||||||
|
tests := map[string]struct {
|
||||||
|
input *config.Config
|
||||||
|
expected *git.GitClientParam
|
||||||
|
}{
|
||||||
|
"ValidConfig": {
|
||||||
|
input: &config.Config{
|
||||||
|
Git: git.GitClientParam{
|
||||||
|
CloneLocation: "/tmp",
|
||||||
|
Remote: "origin",
|
||||||
|
OnClone: "init",
|
||||||
|
AutoPull: false,
|
||||||
|
Depth: 0,
|
||||||
|
QueueSize: 200,
|
||||||
|
QueueWorkerCount: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git.GitClientParam{
|
||||||
|
CloneLocation: "/tmp",
|
||||||
|
Remote: "origin",
|
||||||
|
OnClone: "init",
|
||||||
|
AutoPull: false,
|
||||||
|
Depth: 0,
|
||||||
|
QueueSize: 200,
|
||||||
|
QueueWorkerCount: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"InvalidOnClone": {
|
||||||
|
input: &config.Config{
|
||||||
|
Git: git.GitClientParam{
|
||||||
|
CloneLocation: "/tmp",
|
||||||
|
Remote: "origin",
|
||||||
|
OnClone: "invalid",
|
||||||
|
AutoPull: false,
|
||||||
|
Depth: 0,
|
||||||
|
QueueSize: 200,
|
||||||
|
QueueWorkerCount: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
got, err := config.MakeGitConfig(test.input)
|
||||||
|
expected := test.expected
|
||||||
|
if !reflect.DeepEqual(got, expected) {
|
||||||
|
t.Fatalf("MakeGitConfig(%v) returned %v; expected %v; error %v", test.input, got, expected, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMakeGitlabConfig(t *testing.T) {
|
||||||
|
tests := map[string]struct {
|
||||||
|
input *config.Config
|
||||||
|
expected *gitlab.GitlabClientConfig
|
||||||
|
}{
|
||||||
|
"ValidConfig": {
|
||||||
|
input: &config.Config{
|
||||||
|
Gitlab: gitlab.GitlabClientConfig{
|
||||||
|
URL: "https://gitlab.com",
|
||||||
|
Token: "",
|
||||||
|
GroupIDs: []int{9970},
|
||||||
|
UserIDs: []int{},
|
||||||
|
IncludeCurrentUser: true,
|
||||||
|
PullMethod: "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &gitlab.GitlabClientConfig{
|
||||||
|
URL: "https://gitlab.com",
|
||||||
|
Token: "",
|
||||||
|
GroupIDs: []int{9970},
|
||||||
|
UserIDs: []int{},
|
||||||
|
IncludeCurrentUser: true,
|
||||||
|
PullMethod: "http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"InvalidPullMethod": {
|
||||||
|
input: &config.Config{
|
||||||
|
Gitlab: gitlab.GitlabClientConfig{
|
||||||
|
URL: "https://gitlab.com",
|
||||||
|
Token: "",
|
||||||
|
GroupIDs: []int{9970},
|
||||||
|
UserIDs: []int{},
|
||||||
|
IncludeCurrentUser: true,
|
||||||
|
PullMethod: "invalid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
got, err := config.MakeGitlabConfig(test.input)
|
||||||
|
expected := test.expected
|
||||||
|
if !reflect.DeepEqual(got, expected) {
|
||||||
|
t.Fatalf("MakeGitlabConfig(%v) returned %v; expected %v; error: %v", test.input, got, expected, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
93
main.go
93
main.go
|
@ -5,93 +5,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/badjware/gitlabfs/config"
|
||||||
"github.com/badjware/gitlabfs/fstree"
|
"github.com/badjware/gitlabfs/fstree"
|
||||||
"github.com/badjware/gitlabfs/git"
|
"github.com/badjware/gitlabfs/git"
|
||||||
"github.com/badjware/gitlabfs/platforms/gitlab"
|
"github.com/badjware/gitlabfs/platforms/gitlab"
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
Config struct {
|
|
||||||
FS FSConfig `yaml:"fs,omitempty"`
|
|
||||||
Gitlab gitlab.GitlabClientConfig `yaml:"gitlab,omitempty"`
|
|
||||||
Git git.GitClientParam `yaml:"git,omitempty"`
|
|
||||||
}
|
|
||||||
FSConfig struct {
|
|
||||||
Mountpoint string `yaml:"mountpoint,omitempty"`
|
|
||||||
MountOptions string `yaml:"mountoptions,omitempty"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
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{
|
|
||||||
Mountpoint: "",
|
|
||||||
MountOptions: "nodev,nosuid",
|
|
||||||
},
|
|
||||||
Gitlab: gitlab.GitlabClientConfig{
|
|
||||||
URL: "https://gitlab.com",
|
|
||||||
Token: "",
|
|
||||||
GroupIDs: []int{9970},
|
|
||||||
UserIDs: []int{},
|
|
||||||
IncludeCurrentUser: true,
|
|
||||||
PullMethod: "http",
|
|
||||||
},
|
|
||||||
Git: git.GitClientParam{
|
|
||||||
CloneLocation: defaultCloneLocation,
|
|
||||||
Remote: "origin",
|
|
||||||
OnClone: "init",
|
|
||||||
AutoPull: false,
|
|
||||||
Depth: 0,
|
|
||||||
QueueSize: 200,
|
|
||||||
QueueWorkerCount: 5,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
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.GitlabClientConfig, error) {
|
|
||||||
// parse pull_method
|
|
||||||
if config.Gitlab.PullMethod != gitlab.PullMethodHTTP && config.Gitlab.PullMethod != gitlab.PullMethodSSH {
|
|
||||||
return nil, fmt.Errorf("pull_method must be either \"%v\" or \"%v\"", gitlab.PullMethodHTTP, gitlab.PullMethodSSH)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &config.Gitlab, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeGitConfig(config *Config) (*git.GitClientParam, error) {
|
|
||||||
// parse on_clone
|
|
||||||
if config.Git.OnClone != "init" && config.Git.OnClone != "clone" {
|
|
||||||
return nil, fmt.Errorf("on_clone must be either \"init\" or \"clone\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &config.Git, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
configPath := flag.String("config", "", "The config file")
|
configPath := flag.String("config", "", "The config file")
|
||||||
mountoptionsFlag := flag.String("o", "", "Filesystem mount options. See mount.fuse(8)")
|
mountoptionsFlag := flag.String("o", "", "Filesystem mount options. See mount.fuse(8)")
|
||||||
|
@ -105,7 +26,7 @@ func main() {
|
||||||
}
|
}
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
config, err := loadConfig(*configPath)
|
loadedConfig, err := config.LoadConfig(*configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -115,7 +36,7 @@ func main() {
|
||||||
logger := slog.Default()
|
logger := slog.Default()
|
||||||
|
|
||||||
// Configure mountpoint
|
// Configure mountpoint
|
||||||
mountpoint := config.FS.Mountpoint
|
mountpoint := loadedConfig.FS.Mountpoint
|
||||||
if flag.NArg() == 1 {
|
if flag.NArg() == 1 {
|
||||||
mountpoint = flag.Arg(0)
|
mountpoint = flag.Arg(0)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +47,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure mountoptions
|
// Configure mountoptions
|
||||||
mountoptions := config.FS.MountOptions
|
mountoptions := loadedConfig.FS.MountOptions
|
||||||
if *mountoptionsFlag != "" {
|
if *mountoptionsFlag != "" {
|
||||||
mountoptions = *mountoptionsFlag
|
mountoptions = *mountoptionsFlag
|
||||||
}
|
}
|
||||||
|
@ -136,7 +57,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the git client
|
// Create the git client
|
||||||
gitClientParam, err := makeGitConfig(config)
|
gitClientParam, err := config.MakeGitConfig(loadedConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -144,12 +65,12 @@ func main() {
|
||||||
gitClient, _ := git.NewClient(logger, *gitClientParam)
|
gitClient, _ := git.NewClient(logger, *gitClientParam)
|
||||||
|
|
||||||
// Create the gitlab client
|
// Create the gitlab client
|
||||||
GitlabClientConfig, err := makeGitlabConfig(config)
|
GitlabClientConfig, err := config.MakeGitlabConfig(loadedConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
gitlabClient, _ := gitlab.NewClient(logger, config.Gitlab.URL, config.Gitlab.Token, *GitlabClientConfig)
|
gitlabClient, _ := gitlab.NewClient(logger, loadedConfig.Gitlab.URL, loadedConfig.Gitlab.Token, *GitlabClientConfig)
|
||||||
|
|
||||||
// Start the filesystem
|
// Start the filesystem
|
||||||
err = fstree.Start(
|
err = fstree.Start(
|
||||||
|
|
Loading…
Reference in New Issue