Skip to content

Commit 83f522e

Browse files
author
JojiiOfficial
committed
add create folder -> creates namespace
improve ns trimming
1 parent 87586cd commit 83f522e

File tree

6 files changed

+152
-41
lines changed

6 files changed

+152
-41
lines changed

dmfs/data.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dmfs
33
import (
44
"fmt"
55
"os"
6+
"strings"
67
"time"
78

89
"github.com/DataManager-Go/libdatamanager"
@@ -40,6 +41,7 @@ func (data *dataStruct) loadUserAttributes() error {
4041
var err error
4142
data.userAttributes, err = data.libdm.GetUserAttributeData()
4243
if err != nil {
44+
printResponseError(err, "loading user attributes")
4345
return err
4446
}
4547

@@ -53,3 +55,21 @@ func (data *dataStruct) setUserAttr(inAttr *fuse.AttrOut) {
5355
inAttr.Gid = data.gid
5456
inAttr.Uid = data.uid
5557
}
58+
59+
func (data *dataStruct) trimmedNS(ns string) string {
60+
userPrefix := data.libdm.Config.Username + "_"
61+
if !strings.HasPrefix(ns, userPrefix) {
62+
return ns
63+
}
64+
65+
return ns[len(userPrefix):]
66+
}
67+
68+
func (data *dataStruct) fullNS(ns string) string {
69+
userPrefix := data.libdm.Config.Username + "_"
70+
if strings.HasPrefix(ns, userPrefix) {
71+
return ns
72+
}
73+
74+
return userPrefix + ns
75+
}

dmfs/dmfs_test.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,34 @@ const (
1111
defaultNsTimmed = "default"
1212
)
1313

14-
var (
15-
cfg = libdatamanager.RequestConfig{Username: "jojii"}
16-
)
14+
func TestFullNS(t *testing.T) {
15+
// Build pseudo config
16+
data := dataStruct{
17+
libdm: &libdatamanager.LibDM{
18+
Config: &libdatamanager.RequestConfig{
19+
Username: "jojii",
20+
},
21+
},
22+
}
1723

18-
func TestAddNSName(t *testing.T) {
19-
newNsName := addNsName(defaultNsTimmed, &cfg)
24+
newNsName := data.fullNS(defaultNsFull)
2025

2126
if newNsName != defaultNsFull {
2227
t.Errorf("Expected %s but got %s", defaultNsFull, newNsName)
2328
}
2429
}
2530

26-
func TestRemoveNSName(t *testing.T) {
27-
newNsName := removeNsName(defaultNsFull)
31+
func TestTrimmedNS(t *testing.T) {
32+
// Build pseudo config
33+
data := dataStruct{
34+
libdm: &libdatamanager.LibDM{
35+
Config: &libdatamanager.RequestConfig{
36+
Username: "jojii",
37+
},
38+
},
39+
}
40+
41+
newNsName := data.trimmedNS(defaultNsFull)
2842

2943
if newNsName != defaultNsTimmed {
3044
t.Errorf("Expected %s but got %s", defaultNsTimmed, newNsName)

dmfs/fsGroup.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@ package dmfs
22

33
import (
44
"context"
5-
"fmt"
65
"syscall"
76

87
"github.com/DataManager-Go/libdatamanager"
98
"github.com/hanwen/go-fuse/v2/fs"
109
)
1110

11+
const (
12+
// NoGroupFolder foldername for
13+
// files without groups
14+
NoGroupFolder = "no_group"
15+
)
16+
17+
var (
18+
_ = (fs.NodeOnAdder)((*groupInode)(nil))
19+
)
20+
1221
type groupInode struct {
1322
fs.Inode
1423

@@ -17,14 +26,12 @@ type groupInode struct {
1726
isNoGroupPlaceholder bool
1827
}
1928

20-
var _ = (fs.NodeOnAdder)((*groupInode)(nil))
21-
2229
// List files
2330
func (groupInode *groupInode) OnAdd(ctx context.Context) {
24-
fmt.Println("add group")
2531
groupAdd := []string{groupInode.group}
2632

27-
if len(groupAdd) == 1 && groupAdd[0] == "no_group" {
33+
// Check if group is no_group
34+
if len(groupAdd) == 1 && groupAdd[0] == NoGroupFolder {
2835
groupInode.isNoGroupPlaceholder = true
2936
groupAdd = []string{}
3037
}
@@ -35,7 +42,7 @@ func (groupInode *groupInode) OnAdd(ctx context.Context) {
3542
}, 0)
3643

3744
if err != nil {
38-
fmt.Println(err)
45+
printResponseError(err, "getting files for "+groupInode.group)
3946
return
4047
}
4148

dmfs/fsNamespace.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ package dmfs
22

33
import (
44
"context"
5-
"fmt"
65
"syscall"
7-
"time"
86

97
libdm "github.com/DataManager-Go/libdatamanager"
108
"github.com/hanwen/go-fuse/v2/fs"
@@ -31,6 +29,7 @@ var (
3129
_ = (fs.NodeLookuper)((*namespaceNode)(nil))
3230
)
3331

32+
// Create a new ns node from nsInfo
3433
func newNamespaceNode(nsInfo libdm.Namespaceinfo) *namespaceNode {
3534
return &namespaceNode{
3635
nsInfo: nsInfo,
@@ -82,7 +81,7 @@ func (nsNode *namespaceNode) Lookup(ctx context.Context, name string, out *fuse.
8281
if child == nil {
8382
v := &groupInode{
8483
group: name,
85-
isNoGroupPlaceholder: name == "no_group",
84+
isNoGroupPlaceholder: name == NoGroupFolder,
8685
namespace: nsNode.nsInfo.Name,
8786
}
8887

@@ -96,17 +95,14 @@ func (nsNode *namespaceNode) Lookup(ctx context.Context, name string, out *fuse.
9695

9796
// Delete group if vfile was removed
9897
func (nsNode *namespaceNode) Rmdir(ctx context.Context, name string) syscall.Errno {
99-
// wait 2 seconds to ensure, user didn't cancel
100-
select {
101-
case <-ctx.Done():
102-
return syscall.ECANCELED
103-
case <-time.After(2 * time.Second):
98+
if name == NoGroupFolder {
99+
return 0
104100
}
105101

106102
// Do http delete request
107103
_, err := data.libdm.DeleteAttribute(libdm.GroupAttribute, nsNode.nsInfo.Name, name)
108104
if err != nil {
109-
fmt.Println(err)
105+
printResponseError(err, "rm group dir")
110106
return syscall.ENOENT
111107
}
112108

@@ -115,14 +111,15 @@ func (nsNode *namespaceNode) Rmdir(ctx context.Context, name string) syscall.Err
115111

116112
// On group renamed
117113
func (nsNode *namespaceNode) Rename(ctx context.Context, name string, newParent fs.InodeEmbedder, newName string, flags uint32) syscall.Errno {
118-
if name == "no_group" {
114+
if name == NoGroupFolder {
119115
// TODO add groups to files with no group
120116
return 0
121117
}
122118

123119
// Rename group request
124120
_, err := data.libdm.UpdateAttribute(libdm.GroupAttribute, nsNode.nsInfo.Name, name, newName)
125121
if err != nil {
122+
printResponseError(err, "Updating group")
126123
return syscall.ENOENT
127124
}
128125

dmfs/fsRoot.go

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"syscall"
88
"time"
99

10+
"github.com/DataManager-Go/libdatamanager"
1011
"github.com/hanwen/go-fuse/v2/fs"
1112
"github.com/hanwen/go-fuse/v2/fuse"
1213
"github.com/pkg/errors"
@@ -34,6 +35,7 @@ var (
3435
_ = (fs.NodeRmdirer)((*rootNode)(nil))
3536
_ = (fs.NodeLookuper)((*rootNode)(nil))
3637
_ = (fs.NodeGetattrer)((*rootNode)(nil))
38+
_ = (fs.NodeMkdirer)((*rootNode)(nil))
3739
)
3840

3941
var (
@@ -94,7 +96,7 @@ func (root *rootNode) load(nsCB func(name string)) error {
9496

9597
// Loop Namespaces and add childs in as folders
9698
for _, namespace := range data.userAttributes.Namespace {
97-
nsName := removeNsName(namespace.Name)
99+
nsName := data.trimmedNS(namespace.Name)
98100

99101
// Find namespace node
100102
v, has := root.nsNodes[nsName]
@@ -137,7 +139,12 @@ func (root *rootNode) Lookup(ctx context.Context, name string, out *fuse.EntryOu
137139

138140
// Delete Namespace if virtual file was unlinked
139141
func (root *rootNode) Rmdir(ctx context.Context, name string) syscall.Errno {
140-
namespace := addNsName(name, data.libdm.Config)
142+
// Throw error if not exists
143+
if _, exists := root.nsNodes[data.trimmedNS(name)]; !exists {
144+
return syscall.ENOENT
145+
}
146+
147+
namespace := data.fullNS(name)
141148

142149
// wait 2 seconds to ensure, user didn't cancel
143150
select {
@@ -146,9 +153,19 @@ func (root *rootNode) Rmdir(ctx context.Context, name string) syscall.Errno {
146153
case <-time.After(2 * time.Second):
147154
}
148155

156+
defer func() {
157+
delete(root.nsNodes, data.trimmedNS(namespace))
158+
child := root.GetChild(name)
159+
if child != nil {
160+
child.RmAllChildren()
161+
child.ForgetPersistent()
162+
root.RmChild(name)
163+
}
164+
}()
165+
149166
// Do delete request
150167
if _, err := data.libdm.DeleteNamespace(namespace); err != nil {
151-
fmt.Println(err)
168+
printResponseError(err, "rm namespace dir")
152169
return syscall.EFAULT
153170
}
154171

@@ -160,25 +177,60 @@ func (root *rootNode) Rename(ctx context.Context, name string, newParent fs.Inod
160177
// Don't rename default ns
161178
if name == "default" {
162179
fmt.Println("Can't rename default namespace!")
163-
return syscall.EIO
180+
return syscall.EPERM
164181
}
165182

166183
// Get real namespace names
167-
oldNSName := addNsName(name, data.libdm.Config)
168-
newNSName := addNsName(newName, data.libdm.Config)
184+
oldNSName := data.fullNS(name)
185+
newNSName := data.fullNS(newName)
169186
root.debug("rename namespace", oldNSName, "->", newNSName)
170187

171188
// Make rename request
172189
_, err := data.libdm.UpdateNamespace(oldNSName, newNSName)
173190
if err != nil {
174-
fmt.Println(err)
191+
printResponseError(err, "rename ns dir")
175192
return syscall.EIO
176193
}
177194

178195
// Return success
179196
return 0
180197
}
181198

199+
func (root *rootNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
200+
// Check if created namespace already exists
201+
_, h := root.nsNodes[name]
202+
if h {
203+
return nil, syscall.EEXIST
204+
}
205+
206+
nsName := data.fullNS(name)
207+
208+
// make create request
209+
_, err := data.libdm.CreateNamespace(nsName)
210+
if err != nil {
211+
printResponseError(err, "create ns dir")
212+
return nil, syscall.EIO
213+
}
214+
215+
nsNode := newNamespaceNode(libdatamanager.Namespaceinfo{
216+
Name: nsName,
217+
Groups: []string{NoGroupFolder},
218+
})
219+
root.nsNodes[nsName] = nsNode
220+
data.userAttributes.Namespace = append(data.userAttributes.Namespace, nsNode.nsInfo)
221+
222+
go (func() {
223+
time.Sleep(250 * time.Millisecond)
224+
root.load(nil)
225+
})()
226+
227+
node := root.NewInode(ctx, nsNode, fs.StableAttr{
228+
Mode: syscall.S_IFDIR,
229+
})
230+
231+
return node, 0
232+
}
233+
182234
// Set attributes for files
183235
func (root *rootNode) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
184236
// Set owner/group

dmfs/utils.go

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,45 @@
11
package dmfs
22

33
import (
4-
"strings"
4+
"fmt"
55

66
libdm "github.com/DataManager-Go/libdatamanager"
77
)
88

9-
func removeNsName(ns string) string {
10-
if !strings.Contains(ns, "_") {
11-
return ns
9+
// Print an response error for normies
10+
func printResponseError(err error, msg string) {
11+
if err == nil {
12+
return
1213
}
1314

14-
return ns[strings.Index(ns, "_")+1:]
15-
}
15+
switch err.(type) {
16+
case *libdm.ResponseErr:
17+
lrerr := err.(*libdm.ResponseErr)
18+
19+
var cause string
20+
21+
if lrerr.Response != nil {
22+
cause = lrerr.Response.Message
23+
} else if lrerr.Err != nil {
24+
cause = lrerr.Err.Error()
25+
} else {
26+
cause = lrerr.Error()
27+
}
1628

17-
func addNsName(ns string, libdm *libdm.RequestConfig) string {
18-
userPrefix := libdm.Username + "_"
19-
if strings.HasPrefix(ns, userPrefix) {
20-
return ns
29+
printError(msg, cause)
30+
default:
31+
if err != nil {
32+
printError(msg, err.Error())
33+
} else {
34+
printError(msg, "no error provided")
35+
}
2136
}
37+
}
38+
39+
func printError(message interface{}, err string) {
40+
fmt.Println(getError(message, err))
41+
}
2242

23-
return userPrefix + ns
43+
func getError(message interface{}, err string) string {
44+
return fmt.Sprintf("Error %s: %s\n", message, err)
2445
}

0 commit comments

Comments
 (0)