Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
Merge pull request #43 from puppetlabs/gh-35/main/docker-backend
Browse files Browse the repository at this point in the history
Docker backend for Gems
  • Loading branch information
michaeltlombardi authored Dec 9, 2021
2 parents 3d4d347 + 7fa4180 commit 96a605f
Show file tree
Hide file tree
Showing 13 changed files with 748 additions and 566 deletions.
104 changes: 72 additions & 32 deletions cmd/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package exec

import (
"fmt"
"os/user"
"path/filepath"
"strings"

Expand All @@ -15,14 +16,13 @@ import (
)

var (
localToolPath string
format string
selectedTool string
selectedToolDirPath string
localToolPath string
format string
selectedTool string
// selectedToolInfo string
listTools bool
prmApi *prm.Prm
cachedTools []prm.ToolConfig
listTools bool
prmApi *prm.Prm
toolArgs string
)

func CreateCommand(parent *prm.Prm) *cobra.Command {
Expand All @@ -45,10 +45,6 @@ func CreateCommand(parent *prm.Prm) *cobra.Command {
err := tmp.RegisterFlagCompletionFunc("list", flagCompletion)
cobra.CheckErr(err)

// tmp.Flags().StringVarP(&selectedToolInfo, "info", "i", "", "display the selected template's configuration and default values")
// err = tmp.RegisterFlagCompletionFunc("info", flagCompletion)
// cobra.CheckErr(err)

tmp.Flags().StringVar(&format, "format", "table", "display output in table or json format")
err = tmp.RegisterFlagCompletionFunc("format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
Expand All @@ -63,23 +59,45 @@ func CreateCommand(parent *prm.Prm) *cobra.Command {
err = viper.BindPFlag("toolpath", tmp.Flags().Lookup("toolpath"))
cobra.CheckErr(err)

tmp.Flags().StringVar(&prmApi.CodeDir, "codedir", "", "location of code to execute against")
err = viper.BindPFlag("codedir", tmp.Flags().Lookup("codedir"))
cobra.CheckErr(err)

tmp.Flags().StringVar(&prmApi.CacheDir, "cachedir", "", "location of cache used by PRM")
err = viper.BindPFlag("cachedir", tmp.Flags().Lookup("cachedir"))
cobra.CheckErr(err)

tmp.Flags().StringVar(&toolArgs, "toolArgs", "", "Additional arguments to pass to the tool")
err = viper.BindPFlag("toolArgs", tmp.Flags().Lookup("toolArgs"))
cobra.CheckErr(err)

return tmp
}

func preExecute(cmd *cobra.Command, args []string) error {
if localToolPath == "" {
localToolPath = prmApi.RunningConfig.ToolPath
}
cachedTools = prmApi.List(localToolPath, "")

switch prmApi.RunningConfig.Backend {
case prm.DOCKER:
prmApi.Backend = &prm.Docker{}
default:
prmApi.Backend = &prm.Docker{}
}

// handle the default cachepath
if prmApi.CacheDir == "" {
usr, _ := user.Current()
dir := usr.HomeDir
prmApi.CacheDir = filepath.Join(dir, ".pdk/prm/cache")
}

prmApi.List(localToolPath, "")
return nil
}

func validateArgCount(cmd *cobra.Command, args []string) error {
// show available tools if user runs `prm exec`
if len(args) == 0 && !listTools {
listTools = true
}

if len(args) >= 1 {
if len(strings.Split(args[0], "/")) != 2 {
return fmt.Errorf("Selected tool must be in AUTHOR/ID format")
Expand Down Expand Up @@ -108,10 +126,9 @@ func flagCompletion(cmd *cobra.Command, args []string, toComplete string) ([]str

func completeName(cache string, match string) []string {
var names []string
for _, tool := range cachedTools {
namespacedTemplate := fmt.Sprintf("%s/%s", tool.Plugin.Author, tool.Plugin.Id)
if strings.HasPrefix(namespacedTemplate, match) {
m := namespacedTemplate + "\t" + tool.Plugin.Display
for toolName, tool := range prmApi.Cache {
if strings.HasPrefix(toolName, match) {
m := toolName + "\t" + tool.Cfg.Plugin.Display
names = append(names, m)
}
}
Expand All @@ -130,7 +147,7 @@ func execute(cmd *cobra.Command, args []string) error {
log.Trace().Msgf("Selected Tool: %v", selectedTool)

if listTools {
formattedTemplates, err := prmApi.FormatTools(cachedTools, format)
formattedTemplates, err := prmApi.FormatTools(prmApi.Cache, format)
if err != nil {
return err
}
Expand All @@ -139,21 +156,44 @@ func execute(cmd *cobra.Command, args []string) error {
return nil
}

matchingTools := prmApi.FilterFiles(cachedTools, func(f prm.ToolConfig) bool {
return fmt.Sprintf("%s/%s", f.Plugin.Author, f.Plugin.Id) == selectedTool
})
var additionalToolArgs []string
if toolArgs != "" {
additionalToolArgs = strings.Split(toolArgs, " ")
}

if len(matchingTools) == 1 {
matchingTool := matchingTools[0]
selectedToolDirPath = filepath.Join(localToolPath, matchingTool.Plugin.Author, matchingTool.Plugin.Id, matchingTool.Plugin.Version)
tool, err := prmApi.Get(selectedToolDirPath)
if selectedTool != "" {
// get the tool from the cache
cachedTool, ok := prmApi.IsToolAvailable(selectedTool)
if !ok {
return fmt.Errorf("Tool %s not found in cache", selectedTool)
}
// execute!
err := prmApi.Exec(cachedTool, additionalToolArgs)
if err != nil {
return err
}
} else {
// No tool specified, so check if their code contains a validate.yml, which returns the list of tools
// Their code is expected to be in the directory where the executable is run from
toolList, err := prmApi.CheckLocalConfig()
if err != nil {
return err
}

return prmApi.Exec(&tool, args[1:])
log.Info().Msgf("Found tools: %v ", toolList)

for _, tool := range toolList {
cachedTool, ok := prmApi.IsToolAvailable(tool)
if !ok {
return fmt.Errorf("Tool %s not found in cache", tool)
}
err := prmApi.Exec(cachedTool, additionalToolArgs) // todo: do we want to allow folk to specify args from validate.yml?
if err != nil {
return err
}
}

} else {
return fmt.Errorf("Couldn't find an installed tool that matches '%s'", selectedTool)
}

return nil
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ require (
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/moby/sys/mount v0.3.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/image-spec v1.0.1
github.com/puppetlabs/pdkgo v0.0.0-20211208200151-2414a05b08bf
github.com/rs/zerolog v1.26.0
github.com/spf13/afero v1.6.0
Expand All @@ -32,4 +34,5 @@ require (
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.23 h1:47MSwtKGXet80aIn+7h4YI6fwPmwIghAnsx2aOUrG2M=
github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
Expand Down Expand Up @@ -155,6 +156,7 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ=
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
Expand Down Expand Up @@ -182,6 +184,7 @@ github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
Expand Down Expand Up @@ -342,6 +345,7 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
Expand Down Expand Up @@ -551,8 +555,12 @@ github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGg
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/sys/mount v0.3.0 h1:bXZYMmq7DBQPwHRxH/MG+u9+XF90ZOwoXpHTOznMGp0=
github.com/moby/sys/mount v0.3.0/go.mod h1:U2Z3ur2rXPFrFmy4q6WMwWrBOAQGYtYTRVM8BIvzbwk=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
Expand Down Expand Up @@ -603,6 +611,7 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
Expand Down Expand Up @@ -781,6 +790,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ=
go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I=
Expand Down Expand Up @@ -1028,6 +1038,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand Down
6 changes: 3 additions & 3 deletions internal/pkg/mock/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ func (m *MockBackend) Status() prm.BackendStatus {
}

// Implement when needed
func (m *MockBackend) GetTool(toolName string, prmConfig prm.Config) (prm.Tool, error) {
return prm.Tool{}, nil
func (m *MockBackend) GetTool(tool *prm.Tool, prmConfig prm.Config) error {
return nil
}

// Implement when needed
Expand All @@ -24,6 +24,6 @@ func (m *MockBackend) Validate(tool *prm.Tool) (prm.ToolExitCode, error) {
}

// Implement when needed
func (m *MockBackend) Exec(tool *prm.Tool, args []string) (prm.ToolExitCode, error) {
func (m *MockBackend) Exec(tool *prm.Tool, args []string, prmConfig prm.Config, paths prm.DirectoryPaths) (prm.ToolExitCode, error) {
return prm.FAILURE, nil
}
66 changes: 66 additions & 0 deletions internal/pkg/mock/docker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package mock

import (
"context"
"fmt"
"io"
"strings"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)

type DockerClient struct {
Platform string
Version string
ApiVersion string
ErrorString string
}

func (m *DockerClient) ServerVersion(ctx context.Context) (types.Version, error) {
if m.ErrorString != "" {
return types.Version{}, fmt.Errorf(m.ErrorString)
}
versionInfo := &types.Version{
Platform: struct{ Name string }{m.Platform},
Version: m.Version,
APIVersion: m.ApiVersion,
}
return *versionInfo, nil
}

func (m *DockerClient) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.ContainerCreateCreatedBody, error) {
return container.ContainerCreateCreatedBody{}, nil
}

func (m *DockerClient) ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) {

mockReader := strings.NewReader("FAKE LOG MESSAGES!")
mockReadCloser := io.NopCloser(mockReader)

return mockReadCloser, nil
}

func (m *DockerClient) ContainerRemove(ctx context.Context, containerID string, options types.ContainerRemoveOptions) error {
return nil
}

func (m *DockerClient) ContainerStart(ctx context.Context, containerID string, options types.ContainerStartOptions) error {
return nil
}

func (m *DockerClient) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
waitChan := make(chan container.ContainerWaitOKBody)
errChan := make(chan error)
return waitChan, errChan
}

func (m *DockerClient) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
return types.ImageBuildResponse{}, nil
}

func (m *DockerClient) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
return []types.ImageSummary{}, nil
}
9 changes: 7 additions & 2 deletions pkg/prm/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ const (
)

type BackendI interface {
GetTool(toolName string, prmConfig Config) (Tool, error)
GetTool(tool *Tool, prmConfig Config) error
Validate(tool *Tool) (ToolExitCode, error)
Exec(tool *Tool, args []string) (ToolExitCode, error)
Exec(tool *Tool, args []string, prmConfig Config, paths DirectoryPaths) (ToolExitCode, error)
Status() BackendStatus
}

Expand All @@ -21,3 +21,8 @@ type BackendStatus struct {
IsAvailable bool
StatusMsg string
}

type DirectoryPaths struct {
codeDir string
cacheDir string
}
Loading

0 comments on commit 96a605f

Please sign in to comment.