prepare fs for eventual inclusion of user repos
This commit is contained in:
parent
2063df8920
commit
4aca123c98
|
@ -1,28 +0,0 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/badjware/gitlabfs/git"
|
||||
"github.com/badjware/gitlabfs/gitlab"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
)
|
||||
|
||||
func Start(gf gitlab.GroupFetcher, gp git.GitClonerPuller, mountpoint string, rootGrouptID int) error {
|
||||
fmt.Printf("Mounting in %v\n", mountpoint)
|
||||
|
||||
opts := &fs.Options{}
|
||||
opts.Debug = true
|
||||
root, err := newRootGroupNode(gf, gp, rootGrouptID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("root group fetch fail: %v", err)
|
||||
}
|
||||
server, err := fs.Mount(mountpoint, root, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("mount failed: %v", err)
|
||||
}
|
||||
server.Wait()
|
||||
|
||||
return nil
|
||||
}
|
25
fs/group.go
25
fs/group.go
|
@ -4,8 +4,6 @@ import (
|
|||
"context"
|
||||
"syscall"
|
||||
|
||||
"github.com/badjware/gitlabfs/git"
|
||||
|
||||
"github.com/badjware/gitlabfs/gitlab"
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
|
@ -13,9 +11,8 @@ import (
|
|||
|
||||
type groupNode struct {
|
||||
fs.Inode
|
||||
param *FSParam
|
||||
group *gitlab.Group
|
||||
gf gitlab.GroupFetcher
|
||||
gcp git.GitClonerPuller
|
||||
}
|
||||
|
||||
// Ensure we are implementing the NodeReaddirer interface
|
||||
|
@ -24,30 +21,28 @@ var _ = (fs.NodeReaddirer)((*groupNode)(nil))
|
|||
// Ensure we are implementing the NodeLookuper interface
|
||||
var _ = (fs.NodeLookuper)((*groupNode)(nil))
|
||||
|
||||
func newRootGroupNode(gf gitlab.GroupFetcher, gcp git.GitClonerPuller, gid int) (*groupNode, error) {
|
||||
group, err := gf.FetchGroup(gid)
|
||||
func newRootGroupNode(gid int, param *FSParam) (*groupNode, error) {
|
||||
group, err := param.Gf.FetchGroup(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node := &groupNode{
|
||||
param: param,
|
||||
group: group,
|
||||
gf: gf,
|
||||
gcp: gcp,
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func newGroupNode(gf gitlab.GroupFetcher, gcp git.GitClonerPuller, group *gitlab.Group) (*groupNode, error) {
|
||||
func newGroupNode(group *gitlab.Group, param *FSParam) (*groupNode, error) {
|
||||
node := &groupNode{
|
||||
param: param,
|
||||
group: group,
|
||||
gf: gf,
|
||||
gcp: gcp,
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
|
||||
groupContent, _ := n.gf.FetchGroupContent(n.group)
|
||||
groupContent, _ := n.param.Gf.FetchGroupContent(n.group)
|
||||
entries := make([]fuse.DirEntry, 0, len(groupContent.Groups)+len(groupContent.Repositories))
|
||||
for _, group := range groupContent.Groups {
|
||||
entries = append(entries, fuse.DirEntry{
|
||||
|
@ -67,7 +62,7 @@ func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
|
|||
}
|
||||
|
||||
func (n *groupNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
|
||||
groupContent, _ := n.gf.FetchGroupContent(n.group)
|
||||
groupContent, _ := n.param.Gf.FetchGroupContent(n.group)
|
||||
|
||||
// Check if the map of groups contains it
|
||||
group, ok := groupContent.Groups[name]
|
||||
|
@ -76,7 +71,7 @@ func (n *groupNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut)
|
|||
Ino: uint64(group.ID),
|
||||
Mode: fuse.S_IFDIR,
|
||||
}
|
||||
groupNode, _ := newGroupNode(n.gf, n.gcp, group)
|
||||
groupNode, _ := newGroupNode(group, n.param)
|
||||
return n.NewInode(ctx, groupNode, attrs), 0
|
||||
}
|
||||
|
||||
|
@ -87,7 +82,7 @@ func (n *groupNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut)
|
|||
Ino: uint64(repository.ID),
|
||||
Mode: fuse.S_IFLNK,
|
||||
}
|
||||
repositoryNode, _ := newRepositoryNode(n.gcp, repository)
|
||||
repositoryNode, _ := newRepositoryNode(repository, n.param)
|
||||
return n.NewInode(ctx, repositoryNode, attrs), 0
|
||||
}
|
||||
return nil, syscall.ENOENT
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
type projectsNode struct {
|
||||
fs.Inode
|
||||
param *FSParam
|
||||
|
||||
rootGroupIds []int
|
||||
}
|
||||
|
||||
// Ensure we are implementing the NodeOnAdder interface
|
||||
var _ = (fs.NodeOnAdder)((*projectsNode)(nil))
|
||||
|
||||
func NewProjectsNode(rootGroupIds []int, param *FSParam) *projectsNode {
|
||||
return &projectsNode{
|
||||
param: param,
|
||||
rootGroupIds: rootGroupIds,
|
||||
}
|
||||
}
|
||||
|
||||
func (n *projectsNode) OnAdd(ctx context.Context) {
|
||||
for _, groupID := range n.rootGroupIds {
|
||||
groupNode, err := newRootGroupNode(groupID, n.param)
|
||||
if err != nil {
|
||||
fmt.Printf("root group fetch fail: %v\n", err)
|
||||
}
|
||||
inode := n.NewPersistentInode(
|
||||
ctx,
|
||||
groupNode,
|
||||
fs.StableAttr{
|
||||
Ino: <-n.param.staticInoChan,
|
||||
Mode: fuse.S_IFDIR,
|
||||
},
|
||||
)
|
||||
n.AddChild(groupNode.group.Path, inode, false)
|
||||
}
|
||||
}
|
|
@ -4,26 +4,24 @@ import (
|
|||
"context"
|
||||
"syscall"
|
||||
|
||||
"github.com/badjware/gitlabfs/git"
|
||||
"github.com/badjware/gitlabfs/gitlab"
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
)
|
||||
|
||||
type RepositoryNode struct {
|
||||
fs.Inode
|
||||
param *FSParam
|
||||
repository *gitlab.Repository
|
||||
|
||||
gcp git.GitClonerPuller
|
||||
}
|
||||
|
||||
// Ensure we are implementing the NodeReaddirer interface
|
||||
var _ = (fs.NodeReadlinker)((*RepositoryNode)(nil))
|
||||
|
||||
func newRepositoryNode(gcp git.GitClonerPuller, repository *gitlab.Repository) (*RepositoryNode, error) {
|
||||
func newRepositoryNode(repository *gitlab.Repository, param *FSParam) (*RepositoryNode, error) {
|
||||
|
||||
node := &RepositoryNode{
|
||||
param: param,
|
||||
repository: repository,
|
||||
gcp: gcp,
|
||||
}
|
||||
// Passthrough the error if there is one, nothing to add here
|
||||
// Errors on clone/pull are non-fatal
|
||||
|
@ -32,7 +30,7 @@ func newRepositoryNode(gcp git.GitClonerPuller, repository *gitlab.Repository) (
|
|||
|
||||
func (n *RepositoryNode) Readlink(ctx context.Context) ([]byte, syscall.Errno) {
|
||||
// Create the local copy of the repo
|
||||
localRepoLoc, _ := n.gcp.CloneOrPull(n.repository.CloneURL, n.repository.ID, "master")
|
||||
localRepoLoc, _ := n.param.Gcp.CloneOrPull(n.repository.CloneURL, n.repository.ID, "master")
|
||||
|
||||
return []byte(localRepoLoc), 0
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/badjware/gitlabfs/git"
|
||||
"github.com/badjware/gitlabfs/gitlab"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
const (
|
||||
staticInodeStart = uint64(int(^(uint(0))>>1)) + 1
|
||||
)
|
||||
|
||||
type FSParam struct {
|
||||
Gf gitlab.GroupFetcher
|
||||
Gcp git.GitClonerPuller
|
||||
|
||||
staticInoChan chan uint64
|
||||
}
|
||||
|
||||
type rootNode struct {
|
||||
fs.Inode
|
||||
param *FSParam
|
||||
rootGroupIds []int
|
||||
userIds []int
|
||||
}
|
||||
|
||||
var _ = (fs.NodeOnAdder)((*rootNode)(nil))
|
||||
|
||||
func (n *rootNode) OnAdd(ctx context.Context) {
|
||||
projectsInode := n.NewPersistentInode(
|
||||
ctx,
|
||||
NewProjectsNode(
|
||||
n.rootGroupIds,
|
||||
n.param,
|
||||
),
|
||||
fs.StableAttr{
|
||||
Ino: <-n.param.staticInoChan,
|
||||
Mode: fuse.S_IFDIR,
|
||||
},
|
||||
)
|
||||
n.AddChild("projects", projectsInode, false)
|
||||
|
||||
usersInode := n.NewPersistentInode(
|
||||
ctx,
|
||||
NewUsersNode(
|
||||
n.userIds,
|
||||
n.param,
|
||||
),
|
||||
fs.StableAttr{
|
||||
Ino: <-n.param.staticInoChan,
|
||||
Mode: fuse.S_IFDIR,
|
||||
},
|
||||
)
|
||||
n.AddChild("users", usersInode, false)
|
||||
}
|
||||
|
||||
func Start(mountpoint string, rootGroupIds []int, userIds []int, param *FSParam) error {
|
||||
fmt.Printf("Mounting in %v\n", mountpoint)
|
||||
|
||||
opts := &fs.Options{}
|
||||
opts.Debug = true
|
||||
|
||||
param.staticInoChan = make(chan uint64)
|
||||
root := &rootNode{
|
||||
param: param,
|
||||
rootGroupIds: rootGroupIds,
|
||||
userIds: userIds,
|
||||
}
|
||||
|
||||
go staticInoGenerator(root.param.staticInoChan)
|
||||
|
||||
server, err := fs.Mount(mountpoint, root, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("mount failed: %v", err)
|
||||
}
|
||||
server.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func staticInoGenerator(staticInoChan chan<- uint64) {
|
||||
i := staticInodeStart
|
||||
for {
|
||||
staticInoChan <- i
|
||||
i++
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fs"
|
||||
)
|
||||
|
||||
type usersNode struct {
|
||||
fs.Inode
|
||||
param *FSParam
|
||||
|
||||
userIds []int
|
||||
}
|
||||
|
||||
// Ensure we are implementing the NodeOnAdder interface
|
||||
var _ = (fs.NodeOnAdder)((*usersNode)(nil))
|
||||
|
||||
func NewUsersNode(userIds []int, param *FSParam) *usersNode {
|
||||
return &usersNode{
|
||||
param: param,
|
||||
userIds: userIds,
|
||||
}
|
||||
}
|
||||
|
||||
func (n *usersNode) OnAdd(ctx context.Context) {
|
||||
// for _, userId := range n.userIds {
|
||||
// userNode, err := newRootUserNode(userId, n.param)
|
||||
// if err != nil {
|
||||
// fmt.Printf("user fetch fail: %v\n", err)
|
||||
// }
|
||||
// inode := n.NewPersistentInode(
|
||||
// ctx,
|
||||
// userNode,
|
||||
// fs.StableAttr{
|
||||
// Ino: <-n.param.staticInoChan,
|
||||
// Mode: fuse.S_IFDIR,
|
||||
// },
|
||||
// )
|
||||
// n.AddChild(userNode.user.Path, inode, false)
|
||||
// }
|
||||
}
|
|
@ -127,5 +127,6 @@ func (c *gitClient) pull(gpp *gitClonePullParam) error {
|
|||
// Check if the local repo is on default branch
|
||||
// Check if the local repo is dirty
|
||||
// Checkout the remote default branch
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue