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