client

package
v0.0.0-...-326c00b Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2024 License: BSD-3-Clause Imports: 26 Imported by: 1

Documentation

Overview

Package client provides an exec.Command and ssh like interface for cpu sessions. It attempts to cleave as much as possible to the original. The choice between options and environment variables mirrors this effort. For example, the nonce for the mount protocol back is an environment variable. command name and arguments are passed in os.Args The only required parameter for Command() is a host name; if os.Args is empty, the remote server reads SHELL and starts a shell. Similarly, because the root for the client namespace is known only to the client. it is settable in the Cmd struct.

Index

Constants

View Source
const (

	// DefaultNameSpace is the default used if the user does not request
	// something else.
	DefaultNameSpace = "/lib:/lib64:/usr:/bin:/etc:/home"
)
View Source
const (
	// DefaultPort is the default cpu port.
	DefaultPort = "17010"
)

Variables

View Source
var (
	// DefaultKeyFile is the default key for cpu users.
	DefaultKeyFile = filepath.Join(os.Getenv("HOME"), ".ssh/cpu_rsa")
	// Debug9p enables 9p debugging.
	Debug9p bool
	// Dump9p enables dumping 9p packets.
	Dump9p bool
	// DumpWriter is an io.Writer to which dump packets are written.
	DumpWriter io.Writer = os.Stderr
)

Functions

func GetHostName

func GetHostName(host string) string

GetHostName reads the host name from the ssh config file, if needed. If it is not found, the host name is returned.

func GetKeyFile

func GetKeyFile(host, kf string) string

GetKeyFile picks a keyfile if none has been set. It will use ssh config, else use a default.

func GetPort

func GetPort(host, port string) (string, error)

GetPort gets a port. It verifies that the port fits in 16-bit space. The rules here are messy, since config.Get will return "22" if there is no entry in .ssh/config. 22 is not allowed. So in the case of "22", convert to defaultPort.

func SetVerbose

func SetVerbose(f func(string, ...interface{}))

SetVerbose sets the verbose printing function. e.g., one might call SetVerbose(log.Printf)

Types

type CPIO9P

type CPIO9P struct {
	p9.DefaultWalkGetAttr
	// contains filtered or unexported fields
}

CPIO9P is a p9.Attacher.

func NewCPIO9P

func NewCPIO9P(c string) (*CPIO9P, error)

NewCPIO9P returns a CPIO9P, properly initialized, from a path.

func NewCPIO9PReaderAt

func NewCPIO9PReaderAt(r io.ReaderAt) (*CPIO9P, error)

NewCPIO9PReaderAt returns a CPIO9P, properly initialized, from an io.ReaderAt.

func (*CPIO9P) Attach

func (s *CPIO9P) Attach() (p9.File, error)

Attach implements p9.Attacher.Attach. Only works for root.

type CPIO9PFID

type CPIO9PFID struct {
	p9.DefaultWalkGetAttr
	templatefs.XattrUnimplemented
	templatefs.NilCloser
	templatefs.NilSyncer
	templatefs.NoopRenamed
	// contains filtered or unexported fields
}

CPIO9PFile defines a FID. It kind of sucks because it has a pointer for every FID. Luckily they go away when clunked.

func (*CPIO9PFID) Create

func (l *CPIO9PFID) Create(name string, mode p9.OpenFlags, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.File, p9.QID, uint32, error)

Create implements p9.File.Create.

func (*CPIO9PFID) Flush

func (l *CPIO9PFID) Flush() error

Flush implements p9.File.Flush.

func (*CPIO9PFID) GetAttr

func (l *CPIO9PFID) GetAttr(req p9.AttrMask) (p9.QID, p9.AttrMask, p9.Attr, error)

GetAttr implements p9.File.GetAttr.

Not fully implemented.

func (l *CPIO9PFID) Link(target p9.File, newname string) error

Link implements p9.File.Link.

Not properly implemented.

func (*CPIO9PFID) Lock

func (*CPIO9PFID) Lock(pid int, locktype p9.LockType, flags p9.LockFlags, start, length uint64, client string) (p9.LockStatus, error)

Lock implements lock by doing nothing.

func (*CPIO9PFID) Mkdir

func (l *CPIO9PFID) Mkdir(name string, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.QID, error)

Mkdir implements p9.File.Mkdir.

Not properly implemented.

func (*CPIO9PFID) Mknod

func (*CPIO9PFID) Mknod(name string, mode p9.FileMode, major uint32, minor uint32, _ p9.UID, _ p9.GID) (p9.QID, error)

Mknod implements p9.File.Mknod.

func (*CPIO9PFID) Open

func (l *CPIO9PFID) Open(mode p9.OpenFlags) (p9.QID, uint32, error)

Open implements p9.File.Open.

func (*CPIO9PFID) ReadAt

func (l *CPIO9PFID) ReadAt(p []byte, offset int64) (int, error)

Read implements p9.File.ReadAt.

func (*CPIO9PFID) Readdir

func (l *CPIO9PFID) Readdir(offset uint64, count uint32) (p9.Dirents, error)

Readdir implements p9.File.Readdir. This is a bit of a mess in cpio, but the good news is that files will be in some sort of order ...

func (l *CPIO9PFID) Readlink() (string, error)

Readlink implements p9.File.Readlink.

func (*CPIO9PFID) Rename

func (*CPIO9PFID) Rename(directory p9.File, name string) error

Rename implements p9.File.Rename.

func (*CPIO9PFID) RenameAt

func (l *CPIO9PFID) RenameAt(oldName string, newDir p9.File, newName string) error

RenameAt implements p9.File.RenameAt. There is no guarantee that there is not a zipslip issue.

func (*CPIO9PFID) SetAttr

func (l *CPIO9PFID) SetAttr(mask p9.SetAttrMask, attr p9.SetAttr) error

SetAttr implements SetAttr.

func (*CPIO9PFID) StatFS

func (*CPIO9PFID) StatFS() (p9.FSStat, error)

StatFS implements p9.File.StatFS.

Not implemented.

func (l *CPIO9PFID) Symlink(oldname string, newname string, _ p9.UID, _ p9.GID) (p9.QID, error)

Symlink implements p9.File.Symlink.

Not properly implemented.

func (*CPIO9PFID) UnlinkAt

func (l *CPIO9PFID) UnlinkAt(name string, flags uint32) error

UnlinkAt implements p9.File.UnlinkAt.

func (*CPIO9PFID) Walk

func (l *CPIO9PFID) Walk(names []string) ([]p9.QID, p9.File, error)

Walk implements p9.File.Walk.

func (*CPIO9PFID) WriteAt

func (l *CPIO9PFID) WriteAt(p []byte, offset int64) (int, error)

Write implements p9.File.WriteAt.

type CPU9P

type CPU9P struct {
	p9.DefaultWalkGetAttr
	// contains filtered or unexported fields
}

CPU9P is a p9.Attacher.

func NewCPU9P

func NewCPU9P(root string) *CPU9P

NewCPU9P returns a CPU9P, properly initialized.

func (*CPU9P) Attach

func (l *CPU9P) Attach() (p9.File, error)

Attach implements p9.Attacher.Attach.

func (*CPU9P) Close

func (l *CPU9P) Close() error

Close implements p9.File.Close.

func (*CPU9P) Create

func (l *CPU9P) Create(name string, mode p9.OpenFlags, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.File, p9.QID, uint32, error)

Create implements p9.File.Create.

func (*CPU9P) FSync

func (l *CPU9P) FSync() error

FSync implements p9.File.FSync.

func (*CPU9P) Flush

func (l *CPU9P) Flush() error

Flush implements p9.File.Flush.

func (*CPU9P) GetAttr

func (l *CPU9P) GetAttr(req p9.AttrMask) (p9.QID, p9.AttrMask, p9.Attr, error)

GetAttr implements p9.File.GetAttr.

Not fully implemented.

func (*CPU9P) GetXattr

func (l *CPU9P) GetXattr(attr string) ([]byte, error)

GetXattr implements p9.File.GetXattr

func (l *CPU9P) Link(target p9.File, newname string) error

Link implements p9.File.Link.

Not properly implemented.

func (*CPU9P) ListXattrs

func (l *CPU9P) ListXattrs() ([]string, error)

ListXattrs implements p9.File.ListXattrs

func (*CPU9P) Lock

func (l *CPU9P) Lock(pid int, locktype p9.LockType, flags p9.LockFlags, start, length uint64, client string) (p9.LockStatus, error)

Lock implements p9.File.Lock.

func (*CPU9P) Mkdir

func (l *CPU9P) Mkdir(name string, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.QID, error)

Mkdir implements p9.File.Mkdir.

Not properly implemented.

func (*CPU9P) Mknod

func (*CPU9P) Mknod(name string, mode p9.FileMode, major uint32, minor uint32, _ p9.UID, _ p9.GID) (p9.QID, error)

Mknod implements p9.File.Mknod.

func (*CPU9P) Open

func (l *CPU9P) Open(mode p9.OpenFlags) (p9.QID, uint32, error)

Open implements p9.File.Open.

func (*CPU9P) ReadAt

func (l *CPU9P) ReadAt(p []byte, offset int64) (int, error)

Read implements p9.File.ReadAt.

func (*CPU9P) Readdir

func (l *CPU9P) Readdir(offset uint64, count uint32) (p9.Dirents, error)

Readdir implements p9.File.Readdir.

func (l *CPU9P) Readlink() (string, error)

Readlink implements p9.File.Readlink.

func (*CPU9P) Remove

func (l *CPU9P) Remove() error

Remove implements p9.File.Remove

func (*CPU9P) RemoveXattr

func (l *CPU9P) RemoveXattr(attr string) error

RemoveXattr implements p9.File.RemoveXattr

func (*CPU9P) Rename

func (*CPU9P) Rename(directory p9.File, name string) error

Rename implements p9.File.Rename.

func (*CPU9P) RenameAt

func (l *CPU9P) RenameAt(oldName string, newDir p9.File, newName string) error

RenameAt implements p9.File.RenameAt. There is no guarantee that there is not a zipslip issue.

func (*CPU9P) Renamed

func (l *CPU9P) Renamed(parent p9.File, newName string)

Renamed implements p9.File.Renamed.

func (*CPU9P) SetAttr

func (l *CPU9P) SetAttr(mask p9.SetAttrMask, attr p9.SetAttr) error

SetAttr implements p9.File.SetAttr.

func (*CPU9P) SetXattr

func (l *CPU9P) SetXattr(attr string, data []byte, flags p9.XattrFlags) error

SetXattr implements p9.File.SetXattr

func (*CPU9P) StatFS

func (*CPU9P) StatFS() (p9.FSStat, error)

StatFS implements p9.File.StatFS.

Not implemented.

func (l *CPU9P) Symlink(oldname string, newname string, _ p9.UID, _ p9.GID) (p9.QID, error)

Symlink implements p9.File.Symlink.

Not properly implemented.

func (*CPU9P) UnlinkAt

func (l *CPU9P) UnlinkAt(name string, flags uint32) error

UnlinkAt implements p9.File.UnlinkAt. The flags docs are not very clear, but we always block on the unlink anyway.

func (*CPU9P) Walk

func (l *CPU9P) Walk(names []string) ([]p9.QID, p9.File, error)

Walk implements p9.File.Walk.

func (*CPU9P) WriteAt

func (l *CPU9P) WriteAt(p []byte, offset int64) (int, error)

Write implements p9.File.WriteAt. There is a very rare case where O_APPEND files are written more than once, and we get an error. That error is generated by the Go runtime, after checking the open flag in the os.File struct. I.e. the error is not generated by a system call, so it is very cheap to try the WriteAt, check the error, and call Write if it is the rare case of a second write to an append-only file..

type Cmd

type Cmd struct {

	// CPU-specific options.
	// As in exec.Command, these controls are exposed and can
	// be set directly.
	Host string
	// HostName as found in .ssh/config; set to Host if not found
	HostName          string
	Args              []string
	Root              string
	HostKeyFile       string
	PrivateKeyFile    string
	DisablePrivateKey bool
	Port              string
	Timeout           time.Duration
	Env               []string
	SessionIn         io.WriteCloser
	SessionOut        io.Reader
	SessionErr        io.Reader
	Stdin             io.Reader
	Stdout            io.Writer
	Stderr            io.Writer
	Row               int
	Col               int

	// NameSpace is a string as defined in the cpu documentation.
	NameSpace string
	// FSTab is an fstab(5)-format string
	FSTab string
	// Ninep determines if client will run a 9P server
	Ninep bool
	// contains filtered or unexported fields
}

Cmd is a cpu client. It implements as much of exec.Command as makes sense.

func Command

func Command(host string, args ...string) *Cmd

Command implements exec.Command. The required parameter is a host. The args arg args to $SHELL. If there are no args, then starting $SHELL is assumed.

func (*Cmd) Close

func (c *Cmd) Close() error

Close ends a cpu session, doing whatever is needed.

func (*Cmd) Dial

func (c *Cmd) Dial() error

Dial implements ssh.Dial for cpu. Additionaly, if Cmd.Root is not "", it starts up a server for 9p requests. Note that any bind parsing is deferred until this point, to avoid callers getting ordering of setting variables in the Cmd wrong.

func (*Cmd) HostKeyConfig

func (c *Cmd) HostKeyConfig(hostKeyFile string) error

HostKeyConfig sets the host key. It is optional.

func (*Cmd) Listen

func (c *Cmd) Listen(n, addr string) (net.Listener, error)

Listen implements net.Listen on the ssh socket.

func (*Cmd) Outputs

func (c *Cmd) Outputs() ([]bytes.Buffer, error)

Outputs returns a slice of bytes.Buffer for stdout and stderr, and an error if either had trouble being read.

func (*Cmd) Run

func (c *Cmd) Run() error

Run runs a command with Start, and waits for it to finish with Wait.

func (*Cmd) SSHStdin

func (c *Cmd) SSHStdin(w io.WriteCloser, r io.Reader)

SSHStdin implements an ssh-like reader, honoring ~ commands.

func (*Cmd) SetEnv

func (c *Cmd) SetEnv(envs ...string) error

SetEnv sets zero or more environment variables for a Session. If envs is nil or a zero length slice, no variables are set.

func (*Cmd) SetOptions

func (c *Cmd) SetOptions(opts ...Set) error

SetOptions sets various options into the Command.

func (*Cmd) SetupInteractive

func (c *Cmd) SetupInteractive() error

SetupInteractive sets up a cpu client for interactive access. It adds a function to c.Closers to clean up the terminal.

func (*Cmd) Signal

func (c *Cmd) Signal(s ssh.Signal) error

Signal implements ssh.Signal

func (*Cmd) Start

func (c *Cmd) Start() error

Start implements exec.Start for CPU.

func (*Cmd) TTYIn

func (c *Cmd) TTYIn(s *ssh.Session, w io.WriteCloser, r io.Reader)

TTYIn manages tty input for a cpu session. It exists mainly to deal with ~.

func (*Cmd) UserKeyConfig

func (c *Cmd) UserKeyConfig() error

UserKeyConfig sets up authentication for a User Key. It is required in almost all cases.

func (*Cmd) Wait

func (c *Cmd) Wait() error

Wait waits for a Cmd to finish.

type Set

type Set func(*Cmd) error

Set is the type of function used to set options in SetOptions.

func With9P

func With9P(p9 bool) Set

With9P enables the 9P2000 server in cpu. The server is by default disabled. Ninep is sticky; if set by, e.g., WithNameSpace, the Principle of Least Confusion argues that it should remain set. Hence, we || it with its current value.

func WithDisablePrivateKey

func WithDisablePrivateKey(disable bool) Set

WithDisablePrivateKey disables using private keys to encrypt the SSH connection.

func WithFSTab

func WithFSTab(fstab string) Set

WithFSTab reads a file for the FSTab member.

func WithHostKeyFile

func WithHostKeyFile(key string) Set

WithHostKeyFile adds a host key to a Cmd

func WithNameSpace

func WithNameSpace(ns string) Set

WithNameSpace sets the namespace to Cmd.There is no default: having some default violates the principle of least surprise for package users. If ns is non-empty the Ninep is forced on.

func WithNetwork

func WithNetwork(network string) Set

WithNetwork sets the network. This almost never needs to be set, save for vsock.

func WithPort

func WithPort(port string) Set

WithPort sets the port in the Cmd. It calls GetPort with the passed-in port before assigning it.

func WithPrivateKeyFile

func WithPrivateKeyFile(key string) Set

WithPrivateKeyFile adds a private key file to a Cmd

func WithRoot

func WithRoot(root string) Set

WithRoot adds a root to a Cmd

func WithServer

func WithServer(a p9.Attacher) Set

WithServer allows setting custom 9P servers. One use: should users wish to serve from a flattened docker container saved as a cpio or tar.

func WithTimeout

func WithTimeout(timeout string) Set

WithTimeout sets the 9p timeout.

type Union9P

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

Union9P is a p9.Attacher.

func NewUnion9P

func NewUnion9P(mounts []UnionMount) (*Union9P, error)

NewUnion9P returns a Union9P, properly initialized, from a []UnionMount. Each UnionMount has a []string that defines a walk path. The []string argument is matched to each walk path in the []UnionMount in turn. As in Plan 9, the first match is used; if the walk to that server fails, the code returns the error; it does not go any further.

I.e., if /home and /home/rminnich are in the table, they need to be in the order /home/rminnich /home in the case that the second mount does not include /home/rminnich. (it could be from a different 9p server, for example). Having a UnionMount with an empty []string is allowed; this will match any walk []string and hence acts as a default.

For example, in Sidecore, the code looks like this: home, err := NewCPU9P(...) container, err := NewCPIO9(...) m1 := NewUnionMount([]string{"/home"}, home) m2 := NewUnionMount([]string{}, container) u := NewUnion9P([]UnionMount{home, container}) This ensures /home matches first, and the container CPIO matches the rest.

If a default is not desired, callers should only use Union Mount structs with non-empty []string. Only one Mount with an empty walk slice should be used, as the search will always stop there. It is allowed to have multiple Mounts for a single p9.File. E.g, give a p9.File, f, once can: m1 := NewUnionMount([]string{"/etc", f) m2 := NewUnionMount([]string{"/bin", f) u := NewUnion9P([]UnionMount{m1, m2}) and no matter what other directories exist in f, only /etc and /bin will match.

Again, to add a default case, using, e.g., another p9.File, one might have m1 := NewUnionMount([]string{"/etc}", f) m2 := NewUnionMount([]string{"/bin}", f) mdefault := NewUnionMount([]string{""}, fi2) u := NewUnion9P([]UnionMount{m1, m2, mdefault})

func (*Union9P) Attach

func (u *Union9P) Attach() (p9.File, error)

Attach implements p9.Attacher.Attach.

type UnionMount

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

Bind is a single bind For a given Twalk, the walk []string will be compared to the string slice in the Twalk. If there is match, the mount is called with the complete Twalk []string.

func NewUnionMount

func NewUnionMount(w []string, m p9.File) UnionMount

NewUnionMount creates a new Union Mount from a []string and a p9.File.

Jump to

Keyboard shortcuts

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