Move container phase executor to a separate package

Having an executor within container package creates
potential import cycling. This patch moves it to a separate
package which can be used to conveniently store all the executors
at one place.

Change-Id: Ibd07c2ba46d1971604bdbd9e5e360759bb68a659
Signed-off-by: Ruslan Aliev <raliev@mirantis.com>
Relates-To: #432
This commit is contained in:
Ruslan Aliev
2020-12-10 09:44:27 -06:00
parent b85f8fa8f9
commit 01266f036e
3 changed files with 36 additions and 49 deletions

View File

@@ -21,7 +21,6 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/container"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/events" "opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/k8s/kubeconfig" "opendev.org/airship/airshipctl/pkg/k8s/kubeconfig"
@@ -47,7 +46,7 @@ func DefaultExecutorRegistry() map[schema.GroupVersionKind]ifc.ExecutorFactory {
if err := executors.RegisterIsogenExecutor(execMap); err != nil { if err := executors.RegisterIsogenExecutor(execMap); err != nil {
log.Fatal(ErrExecutorRegistration{ExecutorName: "isogen", Err: err}) log.Fatal(ErrExecutorRegistration{ExecutorName: "isogen", Err: err})
} }
if err := container.RegisterExecutor(execMap); err != nil { if err := executors.RegisterContainerExecutor(execMap); err != nil {
log.Fatal(ErrExecutorRegistration{ExecutorName: "generic-container", Err: err}) log.Fatal(ErrExecutorRegistration{ExecutorName: "generic-container", Err: err})
} }
return execMap return execMap

View File

@@ -12,7 +12,7 @@
limitations under the License. limitations under the License.
*/ */
package container package executors
import ( import (
"bytes" "bytes"
@@ -40,10 +40,10 @@ const (
yamlSeparator = "---\n" yamlSeparator = "---\n"
) )
var _ ifc.Executor = &Executor{} var _ ifc.Executor = &ContainerExecutor{}
// Executor contains resources for generic container executor // ContainerExecutor contains resources for generic container executor
type Executor struct { type ContainerExecutor struct {
ExecutorBundle document.Bundle ExecutorBundle document.Bundle
ExecutorDocument document.Document ExecutorDocument document.Document
@@ -52,19 +52,19 @@ type Executor struct {
targetPath string targetPath string
} }
// RegisterExecutor adds executor to phase executor registry // RegisterContainerExecutor adds executor to phase executor registry
func RegisterExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error { func RegisterContainerExecutor(registry map[schema.GroupVersionKind]ifc.ExecutorFactory) error {
obj := v1alpha1.DefaultGenericContainer() obj := v1alpha1.DefaultGenericContainer()
gvks, _, err := v1alpha1.Scheme.ObjectKinds(obj) gvks, _, err := v1alpha1.Scheme.ObjectKinds(obj)
if err != nil { if err != nil {
return err return err
} }
registry[gvks[0]] = NewExecutor registry[gvks[0]] = NewContainerExecutor
return nil return nil
} }
// NewExecutor creates instance of phase executor // NewContainerExecutor creates instance of phase executor
func NewExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) { func NewContainerExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
bundle, err := cfg.BundleFactory() bundle, err := cfg.BundleFactory()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -78,7 +78,7 @@ func NewExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
return nil, err return nil, err
} }
return &Executor{ return &ContainerExecutor{
ExecutorBundle: bundle, ExecutorBundle: bundle,
ExecutorDocument: cfg.ExecutorDocument, ExecutorDocument: cfg.ExecutorDocument,
@@ -91,7 +91,7 @@ func NewExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
} }
// Run generic container as a phase runner // Run generic container as a phase runner
func (c *Executor) Run(evtCh chan events.Event, opts ifc.RunOptions) { func (c *ContainerExecutor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
defer close(evtCh) defer close(evtCh)
evtCh <- events.NewEvent().WithGenericContainerEvent(events.GenericContainerEvent{ evtCh <- events.NewEvent().WithGenericContainerEvent(events.GenericContainerEvent{
@@ -129,7 +129,7 @@ func (c *Executor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
} }
// SetInput sets input for function // SetInput sets input for function
func (c *Executor) SetInput(evtCh chan events.Event) { func (c *ContainerExecutor) SetInput(evtCh chan events.Event) {
docs, err := c.ExecutorBundle.GetAllDocuments() docs, err := c.ExecutorBundle.GetAllDocuments()
if err != nil { if err != nil {
handleError(evtCh, err) handleError(evtCh, err)
@@ -150,7 +150,7 @@ func (c *Executor) SetInput(evtCh chan events.Event) {
} }
// PrepareFunctions prepares data for function // PrepareFunctions prepares data for function
func (c *Executor) PrepareFunctions(evtCh chan events.Event) { func (c *ContainerExecutor) PrepareFunctions(evtCh chan events.Event) {
rnode, err := kyaml.Parse(c.ContConf.Config) rnode, err := kyaml.Parse(c.ContConf.Config)
if err != nil { if err != nil {
handleError(evtCh, err) handleError(evtCh, err)
@@ -174,7 +174,7 @@ func (c *Executor) PrepareFunctions(evtCh chan events.Event) {
} }
// SetMounts allows to set relative path for storage mounts to prevent security issues // SetMounts allows to set relative path for storage mounts to prevent security issues
func (c *Executor) SetMounts() { func (c *ContainerExecutor) SetMounts() {
if len(c.ContConf.Spec.Container.StorageMounts) == 0 { if len(c.ContConf.Spec.Container.StorageMounts) == 0 {
return return
} }
@@ -186,17 +186,11 @@ func (c *Executor) SetMounts() {
} }
// Validate executor configuration and documents // Validate executor configuration and documents
func (c *Executor) Validate() error { func (c *ContainerExecutor) Validate() error {
return errors.ErrNotImplemented{} return errors.ErrNotImplemented{}
} }
// Render executor documents // Render executor documents
func (c *Executor) Render(_ io.Writer, _ ifc.RenderOptions) error { func (c *ContainerExecutor) Render(_ io.Writer, _ ifc.RenderOptions) error {
return errors.ErrNotImplemented{} return errors.ErrNotImplemented{}
} }
func handleError(ch chan<- events.Event, err error) {
ch <- events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err,
})
}

View File

@@ -12,7 +12,7 @@
limitations under the License. limitations under the License.
*/ */
package container_test package executors_test
import ( import (
"bytes" "bytes"
@@ -27,15 +27,15 @@ import (
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/config" "opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/container"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/events" "opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/phase" "opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/executors"
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
) )
const ( const (
executorDoc = ` containerExecutorDoc = `
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: GenericContainer kind: GenericContainer
metadata: metadata:
@@ -86,7 +86,7 @@ metadata:
config.kubernetes.io/function: "container:\n image: quay.io/test/image:v0.0.1\nexec: config.kubernetes.io/function: "container:\n image: quay.io/test/image:v0.0.1\nexec:
{}\nstarlark: {}\n" {}\nstarlark: {}\n"
` `
singleExecutorBundlePath = "testdata/single" singleExecutorBundlePath = "../../container/testdata/single"
firstDocInput = `--- firstDocInput = `---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
@@ -97,7 +97,7 @@ stringData:
#!/bin/sh #!/bin/sh
echo WORKS! $var >&2 echo WORKS! $var >&2
type: Opaque` type: Opaque`
manyExecutorBundlePath = "testdata/many" manyExecutorBundlePath = "../../container/testdata/many"
secondDocInput = `--- secondDocInput = `---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
@@ -110,27 +110,27 @@ type: Opaque
yamlSeparator = "---\n" yamlSeparator = "---\n"
) )
func TestRegisterExecutor(t *testing.T) { func TestRegisterContainerExecutor(t *testing.T) {
registry := make(map[schema.GroupVersionKind]ifc.ExecutorFactory) registry := make(map[schema.GroupVersionKind]ifc.ExecutorFactory)
expectedGVK := schema.GroupVersionKind{ expectedGVK := schema.GroupVersionKind{
Group: "airshipit.org", Group: "airshipit.org",
Version: "v1alpha1", Version: "v1alpha1",
Kind: "GenericContainer", Kind: "GenericContainer",
} }
err := container.RegisterExecutor(registry) err := executors.RegisterContainerExecutor(registry)
require.NoError(t, err) require.NoError(t, err)
_, found := registry[expectedGVK] _, found := registry[expectedGVK]
assert.True(t, found) assert.True(t, found)
} }
func TestNewExecutor(t *testing.T) { func TestNewContainerExecutor(t *testing.T) {
execDoc, err := document.NewDocumentFromBytes([]byte(executorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
_, err = container.NewExecutor(ifc.ExecutorConfig{ _, err = executors.NewContainerExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: testBundleFactory(singleExecutorBundlePath), BundleFactory: testBundleFactory(singleExecutorBundlePath),
Helper: makeDefaultHelper(t), Helper: makeDefaultContainerHelper(t),
}) })
require.NoError(t, err) require.NoError(t, err)
} }
@@ -138,9 +138,9 @@ func TestNewExecutor(t *testing.T) {
func TestSetInputSingleDocument(t *testing.T) { func TestSetInputSingleDocument(t *testing.T) {
bundle, err := document.NewBundleByPath(singleExecutorBundlePath) bundle, err := document.NewBundleByPath(singleExecutorBundlePath)
require.NoError(t, err) require.NoError(t, err)
execDoc, err := document.NewDocumentFromBytes([]byte(executorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
e := &container.Executor{ e := &executors.ContainerExecutor{
ExecutorBundle: bundle, ExecutorBundle: bundle,
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
@@ -169,9 +169,9 @@ func TestSetInputSingleDocument(t *testing.T) {
func TestSetInputManyDocuments(t *testing.T) { func TestSetInputManyDocuments(t *testing.T) {
bundle, err := document.NewBundleByPath(manyExecutorBundlePath) bundle, err := document.NewBundleByPath(manyExecutorBundlePath)
require.NoError(t, err) require.NoError(t, err)
execDoc, err := document.NewDocumentFromBytes([]byte(executorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
e := &container.Executor{ e := &executors.ContainerExecutor{
ExecutorBundle: bundle, ExecutorBundle: bundle,
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
@@ -207,14 +207,14 @@ func TestSetInputManyDocuments(t *testing.T) {
func TestPrepareFunctions(t *testing.T) { func TestPrepareFunctions(t *testing.T) {
bundle, err := document.NewBundleByPath(singleExecutorBundlePath) bundle, err := document.NewBundleByPath(singleExecutorBundlePath)
require.NoError(t, err) require.NoError(t, err)
execDoc, err := document.NewDocumentFromBytes([]byte(executorDoc)) execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc))
require.NoError(t, err) require.NoError(t, err)
contConf := &v1alpha1.GenericContainer{ contConf := &v1alpha1.GenericContainer{
Spec: runtimeutil.FunctionSpec{}, Spec: runtimeutil.FunctionSpec{},
} }
err = execDoc.ToAPIObject(contConf, v1alpha1.Scheme) err = execDoc.ToAPIObject(contConf, v1alpha1.Scheme)
require.NoError(t, err) require.NoError(t, err)
e := &container.Executor{ e := &executors.ContainerExecutor{
ExecutorBundle: bundle, ExecutorBundle: bundle,
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
@@ -233,16 +233,10 @@ func TestPrepareFunctions(t *testing.T) {
assert.Equal(t, transformedFunction, strFuncs) assert.Equal(t, transformedFunction, strFuncs)
} }
func testBundleFactory(path string) document.BundleFactoryFunc { func makeDefaultContainerHelper(t *testing.T) ifc.Helper {
return func() (document.Bundle, error) {
return document.NewBundleByPath(path)
}
}
func makeDefaultHelper(t *testing.T) ifc.Helper {
t.Helper() t.Helper()
cfg := config.NewConfig() cfg := config.NewConfig()
cfg.Manifests[config.AirshipDefaultManifest].TargetPath = "./testdata" cfg.Manifests[config.AirshipDefaultManifest].TargetPath = "../../container/testdata"
cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml" cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml"
cfg.Manifests[config.AirshipDefaultManifest].Repositories[config.DefaultTestPhaseRepo].URLString = "" cfg.Manifests[config.AirshipDefaultManifest].Repositories[config.DefaultTestPhaseRepo].URLString = ""
cfg.SetLoadedConfigPath(".") cfg.SetLoadedConfigPath(".")