Phase docs are targetPath + phaseRepo + phase.DocumentEntrypoint

Change-Id: I1d5ea75d1c19eb4ebaf37b28918ccde771bcef85
Relates-To: #356
This commit is contained in:
Vladimir Kozhukalov 2020-10-07 00:27:23 +03:00
parent 0dc4ab7491
commit dc68640389
18 changed files with 119 additions and 27 deletions

View File

@ -1,2 +1,2 @@
phase: phase:
path: airshipctl/manifests/phases path: manifests/phases

View File

@ -7,7 +7,7 @@ config:
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: ImageConfiguration kind: ImageConfiguration
name: isogen name: isogen
documentEntryPoint: airshipctl/manifests/site/test-site/ephemeral/bootstrap documentEntryPoint: manifests/site/test-site/ephemeral/bootstrap
--- ---
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: Phase kind: Phase
@ -19,7 +19,7 @@ config:
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: KubernetesApply kind: KubernetesApply
name: kubernetes-apply name: kubernetes-apply
documentEntryPoint: airshipctl/manifests/site/test-site/ephemeral/initinfra documentEntryPoint: manifests/site/test-site/ephemeral/initinfra
--- ---
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: Phase kind: Phase
@ -31,7 +31,7 @@ config:
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: KubernetesApply kind: KubernetesApply
name: kubernetes-apply name: kubernetes-apply
documentEntryPoint: airshipctl/manifests/site/test-site/ephemeral/controlplane documentEntryPoint: manifests/site/test-site/ephemeral/controlplane
--- ---
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: Phase kind: Phase
@ -44,7 +44,7 @@ config:
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: KubernetesApply kind: KubernetesApply
name: kubernetes-apply name: kubernetes-apply
documentEntryPoint: airshipctl/manifests/site/test-site/target/initinfra documentEntryPoint: manifests/site/test-site/target/initinfra
--- ---
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: Phase kind: Phase
@ -57,7 +57,7 @@ config:
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: KubernetesApply kind: KubernetesApply
name: kubernetes-apply name: kubernetes-apply
documentEntryPoint: airshipctl/manifests/site/test-site/target/workers documentEntryPoint: manifests/site/test-site/target/workers
--- ---
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: Phase kind: Phase
@ -102,4 +102,4 @@ config:
apiVersion: airshipit.org/v1alpha1 apiVersion: airshipit.org/v1alpha1
kind: KubernetesApply kind: KubernetesApply
name: kubernetes-apply name: kubernetes-apply
documentEntryPoint: airshipctl/manifests/site/test-site/target/workload documentEntryPoint: manifests/site/test-site/target/workload

View File

@ -222,6 +222,7 @@ func makeDefaultHelper(t *testing.T) ifc.Helper {
cfg := config.NewConfig() cfg := config.NewConfig()
cfg.Manifests[config.AirshipDefaultManifest].TargetPath = "./testdata" cfg.Manifests[config.AirshipDefaultManifest].TargetPath = "./testdata"
cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml" cfg.Manifests[config.AirshipDefaultManifest].MetadataPath = "metadata.yaml"
cfg.Manifests[config.AirshipDefaultManifest].Repositories[config.DefaultTestPhaseRepo].URLString = ""
cfg.SetLoadedConfigPath(".") cfg.SetLoadedConfigPath(".")
helper, err := phase.NewHelper(cfg) helper, err := phase.NewHelper(cfg)
require.NoError(t, err) require.NoError(t, err)

View File

@ -358,6 +358,20 @@ func (c *Config) CurrentContextTargetPath() (string, error) {
return ccm.TargetPath, nil return ccm.TargetPath, nil
} }
// CurrentContextPhaseRepositoryDir returns phase repository directory from current context's manifest
// E.g. let repository url be "http://dummy.org/phaserepo.git" then repo directory under targetPath is "phaserepo"
func (c *Config) CurrentContextPhaseRepositoryDir() (string, error) {
ccm, err := c.CurrentContextManifest()
if err != nil {
return "", err
}
repo, exist := ccm.Repositories[ccm.PhaseRepositoryName]
if !exist {
return "", ErrMissingRepositoryName{}
}
return util.GitDirNameFromURL(repo.URL()), nil
}
// CurrentContextClusterType returns cluster type of current context // CurrentContextClusterType returns cluster type of current context
func (c *Config) CurrentContextClusterType() (string, error) { func (c *Config) CurrentContextClusterType() (string, error) {
context, err := c.GetCurrentContext() context, err := c.GetCurrentContext()
@ -568,12 +582,16 @@ func (c *Config) CurrentContextManifestMetadata() (*Metadata, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
phaseRepoDir, err := c.CurrentContextPhaseRepositoryDir()
if err != nil {
return nil, err
}
meta := &Metadata{ meta := &Metadata{
// Populate with empty values to avoid nil pointers // Populate with empty values to avoid nil pointers
Inventory: &InventoryMeta{}, Inventory: &InventoryMeta{},
PhaseMeta: &PhaseMeta{}, PhaseMeta: &PhaseMeta{},
} }
err = util.ReadYAMLFile(filepath.Join(manifest.TargetPath, manifest.MetadataPath), meta) err = util.ReadYAMLFile(filepath.Join(manifest.TargetPath, phaseRepoDir, manifest.MetadataPath), meta)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -20,6 +20,8 @@ import (
"strings" "strings"
"testing" "testing"
"opendev.org/airship/airshipctl/pkg/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -315,6 +317,26 @@ func TestCurrentTargetPath(t *testing.T) {
assert.Equal(t, conf.Manifests[defaultString].TargetPath, targetPath) assert.Equal(t, conf.Manifests[defaultString].TargetPath, targetPath)
} }
func TestCurrentPhaseRepositoryDir(t *testing.T) {
conf, cleanup := testutil.InitConfig(t)
defer cleanup(t)
conf.CurrentContext = currentContextName
conf.Contexts[currentContextName].Manifest = defaultString
phaseRepoDir, err := conf.CurrentContextPhaseRepositoryDir()
require.NoError(t, err)
assert.Equal(t, util.GitDirNameFromURL(
conf.Manifests[defaultString].Repositories[conf.Manifests[defaultString].PhaseRepositoryName].URL()),
phaseRepoDir)
conf.Manifests[defaultString].PhaseRepositoryName = "nonexisting"
phaseRepoDir, err = conf.CurrentContextPhaseRepositoryDir()
require.Error(t, err)
assert.Equal(t, config.ErrMissingRepositoryName{}, err)
assert.Equal(t, "", phaseRepoDir)
}
func TestCurrentContextEntryPoint(t *testing.T) { func TestCurrentContextEntryPoint(t *testing.T) {
conf, cleanup := testutil.InitConfig(t) conf, cleanup := testutil.InitConfig(t)
defer cleanup(t) defer cleanup(t)
@ -414,9 +436,16 @@ func TestCurrentContextManifestMetadata(t *testing.T) {
context := &config.Context{ context := &config.Context{
Manifest: "testManifest", Manifest: "testManifest",
} }
repos := map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
}
manifest := &config.Manifest{ manifest := &config.Manifest{
MetadataPath: tt.metaPath, MetadataPath: tt.metaPath,
TargetPath: "testdata", TargetPath: "testdata",
PhaseRepositoryName: config.DefaultTestPhaseRepo,
Repositories: repos,
} }
conf.Manifests = map[string]*config.Manifest{ conf.Manifests = map[string]*config.Manifest{
"testManifest": manifest, "testManifest": manifest,

View File

@ -17,7 +17,7 @@ managementConfiguration:
type: redfish type: redfish
manifests: manifests:
dummy_manifest: dummy_manifest:
metadataPath: manifests/site/test-site/metadata.yaml metadataPath: metadata.yaml
phaseRepositoryName: primary phaseRepositoryName: primary
repositories: repositories:
primary: primary:

View File

@ -1,4 +1,4 @@
metadataPath: manifests/site/test-site/metadata.yaml metadataPath: metadata.yaml
phaseRepositoryName: primary phaseRepositoryName: primary
repositories: repositories:
primary: primary:

View File

@ -52,6 +52,7 @@ func NewConfig() *Config {
TargetPath: "/tmp/" + AirshipDefaultManifest, TargetPath: "/tmp/" + AirshipDefaultManifest,
PhaseRepositoryName: DefaultTestPhaseRepo, PhaseRepositoryName: DefaultTestPhaseRepo,
SubPath: AirshipDefaultManifestRepo + "/manifests/site", SubPath: AirshipDefaultManifestRepo + "/manifests/site",
MetadataPath: DefaultManifestMetadataFile,
}, },
}, },
} }

View File

@ -231,6 +231,12 @@ func makeDefaultHelper(t *testing.T) ifc.Helper {
"default-manifest": { "default-manifest": {
MetadataPath: "metadata.yaml", MetadataPath: "metadata.yaml",
TargetPath: "testdata", TargetPath: "testdata",
PhaseRepositoryName: config.DefaultTestPhaseRepo,
Repositories: map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
},
}, },
}, },
} }

View File

@ -154,7 +154,8 @@ func (p *phase) DocumentRoot() (string, error) {
} }
targetPath := p.helper.TargetPath() targetPath := p.helper.TargetPath()
return filepath.Join(targetPath, relativePath), nil phaseRepoDir := p.helper.PhaseRepoDir()
return filepath.Join(targetPath, phaseRepoDir, relativePath), nil
} }
// Details returns description of the phase // Details returns description of the phase

View File

@ -63,6 +63,12 @@ func TestRunCommand(t *testing.T) {
"manifest": { "manifest": {
MetadataPath: "broken_metadata.yaml", MetadataPath: "broken_metadata.yaml",
TargetPath: "testdata", TargetPath: "testdata",
PhaseRepositoryName: config.DefaultTestPhaseRepo,
Repositories: map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
},
}, },
} }
conf.CurrentContext = "context" conf.CurrentContext = "context"
@ -127,6 +133,12 @@ func TestPlanCommand(t *testing.T) {
"manifest": { "manifest": {
MetadataPath: "broken_metadata.yaml", MetadataPath: "broken_metadata.yaml",
TargetPath: "testdata", TargetPath: "testdata",
PhaseRepositoryName: config.DefaultTestPhaseRepo,
Repositories: map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
},
}, },
} }
conf.CurrentContext = "context" conf.CurrentContext = "context"

View File

@ -34,7 +34,7 @@ type Helper struct {
phaseRoot string phaseRoot string
inventoryRoot string inventoryRoot string
targetPath string targetPath string
phaseRepoDir string
metadata *config.Metadata metadata *config.Metadata
} }
@ -47,12 +47,16 @@ func NewHelper(cfg *config.Config) (ifc.Helper, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
helper.phaseRepoDir, err = cfg.CurrentContextPhaseRepositoryDir()
if err != nil {
return nil, err
}
helper.metadata, err = cfg.CurrentContextManifestMetadata() helper.metadata, err = cfg.CurrentContextManifestMetadata()
if err != nil { if err != nil {
return nil, err return nil, err
} }
helper.phaseRoot = filepath.Join(helper.targetPath, helper.metadata.PhaseMeta.Path) helper.phaseRoot = filepath.Join(helper.targetPath, helper.phaseRepoDir, helper.metadata.PhaseMeta.Path)
helper.inventoryRoot = filepath.Join(helper.targetPath, helper.metadata.Inventory.Path) helper.inventoryRoot = filepath.Join(helper.targetPath, helper.phaseRepoDir, helper.metadata.Inventory.Path)
return helper, nil return helper, nil
} }
@ -197,6 +201,12 @@ func (helper *Helper) TargetPath() string {
return helper.targetPath return helper.targetPath
} }
// PhaseRepoDir returns the last part of the repo url
// E.g. http://dummy.org/reponame.git -> reponame
func (helper *Helper) PhaseRepoDir() string {
return helper.phaseRepoDir
}
// PhaseRoot returns path to document root with phase documents // PhaseRoot returns path to document root with phase documents
func (helper *Helper) PhaseRoot() string { func (helper *Helper) PhaseRoot() string {
return helper.phaseRoot return helper.phaseRoot

View File

@ -449,8 +449,11 @@ manifests:
phaseRepositoryName: primary phaseRepositoryName: primary
targetPath: testdata targetPath: testdata
metadataPath: valid_site/metadata.yaml metadataPath: valid_site/metadata.yaml
subPath: valid_site` subPath: valid_site
repositories:
primary:
url: "empty/filename/"
`
conf := &config.Config{} conf := &config.Config{}
err := yaml.Unmarshal([]byte(confString), conf) err := yaml.Unmarshal([]byte(confString), conf)
require.NoError(t, err) require.NoError(t, err)

View File

@ -23,6 +23,7 @@ import (
// Helper is a phase helper that provides phases with additional config related information // Helper is a phase helper that provides phases with additional config related information
type Helper interface { type Helper interface {
TargetPath() string TargetPath() string
PhaseRepoDir() string
WorkDir() (string, error) WorkDir() (string, error)
Phase(phaseID ID) (*v1alpha1.Phase, error) Phase(phaseID ID) (*v1alpha1.Phase, error)
Plan() (*v1alpha1.PhasePlan, error) Plan() (*v1alpha1.PhasePlan, error)

View File

@ -33,6 +33,12 @@ func TestRender(t *testing.T) {
rs := testutil.DummyConfig() rs := testutil.DummyConfig()
dummyManifest := rs.Manifests["dummy_manifest"] dummyManifest := rs.Manifests["dummy_manifest"]
dummyManifest.TargetPath = "testdata" dummyManifest.TargetPath = "testdata"
dummyManifest.PhaseRepositoryName = config.DefaultTestPhaseRepo
dummyManifest.Repositories = map[string]*config.Repository{
config.DefaultTestPhaseRepo: {
URLString: "",
},
}
dummyManifest.SubPath = "" dummyManifest.SubPath = ""
dummyManifest.MetadataPath = "metadata.yaml" dummyManifest.MetadataPath = "metadata.yaml"
fixturePath := "phase" fixturePath := "phase"

View File

@ -56,8 +56,11 @@ func withTestDataPath(path string) Configuration {
if err != nil { if err != nil {
panic(fmt.Sprintf("Unable to initialize management tests. Current Context error %q", err)) panic(fmt.Sprintf("Unable to initialize management tests. Current Context error %q", err))
} }
manifest.TargetPath = fmt.Sprintf("testdata/%s", path) manifest.TargetPath = "testdata"
manifest.MetadataPath = "metadata.yaml" manifest.MetadataPath = "metadata.yaml"
dummyRepo := testutil.DummyRepository()
dummyRepo.URLString = fmt.Sprintf("http://dummy.url.com/%s.git", path)
manifest.Repositories = map[string]*config.Repository{manifest.PhaseRepositoryName: dummyRepo}
} }
} }

View File

@ -69,6 +69,7 @@ func DummyManifest() *config.Manifest {
// Repositories is the map of repository addressable by a name // Repositories is the map of repository addressable by a name
m.Repositories = map[string]*config.Repository{"primary": DummyRepository()} m.Repositories = map[string]*config.Repository{"primary": DummyRepository()}
m.PhaseRepositoryName = "primary" m.PhaseRepositoryName = "primary"
m.MetadataPath = "metadata.yaml"
m.TargetPath = "/var/tmp/" m.TargetPath = "/var/tmp/"
m.SubPath = "manifests/site/test-site" m.SubPath = "manifests/site/test-site"
return m return m

View File

@ -30,7 +30,7 @@ export REMOTE_PROXY=false
export AIRSHIP_CONFIG_ISO_SERVE_HOST=${HOST:-"localhost"} export AIRSHIP_CONFIG_ISO_SERVE_HOST=${HOST:-"localhost"}
export AIRSHIP_CONFIG_ISO_PORT=${SERVE_PORT} export AIRSHIP_CONFIG_ISO_PORT=${SERVE_PORT}
export AIRSHIP_CONFIG_ISO_NAME=${ISO_NAME:-"ubuntu-focal.iso"} export AIRSHIP_CONFIG_ISO_NAME=${ISO_NAME:-"ubuntu-focal.iso"}
export AIRSHIP_CONFIG_METADATA_PATH=${AIRSHIP_CONFIG_METADATA_PATH:-"airshipctl/manifests/metadata.yaml"} export AIRSHIP_CONFIG_METADATA_PATH=${AIRSHIP_CONFIG_METADATA_PATH:-"manifests/metadata.yaml"}
export SYSTEM_ACTION_RETRIES=30 export SYSTEM_ACTION_RETRIES=30
export SYSTEM_REBOOT_DELAY=30 export SYSTEM_REBOOT_DELAY=30
export AIRSHIP_CONFIG_PHASE_REPO_BRANCH=${BRANCH:-"master"} export AIRSHIP_CONFIG_PHASE_REPO_BRANCH=${BRANCH:-"master"}