All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 34s
				
			Test / Sandbox (push) Successful in 2m9s
				
			Test / Hpkg (push) Successful in 3m58s
				
			Test / Sandbox (race detector) (push) Successful in 4m31s
				
			Test / Hakurei (race detector) (push) Successful in 5m19s
				
			Test / Hakurei (push) Successful in 2m12s
				
			Test / Flake checks (push) Successful in 1m31s
				
			This corrects minor mistakes in doc comments and adds them for undocumented constants. Signed-off-by: Ophestra <cat@gensokyo.uk>
		
			
				
	
	
		
			161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package hst
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"reflect"
 | 
						|
 | 
						|
	"hakurei.app/container/check"
 | 
						|
)
 | 
						|
 | 
						|
// FilesystemConfig is an abstract representation of a mount point.
 | 
						|
type FilesystemConfig interface {
 | 
						|
	// Valid returns whether the configuration is valid.
 | 
						|
	Valid() bool
 | 
						|
	// Path returns the target path in the container.
 | 
						|
	Path() *check.Absolute
 | 
						|
	// Host returns a slice of all host paths used by this operation.
 | 
						|
	Host() []*check.Absolute
 | 
						|
	// Apply appends the [container.Op] implementing this operation.
 | 
						|
	Apply(z *ApplyState)
 | 
						|
 | 
						|
	fmt.Stringer
 | 
						|
}
 | 
						|
 | 
						|
// The Ops interface enables [FilesystemConfig] to queue container ops without depending on the container package.
 | 
						|
type Ops interface {
 | 
						|
	// Tmpfs appends an op that mounts tmpfs on a container path.
 | 
						|
	Tmpfs(target *check.Absolute, size int, perm os.FileMode) Ops
 | 
						|
	// Readonly appends an op that mounts read-only tmpfs on a container path.
 | 
						|
	Readonly(target *check.Absolute, perm os.FileMode) Ops
 | 
						|
 | 
						|
	// Bind appends an op that bind mounts a host path on a container path.
 | 
						|
	Bind(source, target *check.Absolute, flags int) Ops
 | 
						|
	// Overlay appends an op that mounts the overlay pseudo filesystem.
 | 
						|
	Overlay(target, state, work *check.Absolute, layers ...*check.Absolute) Ops
 | 
						|
	// OverlayReadonly appends an op that mounts the overlay pseudo filesystem readonly.
 | 
						|
	OverlayReadonly(target *check.Absolute, layers ...*check.Absolute) Ops
 | 
						|
 | 
						|
	// Link appends an op that creates a symlink in the container filesystem.
 | 
						|
	Link(target *check.Absolute, linkName string, dereference bool) Ops
 | 
						|
 | 
						|
	// Root appends an op that expands a directory into a toplevel bind mount mirror on container root.
 | 
						|
	Root(host *check.Absolute, flags int) Ops
 | 
						|
	// Etc appends an op that expands host /etc into a toplevel symlink mirror with /etc semantics.
 | 
						|
	Etc(host *check.Absolute, prefix string) Ops
 | 
						|
}
 | 
						|
 | 
						|
// ApplyState holds the address of [Ops] and any relevant application state.
 | 
						|
type ApplyState struct {
 | 
						|
	// AutoEtcPrefix is the prefix for [FSBind] in autoetc [FSBind.Special] condition.
 | 
						|
	AutoEtcPrefix string
 | 
						|
 | 
						|
	Ops
 | 
						|
}
 | 
						|
 | 
						|
// ErrFSNull is returned by [json] on encountering a null [FilesystemConfig] value.
 | 
						|
var ErrFSNull = errors.New("unexpected null in mount point")
 | 
						|
 | 
						|
// FSTypeError is returned when [ContainerConfig.Filesystem] contains an entry with invalid type.
 | 
						|
type FSTypeError string
 | 
						|
 | 
						|
func (f FSTypeError) Error() string { return fmt.Sprintf("invalid filesystem type %q", string(f)) }
 | 
						|
 | 
						|
// FSImplError is returned for unsupported implementations of [FilesystemConfig].
 | 
						|
type FSImplError struct{ Value FilesystemConfig }
 | 
						|
 | 
						|
func (f FSImplError) Error() string {
 | 
						|
	implType := reflect.TypeOf(f.Value)
 | 
						|
	var name string
 | 
						|
	for implType != nil && implType.Kind() == reflect.Ptr {
 | 
						|
		name += "*"
 | 
						|
		implType = implType.Elem()
 | 
						|
	}
 | 
						|
	if implType != nil {
 | 
						|
		name += implType.Name()
 | 
						|
	} else {
 | 
						|
		name += "nil"
 | 
						|
	}
 | 
						|
	return fmt.Sprintf("implementation %s not supported", name)
 | 
						|
}
 | 
						|
 | 
						|
// FilesystemConfigJSON is the [json] adapter for [FilesystemConfig].
 | 
						|
type FilesystemConfigJSON struct{ FilesystemConfig }
 | 
						|
 | 
						|
// Valid returns whether the [FilesystemConfigJSON] is valid.
 | 
						|
func (f *FilesystemConfigJSON) Valid() bool {
 | 
						|
	return f != nil && f.FilesystemConfig != nil && f.FilesystemConfig.Valid()
 | 
						|
}
 | 
						|
 | 
						|
// fsType holds the string representation of the concrete type of [FilesystemConfig].
 | 
						|
type fsType struct {
 | 
						|
	Type string `json:"type"`
 | 
						|
}
 | 
						|
 | 
						|
func (f *FilesystemConfigJSON) MarshalJSON() ([]byte, error) {
 | 
						|
	if f == nil || f.FilesystemConfig == nil {
 | 
						|
		return nil, ErrFSNull
 | 
						|
	}
 | 
						|
	var v any
 | 
						|
	switch cv := f.FilesystemConfig.(type) {
 | 
						|
	case *FSBind:
 | 
						|
		v = &struct {
 | 
						|
			fsType
 | 
						|
			*FSBind
 | 
						|
		}{fsType{FilesystemBind}, cv}
 | 
						|
 | 
						|
	case *FSEphemeral:
 | 
						|
		v = &struct {
 | 
						|
			fsType
 | 
						|
			*FSEphemeral
 | 
						|
		}{fsType{FilesystemEphemeral}, cv}
 | 
						|
 | 
						|
	case *FSOverlay:
 | 
						|
		v = &struct {
 | 
						|
			fsType
 | 
						|
			*FSOverlay
 | 
						|
		}{fsType{FilesystemOverlay}, cv}
 | 
						|
 | 
						|
	case *FSLink:
 | 
						|
		v = &struct {
 | 
						|
			fsType
 | 
						|
			*FSLink
 | 
						|
		}{fsType{FilesystemLink}, cv}
 | 
						|
 | 
						|
	default:
 | 
						|
		return nil, FSImplError{f.FilesystemConfig}
 | 
						|
	}
 | 
						|
 | 
						|
	return json.Marshal(v)
 | 
						|
}
 | 
						|
 | 
						|
func (f *FilesystemConfigJSON) UnmarshalJSON(data []byte) error {
 | 
						|
	t := new(fsType)
 | 
						|
	if err := json.Unmarshal(data, &t); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if t == nil {
 | 
						|
		return ErrFSNull
 | 
						|
	}
 | 
						|
	switch t.Type {
 | 
						|
	case FilesystemBind:
 | 
						|
		*f = FilesystemConfigJSON{new(FSBind)}
 | 
						|
 | 
						|
	case FilesystemEphemeral:
 | 
						|
		*f = FilesystemConfigJSON{new(FSEphemeral)}
 | 
						|
 | 
						|
	case FilesystemOverlay:
 | 
						|
		*f = FilesystemConfigJSON{new(FSOverlay)}
 | 
						|
 | 
						|
	case FilesystemLink:
 | 
						|
		*f = FilesystemConfigJSON{new(FSLink)}
 | 
						|
 | 
						|
	default:
 | 
						|
		return FSTypeError(t.Type)
 | 
						|
	}
 | 
						|
 | 
						|
	return json.Unmarshal(data, f.FilesystemConfig)
 | 
						|
}
 |