Documentation
¶
Overview ¶
Package gowsl implements an idiomatic interface to manage the Windows Subsystem for Linux from Go. It uses WslApi calls when possible, and otherwise reads the registry or, as a last resort, may subprocess wsl.exe.
This package also contains a mock WSL backend which can be useful for testing, as setting up WSL distros for every test-case can be quite time-consuming. This mock back-end is disabled by default, and can be enabled by using the context returned by the WithMock function.
Index ¶
- Constants
- Variables
- func Install(ctx context.Context, appxName string) error
- func MockAvailable() bool
- func Shutdown(ctx context.Context) error
- func WithMock(ctx context.Context, m *mock.Backend) context.Context
- type Cmd
- func (c *Cmd) CombinedOutput() (out []byte, err error)
- func (c *Cmd) Output() (out []byte, err error)
- func (c *Cmd) Run() error
- func (c *Cmd) Start() (err error)
- func (c *Cmd) StderrPipe() (r io.ReadCloser, err error)
- func (c *Cmd) StdinPipe() (w io.WriteCloser, err error)
- func (c *Cmd) StdoutPipe() (r io.ReadCloser, err error)
- func (c *Cmd) Wait() (err error)
- type Configuration
- type Distro
- func DefaultDistro(ctx context.Context) (d Distro, ok bool, err error)
- func Import(ctx context.Context, distributionName, sourcePath, destinationPath string) (Distro, error)
- func NewDistro(ctx context.Context, name string) Distro
- func RegisteredDistros(ctx context.Context) (distros []Distro, err error)
- func (d *Distro) Command(ctx context.Context, cmd string) *Cmd
- func (d *Distro) DefaultUID(uid uint32) (err error)
- func (d *Distro) DriveMountingEnabled(value bool) (err error)
- func (d Distro) Equal(other Distro) bool
- func (d *Distro) GUID() (id uuid.UUID, err error)
- func (d Distro) GetConfiguration() (c Configuration, err error)
- func (d *Distro) InteropEnabled(value bool) (err error)
- func (d Distro) IsRegistered() (registered bool, err error)
- func (d Distro) Name() string
- func (d *Distro) PathAppended(value bool) (err error)
- func (d *Distro) Register(rootFsPath string) (err error)
- func (d *Distro) SetAsDefault() error
- func (d *Distro) Shell(args ...ShellOption) (err error)
- func (d *Distro) State() (s State, err error)
- func (d Distro) String() string
- func (d *Distro) Terminate() error
- func (d *Distro) Uninstall(ctx context.Context) (err error)
- func (d *Distro) Unregister() (err error)
- type ShellError
- type ShellOption
- type State
Constants ¶
const ( Stopped = state.Stopped Running = state.Running Installing = state.Installing Uninstalling = state.Uninstalling NonRegistered = state.NotRegistered )
The states here reported are the ones obtained via `wsl.exe -l -v`, with the addition of NonRegistered.
Variables ¶
var ErrNotExist = windows.ErrNotExist
ErrNotExist is the error returned when a distro does not exist.
Functions ¶
func MockAvailable ¶
func MockAvailable() bool
MockAvailable indicates if the mock can be accessed at runtime. It is always accessible at compile-time to make writing tests easier, but you should use:
ctx := context.Background() if wsl.MockAvailable() { m := mock.New() // set up the mock ... ctx = wsl.WithMock(ctx, m) }
Types ¶
type Cmd ¶
type Cmd struct { // Public parameters Stdin io.Reader // Reader to read stdin from Stdout io.Writer // Writer to write stdout into Stderr io.Writer // Writer to write stdout into UseCWD bool // Whether WSL is launched in the current working directory (true) or the home directory (false) // Book-keeping Process *os.Process // The windows handle to the WSL process ProcessState *os.ProcessState // Status of the process. Cached because it cannot be read after the process is closed. // contains filtered or unexported fields }
Cmd is a wrapper around the Windows process spawned by WslLaunch. Its interface is the same as the standard library's exec (except for func Command) and its implementation is very similar.
A Cmd cannot be reused after calling its Run method.
func (*Cmd) CombinedOutput ¶
CombinedOutput runs the command and returns its combined standard output and standard error.
func (*Cmd) Output ¶
Output runs the command and returns its standard output. Any returned error will usually be of type *ExitError. If c.Stderr was nil, Output populates ExitError.Stderr.
func (*Cmd) Run ¶
Run starts the specified WslProcess and waits for it to complete.
The returned error is nil if the command runs and exits with a zero exit status.
If the command fails to run or doesn't complete successfully, the error is of type *ExitError.
func (*Cmd) Start ¶
Start starts the specified command but does not wait for it to complete.
The Wait method will return the exit code and release associated resources once the command exits.
func (*Cmd) StderrPipe ¶
func (c *Cmd) StderrPipe() (r io.ReadCloser, err error)
StderrPipe returns a pipe that will be connected to the command's standard error when the command starts.
Wait will close the pipe after seeing the command exit, so most callers need not close the pipe themselves. It is thus incorrect to call Wait before all reads from the pipe have completed. For the same reason, it is incorrect to use Run when using StderrPipe.
func (*Cmd) StdinPipe ¶
func (c *Cmd) StdinPipe() (w io.WriteCloser, err error)
StdinPipe returns a pipe that will be connected to the command's standard input when the command starts. The pipe will be closed automatically after Wait sees the command exit. A caller need only call Close to force the pipe to close sooner. For example, if the command being run will not exit until standard input is closed, the caller must close the pipe.
func (*Cmd) StdoutPipe ¶
func (c *Cmd) StdoutPipe() (r io.ReadCloser, err error)
StdoutPipe returns a pipe that will be connected to the command's standard output when the command starts.
Wait will close the pipe after seeing the command exit, so most callers need not close the pipe themselves. It is thus incorrect to call Wait before all reads from the pipe have completed. For the same reason, it is incorrect to call Run when using StdoutPipe.
func (*Cmd) Wait ¶
Wait waits for the command to exit and waits for any copying to stdin or copying from stdout or stderr to complete.
The command must have been started by Start.
The returned error is nil if the command runs, has no problems copying stdin, stdout, and stderr, and exits with a zero exit status.
If the command fails to run or doesn't complete successfully, the error is of type ExitError. Other error types may be returned for I/O problems.
If any of c.Stdin, c.Stdout or c.Stderr are not an *os.File, Wait also waits for the respective I/O loop copying to or from the process to complete.
Wait releases any resources associated with the Cmd.
type Configuration ¶
type Configuration struct { Version uint8 // Type of filesystem used (lxfs vs. wslfs, relevant only to WSL1) DefaultUID uint32 // User ID of default user flags.Unpacked DefaultEnvironmentVariables map[string]string // Environment variables passed to the distro by default }
Configuration is the configuration of the distro.
type Distro ¶
type Distro struct {
// contains filtered or unexported fields
}
Distro is an abstraction around a WSL distro.
func DefaultDistro ¶
DefaultDistro gets the current default distribution.
func Import ¶
func Import(ctx context.Context, distributionName, sourcePath, destinationPath string) (Distro, error)
Import creates a new distro from a source root filesystem.
func NewDistro ¶
NewDistro declares a new distribution, but does not register it nor check if it exists.
func RegisteredDistros ¶
RegisteredDistros returns a slice of the registered distros.
func (*Distro) Command ¶
Command returns the Cmd struct to execute the named program with the given arguments in the same string.
It sets only the command and stdin/stdout/stderr in the returned structure.
The provided context is used to kill the process (by calling CloseHandle) if the context becomes done before the command completes on its own.
func (*Distro) DefaultUID ¶
DefaultUID sets the user to the one specified.
func (*Distro) DriveMountingEnabled ¶
DriveMountingEnabled sets the ENABLE_DRIVE_MOUNTING flag to the provided value. Enabling it mounts the windows filesystem into WSL's.
func (Distro) GetConfiguration ¶
func (d Distro) GetConfiguration() (c Configuration, err error)
GetConfiguration is a wrapper around Win32's WslGetDistributionConfiguration. It returns a configuration object with information about the distro.
func (*Distro) InteropEnabled ¶
InteropEnabled sets the ENABLE_INTEROP flag to the provided value. Enabling allows you to launch Windows executables from WSL.
func (Distro) IsRegistered ¶
IsRegistered returns a boolean indicating whether a distro is registered or not.
func (*Distro) PathAppended ¶
PathAppended sets the APPEND_NT_PATH flag to the provided value. Enabling it allows WSL to append /mnt/c/... (or wherever your mount point is) in front of Windows executables.
func (*Distro) Register ¶
Register is a wrapper around Win32's WslRegisterDistribution. It creates a new distro with a copy of the given tarball as its filesystem.
func (*Distro) SetAsDefault ¶
SetAsDefault sets a particular distribution as the default one. Equivalent to:
wsl --set-default <distro>
func (*Distro) Shell ¶
func (d *Distro) Shell(args ...ShellOption) (err error)
Shell is a wrapper around Win32's WslLaunchInteractive, which starts a shell on WSL with the specified command. If no command is specified, the default shell for that distro is launched.
If the command is interactive (e.g. python, sh, bash, fish, etc.) an interactive session is started. This is a synchronous, blocking call.
Stdout and Stderr are sent to the console, even if os.Stdout and os.Stderr are redirected:
PS> go run .\examples\demo.go > demo.log # This will not redirect the Shell
Stdin will read from os.Stdin but if you try to pass it via powershell strange things happen, same as if you did:
PS> "exit 5" | wsl.exe
Can be used with optional helper parameters UseCWD and WithCommand.
func (Distro) String ¶
String deserializes a distro its GUID and its configuration as a yaml string. If there is an error, it is printed as part of the yaml.
func (*Distro) Uninstall ¶
Uninstall removes the distro's associated AppxPackage (if there is one) and unregisters the distro.
func (*Distro) Unregister ¶
Unregister is a wrapper around Win32's WslUnregisterDistribution. It irreparably destroys a distro and its filesystem.
type ShellError ¶
type ShellError struct {
// contains filtered or unexported fields
}
ShellError returns error information when shell commands do not succeed.
func (*ShellError) Error ¶
func (err *ShellError) Error() string
Error makes it so ShellError implements the error interface. In displays the exit code and some auxiliary info.
We know that exit codes above 255 come from Windows, but error codes under 256 can come from both sides.
func (*ShellError) ExitCode ¶
func (err *ShellError) ExitCode() uint32
ExitCode is a getter for the exit code of the shell when it produces. Experimentally we've seen that linux produces exit codes under 255, and Windows produces them above or equal to 256.
type ShellOption ¶
type ShellOption func(*shellOptions)
ShellOption is an optional parameter for (*Distro).Shell. Use any of the provided functions such as UseCWD().
func UseCWD ¶
func UseCWD() ShellOption
UseCWD is an optional parameter for (*Distro).Shell that makes it so the shell is started on the current working directory. Otherwise, it starts at the distro's $HOME.
func WithCommand ¶
func WithCommand(cmd string) ShellOption
WithCommand is an optional parameter for (*Distro).Shell that allows you to shell into WSL with the specified command. Particularly useful to choose what shell to use. Otherwise, it uses the distro's default shell.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
internal
|
|
backend
Package backend defines all the actions that a back-end to GoWSL must be able to perform in order to run, or otherwise mock WSL.
|
Package backend defines all the actions that a back-end to GoWSL must be able to perform in order to run, or otherwise mock WSL. |
backend/windows
Package windows contains the production backend.
|
Package windows contains the production backend. |
flags
Package flags contains the enum used by WSL to display some configuration of a WSL distro.
|
Package flags contains the enum used by WSL to display some configuration of a WSL distro. |
state
Package state defines the state enum so that both backends can use it
|
Package state defines the state enum so that both backends can use it |
Package mock mocks the WSL api, useful for tests as it allows parallelism, decoupling, and execution speed.
|
Package mock mocks the WSL api, useful for tests as it allows parallelism, decoupling, and execution speed. |
internal/distrostate
Package distrostate implements the mocking of the state of the distro (i.e.
|
Package distrostate implements the mocking of the state of the distro (i.e. |