Commit 9f60272a authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

AutoUnionFs: allow manual configuration by symlinking inside the

config/ directory.
parent 4f3be4ed
...@@ -56,13 +56,16 @@ func (me *AutoUnionFs) Mount(connector *fuse.FileSystemConnector) fuse.Status { ...@@ -56,13 +56,16 @@ func (me *AutoUnionFs) Mount(connector *fuse.FileSystemConnector) fuse.Status {
return fuse.OK return fuse.OK
} }
func (me *AutoUnionFs) addFs(roots []string) { func (me *AutoUnionFs) addAutomaticFs(roots []string) {
relative := strings.TrimLeft(strings.Replace(roots[0], me.root, "", -1), "/") relative := strings.TrimLeft(strings.Replace(roots[0], me.root, "", -1), "/")
name := strings.Replace(relative, "/", "-", -1) name := strings.Replace(relative, "/", "-", -1)
me.addFs(name, roots)
}
func (me *AutoUnionFs) addFs(name string, roots []string) bool {
if name == _CONFIG || name == _STATUS { if name == _CONFIG || name == _STATUS {
log.Println("Illegal name for overlay", roots) log.Println("Illegal name for overlay", roots)
return return false
} }
me.lock.Lock() me.lock.Lock()
...@@ -77,18 +80,28 @@ func (me *AutoUnionFs) addFs(roots []string) { ...@@ -77,18 +80,28 @@ func (me *AutoUnionFs) addFs(roots []string) {
if gofs != nil { if gofs != nil {
me.connector.Mount("/"+name, gofs, &me.options.MountOptions) me.connector.Mount("/"+name, gofs, &me.options.MountOptions)
} }
return true
} }
// TODO - should hide these methods. // TODO - should hide these methods.
func (me *AutoUnionFs) VisitDir(path string, f *os.FileInfo) bool { func (me *AutoUnionFs) VisitDir(path string, f *os.FileInfo) bool {
roots := me.getRoots(path)
if roots != nil {
me.addAutomaticFs(roots)
}
return true
}
func (me *AutoUnionFs) getRoots(path string) []string {
ro := filepath.Join(path, _READONLY) ro := filepath.Join(path, _READONLY)
fi, err := os.Lstat(ro) fi, err := os.Lstat(ro)
if err == nil && fi.IsSymlink() { fiDir, errDir := os.Stat(ro)
if err == nil && errDir == nil && fi.IsSymlink() && fiDir.IsDirectory() {
// TODO - should recurse and chain all READONLYs // TODO - should recurse and chain all READONLYs
// together. // together.
me.addFs([]string{path, ro}) return []string{path, ro}
} }
return true return nil
} }
func (me *AutoUnionFs) VisitFile(path string, f *os.FileInfo) { func (me *AutoUnionFs) VisitFile(path string, f *os.FileInfo) {
...@@ -98,6 +111,7 @@ func (me *AutoUnionFs) VisitFile(path string, f *os.FileInfo) { ...@@ -98,6 +111,7 @@ func (me *AutoUnionFs) VisitFile(path string, f *os.FileInfo) {
func (me *AutoUnionFs) updateKnownFses() { func (me *AutoUnionFs) updateKnownFses() {
log.Println("Looking for new filesystems") log.Println("Looking for new filesystems")
filepath.Walk(me.root, me, nil) filepath.Walk(me.root, me, nil)
log.Println("Done looking")
} }
func (me *AutoUnionFs) Readlink(path string) (out string, code fuse.Status) { func (me *AutoUnionFs) Readlink(path string) (out string, code fuse.Status) {
...@@ -119,6 +133,34 @@ func (me *AutoUnionFs) Readlink(path string) (out string, code fuse.Status) { ...@@ -119,6 +133,34 @@ func (me *AutoUnionFs) Readlink(path string) (out string, code fuse.Status) {
return fs.Roots()[0], fuse.OK return fs.Roots()[0], fuse.OK
} }
func (me *AutoUnionFs) getUnionFs(name string) *UnionFs {
me.lock.RLock()
defer me.lock.RUnlock()
return me.knownFileSystems[name]
}
func (me *AutoUnionFs) Symlink(pointedTo string, linkName string) (code fuse.Status) {
comps := strings.Split(linkName, "/", -1)
if len(comps) != 2 {
return fuse.EPERM
}
if comps[0] == _CONFIG {
roots := me.getRoots(pointedTo)
if roots == nil {
return syscall.ENOTDIR
}
name := comps[1]
if !me.addFs(name, roots) {
return fuse.EPERM
}
return fuse.OK
}
return fuse.EPERM
}
// Must define this, because ENOSYS will suspend all GetXAttr calls. // Must define this, because ENOSYS will suspend all GetXAttr calls.
func (me *AutoUnionFs) GetXAttr(name string, attr string) ([]byte, fuse.Status) { func (me *AutoUnionFs) GetXAttr(name string, attr string) ([]byte, fuse.Status) {
return nil, syscall.ENODATA return nil, syscall.ENODATA
...@@ -148,10 +190,8 @@ func (me *AutoUnionFs) GetAttr(path string) (*fuse.Attr, fuse.Status) { ...@@ -148,10 +190,8 @@ func (me *AutoUnionFs) GetAttr(path string) (*fuse.Attr, fuse.Status) {
comps := strings.Split(path, filepath.SeparatorString, -1) comps := strings.Split(path, filepath.SeparatorString, -1)
me.lock.RLock()
defer me.lock.RUnlock()
if len(comps) > 1 && comps[0] == _CONFIG { if len(comps) > 1 && comps[0] == _CONFIG {
fs := me.knownFileSystems[comps[1]] fs := me.getUnionFs(comps[1])
if fs == nil { if fs == nil {
return nil, fuse.ENOENT return nil, fuse.ENOENT
...@@ -163,7 +203,7 @@ func (me *AutoUnionFs) GetAttr(path string) (*fuse.Attr, fuse.Status) { ...@@ -163,7 +203,7 @@ func (me *AutoUnionFs) GetAttr(path string) (*fuse.Attr, fuse.Status) {
return a, fuse.OK return a, fuse.OK
} }
if me.knownFileSystems[path] != nil { if me.getUnionFs(path) != nil {
return &fuse.Attr{ return &fuse.Attr{
Mode: fuse.S_IFDIR | 0755, Mode: fuse.S_IFDIR | 0755,
},fuse.OK },fuse.OK
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment