Documentation
¶
Index ¶
- Constants
- Variables
- func CreateProcess(name string, args ...string) error
- func CreateProcessForeground(name string, args ...string) error
- func NewCommand(name string, args ...string) *exec.Cmd
- type APICommand
- type BaseBuild
- type BaseInstance
- func (i *BaseInstance) Close()
- func (i *BaseInstance) Get(fuzzerName, targetSrc, hostDst string) error
- func (i *BaseInstance) Handle() (Handle, error)
- func (i *BaseInstance) ListFuzzers() []string
- func (i *BaseInstance) Put(fuzzerName, hostSrc, targetDst string) error
- func (i *BaseInstance) RunFuzzer(out io.Writer, name, hostArtifactDir string, args ...string) error
- func (i *BaseInstance) Start() error
- func (i *BaseInstance) Stop() error
- type Build
- type Connector
- type Fuzzer
- type Handle
- type Instance
- type InstanceCmd
- type InstanceCmdError
- type Launcher
- type QemuLauncher
- type SSHConnector
- func (c *SSHConnector) Close()
- func (c *SSHConnector) Command(name string, args ...string) InstanceCmd
- func (c *SSHConnector) Connect() error
- func (c *SSHConnector) Get(targetSrc string, hostDst string) error
- func (c *SSHConnector) GetSysLog(pid int) (string, error)
- func (c *SSHConnector) Put(hostSrc string, targetDst string) error
- type SSHInstanceCmd
- func (c *SSHInstanceCmd) Kill() error
- func (c *SSHInstanceCmd) Output() ([]byte, error)
- func (c *SSHInstanceCmd) Run() error
- func (c *SSHInstanceCmd) SetTimeout(duration time.Duration)
- func (c *SSHInstanceCmd) Start() error
- func (c *SSHInstanceCmd) StdinPipe() (io.WriteCloser, error)
- func (c *SSHInstanceCmd) StdoutPipe() (io.ReadCloser, error)
- func (c *SSHInstanceCmd) Wait() error
Constants ¶
const ( VersionMajor = 0 VersionMinor = 1 VersionPatch = 0 )
API version
const ( StartInstance = "start_instance" StopInstance = "stop_instance" ListFuzzers = "list_fuzzers" RunFuzzer = "run_fuzzer" GetData = "get_data" PutData = "put_data" Version = "version" )
Available subcommand names TODO(fxbug.dev/47231): add resolve_fuzzer command
const ( FakeQemuNormal = "qemu-system-x86_64" FakeQemuFailing = "failing-qemu" FakeQemuSlow = "slow-qemu" )
Variables ¶
var Archs = map[string]struct { Binary string Kernel string }{ "x64": {"qemu-system-x86_64", "multiboot.bin"}, "arm64": {"qemu-system-aarch64", "qemu-boot-shim.bin"}, }
var ExecCommand = exec.Command
ExecCommand is the function used by CreateProcess to create Cmd objects. Test code can replace the default to mock process creation.
var NewBuild = NewBuildFromEnvironment
This is stubbed out to allow for test code to replace it
var Platforms = map[string]string{
"linux": "linux",
"darwin": "mac",
}
Functions ¶
func CreateProcess ¶
Run a command to completion
func CreateProcessForeground ¶
CreateProcessForeground is like CreateProcess but passes through any command output
Types ¶
type APICommand ¶
type APICommand struct {
// contains filtered or unexported fields
}
An APICommand is the structured result of parsing the command-line args
func ParseArgs ¶
func ParseArgs(args []string) (*APICommand, error)
ParseArgs converts command-line args into an API-command
type BaseBuild ¶
BaseBuild is a simple implementation of the Build interface
func (*BaseBuild) ListFuzzers ¶
ListFuzzers lists the names of fuzzers present in the build TODO(fxbug.dev/45108): handle variant stripping
func (*BaseBuild) LoadFuzzers ¶
LoadFuzzers reads and parses fuzzers.json to populate the build's map of Fuzzers. Unless an error is returned, any previously loaded fuzzers will be discarded.
func (*BaseBuild) Path ¶
Path returns the absolute paths to the list of files indicated by keys. This allows callers to abstract away the detail of where specific file resources are.
type BaseInstance ¶
BaseInstance groups the core subobjects, to which most work will be delegated
func (*BaseInstance) Close ¶
func (i *BaseInstance) Close()
Close releases the Instance, but doesn't Stop it
func (*BaseInstance) Get ¶
func (i *BaseInstance) Get(fuzzerName, targetSrc, hostDst string) error
Get copies files from a fuzzer namespace on the Instance to the host
func (*BaseInstance) Handle ¶
func (i *BaseInstance) Handle() (Handle, error)
Handle returns a Handle representing the Instance
func (*BaseInstance) ListFuzzers ¶
func (i *BaseInstance) ListFuzzers() []string
ListFuzzers lists fuzzers available on the Instance
func (*BaseInstance) Put ¶
func (i *BaseInstance) Put(fuzzerName, hostSrc, targetDst string) error
Put copies files from the host to a fuzzer namespace on the Instance
func (*BaseInstance) RunFuzzer ¶
RunFuzzer runs the named fuzzer on the Instance. If `hostArtifactDir` is specified and the run generated any output artifacts, they will be copied to that directory. `args` is an optional list of arguments in the form `-key=value` that will be passed to libFuzzer.
func (*BaseInstance) Start ¶
func (i *BaseInstance) Start() error
Start boots up the instance and waits for connectivity to be established
type Build ¶
type Build interface {
// Ensures all the needed resources are present and fetches any that are
// missing. Multiple calls to Prepare should be idempotent for the same
// Build.
Prepare() error
// Returns a fuzzer specified by a `package/binary` name, or an error if it
// isn't found.
Fuzzer(name string) (*Fuzzer, error)
// Returns the absolute host paths for each key. Each key corresponds to a
// specific resource provided by the Build. This abstraction allows for
// different build types to have different structures.
Path(keys ...string) ([]string, error)
// Reads input from `in`, symbolizes it, and writes it back to `out`.
// Returns on error, or when `in` has no more data to read. Processing
// will be streamed, line-by-line.
// TODO(fxbug.dev/47482): does this belong elsewhere?
Symbolize(in io.Reader, out io.Writer) error
// Returns a list of the names of the fuzzers that are available to run
ListFuzzers() []string
}
A Build represents a Fuchsia build, consisting of all the resources needed to run a fuzzer on an instance (e.g. a Fuchsia image, fuzzer packages and metadata, binary symbols, support utilities, etc.).
func NewBuildFromEnvironment ¶
Attempt to auto-detect the correct Build type
func NewClusterFuzzLegacyBuild ¶
NewClusterFuzzLegacyBuild will create a BaseBuild with path layouts corresponding to the legacy build bundles used by ClusterFuzz's original Python integration. Note that these build bundles only support x64.
func NewLocalFuchsiaBuild ¶
NewLocalFuchsiaBuild will create a BaseBuild with path layouts corresponding to a local Fuchsia checkout
type Connector ¶
type Connector interface {
// Connect establishes all necessary connections to the instance. It does
// not need to be explicitly called, because the other Connector methods will
// automatically connect if necessary, but may be called during initializiation.
// It the connector is already connected, an error will be returned.
Connect() error
// Close closes any open connections to the instance. It is the client's
// responsibility to call Close() when cleaning up the Connector.
Close()
// Returns an InstanceCmd representing the command to be run on the instance. Only one
// command should be active at a time.
// TODO(fxbug.dev/47479): In some cases, we should be able to relax the above restriction
Command(name string, args ...string) InstanceCmd
// Copies targetSrc (may include globs) to hostDst, which is always assumed
// to be a directory. Directories are copied recursively.
Get(targetSrc, hostDst string) error
// Copies hostSrc (may include globs) to targetDst, which is always assumed
// to be a directory. Directories are copied recursively.
Put(hostSrc, targetDst string) error
// Retrieves a syslog from the instance, filtered to the given process ID
GetSysLog(pid int) (string, error)
}
A Connector is used to communicate with an instance
type Fuzzer ¶
type Fuzzer struct {
// Name is `package/binary`
Name string
// contains filtered or unexported fields
}
A Fuzzer represents a fuzzer present on an instance.
func (*Fuzzer) AbsPath ¶
AbsPath returns the absolute target path for a given relative path in a fuzzer package. The path may differ depending on whether it is identified as a resource, data, or neither.
func (*Fuzzer) Parse ¶
Parse command line arguments for the fuzzer. For '-key=val' style options, the last 'val' for a given 'key' is used.
type Handle ¶
type Handle []byte
A Handle provides a way to serialize information about an Instance. A Handle must be immutable for the lifetime of the Instance.
func LoadHandleFromString ¶
LoadHandleFromString creates a Handle from its string representation as returned by Serialize()
func NewHandleFromObjects ¶
NewHandleFromObjects creates a Handle encoding data from the provided objects All exported fields of the objects will be captured, and merged
func (Handle) PopulateObject ¶
PopulateObject will load configuration data from the Handle into the provided object Field names must be globally unique
type Instance ¶
type Instance interface {
Start() error
Stop() error
ListFuzzers() []string
Get(fuzzerName, targetSrc, hostDst string) error
Put(fuzzerName, hostSrc, targetDst string) error
RunFuzzer(out io.Writer, name, hostArtifactDir string, args ...string) error
Handle() (Handle, error)
Close()
}
An Instance is a specific combination of build, connector, and launcher, representable by a handle. Most methods of this interface map directly to the ClusterFuchsia API.
type InstanceCmd ¶
type InstanceCmd interface {
// Output runs the command and returns its combined output.
Output() ([]byte, error)
// Runs the specified command and waits for it to complete.
//
// The returned error is nil if the command runs, has no problems copying
// input and output, and exits with a zero exit status.
Run() error
// Start starts the specified command but does not wait for it to complete.
Start() error
// StdinPipe returns a pipe that will be connected to the command's 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 the input is closed, the caller must close the pipe.
StdinPipe() (io.WriteCloser, error)
// StdoutPipe returns a pipe that will be connected to the command's output
// when the command starts.
//
// Wait will close the pipe after seeing the command exit, so most callers
// need not close the pipe themselves; however, an implication is that it
// is 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.
StdoutPipe() (io.ReadCloser, error)
// Wait waits for the command to exit and waits for any copying
// to input or from output to complete.
//
// The command must have been started by Start.
//
// The returned error is nil if the command runs, has no problems
// copying input and output, and exits with a zero exit status
// before any timeout set with SetTimeout is triggered.
//
// Wait releases any resources associated with the InstanceCmd.
Wait() error
// SetTimeout sets a timeout that will be used for all blocking
// methods. If a method takes longer than the timeout duration to
// complete, it will return early with an error. If not set, or
// set to 0, methods will block forever.
SetTimeout(duration time.Duration)
// Kill forcefully terminates the remote command
Kill() error
}
An InstanceCmd represents a remote command to be run on an Instance This interface is similar to that of os.exec.Cmd
type InstanceCmdError ¶
InstanceCmdError includes extra information when commands fail
func (*InstanceCmdError) Error ¶
func (e *InstanceCmdError) Error() string
type Launcher ¶
type Launcher interface {
// Do any preparation necessary before starting. This is idempotent, and
// does not need to be explicitly called by the client, as it will be
// automatically called by Start as necessary.
Prepare() error
// Starts the instance, returning a Connector that can be used to communicate with it
Start() (Connector, error)
// Returns true iff the instance is running.
IsRunning() (bool, error)
// Stops the instance. This is allowed to take up to 3 seconds to return.
Kill() error
}
A Launcher manages the lifecycle of an instance; e.g. starting and stopping
type QemuLauncher ¶
A QemuLauncher starts Fuchsia on QEMU
func NewQemuLauncher ¶
func NewQemuLauncher(build Build) *QemuLauncher
NewQemuLauncher constructs a new QemuLauncher
func (*QemuLauncher) IsRunning ¶
func (q *QemuLauncher) IsRunning() (bool, error)
IsRunning checks if the qemu process is alive
func (*QemuLauncher) Kill ¶
func (q *QemuLauncher) Kill() error
Kill tells the QEMU process to terminate, and cleans up the TmpDir
func (*QemuLauncher) Prepare ¶
func (q *QemuLauncher) Prepare() error
Prepare files that are needed by QEMU, if they haven't already been prepared
func (*QemuLauncher) Start ¶
func (q *QemuLauncher) Start() (Connector, error)
Start launches QEMU and waits for it to get through the basic boot sequence. Note that networking will not necessarily be fully up by the time Start() returns
type SSHConnector ¶
type SSHConnector struct {
// Host can be any IP or hostname as accepted by net.Dial
Host string
Port int
// Key is a path to the SSH private key that should be used for
// authentication
Key string
// contains filtered or unexported fields
}
An SSHConnector is a Connector that uses SSH/SFTP for transport Note: exported fields will be serialized to the handle
func (*SSHConnector) Command ¶
func (c *SSHConnector) Command(name string, args ...string) InstanceCmd
Command returns an InstanceCmd that can be used to given command over SSH
func (*SSHConnector) Get ¶
func (c *SSHConnector) Get(targetSrc string, hostDst string) error
Get fetches files over SFTP
type SSHInstanceCmd ¶
type SSHInstanceCmd struct {
// contains filtered or unexported fields
}
A SSHInstanceCmd represents a command to be run over SSH
func (*SSHInstanceCmd) Kill ¶
func (c *SSHInstanceCmd) Kill() error
Kill sends a KILL signal to the remote process
func (*SSHInstanceCmd) Output ¶
func (c *SSHInstanceCmd) Output() ([]byte, error)
Output executes the command and returns its output
func (*SSHInstanceCmd) Run ¶
func (c *SSHInstanceCmd) Run() error
Run runs the command to completion
func (*SSHInstanceCmd) SetTimeout ¶
func (c *SSHInstanceCmd) SetTimeout(duration time.Duration)
SetTimeout sets the global timeout
func (*SSHInstanceCmd) Start ¶
func (c *SSHInstanceCmd) Start() error
Start the command, but don't wait for it to complete
func (*SSHInstanceCmd) StdinPipe ¶
func (c *SSHInstanceCmd) StdinPipe() (io.WriteCloser, error)
StdinPipe returns a pipe connected to the command's input
func (*SSHInstanceCmd) StdoutPipe ¶
func (c *SSHInstanceCmd) StdoutPipe() (io.ReadCloser, error)
StdoutPipe returns a pipe connected to the command's output TODO(fxbug.dev/45424): this currently includes stderr in addition to stdout TODO(fxbug.dev/45424): use ssh.Session's implementation of pipe stuff, etc
func (*SSHInstanceCmd) Wait ¶
func (c *SSHInstanceCmd) Wait() error
Wait for the remote command to complete