Skip to content
This repository has been archived by the owner on Jun 2, 2022. It is now read-only.

Commit

Permalink
feat: Added ability to use exec on filesystems.
Browse files Browse the repository at this point in the history
Currently works only for the docker plugin.

Signed-off-by: Spencer Brower <[email protected]>
  • Loading branch information
Spencer Brower committed Apr 15, 2020
1 parent 00ae27b commit ebe4432
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 2 deletions.
2 changes: 1 addition & 1 deletion plugin/docker/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (c *container) Exec(ctx context.Context, cmd string, args []string, opts pl
command := append([]string{cmd}, args...)
activity.Record(ctx, "Exec %v on %v", command, c.Name())

cfg := types.ExecConfig{Cmd: command, AttachStdout: true, AttachStderr: true, Tty: opts.Tty}
cfg := types.ExecConfig{Cmd: command, AttachStdout: true, AttachStderr: true, Tty: opts.Tty, WorkingDir: opts.WorkingDir}
if opts.Stdin != nil || opts.Tty {
cfg.AttachStdin = true
}
Expand Down
3 changes: 3 additions & 0 deletions plugin/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ type ExecOptions struct {

// Elevate execution to run as a privileged user if not already running as a privileged user.
Elevate bool `json:"elevate"`

// WorkingDir is the directory in which to execute the command.
WorkingDir string
}

// ExecPacketType identifies the packet type.
Expand Down
5 changes: 4 additions & 1 deletion volume/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type dirMap struct {
// ChildSchemas returns a volume's child schema
func ChildSchemas() []*plugin.EntrySchema {
return []*plugin.EntrySchema{
(&dir{}).Schema(),
(&execableDir{}).Schema(),
(&file{}).Schema(),
}
}
Expand All @@ -66,6 +66,9 @@ const RootPath = ""
// Requests are cached against the supplied Interface using the VolumeListCB op.
func List(ctx context.Context, impl Interface) ([]plugin.Entry, error) {
// Start with the implementation as the cache key so we re-use data we get from it for subdirectory queries.
if exImpl, ok := impl.(execableInterface); ok {
return newExecDir("dummy", plugin.EntryAttributes{}, exImpl, RootPath).List(ctx)
}
return newDir("dummy", plugin.EntryAttributes{}, impl, RootPath).List(ctx)
}

Expand Down
59 changes: 59 additions & 0 deletions volume/execable_dir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package volume

import (
"context"
"fmt"

"github.com/puppetlabs/wash/plugin"
)

type execableInterface interface {
Interface
VolumeExec(ctx context.Context, path string, cmd string, args []string, opts plugin.ExecOptions) (plugin.ExecCommand, error)
}

// execableDir adds the exec action to dir.
type execableDir struct {
dir
impl execableInterface
}

func newExecDir(name string, attr plugin.EntryAttributes, impl execableInterface, path string) *execableDir {
e := new(execableDir)
e.dir = *newDir(name, attr, impl, path)
e.impl = impl
return e
}

func (v *execableDir) Exec(ctx context.Context, cmd string, args []string, opts plugin.ExecOptions) (plugin.ExecCommand, error) {
return v.impl.VolumeExec(ctx, v.path, cmd, args, opts)
}

func (v *execableDir) generateChildren(dirmap *dirMap) []plugin.Entry {
entries := v.dir.generateChildren(dirmap)

for i, entry := range entries {
dir, ok := entry.(*dir)
if ok {
fmt.Println(dir)
entries[i] = &execableDir{dir: *dir, impl: v.impl}
}
}
return entries
}

// List lists the children of the directory.
func (v *execableDir) List(ctx context.Context) ([]plugin.Entry, error) {
if v.dirmap != nil {
// Children have been pre-populated by a source parent.
return v.generateChildren(v.dirmap), nil
}

// Generate child hierarchy. Don't store it on this entry, but populate new dirs from it.
dirmap, err := v.impl.VolumeList(ctx, v.path)
if err != nil {
return nil, err
}

return v.generateChildren(&dirMap{mp: dirmap}), nil
}
6 changes: 6 additions & 0 deletions volume/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ func (d *FS) loginShell() plugin.Shell {
return plugin.POSIXShell
}

// VolumeExec executes cmd in the directory at path.
func (d *FS) VolumeExec(ctx context.Context, path string, cmd string, args []string, opts plugin.ExecOptions) (plugin.ExecCommand, error) {
opts.WorkingDir = path
return d.executor.Exec(ctx, cmd, args, opts)
}

const fsDescription = `
This represents the root directory of a container/VM. It lets you navigate
and interact with that container/VM's filesystem as if you were logged into
Expand Down

0 comments on commit ebe4432

Please sign in to comment.