remotefs

package
v2.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package remotefs provides fs.FS implementations for remote filesystems.

Index

Constants

View Source
const (
	OpClose     = "close"      // OpClose Close operation
	OpOpen      = "open"       // OpOpen Open operation
	OpRead      = "read"       // OpRead Read operation
	OpRemove    = "remove"     // OpRemove Remove operation
	OpRemoveAll = "remove all" // OpRemoveAll RemoveAll operation
	OpSeek      = "seek"       // OpSeek Seek operation
	OpStat      = "stat"       // OpStat Stat operation
	OpWrite     = "write"      // OpWrite Write operation
	OpCopyTo    = "copy-to"    // OpCopyTo CopyTo operation
	OpCopyFrom  = "copy-from"  // OpCopyFrom CopyFrom operation
)

Operation constants for remote filesystem operations.

Variables

View Source
var (
	// DefaultRegistry is the default registry of remote filesystem implementations.
	DefaultRegistry = sync.OnceValue(func() *Registry {
		r := NewRegistry()
		RegisterDefaults(r)
		return r
	})

	// ErrNoFS is returned when no supported remote filesystem implementation is found.
	ErrNoFS = errors.New("no supported remote filesystem implementation found")
)
View Source
var (
	// ErrNilPatch is returned by PatchFile when a Patch with a nil apply function is encountered.
	ErrNilPatch = errors.New("patch has nil apply function")
	// ErrInvalidMatch is returned when a zero-value LineMatch (no matcher function set) is used.
	ErrInvalidMatch = errors.New("invalid line match: use ByPrefix, ByExact, ByContains, or ByRegex")
	// ErrMultilinePatch is returned by patch constructors when the line argument contains newline characters.
	ErrMultilinePatch = errors.New("patch line contains newline characters")
	// ErrNotRegularFile is returned by PatchFile when the target path is not a regular file.
	ErrNotRegularFile = errors.New("not a regular file")
)
View Source
var ErrChecksumMismatch = errors.New("checksum mismatch")

ErrChecksumMismatch is returned when the checksum of the uploaded file does not match the local checksum.

View Source
var ErrDownloadNotSupported = errors.New("download not supported by this filesystem type")

ErrDownloadNotSupported is returned by the DownloadURL methods when the FS implementation cannot fetch URLs, so a caller can tell that apart from a transfer that was attempted and failed.

Download never raises it itself, since every remotefs.FS exposes DownloadURL for it to fall back to, but it does propagate one raised by the FS it was given -- so testing for it with errors.Is stays meaningful there.

View Source
var ErrEmptyMachineID = errors.New("machine-id: empty")

ErrEmptyMachineID is returned by MachineID when the host returns an empty value.

View Source
var ErrHTTPHeadNotSupported = errors.New("http head not supported by this filesystem type")

ErrHTTPHeadNotSupported is returned by HTTPHead when the FS implementation or the remote host cannot perform HTTP HEAD requests. Callers can detect this with errors.Is.

View Source
var ErrHTTPStatusNotSupported = errors.New("http status check not supported by this filesystem type")

ErrHTTPStatusNotSupported is returned by HTTPStatusInsecure when the FS implementation does not support HTTP status checks. Callers can detect this with errors.Is.

View Source
var (

	// ErrNotSupported is returned when a function is not supported on Windows.
	ErrNotSupported = errors.New("not supported on windows")
)
View Source
var ErrTimeout = fmt.Errorf("rigrcp session stalled: %w", context.DeadlineExceeded)

ErrTimeout is returned by operations on a file on a Windows host when the rigrcp session backing the file stops making progress for 30 seconds. That means the session has died -- typically the host went away mid-transfer without the shell ever being torn down on this end -- so the session is aborted when it happens: the remote helper is stopped and further operations on the file fail too. It wraps context.DeadlineExceeded, so a caller that does not want to depend on this sentinel can match that instead.

Functions

func DiscardPartial added in v2.2.0

func DiscardPartial(fsys FS, url, dst string) error

DiscardPartial removes the partially transferred file that a Download with WithResume leaves behind for this url and destination.

Call it when abandoning a download for good. The partial is deliberately kept across failures so that a later attempt can continue it, which means nothing else will ever remove it, and an abandoned one holds its bytes on the destination's filesystem indefinitely. For a large artifact that is the whole download sitting there unreferenced.

Having nothing to discard is not an error, so it is safe to call after a download that succeeded or never started one.

func Download added in v2.2.0

func Download(ctx context.Context, fsys FS, url, dst string, opts ...DownloadOption) error

Download fetches url to dst on the remote host.

The transfer goes to a file beside dst and is renamed onto it only once it completes, so dst is never observed half-written.

Downloads are not retried here. A failed call returns its error and the caller decides whether to try again; see WithResume for making that retry continue where the last attempt stopped rather than starting over.

An FS from outside this package is transferred through its exported DownloadURL, so it still gets the atomic move and the url validation, but neither cancellation nor resume: both need the richer internal provider that PosixFS and WinFS implement.

func HTTPStatusInsecure

func HTTPStatusInsecure(ctx context.Context, fs FS, url string) (int, error)

HTTPStatusInsecure checks whether url is reachable and returns the HTTP status code, skipping TLS certificate verification. On Windows with PowerShell 5.x, TLS certificate verification is not skipped and requests will fail for self-signed certificates.

func PatchFile

func PatchFile(fsys FS, path string, patches []Patch, opts ...PatchOption) error

PatchFile reads path, applies each patch in sequence, and writes the result back atomically via WriteFileAtomic. Existing permission bits (rwxrwxrwx) are preserved; setuid, setgid, and sticky bits are not. If the file does not exist and WithCreate is provided, the file is created with the given mode; otherwise ErrNotExist is returned. Non-regular files (directories, FIFOs, devices) are rejected with ErrNotRegularFile.

If path is a symlink, the link itself is replaced by the rewritten file; the symlink target is not modified. On platforms where stat follows symlinks (GNU Linux), the target's permission bits are preserved. On platforms where stat reports the link itself (BSD), symlink permissions are meaningless (0o777), so the replacement file is created with 0o600 instead.

CRLF handling: if the original file contains any CR+LF sequence, the entire output is written with CR+LF line endings. Files with mixed line endings are fully normalised to CRLF. Bare CR bytes (old Mac-style) are not treated as line endings and are left as-is. Otherwise LF is used throughout.

The trailing newline status of the original file is preserved: files that end with a newline will continue to do so; files that do not will not gain one. New files created via WithCreate get a trailing newline when the output is non-empty; an empty result (or an existing empty file) produces an empty file.

Because WriteFileAtomic replaces the original inode via a temp-file rename, only permission bits are restored. Owner, group, ACLs, extended attributes, hard links, and timestamps of the original file are not preserved.

PatchFile performs a read-then-write cycle without inter-process locking. A concurrent writer between the read and the rename will have its changes silently overwritten by the atomic rename.

If the patches produce output identical to the original content, WriteFileAtomic is skipped and the file (including any symlink) is left untouched.

func PathError

func PathError(op, path string, err error) *fs.PathError

PathError returns a fs.PathError with the given operation, path and error.

func PathErrorf

func PathErrorf(op, path string, template string, args ...any) *fs.PathError

PathErrorf returns a fs.PathError with the given operation, path and error created using a sprintf style format string and arguments.

func RegisterDefaults added in v2.2.0

func RegisterDefaults(r *Registry)

RegisterDefaults registers the filesystem implementations rig ships with, which is what DefaultRegistry holds. Use it to build a registry of your own without having to list them, and without missing implementations added in later versions.

The factories are appended, so one of your own that has to take precedence over them must be registered before this call, or with Registry.RegisterFirst.

func RegisterPosix

func RegisterPosix(r *Registry)

RegisterPosix registers the POSIX filesystem implementation.

func RegisterWindows

func RegisterWindows(r *Registry)

RegisterWindows registers the Windows filesystem implementation.

func Upload

func Upload(fsys FS, src, dst string, opts ...UploadOption) error

Upload a file to the remote host atomically: the content is written to a temporary file in the same directory as dst, verified via SHA-256, and then renamed into place. The temporary file is removed on failure, except when the remote session timed out: the connection is gone at that point, so the cleanup would block on it, and the file is left for the next upload.

Permissions: the temporary file is created with mode 0o600 and then chmod'd to perm before the rename. When WithPermissions is not given, perm is taken from the local file's mode. This means that overwriting an existing remote file always sets its mode to perm — unlike a direct truncating write, which would leave the remote file's existing mode unchanged.

func WriteFileAtomic

func WriteFileAtomic(host OS, path string, data []byte, perm fs.FileMode) error

WriteFileAtomic writes data to path atomically: a temp file is created in the same directory, written with restricted permissions, chmod'd to perm, then renamed into place. Parent directories are created as needed. Cleanup of the temp file is always attempted; if it fails the error is ignored.

Types

type Copier

type Copier interface {
	CopyFrom(src io.Reader) (int64, error)
	CopyTo(dst io.Writer) (int64, error)
}

Copier is a file-like struct that can copy data to and from io.Reader and io.Writer.

type DownloadOption added in v2.2.0

type DownloadOption func(*downloadOptions)

DownloadOption configures Download.

func WithResume added in v2.2.0

func WithResume() DownloadOption

WithResume keeps the partially transferred file when a download fails, and continues it on the next Download call for the same url and destination instead of starting over. Retrying is left to the caller; this only makes a retry cheap.

The partial is kept beside the destination under a name derived from both the destination and the url, so a later call can only continue a file that its own url and destination produced. Without this option a failed download leaves nothing behind.

Resuming assumes the bytes already on disk are a prefix of what the url serves now. That holds for an interrupted transfer of unchanging content, which is what versioned artifact URLs provide. It does not hold if the content behind the url is replaced between attempts: neither curl nor wget can detect that, and the result would be half of each version.

To catch that before spending a transfer on it, record the ETag or LastModified that HTTPHead reports for the url alongside the download, compare it before retrying, and call DiscardPartial when it has changed. A checksum over the finished file catches what no header can say.

Windows hosts always restart the transfer: Invoke-WebRequest under Windows PowerShell 5.1 cannot continue one. So does an FS from outside this package, which can only be driven through its exported DownloadURL. The partial is still kept and the result is still correct, so the option is safe to pass in both cases, it just saves nothing.

type Downloader

type Downloader interface {
	DownloadURL(url, dst string) error
}

Downloader can download content from a URL to a file on the remote host.

type FS

FS is a filesystem on the remote host.

func NewFS

func NewFS(c cmd.Runner) FS

NewFS returns a fs.FS compatible implementation for access to remote filesystems.

type FSProvider

type FSProvider func(cmd.Runner) (FS, error)

FSProvider is a function that returns a remote filesystem implementation given a runner.

type Factory

type Factory = plumbing.Factory[cmd.Runner, FS]

Factory is a type alias for plumbing.Factory specialized for FS.

type File

type File interface {
	Name() string
	fs.File
	io.Seeker
	io.ReadCloser
	io.Writer
	Copier
}

File is a file in the remote filesystem.

func CreateTemp

func CreateTemp(fs FS, dir, pattern string) (File, error)

CreateTemp creates a new temporary file in the directory dir with a name built using the pattern, opens the file for reading and writing, and returns the resulting File. If dir is the empty string, CreateTemp uses the default directory for temporary files.

type FileInfo

type FileInfo struct {
	FName    string      `json:"name"`
	FSize    int64       `json:"size"`
	FMode    fs.FileMode `json:"mode"`
	FUnix    fs.FileMode `json:"unixMode"`
	FModTime time.Time   `json:"-"`
	FIsDir   bool        `json:"isDir"`
	ModtimeS int64       `json:"modTime"`
	// contains filtered or unexported fields
}

FileInfo implements fs.FileInfo for stat on remote files.

func (*FileInfo) FullPath

func (f *FileInfo) FullPath() string

FullPath returns the full path.

func (*FileInfo) Info

func (f *FileInfo) Info() (fs.FileInfo, error)

Info returns self. It's here to satisfy fs.DirEntry interface.

func (*FileInfo) IsDir

func (f *FileInfo) IsDir() bool

IsDir returns true if the file path points to a directory.

func (*FileInfo) ModTime

func (f *FileInfo) ModTime() time.Time

ModTime returns the last modification time of a file.

func (*FileInfo) Mode

func (f *FileInfo) Mode() fs.FileMode

Mode returns the file permission mode.

func (*FileInfo) Name

func (f *FileInfo) Name() string

Name returns the file name.

func (*FileInfo) Size

func (f *FileInfo) Size() int64

Size returns the file size.

func (*FileInfo) Sys

func (f *FileInfo) Sys() any

Sys returns the underlying data source.

func (*FileInfo) Type

func (f *FileInfo) Type() fs.FileMode

Type returns the file type. It's here to satisfy fs.DirEntry interface.

func (*FileInfo) UnmarshalJSON

func (f *FileInfo) UnmarshalJSON(b []byte) error

UnmarshalJSON implements json.Unmarshaler.

type LineMatch

type LineMatch struct {
	// contains filtered or unexported fields
}

LineMatch matches a single text line. It is created by ByPrefix, ByExact, ByContains, or ByRegex and consumed by Patch constructors.

func ByContains

func ByContains(s string) LineMatch

ByContains returns a LineMatch that matches lines containing s.

func ByExact

func ByExact(s string) LineMatch

ByExact returns a LineMatch that matches lines equal to s.

func ByPrefix

func ByPrefix(s string) LineMatch

ByPrefix returns a LineMatch that matches lines beginning with s.

func ByRegex

func ByRegex(pattern string) LineMatch

ByRegex returns a LineMatch that matches lines matching pattern. If pattern fails to compile, the error surfaces when the Patch is applied in PatchFile.

type OS

type OS interface {
	Remove(path string) error
	RemoveAll(path string) error
	Mkdir(path string, perm fs.FileMode) error
	MkdirAll(path string, perm fs.FileMode) error
	MkdirTemp(dir, prefix string) (string, error)
	CreateTemp(dir, prefix string) (string, error)
	WriteFile(path string, data []byte, perm fs.FileMode) error
	FileExist(path string) bool
	LookPath(cmd string) (string, error)
	Join(elem ...string) string
	Chmod(path string, mode fs.FileMode) error
	Chown(path string, owner string) error
	ChownInt(path string, uid, gid int) error
	ChownTree(path string, owner string) error
	ChownTreeInt(path string, uid, gid int) error
	Chtimes(path string, atime, mtime int64) error
	Touch(path string, ts ...time.Time) error
	Truncate(path string, size int64) error
	Getenv(key string) string
	Rename(oldpath, newpath string) error
	FileContains(path, substr string) (bool, error)
	Follow(ctx context.Context, path string, w io.Writer) error
	IsContainer() (bool, error)
	Hostname() (string, error)
	LongHostname() (string, error)
	MachineID() (string, error)
	SystemTime() (time.Time, error)
	TempDir() string
	UserCacheDir() string
	UserConfigDir() string
	UserHomeDir() string
	Dir(path string) string
	Base(path string) string
	CommandExist(name string) bool
	Reboot(ctx context.Context) error
	NativePath(path string) string
	ShellQuote(s string) string
}

OS is a os/filesystem utility interface, these operations are modeled after stdlib's OS package.

type Opener

type Opener interface {
	OpenFile(path string, flag int, perm fs.FileMode) (File, error)
}

Opener is a file opener interface, modeled after stdlib's OS package.

type Patch

type Patch struct {
	// contains filtered or unexported fields
}

Patch is a single file-editing operation that transforms a slice of lines. Construct patches with ReplaceOrAppend, DeleteMatching, AppendIfMissing, InsertAfter, InsertBefore, or Transform.

func AppendIfMissing

func AppendIfMissing(line string) Patch

AppendIfMissing appends line if no existing line is exactly equal to it.

func DeleteMatching

func DeleteMatching(match LineMatch) Patch

DeleteMatching removes all lines matching match.

func InsertAfter

func InsertAfter(match LineMatch, line string) Patch

InsertAfter inserts line after the first line matching match. If no line matches, the file is left unchanged.

func InsertBefore

func InsertBefore(match LineMatch, line string) Patch

InsertBefore inserts line before the first line matching match. If no line matches, the file is left unchanged.

func ReplaceOrAppend

func ReplaceOrAppend(match LineMatch, line string) Patch

ReplaceOrAppend replaces the first line matching match with line, or appends line if no existing line matches.

func Transform

func Transform(fn func(lines []string) ([]string, error)) Patch

Transform applies fn to the full slice of lines and is an escape hatch for cases that do not fit the structured patch constructors.

type PatchOption

type PatchOption func(*patchOptions)

PatchOption is a functional option for PatchFile.

func WithCreate

func WithCreate(perm fs.FileMode) PatchOption

WithCreate causes PatchFile to create the file with the given permissions if it does not already exist. Without this option, PatchFile returns an error when the target file is missing.

type PosixDir

type PosixDir struct {
	PosixFile
	// contains filtered or unexported fields
}

PosixDir implements fs.ReadDirFile for a remote directory.

func (*PosixDir) Name

func (w *PosixDir) Name() string

func (*PosixDir) ReadDir

func (f *PosixDir) ReadDir(n int) ([]fs.DirEntry, error)

ReadDir returns a list of directory entries.

type PosixFS

type PosixFS struct {
	cmd.Runner
	log.LoggerInjectable
	// contains filtered or unexported fields
}

PosixFS implements fs.FS for a remote filesystem that uses POSIX commands for access.

func NewPosixFS

func NewPosixFS(conn cmd.Runner) *PosixFS

NewPosixFS returns a fs.FS implementation for a remote filesystem that uses POSIX commands for access.

func (*PosixFS) Base

func (s *PosixFS) Base(p string) string

Base returns the last element of path.

func (*PosixFS) Chmod

func (s *PosixFS) Chmod(name string, mode fs.FileMode) error

Chmod changes the mode of the named file to mode. The permission bits and the setuid, setgid and sticky bits are applied; the file type bits are ignored, as chmod has no representation for them.

func (*PosixFS) Chown

func (s *PosixFS) Chown(name string, owner string) error

Chown changes the ownership of the named file. The owner parameter follows the standard chown format: "user", "user:group", or ":group".

func (*PosixFS) ChownInt

func (s *PosixFS) ChownInt(name string, uid, gid int) error

ChownInt changes the ownership of the named file using numeric uid and gid.

func (*PosixFS) ChownTree

func (s *PosixFS) ChownTree(name string, owner string) error

ChownTree recursively changes the ownership of path and all its contents. The owner parameter follows the standard chown format: "user", "user:group", or ":group".

func (*PosixFS) ChownTreeInt

func (s *PosixFS) ChownTreeInt(name string, uid, gid int) error

ChownTreeInt recursively changes the ownership of path and all its contents using numeric uid and gid.

func (*PosixFS) Chtimes

func (s *PosixFS) Chtimes(name string, atime, mtime int64) error

Chtimes changes the access and modification times of the named file.

func (*PosixFS) CommandExist

func (s *PosixFS) CommandExist(name string) bool

CommandExist reports whether the named command is available on the remote host.

func (*PosixFS) CreateTemp

func (s *PosixFS) CreateTemp(dir, prefix string) (string, error)

CreateTemp creates a new temporary file in the directory dir with a name beginning with prefix and returns the path of the new file. If dir is empty, TempDir() is used.

func (*PosixFS) Dir

func (s *PosixFS) Dir(p string) string

Dir returns all but the last element of path, typically the path's directory.

func (*PosixFS) DownloadURL

func (s *PosixFS) DownloadURL(url, dst string) error

DownloadURL downloads the contents of url to dst.

The transfer goes to a temporary file next to dst and is renamed into place only once it completes, so an interrupted download never leaves a truncated file sitting at dst looking complete.

func (*PosixFS) FileContains

func (s *PosixFS) FileContains(name, substr string) (bool, error)

FileContains reports whether the file at path contains the given substring. Returns a not-exist error if the file does not exist.

func (*PosixFS) FileExist

func (s *PosixFS) FileExist(name string) bool

FileExist checks if a file exists on the host.

func (*PosixFS) Follow

func (s *PosixFS) Follow(ctx context.Context, path string, w io.Writer) error

Follow streams new content appended to path to w until ctx is cancelled. Cancelling ctx is the expected way to stop following and does not return an error.

func (*PosixFS) Getenv

func (s *PosixFS) Getenv(key string) string

Getenv returns the value of the environment variable named by the key.

func (*PosixFS) Hostname

func (s *PosixFS) Hostname() (string, error)

Hostname returns the name of the host.

func (*PosixFS) IsContainer

func (s *PosixFS) IsContainer() (bool, error)

IsContainer reports whether the remote host is running inside a container (Docker, Podman, LXC, nspawn, etc.).

func (*PosixFS) Join

func (s *PosixFS) Join(elem ...string) string

Join joins any number of path elements into a single path, adding a separating slash if necessary.

func (*PosixFS) LongHostname

func (s *PosixFS) LongHostname() (string, error)

LongHostname returns the FQDN of the host.

func (*PosixFS) LookPath

func (s *PosixFS) LookPath(name string) (string, error)

LookPath checks if a command exists on the host.

func (*PosixFS) MachineID

func (s *PosixFS) MachineID() (string, error)

MachineID returns the unique machine ID from /etc/machine-id.

func (*PosixFS) Mkdir

func (s *PosixFS) Mkdir(name string, perm fs.FileMode) error

Mkdir creates a new directory with the specified name and permission bits.

The permission bits and the setgid, setuid and sticky bits of perm are applied; the file type bits are ignored.

func (*PosixFS) MkdirAll

func (s *PosixFS) MkdirAll(name string, perm fs.FileMode) error

MkdirAll creates a new directory structure with the specified name and permission bits. If the directory already exists, MkDirAll does nothing and returns nil.

The permission bits of perm are applied to every directory that is created, like os.MkdirAll does; directories that already exist are left alone. The setgid, setuid and sticky bits of perm are applied to the last directory of the path only. The file type bits are ignored.

The mode comes from a umask instead of `install -d -m ...` because the uutils (Rust) reimplementation of coreutils, the default on Ubuntu 25.10 and later, applies -m only to the last component of the path while GNU install applies it to every directory it creates, leaving the intermediate directories at the remote default mode. A umask covers all of them, but only the nine permission bits, so the special bits need the trailing chmod.

Note that a perm without u+wx makes creating nested directories fail for a non-root user, as it does with os.MkdirAll: the intermediate directory can't be written to once it has been created.

func (*PosixFS) MkdirTemp

func (s *PosixFS) MkdirTemp(dir, prefix string) (string, error)

MkdirTemp creates a new temporary directory in the directory dir with a name beginning with prefix and returns the path of the new directory.

func (*PosixFS) NativePath

func (s *PosixFS) NativePath(p string) string

NativePath returns the path unchanged; on POSIX systems the native separator is already a forward slash.

func (*PosixFS) Open

func (s *PosixFS) Open(name string) (fs.File, error)

Open opens the named file for reading.

func (*PosixFS) OpenFile

func (s *PosixFS) OpenFile(name string, flags int, perm fs.FileMode) (File, error)

OpenFile is used to open a file with access/creation flags for reading or writing. For info on flags, see https://pkg.go.dev/os#pkg-constants

func (*PosixFS) ReadDir

func (s *PosixFS) ReadDir(name string) ([]fs.DirEntry, error)

ReadDir reads the directory named by dirname and returns a list of directory entries.

func (*PosixFS) ReadFile

func (s *PosixFS) ReadFile(filename string) ([]byte, error)

ReadFile reads the file named by filename and returns the contents.

func (*PosixFS) Reboot

func (s *PosixFS) Reboot(ctx context.Context) error

Reboot triggers an immediate restart of the remote host. It first tries the simple 'reboot' command; if that fails with a logical error (not a transport tear-down), it falls back to 'shutdown -r now'. A transport-level error from either is treated as success since the kernel is already going down.

func (*PosixFS) Remove

func (s *PosixFS) Remove(name string) error

Remove deletes the named file. A path that does not exist is an error, matching os.Remove.

Unlike os.Remove it does not delete an empty directory: rm refuses one without an option POSIX does not require it to have. Use RemoveAll for a directory.

func (*PosixFS) RemoveAll

func (s *PosixFS) RemoveAll(name string) error

RemoveAll removes path and any children it contains. A path that does not exist is not an error, matching os.RemoveAll.

func (*PosixFS) Rename

func (s *PosixFS) Rename(oldpath, newpath string) error

Rename renames (moves) oldpath to newpath.

func (*PosixFS) Sha256

func (s *PosixFS) Sha256(name string) (string, error)

Sha256 returns the sha256 checksum of the file at path.

func (*PosixFS) ShellQuote

func (s *PosixFS) ShellQuote(str string) string

ShellQuote returns a shell-escaped version of str, safe for use as a single argument in a POSIX shell command.

func (*PosixFS) Stat

func (s *PosixFS) Stat(name string) (fs.FileInfo, error)

Stat returns the FileInfo structure describing file.

func (*PosixFS) SystemTime

func (s *PosixFS) SystemTime() (time.Time, error)

SystemTime returns the current UTC time on the remote host. Note: date +%s is not POSIX but is supported on GNU coreutils, busybox, and macOS.

func (*PosixFS) TempDir

func (s *PosixFS) TempDir() string

TempDir returns the default directory to use for temporary files.

func (*PosixFS) Touch

func (s *PosixFS) Touch(name string, ts ...time.Time) error

Touch creates a new empty file at path or updates the timestamps of an existing file. Without ts, both access and modification times are set to the current time. When ts is supplied, both times are set to the first timestamp provided.

func (*PosixFS) Truncate

func (s *PosixFS) Truncate(name string, size int64) error

Truncate changes the size of the named file or creates a new file if it doesn't exist.

func (*PosixFS) UserCacheDir

func (s *PosixFS) UserCacheDir() string

UserCacheDir returns the default root directory to use for user-specific cached data.

func (*PosixFS) UserConfigDir

func (s *PosixFS) UserConfigDir() string

UserConfigDir returns the default root directory to use for user-specific configuration data.

func (*PosixFS) UserHomeDir

func (s *PosixFS) UserHomeDir() string

UserHomeDir returns the current user's home directory.

func (*PosixFS) WriteFile

func (s *PosixFS) WriteFile(filename string, data []byte, perm fs.FileMode) error

WriteFile writes data to a file named by filename. Any missing parent directories are created.

The file is created via a shell redirect instead of `install -m ... /dev/stdin` because the uutils (Rust) reimplementation of coreutils, the default on Ubuntu 25.10 and later, fails with "install: No such file or directory" when the source is /dev/stdin and the destination already exists — which is exactly what writing to a mktemp'd file does. See https://github.com/uutils/coreutils/issues/12407.

The umask keeps a newly created file from being more permissive than perm while the content is written; the trailing chmod then applies perm's permission bits along with its setuid, setgid and sticky bits, also to a file that already existed. The file type bits of perm are ignored, as chmod has no representation for them. A umask only covers the nine permission bits, so the special bits come from the chmod alone — which is the safe ordering anyway, as the content is fully written by then. The umask is set after mkdir so that it does not affect the mode of the created parent directories.

Missing parent directories get the remote default mode (0777 minus the remote umask) instead of the fixed 0755 that GNU `install -D` used. Use MkdirAll if the parent directories need a specific mode.

type PosixFile

type PosixFile struct {
	// contains filtered or unexported fields
}

PosixFile implements fs.File for a remote file.

func (*PosixFile) Close

func (f *PosixFile) Close() error

Close closes the file, rendering it unusable for I/O. It returns an error, if any.

func (*PosixFile) CopyFrom

func (f *PosixFile) CopyFrom(src io.Reader) (int64, error)

CopyFrom copies the local reader src to the remote file.

func (*PosixFile) CopyTo

func (f *PosixFile) CopyTo(dst io.Writer) (int64, error)

CopyTo copies the remote file to the writer dst.

func (*PosixFile) Name

func (w *PosixFile) Name() string

func (*PosixFile) Read

func (f *PosixFile) Read(p []byte) (int, error)

Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered.

func (*PosixFile) Seek

func (f *PosixFile) Seek(offset int64, whence int) (int64, error)

Seek sets the offset for the next Read or Write to offset, interpreted according to whence: io.SeekStart means relative to the origin of the file, io.SeekCurrent means relative to the current offset, and io.SeekEnd means relative to the end. Seek returns the new offset relative to the start of the file and an error, if any.

func (*PosixFile) Stat

func (f *PosixFile) Stat() (fs.FileInfo, error)

Stat returns a FileInfo describing the named file.

func (*PosixFile) Write

func (f *PosixFile) Write(p []byte) (int, error)

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider provides a unified interface to interact with the filesystem on a remote host. It ensures that a suitable remotefs.FS implementation is lazily initialized and made available for filesystem operations. It supports operations like opening files and implements io/fs.FS.

func NewRemoteFSProvider

func NewRemoteFSProvider(get FSProvider, runner cmd.Runner) *Provider

NewRemoteFSProvider creates a new instance of Provider with the provided FSProvider function and runner.

func (*Provider) FS

func (p *Provider) FS() (FS, error)

FS returns a FS or an error if a filesystem client could not be initialized.

type Registry

type Registry = plumbing.Provider[cmd.Runner, FS]

Registry is a type alias for plumbing.Provider specialized for FS.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new Registry.

type Sha256summer

type Sha256summer interface {
	Sha256(path string) (string, error)
}

Sha256summer implementing struct can calculate sha256 checksum of a file.

type URLInfo added in v2.2.0

type URLInfo struct {
	// StatusCode is the status of the final response, after any redirects.
	StatusCode int

	// ContentLength is the Content-Length of the final response, or -1 when the
	// server did not report one, which happens under chunked transfer encoding.
	ContentLength int64

	// ETag is the entity tag exactly as the server sent it, including the quotes
	// and any weak validator prefix, or empty when the server sent none. It is
	// opaque: compare it for equality with a previously recorded value, never
	// try to derive a content hash from it.
	ETag string

	// LastModified is the parsed Last-Modified header, or the zero time when the
	// server sent none or it could not be parsed.
	LastModified time.Time

	// AcceptRanges reports whether the server advertised support for range
	// requests.
	AcceptRanges bool
}

URLInfo describes what an HTTP HEAD request reported about a URL. It carries the values that are useful for deciding whether a previously downloaded file is still current.

func HTTPHead added in v2.2.0

func HTTPHead(ctx context.Context, fs FS, url string) (*URLInfo, error)

HTTPHead performs an HTTP HEAD request for url from the remote host and reports what the server said about it. Unlike HTTPStatusInsecure, TLS certificates are verified.

The request is made from the remote host rather than from the machine running rig, so the result reflects what that host can actually reach. This matters when the two do not share a view of the network, as with an internal mirror.

A non-2xx StatusCode is returned without an error; inspecting it is left to the caller. Servers that reject HEAD typically answer 405, which is reported the same way.

type UploadOption

type UploadOption func(*uploadOptions)

UploadOption is a functional option for Upload.

func WithPermissions

func WithPermissions(mode fs.FileMode) UploadOption

WithPermissions sets the file mode for the uploaded file. If not set, the local file's mode is used.

type WinFS

type WinFS struct {
	cmd.Runner
	log.LoggerInjectable
}

WinFS is a fs.FS implemen{.

func NewWindowsFS

func NewWindowsFS(conn cmd.Runner) *WinFS

NewWindowsFS returns a new fs.FS implementing filesystem for Windows targets.

func (*WinFS) Base

func (s *WinFS) Base(path string) string

Base returns the last element of path. Both forward and backward slashes are recognised as separators.

func (*WinFS) Chmod

func (s *WinFS) Chmod(name string, mode fs.FileMode) error

Chmod changes the mode of the named file to mode. On Windows, only the 0200 bit (owner writable) of mode is used: if set, the read-only attribute is cleared; if unset, it is set.

func (*WinFS) Chown

func (s *WinFS) Chown(name string, _ string) error

Chown changes the ownership of the named file. On Windows it returns an error.

func (*WinFS) ChownInt

func (s *WinFS) ChownInt(name string, _, _ int) error

ChownInt changes the ownership using numeric uid and gid. On Windows it returns an error.

func (*WinFS) ChownTree

func (s *WinFS) ChownTree(name string, _ string) error

ChownTree recursively changes the ownership. On Windows it returns an error.

func (*WinFS) ChownTreeInt

func (s *WinFS) ChownTreeInt(name string, _, _ int) error

ChownTreeInt recursively changes the ownership using numeric uid and gid. On Windows it returns an error.

func (*WinFS) Chtimes

func (s *WinFS) Chtimes(name string, atime, mtime int64) error

Chtimes changes the access and modification times of the named file, similar to the Unix utime() or utimes() functions.

func (*WinFS) CommandExist

func (s *WinFS) CommandExist(name string) bool

CommandExist reports whether the named command is available on the remote host.

func (*WinFS) CreateTemp

func (s *WinFS) CreateTemp(dir, prefix string) (string, error)

CreateTemp creates a new temporary file in the directory dir with a name beginning with prefix and returns the path of the new file. If dir is empty, TempDir() is used.

func (*WinFS) Dir

func (s *WinFS) Dir(path string) string

Dir returns all but the last element of path, typically the path's directory. Both forward and backward slashes are recognised as separators.

func (*WinFS) DownloadURL

func (s *WinFS) DownloadURL(url, dst string) error

DownloadURL downloads the contents of url to dst using Invoke-WebRequest.

The transfer goes to a temporary file next to dst and is renamed into place only once it completes, so an interrupted download never leaves a truncated file sitting at dst looking complete.

func (*WinFS) FileContains

func (s *WinFS) FileContains(name, substr string) (bool, error)

FileContains reports whether the file at path contains the given substring. Returns a not-exist error if the file does not exist.

func (*WinFS) FileExist

func (s *WinFS) FileExist(name string) bool

FileExist checks if a file exists on the host. It is a more efficient shortcut for something like:

	if _, err := fs.Stat(name); os.IsNotExist(err) { ... }
 if !fs.FileExist(name) { ... }

func (*WinFS) Follow

func (s *WinFS) Follow(ctx context.Context, path string, w io.Writer) error

Follow streams new content appended to path to w until ctx is cancelled. Cancelling ctx is the expected way to stop following and does not return an error.

func (*WinFS) Getenv

func (s *WinFS) Getenv(key string) string

Getenv retrieves the value of the environment variable named by the key.

func (*WinFS) Hostname

func (s *WinFS) Hostname() (string, error)

Hostname returns the hostname of the remote host.

func (*WinFS) IsContainer

func (s *WinFS) IsContainer() (bool, error)

IsContainer reports whether the host is running inside a container. Container detection is not supported on Windows.

func (*WinFS) Join

func (s *WinFS) Join(elem ...string) string

Join joins any number of path elements into a single path, adding a separating slash if necessary.

func (*WinFS) LongHostname

func (s *WinFS) LongHostname() (string, error)

LongHostname resolves the FQDN (long) hostname.

func (*WinFS) LookPath

func (s *WinFS) LookPath(name string) (string, error)

LookPath checks if a command exists on the host.

func (*WinFS) MachineID

func (s *WinFS) MachineID() (string, error)

MachineID returns the unique machine ID from the Windows registry.

func (*WinFS) Mkdir

func (s *WinFS) Mkdir(name string, _ fs.FileMode) error

Mkdir creates a new directory with the specified name and permission bits. The permission bits are ignored on Windows.

func (*WinFS) MkdirAll

func (s *WinFS) MkdirAll(name string, _ fs.FileMode) error

MkdirAll creates a directory named path, along with any necessary parents. The permission bits are ignored on Windows.

func (*WinFS) MkdirTemp

func (s *WinFS) MkdirTemp(dir, prefix string) (string, error)

MkdirTemp creates a new temporary directory in the directory dir with a name beginning with prefix and returns the path of the new directory.

func (*WinFS) NativePath

func (s *WinFS) NativePath(p string) string

NativePath converts forward slashes in path to backslashes, returning a Windows-native path.

func (*WinFS) Open

func (s *WinFS) Open(name string) (fs.File, error)

Open opens the named file for reading and returns fs.File. Use OpenFile to get a file that can be written to or if you need any of the methods not available on fs.File interface without type assertion.

func (*WinFS) OpenFile

func (s *WinFS) OpenFile(name string, flags int, _ fs.FileMode) (File, error)

OpenFile opens the named remote file with the specified flags. os.O_EXCL and permission bits are ignored on Windows. For a description of the flags, see https://pkg.go.dev/os#pkg-constants

func (*WinFS) ReadDir

func (s *WinFS) ReadDir(name string) (entries []fs.DirEntry, err error)

ReadDir reads the directory named by dirname and returns a list of directory entries.

func (*WinFS) ReadFile

func (s *WinFS) ReadFile(name string) (contents []byte, err error)

ReadFile reads the named file and returns its contents.

func (*WinFS) Reboot

func (s *WinFS) Reboot(ctx context.Context) error

Reboot triggers an immediate restart of the remote host via a SYSTEM-context on-demand scheduled task running 'shutdown.exe /r /f /t 5'. Running via a scheduled task bypasses the filtered Administrator token used by WinRM sessions (e.g. on AWS EC2) which lacks SeShutdownPrivilege — issuing 'shutdown /r' directly in such a session is silently ignored by the OS.

The task is registered without a time-based trigger so it can only fire when explicitly started via Start-ScheduledTask. A best-effort Unregister-ScheduledTask is attempted in all cases.

func (*WinFS) Remove

func (s *WinFS) Remove(name string) error

Remove deletes the named file or (empty) directory. A path that does not exist is an error, matching os.Remove.

Every failure is reported as a *fs.PathError whose Op is OpRemove, so a caller reading it sees the call it made rather than one of the commands used to carry it out.

func (*WinFS) RemoveAll

func (s *WinFS) RemoveAll(name string) error

RemoveAll deletes the named file or directory and all its child items. A path that does not exist is not an error, matching os.RemoveAll.

Failures are reported as a *fs.PathError whose Op is OpRemoveAll, on the same reasoning as Remove.

func (*WinFS) Rename

func (s *WinFS) Rename(oldpath, newpath string) error

Rename renames (moves) oldpath to newpath, overwriting newpath if it exists.

func (*WinFS) Sha256

func (s *WinFS) Sha256(name string) (string, error)

Sha256 returns the SHA256 hash of the remote file.

func (*WinFS) ShellQuote

func (s *WinFS) ShellQuote(str string) string

ShellQuote returns a single-quoted version of str, safe for use as a single argument in a PowerShell command. Single-quoting prevents PowerShell variable interpolation (e.g. $var, $()) and is safe with untrusted input.

func (*WinFS) Stat

func (s *WinFS) Stat(name string) (fs.FileInfo, error)

Stat returns fs.FileInfo for the remote file.

func (*WinFS) SystemTime

func (s *WinFS) SystemTime() (time.Time, error)

SystemTime returns the current UTC time on the remote host.

func (*WinFS) TempDir

func (s *WinFS) TempDir() string

TempDir returns the default directory to use for temporary files.

func (*WinFS) Touch

func (s *WinFS) Touch(name string, ts ...time.Time) error

Touch creates a new file with the given name if it does not exist. Without ts, the file's modification time is set to the current time. When ts is supplied, the file's modification time is set to the first timestamp provided.

func (*WinFS) Truncate

func (s *WinFS) Truncate(name string, size int64) error

Truncate changes the size of the named file.

func (*WinFS) UserCacheDir

func (s *WinFS) UserCacheDir() string

UserCacheDir returns the default root directory to use for user-specific non-essential data files.

func (*WinFS) UserConfigDir

func (s *WinFS) UserConfigDir() string

UserConfigDir returns the default root directory to use for user-specific configuration data.

func (*WinFS) UserHomeDir

func (s *WinFS) UserHomeDir() string

UserHomeDir returns the current user's home directory.

func (*WinFS) WriteFile

func (s *WinFS) WriteFile(name string, data []byte, mode fs.FileMode) (err error)

WriteFile writes data to the named file, creating it if necessary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL