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
- Variables
- func GetHostName(host string) string
- func GetKeyFile(host, kf string) string
- func GetPort(host, port string) (string, error)
- func SetVerbose(f func(string, ...interface{}))
- type CPIO9P
- type CPIO9PFID
- func (l *CPIO9PFID) Create(name string, mode p9.OpenFlags, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.File, p9.QID, uint32, error)
- func (l *CPIO9PFID) Flush() error
- func (l *CPIO9PFID) GetAttr(req p9.AttrMask) (p9.QID, p9.AttrMask, p9.Attr, error)
- func (l *CPIO9PFID) Link(target p9.File, newname string) error
- func (*CPIO9PFID) Lock(pid int, locktype p9.LockType, flags p9.LockFlags, start, length uint64, ...) (p9.LockStatus, error)
- func (l *CPIO9PFID) Mkdir(name string, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.QID, error)
- func (*CPIO9PFID) Mknod(name string, mode p9.FileMode, major uint32, minor uint32, _ p9.UID, _ p9.GID) (p9.QID, error)
- func (l *CPIO9PFID) Open(mode p9.OpenFlags) (p9.QID, uint32, error)
- func (l *CPIO9PFID) ReadAt(p []byte, offset int64) (int, error)
- func (l *CPIO9PFID) Readdir(offset uint64, count uint32) (p9.Dirents, error)
- func (l *CPIO9PFID) Readlink() (string, error)
- func (*CPIO9PFID) Rename(directory p9.File, name string) error
- func (l *CPIO9PFID) RenameAt(oldName string, newDir p9.File, newName string) error
- func (l *CPIO9PFID) SetAttr(mask p9.SetAttrMask, attr p9.SetAttr) error
- func (*CPIO9PFID) StatFS() (p9.FSStat, error)
- func (l *CPIO9PFID) Symlink(oldname string, newname string, _ p9.UID, _ p9.GID) (p9.QID, error)
- func (l *CPIO9PFID) UnlinkAt(name string, flags uint32) error
- func (l *CPIO9PFID) Walk(names []string) ([]p9.QID, p9.File, error)
- func (l *CPIO9PFID) WriteAt(p []byte, offset int64) (int, error)
- type CPU9P
- func (l *CPU9P) Attach() (p9.File, error)
- func (l *CPU9P) Close() error
- func (l *CPU9P) Create(name string, mode p9.OpenFlags, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.File, p9.QID, uint32, error)
- func (l *CPU9P) FSync() error
- func (l *CPU9P) Flush() error
- func (l *CPU9P) GetAttr(req p9.AttrMask) (p9.QID, p9.AttrMask, p9.Attr, error)
- func (l *CPU9P) GetXattr(attr string) ([]byte, error)
- func (l *CPU9P) Link(target p9.File, newname string) error
- func (l *CPU9P) ListXattrs() ([]string, error)
- func (l *CPU9P) Lock(pid int, locktype p9.LockType, flags p9.LockFlags, start, length uint64, ...) (p9.LockStatus, error)
- func (l *CPU9P) Mkdir(name string, permissions p9.FileMode, _ p9.UID, _ p9.GID) (p9.QID, error)
- func (*CPU9P) Mknod(name string, mode p9.FileMode, major uint32, minor uint32, _ p9.UID, _ p9.GID) (p9.QID, error)
- func (l *CPU9P) Open(mode p9.OpenFlags) (p9.QID, uint32, error)
- func (l *CPU9P) ReadAt(p []byte, offset int64) (int, error)
- func (l *CPU9P) Readdir(offset uint64, count uint32) (p9.Dirents, error)
- func (l *CPU9P) Readlink() (string, error)
- func (l *CPU9P) Remove() error
- func (l *CPU9P) RemoveXattr(attr string) error
- func (*CPU9P) Rename(directory p9.File, name string) error
- func (l *CPU9P) RenameAt(oldName string, newDir p9.File, newName string) error
- func (l *CPU9P) Renamed(parent p9.File, newName string)
- func (l *CPU9P) SetAttr(mask p9.SetAttrMask, attr p9.SetAttr) error
- func (l *CPU9P) SetXattr(attr string, data []byte, flags p9.XattrFlags) error
- func (*CPU9P) StatFS() (p9.FSStat, error)
- func (l *CPU9P) Symlink(oldname string, newname string, _ p9.UID, _ p9.GID) (p9.QID, error)
- func (l *CPU9P) UnlinkAt(name string, flags uint32) error
- func (l *CPU9P) Walk(names []string) ([]p9.QID, p9.File, error)
- func (l *CPU9P) WriteAt(p []byte, offset int64) (int, error)
- type Cmd
- func (c *Cmd) Close() error
- func (c *Cmd) Dial() error
- func (c *Cmd) HostKeyConfig(hostKeyFile string) error
- func (c *Cmd) Listen(n, addr string) (net.Listener, error)
- func (c *Cmd) Outputs() ([]bytes.Buffer, error)
- func (c *Cmd) Run() error
- func (c *Cmd) SSHStdin(w io.WriteCloser, r io.Reader)
- func (c *Cmd) SetEnv(envs ...string) error
- func (c *Cmd) SetOptions(opts ...Set) error
- func (c *Cmd) SetupInteractive() error
- func (c *Cmd) Signal(s ssh.Signal) error
- func (c *Cmd) Start() error
- func (c *Cmd) TTYIn(s *ssh.Session, w io.WriteCloser, r io.Reader)
- func (c *Cmd) UserKeyConfig() error
- func (c *Cmd) Wait() error
- type Set
- func With9P(p9 bool) Set
- func WithDisablePrivateKey(disable bool) Set
- func WithFSTab(fstab string) Set
- func WithHostKeyFile(key string) Set
- func WithNameSpace(ns string) Set
- func WithNetwork(network string) Set
- func WithPort(port string) Set
- func WithPrivateKeyFile(key string) Set
- func WithRoot(root string) Set
- func WithServer(a p9.Attacher) Set
- func WithTimeout(timeout string) Set
- type Union9P
- type UnionMount
Constants ¶
const ( // DefaultNameSpace is the default used if the user does not request // something else. DefaultNameSpace = "/lib:/lib64:/usr:/bin:/etc:/home" )
const (
// DefaultPort is the default cpu port.
DefaultPort = "17010"
)
Variables ¶
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 ¶
GetHostName reads the host name from the ssh config file, if needed. If it is not found, the host name is returned.
func GetKeyFile ¶
GetKeyFile picks a keyfile if none has been set. It will use ssh config, else use a default.
func GetPort ¶
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 NewCPIO9PReaderAt ¶
NewCPIO9PReaderAt returns a CPIO9P, properly initialized, from an io.ReaderAt.
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) 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) 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) Readdir ¶
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 (*CPIO9PFID) RenameAt ¶
RenameAt implements p9.File.RenameAt. There is no guarantee that there is not a zipslip issue.
type CPU9P ¶
type CPU9P struct { p9.DefaultWalkGetAttr // contains filtered or unexported fields }
CPU9P is a p9.Attacher.
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) ListXattrs ¶
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) 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) RemoveXattr ¶
RemoveXattr implements p9.File.RemoveXattr
func (*CPU9P) RenameAt ¶
RenameAt implements p9.File.RenameAt. There is no guarantee that there is not a zipslip issue.
func (*CPU9P) UnlinkAt ¶
UnlinkAt implements p9.File.UnlinkAt. The flags docs are not very clear, but we always block on the unlink anyway.
func (*CPU9P) WriteAt ¶
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 ¶
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) Dial ¶
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 ¶
HostKeyConfig sets the host key. It is optional.
func (*Cmd) Outputs ¶
Outputs returns a slice of bytes.Buffer for stdout and stderr, and an error if either had trouble being read.
func (*Cmd) SSHStdin ¶
func (c *Cmd) SSHStdin(w io.WriteCloser, r io.Reader)
SSHStdin implements an ssh-like reader, honoring ~ commands.
func (*Cmd) SetEnv ¶
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 ¶
SetOptions sets various options into the Command.
func (*Cmd) SetupInteractive ¶
SetupInteractive sets up a cpu client for interactive access. It adds a function to c.Closers to clean up the terminal.
func (*Cmd) UserKeyConfig ¶
UserKeyConfig sets up authentication for a User Key. It is required in almost all cases.
type Set ¶
Set is the type of function used to set options in SetOptions.
func With9P ¶
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 ¶
WithDisablePrivateKey disables using private keys to encrypt the SSH connection.
func WithHostKeyFile ¶
WithHostKeyFile adds a host key to a Cmd
func WithNameSpace ¶
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 ¶
WithNetwork sets the network. This almost never needs to be set, save for vsock.
func WithPort ¶
WithPort sets the port in the Cmd. It calls GetPort with the passed-in port before assigning it.
func WithPrivateKeyFile ¶
WithPrivateKeyFile adds a private key file to a Cmd
func WithServer ¶
WithServer allows setting custom 9P servers. One use: should users wish to serve from a flattened docker container saved as a cpio or tar.
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})
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.