aboutsummaryrefslogtreecommitdiffhomepage
path: root/hst/fslink.go
blob: 57c1ffc71d6198f44d8097d223b3b42378f17f3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package hst

import (
	"encoding/gob"
	"path"

	"hakurei.app/container/check"
)

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 {
	// Pathname in the container mount namespace.
	Target *check.Absolute `json:"dst"`
	// Arbitrary linkname value store in the symlink.
	Linkname string `json:"linkname"`

	// Whether to treat Linkname as an absolute pathname and dereference 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() *check.Absolute {
	if !l.Valid() {
		return nil
	}
	return l.Target
}

func (l *FSLink) Host() []*check.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>"
	}

	var dereference string
	if l.Dereference {
		if l.Target.String() == l.Linkname {
			return l.Target.String() + "@"
		}
		dereference = "*"
	}
	return l.Target.String() + " -> " + dereference + l.Linkname
}