hst/fs: implement link fstype
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m16s
Test / Hpkg (push) Successful in 4m8s
Test / Sandbox (race detector) (push) Successful in 4m24s
Test / Hakurei (race detector) (push) Successful in 5m9s
Test / Hakurei (push) Successful in 2m31s
Test / Flake checks (push) Successful in 1m40s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m16s
Test / Hpkg (push) Successful in 4m8s
Test / Sandbox (race detector) (push) Successful in 4m24s
Test / Hakurei (race detector) (push) Successful in 5m9s
Test / Hakurei (push) Successful in 2m31s
Test / Flake checks (push) Successful in 1m40s
Symlinks do not require special treatment, and doing this allows placing links in order. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
125f150784
commit
26cafe3e80
@ -95,6 +95,12 @@ func (f *FilesystemConfigJSON) MarshalJSON() ([]byte, error) {
|
||||
*FSOverlay
|
||||
}{fsType{FilesystemOverlay}, cv}
|
||||
|
||||
case *FSLink:
|
||||
v = &struct {
|
||||
fsType
|
||||
*FSLink
|
||||
}{fsType{FilesystemLink}, cv}
|
||||
|
||||
default:
|
||||
return nil, FSImplError{f.FilesystemConfig}
|
||||
}
|
||||
@ -120,6 +126,9 @@ func (f *FilesystemConfigJSON) UnmarshalJSON(data []byte) error {
|
||||
case FilesystemOverlay:
|
||||
*f = FilesystemConfigJSON{new(FSOverlay)}
|
||||
|
||||
case FilesystemLink:
|
||||
*f = FilesystemConfigJSON{new(FSLink)}
|
||||
|
||||
default:
|
||||
return FSTypeError(t.Type)
|
||||
}
|
||||
|
@ -70,6 +70,16 @@ func TestFilesystemConfigJSON(t *testing.T) {
|
||||
}, nil,
|
||||
`{"type":"overlay","dst":"/nix/store","lower":["/mnt-root/nix/.ro-store"],"upper":"/mnt-root/nix/.rw-store/upper","work":"/mnt-root/nix/.rw-store/work"}`,
|
||||
`{"fs":{"type":"overlay","dst":"/nix/store","lower":["/mnt-root/nix/.ro-store"],"upper":"/mnt-root/nix/.rw-store/upper","work":"/mnt-root/nix/.rw-store/work"},"magic":3236757504}`},
|
||||
|
||||
{"link", hst.FilesystemConfigJSON{
|
||||
FilesystemConfig: &hst.FSLink{
|
||||
Target: m("/run/current-system"),
|
||||
Linkname: "/run/current-system",
|
||||
Dereference: true,
|
||||
},
|
||||
}, nil,
|
||||
`{"type":"link","dst":"/run/current-system","linkname":"/run/current-system","dereference":true}`,
|
||||
`{"fs":{"type":"link","dst":"/run/current-system","linkname":"/run/current-system","dereference":true},"magic":3236757504}`},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
58
hst/fslink.go
Normal file
58
hst/fslink.go
Normal file
@ -0,0 +1,58 @@
|
||||
package hst
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"path"
|
||||
|
||||
"hakurei.app/container"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(FSLink)) }
|
||||
|
||||
// FilesystemLink is the type string of a symbolic link.
|
||||
const FilesystemLink = "link"
|
||||
|
||||
// FSLink represents a symlink in the container filesystem.
|
||||
type FSLink struct {
|
||||
// link path in container
|
||||
Target *container.Absolute `json:"dst"`
|
||||
// linkname the symlink points to
|
||||
Linkname string `json:"linkname"`
|
||||
// whether to dereference linkname before creating the link
|
||||
Dereference bool `json:"dereference,omitempty"`
|
||||
}
|
||||
|
||||
func (l *FSLink) Valid() bool {
|
||||
if l == nil || l.Target == nil || l.Linkname == "" {
|
||||
return false
|
||||
}
|
||||
return !l.Dereference || path.IsAbs(l.Linkname)
|
||||
}
|
||||
|
||||
func (l *FSLink) Path() *container.Absolute {
|
||||
if !l.Valid() {
|
||||
return nil
|
||||
}
|
||||
return l.Target
|
||||
}
|
||||
|
||||
func (l *FSLink) Host() []*container.Absolute { return nil }
|
||||
|
||||
func (l *FSLink) Apply(z *ApplyState) {
|
||||
if !l.Valid() {
|
||||
return
|
||||
}
|
||||
z.Link(l.Target, l.Linkname, l.Dereference)
|
||||
}
|
||||
|
||||
func (l *FSLink) String() string {
|
||||
if !l.Valid() {
|
||||
return "<invalid>"
|
||||
}
|
||||
|
||||
dereference := ""
|
||||
if l.Dereference {
|
||||
dereference = "*"
|
||||
}
|
||||
return "&" + l.Target.String() + ":" + dereference + l.Linkname
|
||||
}
|
49
hst/fslink_test.go
Normal file
49
hst/fslink_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
package hst_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
func TestFSLink(t *testing.T) {
|
||||
checkFs(t, []fsTestCase{
|
||||
{"nil", (*hst.FSLink)(nil), false, nil, nil, nil, "<invalid>"},
|
||||
{"zero", new(hst.FSLink), false, nil, nil, nil, "<invalid>"},
|
||||
|
||||
{"deref rel", &hst.FSLink{Target: m("/"), Linkname: ":3", Dereference: true}, false, nil, nil, nil, "<invalid>"},
|
||||
{"deref", &hst.FSLink{
|
||||
Target: m("/run/current-system"),
|
||||
Linkname: "/run/current-system",
|
||||
Dereference: true,
|
||||
}, true, container.Ops{
|
||||
&container.SymlinkOp{
|
||||
Target: m("/run/current-system"),
|
||||
LinkName: "/run/current-system",
|
||||
Dereference: true,
|
||||
},
|
||||
}, m("/run/current-system"), nil,
|
||||
"&/run/current-system:*/run/current-system"},
|
||||
|
||||
{"direct", &hst.FSLink{
|
||||
Target: m("/etc/mtab"),
|
||||
Linkname: "/proc/mounts",
|
||||
}, true, container.Ops{
|
||||
&container.SymlinkOp{
|
||||
Target: m("/etc/mtab"),
|
||||
LinkName: "/proc/mounts",
|
||||
},
|
||||
}, m("/etc/mtab"), nil, "&/etc/mtab:/proc/mounts"},
|
||||
|
||||
{"direct rel", &hst.FSLink{
|
||||
Target: m("/etc/mtab"),
|
||||
Linkname: "../proc/mounts",
|
||||
}, true, container.Ops{
|
||||
&container.SymlinkOp{
|
||||
Target: m("/etc/mtab"),
|
||||
LinkName: "../proc/mounts",
|
||||
},
|
||||
}, m("/etc/mtab"), nil, "&/etc/mtab:../proc/mounts"},
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user