mirror of
https://github.com/openshift/installer.git
synced 2026-02-06 00:48:45 +01:00
Merge pull request #890 from staebler/asset_loading_tests
assets: add tests for validating asset fetching of targets
This commit is contained in:
@@ -26,14 +26,8 @@ import (
|
||||
configclient "github.com/openshift/client-go/config/clientset/versioned"
|
||||
routeclient "github.com/openshift/client-go/route/clientset/versioned"
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
"github.com/openshift/installer/pkg/asset/cluster"
|
||||
"github.com/openshift/installer/pkg/asset/ignition/bootstrap"
|
||||
"github.com/openshift/installer/pkg/asset/ignition/machine"
|
||||
"github.com/openshift/installer/pkg/asset/installconfig"
|
||||
"github.com/openshift/installer/pkg/asset/kubeconfig"
|
||||
"github.com/openshift/installer/pkg/asset/manifests"
|
||||
"github.com/openshift/installer/pkg/asset/templates"
|
||||
"github.com/openshift/installer/pkg/asset/tls"
|
||||
assetstore "github.com/openshift/installer/pkg/asset/store"
|
||||
targetassets "github.com/openshift/installer/pkg/asset/targets"
|
||||
destroybootstrap "github.com/openshift/installer/pkg/destroy/bootstrap"
|
||||
cov1helpers "github.com/openshift/library-go/pkg/config/clusteroperator/v1helpers"
|
||||
)
|
||||
@@ -55,7 +49,7 @@ var (
|
||||
// FIXME: add longer descriptions for our commands with examples for better UX.
|
||||
// Long: "",
|
||||
},
|
||||
assets: []asset.WritableAsset{&installconfig.InstallConfig{}},
|
||||
assets: targetassets.InstallConfig,
|
||||
}
|
||||
|
||||
manifestsTarget = target{
|
||||
@@ -66,7 +60,7 @@ var (
|
||||
// FIXME: add longer descriptions for our commands with examples for better UX.
|
||||
// Long: "",
|
||||
},
|
||||
assets: []asset.WritableAsset{&manifests.Manifests{}, &manifests.Openshift{}},
|
||||
assets: targetassets.Manifests,
|
||||
}
|
||||
|
||||
manifestTemplatesTarget = target{
|
||||
@@ -76,7 +70,7 @@ var (
|
||||
Short: "Generates the unrendered Kubernetes manifest templates",
|
||||
Long: "",
|
||||
},
|
||||
assets: []asset.WritableAsset{&templates.Templates{}},
|
||||
assets: targetassets.ManifestTemplates,
|
||||
}
|
||||
|
||||
ignitionConfigsTarget = target{
|
||||
@@ -87,7 +81,7 @@ var (
|
||||
// FIXME: add longer descriptions for our commands with examples for better UX.
|
||||
// Long: "",
|
||||
},
|
||||
assets: []asset.WritableAsset{&bootstrap.Bootstrap{}, &machine.Master{}, &machine.Worker{}, &kubeconfig.Admin{}, &cluster.Metadata{}},
|
||||
assets: targetassets.IgnitionConfigs,
|
||||
}
|
||||
|
||||
clusterTarget = target{
|
||||
@@ -128,7 +122,7 @@ var (
|
||||
}
|
||||
},
|
||||
},
|
||||
assets: []asset.WritableAsset{&cluster.TerraformVariables{}, &kubeconfig.Admin{}, &tls.JournalCertKey{}, &cluster.Metadata{}, &cluster.Cluster{}},
|
||||
assets: targetassets.Cluster,
|
||||
}
|
||||
|
||||
targets = []target{installConfigTarget, manifestTemplatesTarget, manifestsTarget, ignitionConfigsTarget, clusterTarget}
|
||||
@@ -154,7 +148,7 @@ func newCreateCmd() *cobra.Command {
|
||||
|
||||
func runTargetCmd(targets ...asset.WritableAsset) func(cmd *cobra.Command, args []string) {
|
||||
runner := func(directory string) error {
|
||||
assetStore, err := asset.NewStore(directory)
|
||||
assetStore, err := assetstore.NewStore(directory)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create asset store")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
assetstore "github.com/openshift/installer/pkg/asset/store"
|
||||
"github.com/openshift/installer/pkg/destroy"
|
||||
"github.com/openshift/installer/pkg/destroy/bootstrap"
|
||||
_ "github.com/openshift/installer/pkg/destroy/libvirt"
|
||||
@@ -52,7 +52,7 @@ func runDestroyCmd(directory string) error {
|
||||
return errors.Wrap(err, "Failed to destroy cluster")
|
||||
}
|
||||
|
||||
store, err := asset.NewStore(directory)
|
||||
store, err := assetstore.NewStore(directory)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create asset store")
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 91 KiB |
@@ -5,6 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -58,9 +59,9 @@ func PersistToFile(asset WritableAsset, directory string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteAssetFromDisk removes all the files for asset from disk.
|
||||
// DeleteAssetFromDisk removes all the files for asset from disk.
|
||||
// this is function is not safe for calling concurrently on the same directory.
|
||||
func deleteAssetFromDisk(asset WritableAsset, directory string) error {
|
||||
func DeleteAssetFromDisk(asset WritableAsset, directory string) error {
|
||||
logrus.Debugf("Purging asset %q from disk", asset.Name())
|
||||
for _, f := range asset.Files() {
|
||||
path := filepath.Join(directory, f.Filename)
|
||||
@@ -95,3 +96,8 @@ func isDirEmpty(name string) (bool, error) {
|
||||
}
|
||||
return false, err // Either not empty or error, suits both cases
|
||||
}
|
||||
|
||||
// SortFiles sorts the specified files by file name.
|
||||
func SortFiles(files []*File) {
|
||||
sort.Slice(files, func(i, j int) bool { return files[i].Filename < files[j].Filename })
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package asset
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
)
|
||||
|
||||
//go:generate mockgen -source=./filefetcher.go -destination=./mock/filefetcher_generated.go -package=mock
|
||||
|
||||
// FileFetcher fetches the asset files from disk.
|
||||
@@ -15,45 +9,3 @@ type FileFetcher interface {
|
||||
// FetchByPattern returns the files whose name match the given glob.
|
||||
FetchByPattern(pattern string) ([]*File, error)
|
||||
}
|
||||
|
||||
type fileFetcher struct {
|
||||
directory string
|
||||
}
|
||||
|
||||
// FetchByName returns the file with the given name.
|
||||
func (f *fileFetcher) FetchByName(name string) (*File, error) {
|
||||
data, err := ioutil.ReadFile(filepath.Join(f.directory, name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &File{Filename: name, Data: data}, nil
|
||||
}
|
||||
|
||||
// FetchByPattern returns the files whose name match the given regexp.
|
||||
func (f *fileFetcher) FetchByPattern(pattern string) (files []*File, err error) {
|
||||
matches, err := filepath.Glob(filepath.Join(f.directory, pattern))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files = make([]*File, 0, len(matches))
|
||||
for _, path := range matches {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filename, err := filepath.Rel(f.directory, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files = append(files, &File{
|
||||
Filename: filename,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(files, func(i, j int) bool { return files[i].Filename < files[j].Filename })
|
||||
return files, nil
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ func (m *Master) Generate(dependencies asset.Parents) error {
|
||||
}
|
||||
m.MachinesRaw = raw
|
||||
case nonetypes.Name:
|
||||
// This is needed to ensure that roundtrip generate-load tests pass when
|
||||
// comparing this value. Otherwise, generate will use a nil value while
|
||||
// load will use an empty byte slice.
|
||||
m.MachinesRaw = []byte{}
|
||||
case openstacktypes.Name:
|
||||
mpool := defaultOpenStackMachinePoolPlatform(ic.Platform.OpenStack.FlavorName)
|
||||
mpool.Set(ic.Platform.OpenStack.DefaultMachinePlatform)
|
||||
|
||||
@@ -131,6 +131,10 @@ func (w *Worker) Generate(dependencies asset.Parents) error {
|
||||
}
|
||||
w.MachineSetRaw = raw
|
||||
case nonetypes.Name:
|
||||
// This is needed to ensure that roundtrip generate-load tests pass when
|
||||
// comparing this value. Otherwise, generate will use a nil value while
|
||||
// load will use an empty byte slice.
|
||||
w.MachineSetRaw = []byte{}
|
||||
case openstacktypes.Name:
|
||||
mpool := defaultOpenStackMachinePoolPlatform(ic.Platform.OpenStack.FlavorName)
|
||||
mpool.Set(ic.Platform.OpenStack.DefaultMachinePlatform)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package manifests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@@ -22,7 +21,6 @@ var (
|
||||
|
||||
// DNS generates the cluster-dns-*.yml files.
|
||||
type DNS struct {
|
||||
config *configv1.DNS
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -46,7 +44,7 @@ func (d *DNS) Generate(dependencies asset.Parents) error {
|
||||
installConfig := &installconfig.InstallConfig{}
|
||||
dependencies.Get(installConfig)
|
||||
|
||||
d.config = &configv1.DNS{
|
||||
config := &configv1.DNS{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: configv1.SchemeGroupVersion.String(),
|
||||
Kind: "DNS",
|
||||
@@ -60,7 +58,7 @@ func (d *DNS) Generate(dependencies asset.Parents) error {
|
||||
},
|
||||
}
|
||||
|
||||
configData, err := yaml.Marshal(d.config)
|
||||
configData, err := yaml.Marshal(config)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create %s manifests from InstallConfig", d.Name())
|
||||
}
|
||||
@@ -91,31 +89,5 @@ func (d *DNS) Files() []*asset.File {
|
||||
|
||||
// Load loads the already-rendered files back from disk.
|
||||
func (d *DNS) Load(f asset.FileFetcher) (bool, error) {
|
||||
crdFile, err := f.FetchByName(filepath.Join(manifestDir, dnsCrdFilename))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
cfgFile, err := f.FetchByName(dnsCfgFilename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
dnsConfig := &configv1.DNS{}
|
||||
if err := yaml.Unmarshal(cfgFile.Data, dnsConfig); err != nil {
|
||||
return false, errors.Wrapf(err, "failed to unmarshal %s", dnsCfgFilename)
|
||||
}
|
||||
|
||||
fileList := []*asset.File{crdFile, cfgFile}
|
||||
|
||||
d.FileList, d.config = fileList, dnsConfig
|
||||
|
||||
return true, nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package manifests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@@ -23,7 +22,6 @@ var (
|
||||
|
||||
// Ingress generates the cluster-ingress-*.yml files.
|
||||
type Ingress struct {
|
||||
config *configv1.Ingress
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -47,7 +45,7 @@ func (ing *Ingress) Generate(dependencies asset.Parents) error {
|
||||
installConfig := &installconfig.InstallConfig{}
|
||||
dependencies.Get(installConfig)
|
||||
|
||||
ing.config = &configv1.Ingress{
|
||||
config := &configv1.Ingress{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: configv1.SchemeGroupVersion.String(),
|
||||
Kind: "Ingress",
|
||||
@@ -61,7 +59,7 @@ func (ing *Ingress) Generate(dependencies asset.Parents) error {
|
||||
},
|
||||
}
|
||||
|
||||
configData, err := yaml.Marshal(ing.config)
|
||||
configData, err := yaml.Marshal(config)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create %s manifests from InstallConfig", ing.Name())
|
||||
}
|
||||
@@ -90,33 +88,7 @@ func (ing *Ingress) Files() []*asset.File {
|
||||
return ing.FileList
|
||||
}
|
||||
|
||||
// Load loads the already-rendered files back from disk.
|
||||
// Load returns false since this asset is not written to disk by the installer.
|
||||
func (ing *Ingress) Load(f asset.FileFetcher) (bool, error) {
|
||||
crdFile, err := f.FetchByName(filepath.Join(manifestDir, ingCrdFilename))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
cfgFile, err := f.FetchByName(ingCfgFilename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
ingressConfig := &configv1.Ingress{}
|
||||
if err := yaml.Unmarshal(cfgFile.Data, ingressConfig); err != nil {
|
||||
return false, errors.Wrapf(err, "failed to unmarshal %s", ingCfgFilename)
|
||||
}
|
||||
|
||||
fileList := []*asset.File{crdFile, cfgFile}
|
||||
|
||||
ing.FileList, ing.config = fileList, ingressConfig
|
||||
|
||||
return true, nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package manifests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@@ -33,7 +32,7 @@ var (
|
||||
|
||||
// Networking generates the cluster-network-*.yml files.
|
||||
type Networking struct {
|
||||
config *configv1.Network
|
||||
Config *configv1.Network
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -74,7 +73,7 @@ func (no *Networking) Generate(dependencies asset.Parents) error {
|
||||
return errors.Errorf("ClusterNetworks must be specified")
|
||||
}
|
||||
|
||||
no.config = &configv1.Network{
|
||||
no.Config = &configv1.Network{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: configv1.SchemeGroupVersion.String(),
|
||||
Kind: "Network",
|
||||
@@ -90,7 +89,7 @@ func (no *Networking) Generate(dependencies asset.Parents) error {
|
||||
},
|
||||
}
|
||||
|
||||
configData, err := yaml.Marshal(no.config)
|
||||
configData, err := yaml.Marshal(no.Config)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create %s manifests from InstallConfig", no.Name())
|
||||
}
|
||||
@@ -123,19 +122,19 @@ func (no *Networking) Files() []*asset.File {
|
||||
// object. This is called by ClusterK8sIO, which captures generalized cluster
|
||||
// state but shouldn't need to be fully networking aware.
|
||||
func (no *Networking) ClusterNetwork() (*clusterv1a1.ClusterNetworkingConfig, error) {
|
||||
if no.config == nil {
|
||||
if no.Config == nil {
|
||||
// should be unreachable.
|
||||
return nil, errors.Errorf("ClusterNetwork called before initialization")
|
||||
}
|
||||
|
||||
pods := []string{}
|
||||
for _, cn := range no.config.Spec.ClusterNetwork {
|
||||
for _, cn := range no.Config.Spec.ClusterNetwork {
|
||||
pods = append(pods, cn.CIDR)
|
||||
}
|
||||
|
||||
cn := &clusterv1a1.ClusterNetworkingConfig{
|
||||
Services: clusterv1a1.NetworkRanges{
|
||||
CIDRBlocks: no.config.Spec.ServiceNetwork,
|
||||
CIDRBlocks: no.Config.Spec.ServiceNetwork,
|
||||
},
|
||||
Pods: clusterv1a1.NetworkRanges{
|
||||
CIDRBlocks: pods,
|
||||
@@ -144,33 +143,7 @@ func (no *Networking) ClusterNetwork() (*clusterv1a1.ClusterNetworkingConfig, er
|
||||
return cn, nil
|
||||
}
|
||||
|
||||
// Load loads the already-rendered files back from disk.
|
||||
// Load returns false since this asset is not written to disk by the installer.
|
||||
func (no *Networking) Load(f asset.FileFetcher) (bool, error) {
|
||||
crdFile, err := f.FetchByName(noCrdFilename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
cfgFile, err := f.FetchByName(noCfgFilename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
netConfig := &configv1.Network{}
|
||||
if err := yaml.Unmarshal(cfgFile.Data, netConfig); err != nil {
|
||||
return false, errors.Wrapf(err, "failed to unmarshal %s", noCfgFilename)
|
||||
}
|
||||
|
||||
fileList := []*asset.File{crdFile, cfgFile}
|
||||
|
||||
no.FileList, no.config = fileList, netConfig
|
||||
|
||||
return true, nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -146,6 +146,8 @@ func (o *Openshift) Generate(dependencies asset.Parents) error {
|
||||
})
|
||||
}
|
||||
|
||||
asset.SortFiles(o.FileList)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -161,5 +163,6 @@ func (o *Openshift) Load(f asset.FileFetcher) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
o.FileList = fileList
|
||||
asset.SortFiles(o.FileList)
|
||||
return len(fileList) > 0, nil
|
||||
}
|
||||
|
||||
@@ -116,6 +116,8 @@ func (m *Manifests) Generate(dependencies asset.Parents) error {
|
||||
m.FileList = append(m.FileList, network.Files()...)
|
||||
m.FileList = append(m.FileList, infra.Files()...)
|
||||
|
||||
asset.SortFiles(m.FileList)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -264,6 +266,8 @@ func (m *Manifests) Load(f asset.FileFetcher) (bool, error) {
|
||||
|
||||
m.FileList, m.KubeSysConfig = fileList, kubeSysConfig
|
||||
|
||||
asset.SortFiles(m.FileList)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
package asset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
stateFileName = ".openshift_install_state.json"
|
||||
)
|
||||
|
||||
// Store is a store for the states of assets.
|
||||
type Store interface {
|
||||
// Fetch retrieves the state of the given asset, generating it and its
|
||||
@@ -29,338 +14,3 @@ type Store interface {
|
||||
// state file
|
||||
DestroyState() error
|
||||
}
|
||||
|
||||
// assetSource indicates from where the asset was fetched
|
||||
type assetSource int
|
||||
|
||||
const (
|
||||
// unsourced indicates that the asset has not been fetched
|
||||
unfetched assetSource = iota
|
||||
// generatedSource indicates that the asset was generated
|
||||
generatedSource
|
||||
// onDiskSource indicates that the asset was fetched from disk
|
||||
onDiskSource
|
||||
// stateFileSource indicates that the asset was fetched from the state file
|
||||
stateFileSource
|
||||
)
|
||||
|
||||
type assetState struct {
|
||||
// asset is the asset.
|
||||
// If the asset has not been fetched, then this will be nil.
|
||||
asset Asset
|
||||
// source is the source from which the asset was fetched
|
||||
source assetSource
|
||||
// anyParentsDirty is true if any of the parents of the asset are dirty
|
||||
anyParentsDirty bool
|
||||
// presentOnDisk is true if the asset in on-disk. This is set whether the
|
||||
// asset is sourced from on-disk or not. It is used in purging consumed assets.
|
||||
presentOnDisk bool
|
||||
}
|
||||
|
||||
// StoreImpl is the implementation of Store.
|
||||
type StoreImpl struct {
|
||||
directory string
|
||||
assets map[reflect.Type]*assetState
|
||||
stateFileAssets map[string]json.RawMessage
|
||||
fileFetcher FileFetcher
|
||||
}
|
||||
|
||||
// NewStore returns an asset store that implements the Store interface.
|
||||
func NewStore(dir string) (Store, error) {
|
||||
store := &StoreImpl{
|
||||
directory: dir,
|
||||
fileFetcher: &fileFetcher{directory: dir},
|
||||
assets: map[reflect.Type]*assetState{},
|
||||
}
|
||||
|
||||
if err := store.loadStateFile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return store, nil
|
||||
}
|
||||
|
||||
// Fetch retrieves the state of the given asset, generating it and its
|
||||
// dependencies if necessary.
|
||||
func (s *StoreImpl) Fetch(asset Asset) error {
|
||||
if err := s.fetch(asset, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.saveStateFile(); err != nil {
|
||||
return errors.Wrapf(err, "failed to save state")
|
||||
}
|
||||
if wa, ok := asset.(WritableAsset); ok {
|
||||
return errors.Wrapf(s.purge(wa), "failed to purge asset")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Destroy removes the asset from all its internal state and also from
|
||||
// disk if possible.
|
||||
func (s *StoreImpl) Destroy(asset Asset) error {
|
||||
if sa, ok := s.assets[reflect.TypeOf(asset)]; ok {
|
||||
reflect.ValueOf(asset).Elem().Set(reflect.ValueOf(sa.asset).Elem())
|
||||
} else if s.isAssetInState(asset) {
|
||||
if err := s.loadAssetFromState(asset); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// nothing to do
|
||||
return nil
|
||||
}
|
||||
|
||||
if wa, ok := asset.(WritableAsset); ok {
|
||||
if err := deleteAssetFromDisk(wa, s.directory); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
delete(s.assets, reflect.TypeOf(asset))
|
||||
delete(s.stateFileAssets, reflect.TypeOf(asset).String())
|
||||
return s.saveStateFile()
|
||||
}
|
||||
|
||||
// DestroyState removes the state file from disk
|
||||
func (s *StoreImpl) DestroyState() error {
|
||||
s.stateFileAssets = nil
|
||||
path := filepath.Join(s.directory, stateFileName)
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadStateFile retrieves the state from the state file present in the given directory
|
||||
// and returns the assets map
|
||||
func (s *StoreImpl) loadStateFile() error {
|
||||
path := filepath.Join(s.directory, stateFileName)
|
||||
assets := map[string]json.RawMessage{}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(data, &assets)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to unmarshal state file %q", path)
|
||||
}
|
||||
s.stateFileAssets = assets
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadAssetFromState renders the asset object arguments from the state file contents.
|
||||
func (s *StoreImpl) loadAssetFromState(asset Asset) error {
|
||||
bytes, ok := s.stateFileAssets[reflect.TypeOf(asset).String()]
|
||||
if !ok {
|
||||
return errors.Errorf("asset %q is not found in the state file", asset.Name())
|
||||
}
|
||||
return json.Unmarshal(bytes, asset)
|
||||
}
|
||||
|
||||
// isAssetInState tests whether the asset is in the state file.
|
||||
func (s *StoreImpl) isAssetInState(asset Asset) bool {
|
||||
_, ok := s.stateFileAssets[reflect.TypeOf(asset).String()]
|
||||
return ok
|
||||
}
|
||||
|
||||
// saveStateFile dumps the entire state map into a file
|
||||
func (s *StoreImpl) saveStateFile() error {
|
||||
if s.stateFileAssets == nil {
|
||||
s.stateFileAssets = map[string]json.RawMessage{}
|
||||
}
|
||||
for k, v := range s.assets {
|
||||
if v.source == unfetched {
|
||||
continue
|
||||
}
|
||||
data, err := json.MarshalIndent(v.asset, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.stateFileAssets[k.String()] = json.RawMessage(data)
|
||||
}
|
||||
data, err := json.MarshalIndent(s.stateFileAssets, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := filepath.Join(s.directory, stateFileName)
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(path, data, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fetch populates the given asset, generating it and its dependencies if
|
||||
// necessary, and returns whether or not the asset had to be regenerated and
|
||||
// any errors.
|
||||
func (s *StoreImpl) fetch(asset Asset, indent string) error {
|
||||
logrus.Debugf("%sFetching %q...", indent, asset.Name())
|
||||
|
||||
assetState, ok := s.assets[reflect.TypeOf(asset)]
|
||||
if !ok {
|
||||
if _, err := s.load(asset, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
assetState = s.assets[reflect.TypeOf(asset)]
|
||||
}
|
||||
|
||||
// Return immediately if the asset has been fetched before,
|
||||
// this is because we are doing a depth-first-search, it's guaranteed
|
||||
// that we always fetch the parent before children, so we don't need
|
||||
// to worry about invalidating anything in the cache.
|
||||
if assetState.source != unfetched {
|
||||
logrus.Debugf("%sReusing previously-fetched %q", indent, asset.Name())
|
||||
reflect.ValueOf(asset).Elem().Set(reflect.ValueOf(assetState.asset).Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
// Re-generate the asset
|
||||
dependencies := asset.Dependencies()
|
||||
parents := make(Parents, len(dependencies))
|
||||
for _, d := range dependencies {
|
||||
if err := s.fetch(d, increaseIndent(indent)); err != nil {
|
||||
return errors.Wrapf(err, "failed to fetch dependency of %q", asset.Name())
|
||||
}
|
||||
parents.Add(d)
|
||||
}
|
||||
logrus.Debugf("%sGenerating %q...", indent, asset.Name())
|
||||
if err := asset.Generate(parents); err != nil {
|
||||
return errors.Wrapf(err, "failed to generate asset %q", asset.Name())
|
||||
}
|
||||
assetState.asset = asset
|
||||
assetState.source = generatedSource
|
||||
return nil
|
||||
}
|
||||
|
||||
// load loads the asset and all of its ancestors from on-disk and the state file.
|
||||
func (s *StoreImpl) load(asset Asset, indent string) (*assetState, error) {
|
||||
logrus.Debugf("%sLoading %q...", indent, asset.Name())
|
||||
|
||||
// Stop descent if the asset has already been loaded.
|
||||
if state, ok := s.assets[reflect.TypeOf(asset)]; ok {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// Load dependencies from on-disk.
|
||||
anyParentsDirty := false
|
||||
for _, d := range asset.Dependencies() {
|
||||
state, err := s.load(d, increaseIndent(indent))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if state.anyParentsDirty || state.source == onDiskSource {
|
||||
anyParentsDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load from on-disk.
|
||||
var (
|
||||
onDiskAsset WritableAsset
|
||||
foundOnDisk bool
|
||||
)
|
||||
if _, isWritable := asset.(WritableAsset); isWritable {
|
||||
onDiskAsset = reflect.New(reflect.TypeOf(asset).Elem()).Interface().(WritableAsset)
|
||||
var err error
|
||||
foundOnDisk, err = onDiskAsset.Load(s.fileFetcher)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to load asset %q", asset.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load from state file.
|
||||
var (
|
||||
stateFileAsset Asset
|
||||
foundInStateFile bool
|
||||
onDiskMatchesStateFile bool
|
||||
)
|
||||
// Do not need to bother with loading from state file if any of the parents
|
||||
// are dirty because the asset must be re-generated in this case.
|
||||
if !anyParentsDirty {
|
||||
foundInStateFile = s.isAssetInState(asset)
|
||||
if foundInStateFile {
|
||||
stateFileAsset = reflect.New(reflect.TypeOf(asset).Elem()).Interface().(Asset)
|
||||
if err := s.loadAssetFromState(stateFileAsset); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to load asset %q from state file", asset.Name())
|
||||
}
|
||||
}
|
||||
|
||||
if foundOnDisk && foundInStateFile {
|
||||
logrus.Debugf("%sLoading %q from both state file and target directory", indent, asset.Name())
|
||||
|
||||
// If the on-disk asset is the same as the one in the state file, there
|
||||
// is no need to consider the one on disk and to mark the asset dirty.
|
||||
onDiskMatchesStateFile = reflect.DeepEqual(onDiskAsset, stateFileAsset)
|
||||
if onDiskMatchesStateFile {
|
||||
logrus.Debugf("%sOn-disk %q matches asset in state file", indent, asset.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
assetToStore Asset
|
||||
source assetSource
|
||||
)
|
||||
switch {
|
||||
// A parent is dirty. The asset must be re-generated.
|
||||
case anyParentsDirty:
|
||||
if foundOnDisk {
|
||||
logrus.Warningf("%sDiscarding the %q that was provided in the target directory because its dependencies are dirty and it needs to be regenerated", indent, asset.Name())
|
||||
}
|
||||
source = unfetched
|
||||
// The asset is on disk and that differs from what is in the source file.
|
||||
// The asset is sourced from on disk.
|
||||
case foundOnDisk && !onDiskMatchesStateFile:
|
||||
logrus.Debugf("%sUsing %q loaded from target directory", indent, asset.Name())
|
||||
assetToStore = onDiskAsset
|
||||
source = onDiskSource
|
||||
// The asset is in the state file. The asset is sourced from state file.
|
||||
case foundInStateFile:
|
||||
logrus.Debugf("%sUsing %q loaded from state file", indent, asset.Name())
|
||||
assetToStore = stateFileAsset
|
||||
source = stateFileSource
|
||||
// There is no existing source for the asset. The asset will be generated.
|
||||
default:
|
||||
source = unfetched
|
||||
}
|
||||
|
||||
state := &assetState{
|
||||
asset: assetToStore,
|
||||
source: source,
|
||||
anyParentsDirty: anyParentsDirty,
|
||||
presentOnDisk: foundOnDisk,
|
||||
}
|
||||
s.assets[reflect.TypeOf(asset)] = state
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// purge deletes the on-disk assets that are consumed already.
|
||||
// E.g., install-config.yaml will be deleted after fetching 'manifests'.
|
||||
// The target asset is excluded.
|
||||
func (s *StoreImpl) purge(excluded WritableAsset) error {
|
||||
for _, assetState := range s.assets {
|
||||
if !assetState.presentOnDisk {
|
||||
continue
|
||||
}
|
||||
if reflect.TypeOf(assetState.asset) == reflect.TypeOf(excluded) {
|
||||
continue
|
||||
}
|
||||
logrus.Infof("Consuming %q from target directory", assetState.asset.Name())
|
||||
if err := deleteAssetFromDisk(assetState.asset.(WritableAsset), s.directory); err != nil {
|
||||
return err
|
||||
}
|
||||
assetState.presentOnDisk = false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func increaseIndent(indent string) string {
|
||||
return indent + " "
|
||||
}
|
||||
|
||||
113
pkg/asset/store/assetcreate_test.go
Normal file
113
pkg/asset/store/assetcreate_test.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
"github.com/openshift/installer/pkg/asset/targets"
|
||||
)
|
||||
|
||||
const userProvidedAssets = `{
|
||||
"*installconfig.baseDomain": {
|
||||
"BaseDomain": "test-domain"
|
||||
},
|
||||
"*installconfig.clusterID": {
|
||||
"ClusterID": "test-cluster-id"
|
||||
},
|
||||
"*installconfig.clusterName": {
|
||||
"ClusterName": "test-cluster"
|
||||
},
|
||||
"*installconfig.platform": {
|
||||
"none": {}
|
||||
},
|
||||
"*installconfig.pullSecret": {
|
||||
"PullSecret": "{\"auths\": {\"example.com\": {\"auth\": \"test-auth\"}}}\n"
|
||||
},
|
||||
"*installconfig.sshPublicKey": {}
|
||||
}`
|
||||
|
||||
func TestCreatedAssetsAreNotDirty(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
targets []asset.WritableAsset
|
||||
}{
|
||||
{
|
||||
name: "install config",
|
||||
targets: targets.InstallConfig,
|
||||
},
|
||||
{
|
||||
name: "manifest templates",
|
||||
targets: targets.ManifestTemplates,
|
||||
},
|
||||
{
|
||||
name: "manifests",
|
||||
targets: targets.Manifests,
|
||||
},
|
||||
{
|
||||
name: "ignition configs",
|
||||
targets: targets.IgnitionConfigs,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tempDir, err := ioutil.TempDir("", "TestCreatedAssetsAreNotDirty")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create the temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(tempDir, stateFileName), []byte(userProvidedAssets), 0666); err != nil {
|
||||
t.Fatalf("could not write the state file: %v", err)
|
||||
}
|
||||
|
||||
assetStore, err := newStore(tempDir)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create asset store: %v", err)
|
||||
}
|
||||
|
||||
for _, a := range tc.targets {
|
||||
if err := assetStore.Fetch(a); err != nil {
|
||||
t.Fatalf("failed to fetch %q: %v", a.Name(), err)
|
||||
}
|
||||
|
||||
if err := asset.PersistToFile(a, tempDir); err != nil {
|
||||
t.Fatalf("failed to write asset %q to disk: %v", a.Name(), err)
|
||||
}
|
||||
}
|
||||
|
||||
newAssetStore, err := newStore(tempDir)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create new asset store: %v", err)
|
||||
}
|
||||
|
||||
for _, a := range tc.targets {
|
||||
newAsset := reflect.New(reflect.TypeOf(a).Elem()).Interface().(asset.WritableAsset)
|
||||
if err := newAssetStore.Fetch(newAsset); err != nil {
|
||||
t.Fatalf("failed to fetch %q in new store: %v", a.Name(), err)
|
||||
}
|
||||
assetState := newAssetStore.assets[reflect.TypeOf(a)]
|
||||
// Make an exception for metadata. It's files are read-only.
|
||||
if a.Name() != "Metadata" {
|
||||
assert.Truef(t, assetState.presentOnDisk, "asset %q was not found on disk", a.Name())
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(t, len(assetStore.assets), len(newAssetStore.assets), "new asset store does not have the same number of assets as original")
|
||||
|
||||
for _, a := range newAssetStore.assets {
|
||||
originalAssetState, ok := assetStore.assets[reflect.TypeOf(a.asset)]
|
||||
if !ok {
|
||||
t.Fatalf("asset %q not found in original store", a.asset.Name())
|
||||
}
|
||||
assert.Equalf(t, originalAssetState.asset, a.asset, "fetched and generated asset %q are not equal", a.asset.Name())
|
||||
assert.Equalf(t, stateFileSource, a.source, "asset %q was not fetched from the state file", a.asset.Name())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
1
pkg/asset/store/data
Symbolic link
1
pkg/asset/store/data
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../data/data
|
||||
49
pkg/asset/store/filefetcher.go
Normal file
49
pkg/asset/store/filefetcher.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
)
|
||||
|
||||
type fileFetcher struct {
|
||||
directory string
|
||||
}
|
||||
|
||||
// FetchByName returns the file with the given name.
|
||||
func (f *fileFetcher) FetchByName(name string) (*asset.File, error) {
|
||||
data, err := ioutil.ReadFile(filepath.Join(f.directory, name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &asset.File{Filename: name, Data: data}, nil
|
||||
}
|
||||
|
||||
// FetchByPattern returns the files whose name match the given regexp.
|
||||
func (f *fileFetcher) FetchByPattern(pattern string) (files []*asset.File, err error) {
|
||||
matches, err := filepath.Glob(filepath.Join(f.directory, pattern))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files = make([]*asset.File, 0, len(matches))
|
||||
for _, path := range matches {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filename, err := filepath.Rel(f.directory, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files = append(files, &asset.File{
|
||||
Filename: filename,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package asset
|
||||
package store
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
)
|
||||
|
||||
func TestFetchByName(t *testing.T) {
|
||||
@@ -14,7 +16,7 @@ func TestFetchByName(t *testing.T) {
|
||||
name string
|
||||
files map[string][]byte
|
||||
input string
|
||||
expectFile *File
|
||||
expectFile *asset.File
|
||||
}{
|
||||
{
|
||||
name: "input doesn't match",
|
||||
@@ -26,7 +28,7 @@ func TestFetchByName(t *testing.T) {
|
||||
name: "with contents",
|
||||
files: map[string][]byte{"foo.bar": []byte("some data")},
|
||||
input: "foo.bar",
|
||||
expectFile: &File{
|
||||
expectFile: &asset.File{
|
||||
Filename: "foo.bar",
|
||||
Data: []byte("some data"),
|
||||
},
|
||||
@@ -35,7 +37,7 @@ func TestFetchByName(t *testing.T) {
|
||||
name: "match one file",
|
||||
files: map[string][]byte{"foo.bar": []byte("some data")},
|
||||
input: "foo.bar",
|
||||
expectFile: &File{
|
||||
expectFile: &asset.File{
|
||||
Filename: "foo.bar",
|
||||
Data: []byte("some data"),
|
||||
},
|
||||
@@ -110,11 +112,11 @@ func TestFetchByPattern(t *testing.T) {
|
||||
}
|
||||
tests := []struct {
|
||||
input string
|
||||
expectFiles []*File
|
||||
expectFiles []*asset.File
|
||||
}{
|
||||
{
|
||||
input: "master-[0-9]*.ign",
|
||||
expectFiles: []*File{
|
||||
expectFiles: []*asset.File{
|
||||
{
|
||||
Filename: "master-0.ign",
|
||||
Data: []byte("some data 0"),
|
||||
@@ -147,7 +149,7 @@ func TestFetchByPattern(t *testing.T) {
|
||||
},
|
||||
{
|
||||
input: filepath.Join("manifests", "*"),
|
||||
expectFiles: []*File{
|
||||
expectFiles: []*asset.File{
|
||||
{
|
||||
Filename: "manifests/0",
|
||||
Data: []byte("some data 11"),
|
||||
357
pkg/asset/store/store.go
Normal file
357
pkg/asset/store/store.go
Normal file
@@ -0,0 +1,357 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
)
|
||||
|
||||
const (
|
||||
stateFileName = ".openshift_install_state.json"
|
||||
)
|
||||
|
||||
// assetSource indicates from where the asset was fetched
|
||||
type assetSource int
|
||||
|
||||
const (
|
||||
// unsourced indicates that the asset has not been fetched
|
||||
unfetched assetSource = iota
|
||||
// generatedSource indicates that the asset was generated
|
||||
generatedSource
|
||||
// onDiskSource indicates that the asset was fetched from disk
|
||||
onDiskSource
|
||||
// stateFileSource indicates that the asset was fetched from the state file
|
||||
stateFileSource
|
||||
)
|
||||
|
||||
type assetState struct {
|
||||
// asset is the asset.
|
||||
// If the asset has not been fetched, then this will be nil.
|
||||
asset asset.Asset
|
||||
// source is the source from which the asset was fetched
|
||||
source assetSource
|
||||
// anyParentsDirty is true if any of the parents of the asset are dirty
|
||||
anyParentsDirty bool
|
||||
// presentOnDisk is true if the asset in on-disk. This is set whether the
|
||||
// asset is sourced from on-disk or not. It is used in purging consumed assets.
|
||||
presentOnDisk bool
|
||||
}
|
||||
|
||||
// storeImpl is the implementation of Store.
|
||||
type storeImpl struct {
|
||||
directory string
|
||||
assets map[reflect.Type]*assetState
|
||||
stateFileAssets map[string]json.RawMessage
|
||||
fileFetcher asset.FileFetcher
|
||||
}
|
||||
|
||||
// NewStore returns an asset store that implements the asset.Store interface.
|
||||
func NewStore(dir string) (asset.Store, error) {
|
||||
return newStore(dir)
|
||||
}
|
||||
|
||||
func newStore(dir string) (*storeImpl, error) {
|
||||
store := &storeImpl{
|
||||
directory: dir,
|
||||
fileFetcher: &fileFetcher{directory: dir},
|
||||
assets: map[reflect.Type]*assetState{},
|
||||
}
|
||||
|
||||
if err := store.loadStateFile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return store, nil
|
||||
}
|
||||
|
||||
// Fetch retrieves the state of the given asset, generating it and its
|
||||
// dependencies if necessary.
|
||||
func (s *storeImpl) Fetch(a asset.Asset) error {
|
||||
if err := s.fetch(a, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.saveStateFile(); err != nil {
|
||||
return errors.Wrapf(err, "failed to save state")
|
||||
}
|
||||
if wa, ok := a.(asset.WritableAsset); ok {
|
||||
return errors.Wrapf(s.purge(wa), "failed to purge asset")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Destroy removes the asset from all its internal state and also from
|
||||
// disk if possible.
|
||||
func (s *storeImpl) Destroy(a asset.Asset) error {
|
||||
if sa, ok := s.assets[reflect.TypeOf(a)]; ok {
|
||||
reflect.ValueOf(a).Elem().Set(reflect.ValueOf(sa.asset).Elem())
|
||||
} else if s.isAssetInState(a) {
|
||||
if err := s.loadAssetFromState(a); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// nothing to do
|
||||
return nil
|
||||
}
|
||||
|
||||
if wa, ok := a.(asset.WritableAsset); ok {
|
||||
if err := asset.DeleteAssetFromDisk(wa, s.directory); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
delete(s.assets, reflect.TypeOf(a))
|
||||
delete(s.stateFileAssets, reflect.TypeOf(a).String())
|
||||
return s.saveStateFile()
|
||||
}
|
||||
|
||||
// DestroyState removes the state file from disk
|
||||
func (s *storeImpl) DestroyState() error {
|
||||
s.stateFileAssets = nil
|
||||
path := filepath.Join(s.directory, stateFileName)
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadStateFile retrieves the state from the state file present in the given directory
|
||||
// and returns the assets map
|
||||
func (s *storeImpl) loadStateFile() error {
|
||||
path := filepath.Join(s.directory, stateFileName)
|
||||
assets := map[string]json.RawMessage{}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(data, &assets)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to unmarshal state file %q", path)
|
||||
}
|
||||
s.stateFileAssets = assets
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadAssetFromState renders the asset object arguments from the state file contents.
|
||||
func (s *storeImpl) loadAssetFromState(a asset.Asset) error {
|
||||
bytes, ok := s.stateFileAssets[reflect.TypeOf(a).String()]
|
||||
if !ok {
|
||||
return errors.Errorf("asset %q is not found in the state file", a.Name())
|
||||
}
|
||||
return json.Unmarshal(bytes, a)
|
||||
}
|
||||
|
||||
// isAssetInState tests whether the asset is in the state file.
|
||||
func (s *storeImpl) isAssetInState(a asset.Asset) bool {
|
||||
_, ok := s.stateFileAssets[reflect.TypeOf(a).String()]
|
||||
return ok
|
||||
}
|
||||
|
||||
// saveStateFile dumps the entire state map into a file
|
||||
func (s *storeImpl) saveStateFile() error {
|
||||
if s.stateFileAssets == nil {
|
||||
s.stateFileAssets = map[string]json.RawMessage{}
|
||||
}
|
||||
for k, v := range s.assets {
|
||||
if v.source == unfetched {
|
||||
continue
|
||||
}
|
||||
data, err := json.MarshalIndent(v.asset, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.stateFileAssets[k.String()] = json.RawMessage(data)
|
||||
}
|
||||
data, err := json.MarshalIndent(s.stateFileAssets, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := filepath.Join(s.directory, stateFileName)
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(path, data, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fetch populates the given asset, generating it and its dependencies if
|
||||
// necessary, and returns whether or not the asset had to be regenerated and
|
||||
// any errors.
|
||||
func (s *storeImpl) fetch(a asset.Asset, indent string) error {
|
||||
logrus.Debugf("%sFetching %q...", indent, a.Name())
|
||||
|
||||
assetState, ok := s.assets[reflect.TypeOf(a)]
|
||||
if !ok {
|
||||
if _, err := s.load(a, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
assetState = s.assets[reflect.TypeOf(a)]
|
||||
}
|
||||
|
||||
// Return immediately if the asset has been fetched before,
|
||||
// this is because we are doing a depth-first-search, it's guaranteed
|
||||
// that we always fetch the parent before children, so we don't need
|
||||
// to worry about invalidating anything in the cache.
|
||||
if assetState.source != unfetched {
|
||||
logrus.Debugf("%sReusing previously-fetched %q", indent, a.Name())
|
||||
reflect.ValueOf(a).Elem().Set(reflect.ValueOf(assetState.asset).Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
// Re-generate the asset
|
||||
dependencies := a.Dependencies()
|
||||
parents := make(asset.Parents, len(dependencies))
|
||||
for _, d := range dependencies {
|
||||
if err := s.fetch(d, increaseIndent(indent)); err != nil {
|
||||
return errors.Wrapf(err, "failed to fetch dependency of %q", a.Name())
|
||||
}
|
||||
parents.Add(d)
|
||||
}
|
||||
logrus.Debugf("%sGenerating %q...", indent, a.Name())
|
||||
if err := a.Generate(parents); err != nil {
|
||||
return errors.Wrapf(err, "failed to generate asset %q", a.Name())
|
||||
}
|
||||
assetState.asset = a
|
||||
assetState.source = generatedSource
|
||||
return nil
|
||||
}
|
||||
|
||||
// load loads the asset and all of its ancestors from on-disk and the state file.
|
||||
func (s *storeImpl) load(a asset.Asset, indent string) (*assetState, error) {
|
||||
logrus.Debugf("%sLoading %q...", indent, a.Name())
|
||||
|
||||
// Stop descent if the asset has already been loaded.
|
||||
if state, ok := s.assets[reflect.TypeOf(a)]; ok {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// Load dependencies from on-disk.
|
||||
anyParentsDirty := false
|
||||
for _, d := range a.Dependencies() {
|
||||
state, err := s.load(d, increaseIndent(indent))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if state.anyParentsDirty || state.source == onDiskSource {
|
||||
anyParentsDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load from on-disk.
|
||||
var (
|
||||
onDiskAsset asset.WritableAsset
|
||||
foundOnDisk bool
|
||||
)
|
||||
if _, isWritable := a.(asset.WritableAsset); isWritable {
|
||||
onDiskAsset = reflect.New(reflect.TypeOf(a).Elem()).Interface().(asset.WritableAsset)
|
||||
var err error
|
||||
foundOnDisk, err = onDiskAsset.Load(s.fileFetcher)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to load asset %q", a.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load from state file.
|
||||
var (
|
||||
stateFileAsset asset.Asset
|
||||
foundInStateFile bool
|
||||
onDiskMatchesStateFile bool
|
||||
)
|
||||
// Do not need to bother with loading from state file if any of the parents
|
||||
// are dirty because the asset must be re-generated in this case.
|
||||
if !anyParentsDirty {
|
||||
foundInStateFile = s.isAssetInState(a)
|
||||
if foundInStateFile {
|
||||
stateFileAsset = reflect.New(reflect.TypeOf(a).Elem()).Interface().(asset.Asset)
|
||||
if err := s.loadAssetFromState(stateFileAsset); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to load asset %q from state file", a.Name())
|
||||
}
|
||||
}
|
||||
|
||||
if foundOnDisk && foundInStateFile {
|
||||
logrus.Debugf("%sLoading %q from both state file and target directory", indent, a.Name())
|
||||
|
||||
// If the on-disk asset is the same as the one in the state file, there
|
||||
// is no need to consider the one on disk and to mark the asset dirty.
|
||||
onDiskMatchesStateFile = reflect.DeepEqual(onDiskAsset, stateFileAsset)
|
||||
if onDiskMatchesStateFile {
|
||||
logrus.Debugf("%sOn-disk %q matches asset in state file", indent, a.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
assetToStore asset.Asset
|
||||
source assetSource
|
||||
)
|
||||
switch {
|
||||
// A parent is dirty. The asset must be re-generated.
|
||||
case anyParentsDirty:
|
||||
if foundOnDisk {
|
||||
logrus.Warningf("%sDiscarding the %q that was provided in the target directory because its dependencies are dirty and it needs to be regenerated", indent, a.Name())
|
||||
}
|
||||
source = unfetched
|
||||
// The asset is on disk and that differs from what is in the source file.
|
||||
// The asset is sourced from on disk.
|
||||
case foundOnDisk && !onDiskMatchesStateFile:
|
||||
logrus.Debugf("%sUsing %q loaded from target directory", indent, a.Name())
|
||||
assetToStore = onDiskAsset
|
||||
source = onDiskSource
|
||||
// The asset is in the state file. The asset is sourced from state file.
|
||||
case foundInStateFile:
|
||||
logrus.Debugf("%sUsing %q loaded from state file", indent, a.Name())
|
||||
assetToStore = stateFileAsset
|
||||
source = stateFileSource
|
||||
// There is no existing source for the asset. The asset will be generated.
|
||||
default:
|
||||
source = unfetched
|
||||
}
|
||||
|
||||
state := &assetState{
|
||||
asset: assetToStore,
|
||||
source: source,
|
||||
anyParentsDirty: anyParentsDirty,
|
||||
presentOnDisk: foundOnDisk,
|
||||
}
|
||||
s.assets[reflect.TypeOf(a)] = state
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// purge deletes the on-disk assets that are consumed already.
|
||||
// E.g., install-config.yaml will be deleted after fetching 'manifests'.
|
||||
// The target asset is excluded.
|
||||
func (s *storeImpl) purge(excluded asset.WritableAsset) error {
|
||||
for _, assetState := range s.assets {
|
||||
if !assetState.presentOnDisk {
|
||||
continue
|
||||
}
|
||||
if reflect.TypeOf(assetState.asset) == reflect.TypeOf(excluded) {
|
||||
continue
|
||||
}
|
||||
logrus.Infof("Consuming %q from target directory", assetState.asset.Name())
|
||||
if err := asset.DeleteAssetFromDisk(assetState.asset.(asset.WritableAsset), s.directory); err != nil {
|
||||
return err
|
||||
}
|
||||
assetState.presentOnDisk = false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func increaseIndent(indent string) string {
|
||||
return indent + " "
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package asset
|
||||
package store
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -14,30 +16,30 @@ var (
|
||||
// asset store creates new assets by type, so the tests cannot store behavior
|
||||
// state in the assets themselves.
|
||||
generationLog []string
|
||||
dependencies map[reflect.Type][]Asset
|
||||
dependencies map[reflect.Type][]asset.Asset
|
||||
onDiskAssets map[reflect.Type]bool
|
||||
)
|
||||
|
||||
func clearAssetBehaviors() {
|
||||
generationLog = []string{}
|
||||
dependencies = map[reflect.Type][]Asset{}
|
||||
dependencies = map[reflect.Type][]asset.Asset{}
|
||||
onDiskAssets = map[reflect.Type]bool{}
|
||||
}
|
||||
|
||||
func dependenciesTestStoreAsset(a Asset) []Asset {
|
||||
func dependenciesTestStoreAsset(a asset.Asset) []asset.Asset {
|
||||
return dependencies[reflect.TypeOf(a)]
|
||||
}
|
||||
|
||||
func generateTestStoreAsset(a Asset) error {
|
||||
func generateTestStoreAsset(a asset.Asset) error {
|
||||
generationLog = append(generationLog, a.Name())
|
||||
return nil
|
||||
}
|
||||
|
||||
func fileTestStoreAsset(a Asset) []*File {
|
||||
return []*File{{Filename: a.Name()}}
|
||||
func fileTestStoreAsset(a asset.Asset) []*asset.File {
|
||||
return []*asset.File{{Filename: a.Name()}}
|
||||
}
|
||||
|
||||
func loadTestStoreAsset(a Asset) (bool, error) {
|
||||
func loadTestStoreAsset(a asset.Asset) (bool, error) {
|
||||
return onDiskAssets[reflect.TypeOf(a)], nil
|
||||
}
|
||||
|
||||
@@ -47,19 +49,19 @@ func (a *testStoreAssetA) Name() string {
|
||||
return "a"
|
||||
}
|
||||
|
||||
func (a *testStoreAssetA) Dependencies() []Asset {
|
||||
func (a *testStoreAssetA) Dependencies() []asset.Asset {
|
||||
return dependenciesTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetA) Generate(Parents) error {
|
||||
func (a *testStoreAssetA) Generate(asset.Parents) error {
|
||||
return generateTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetA) Files() []*File {
|
||||
func (a *testStoreAssetA) Files() []*asset.File {
|
||||
return fileTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetA) Load(FileFetcher) (bool, error) {
|
||||
func (a *testStoreAssetA) Load(asset.FileFetcher) (bool, error) {
|
||||
return loadTestStoreAsset(a)
|
||||
}
|
||||
|
||||
@@ -69,19 +71,19 @@ func (a *testStoreAssetB) Name() string {
|
||||
return "b"
|
||||
}
|
||||
|
||||
func (a *testStoreAssetB) Dependencies() []Asset {
|
||||
func (a *testStoreAssetB) Dependencies() []asset.Asset {
|
||||
return dependenciesTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetB) Generate(Parents) error {
|
||||
func (a *testStoreAssetB) Generate(asset.Parents) error {
|
||||
return generateTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetB) Files() []*File {
|
||||
func (a *testStoreAssetB) Files() []*asset.File {
|
||||
return fileTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetB) Load(FileFetcher) (bool, error) {
|
||||
func (a *testStoreAssetB) Load(asset.FileFetcher) (bool, error) {
|
||||
return loadTestStoreAsset(a)
|
||||
}
|
||||
|
||||
@@ -91,19 +93,19 @@ func (a *testStoreAssetC) Name() string {
|
||||
return "c"
|
||||
}
|
||||
|
||||
func (a *testStoreAssetC) Dependencies() []Asset {
|
||||
func (a *testStoreAssetC) Dependencies() []asset.Asset {
|
||||
return dependenciesTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetC) Generate(Parents) error {
|
||||
func (a *testStoreAssetC) Generate(asset.Parents) error {
|
||||
return generateTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetC) Files() []*File {
|
||||
func (a *testStoreAssetC) Files() []*asset.File {
|
||||
return fileTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetC) Load(FileFetcher) (bool, error) {
|
||||
func (a *testStoreAssetC) Load(asset.FileFetcher) (bool, error) {
|
||||
return loadTestStoreAsset(a)
|
||||
}
|
||||
|
||||
@@ -113,23 +115,23 @@ func (a *testStoreAssetD) Name() string {
|
||||
return "d"
|
||||
}
|
||||
|
||||
func (a *testStoreAssetD) Dependencies() []Asset {
|
||||
func (a *testStoreAssetD) Dependencies() []asset.Asset {
|
||||
return dependenciesTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetD) Generate(Parents) error {
|
||||
func (a *testStoreAssetD) Generate(asset.Parents) error {
|
||||
return generateTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetD) Files() []*File {
|
||||
func (a *testStoreAssetD) Files() []*asset.File {
|
||||
return fileTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func (a *testStoreAssetD) Load(FileFetcher) (bool, error) {
|
||||
func (a *testStoreAssetD) Load(asset.FileFetcher) (bool, error) {
|
||||
return loadTestStoreAsset(a)
|
||||
}
|
||||
|
||||
func newTestStoreAsset(name string) Asset {
|
||||
func newTestStoreAsset(name string) asset.Asset {
|
||||
switch name {
|
||||
case "a":
|
||||
return &testStoreAssetA{}
|
||||
@@ -262,16 +264,16 @@ func TestStoreFetch(t *testing.T) {
|
||||
t.Fatalf("failed to create temporary directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
store := &StoreImpl{
|
||||
store := &storeImpl{
|
||||
directory: dir,
|
||||
assets: map[reflect.Type]*assetState{},
|
||||
}
|
||||
assets := make(map[string]Asset, len(tc.assets))
|
||||
assets := make(map[string]asset.Asset, len(tc.assets))
|
||||
for name := range tc.assets {
|
||||
assets[name] = newTestStoreAsset(name)
|
||||
}
|
||||
for name, deps := range tc.assets {
|
||||
dependenciesOfAsset := make([]Asset, len(deps))
|
||||
dependenciesOfAsset := make([]asset.Asset, len(deps))
|
||||
for i, d := range deps {
|
||||
dependenciesOfAsset[i] = assets[d]
|
||||
}
|
||||
@@ -361,15 +363,15 @@ func TestStoreFetchOnDiskAssets(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
clearAssetBehaviors()
|
||||
store := &StoreImpl{
|
||||
store := &storeImpl{
|
||||
assets: map[reflect.Type]*assetState{},
|
||||
}
|
||||
assets := make(map[string]Asset, len(tc.assets))
|
||||
assets := make(map[string]asset.Asset, len(tc.assets))
|
||||
for name := range tc.assets {
|
||||
assets[name] = newTestStoreAsset(name)
|
||||
}
|
||||
for name, deps := range tc.assets {
|
||||
dependenciesOfAsset := make([]Asset, len(deps))
|
||||
dependenciesOfAsset := make([]asset.Asset, len(deps))
|
||||
for i, d := range deps {
|
||||
dependenciesOfAsset[i] = assets[d]
|
||||
}
|
||||
67
pkg/asset/targets/targets.go
Normal file
67
pkg/asset/targets/targets.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package targets
|
||||
|
||||
import (
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
"github.com/openshift/installer/pkg/asset/cluster"
|
||||
"github.com/openshift/installer/pkg/asset/ignition/bootstrap"
|
||||
"github.com/openshift/installer/pkg/asset/ignition/machine"
|
||||
"github.com/openshift/installer/pkg/asset/installconfig"
|
||||
"github.com/openshift/installer/pkg/asset/kubeconfig"
|
||||
"github.com/openshift/installer/pkg/asset/manifests"
|
||||
"github.com/openshift/installer/pkg/asset/templates/content/bootkube"
|
||||
"github.com/openshift/installer/pkg/asset/templates/content/openshift"
|
||||
"github.com/openshift/installer/pkg/asset/tls"
|
||||
)
|
||||
|
||||
var (
|
||||
// InstallConfig are the install-config targeted assets.
|
||||
InstallConfig = []asset.WritableAsset{
|
||||
&installconfig.InstallConfig{},
|
||||
}
|
||||
|
||||
// Manifests are the manifests targeted assets.
|
||||
Manifests = []asset.WritableAsset{
|
||||
&manifests.Manifests{},
|
||||
&manifests.Openshift{},
|
||||
}
|
||||
|
||||
// ManifestTemplates are the manifest-templates targeted assets.
|
||||
ManifestTemplates = []asset.WritableAsset{
|
||||
&bootkube.KubeCloudConfig{},
|
||||
&bootkube.MachineConfigServerTLSSecret{},
|
||||
&bootkube.OpenshiftServiceCertSignerSecret{},
|
||||
&bootkube.Pull{},
|
||||
&bootkube.CVOOverrides{},
|
||||
&bootkube.HostEtcdServiceEndpointsKubeSystem{},
|
||||
&bootkube.KubeSystemConfigmapEtcdServingCA{},
|
||||
&bootkube.KubeSystemConfigmapRootCA{},
|
||||
&bootkube.KubeSystemSecretEtcdClient{},
|
||||
&bootkube.OpenshiftMachineConfigOperator{},
|
||||
&bootkube.OpenshiftClusterAPINamespace{},
|
||||
&bootkube.OpenshiftServiceCertSignerNamespace{},
|
||||
&bootkube.EtcdServiceKubeSystem{},
|
||||
&bootkube.HostEtcdServiceKubeSystem{},
|
||||
&openshift.BindingDiscovery{},
|
||||
&openshift.CloudCredsSecret{},
|
||||
&openshift.KubeadminPasswordSecret{},
|
||||
&openshift.RoleCloudCredsSecretReader{},
|
||||
}
|
||||
|
||||
// IgnitionConfigs are the ignition-configs targeted assets.
|
||||
IgnitionConfigs = []asset.WritableAsset{
|
||||
&kubeconfig.Admin{},
|
||||
&machine.Master{},
|
||||
&machine.Worker{},
|
||||
&bootstrap.Bootstrap{},
|
||||
&cluster.Metadata{},
|
||||
}
|
||||
|
||||
// Cluster are the cluster targeted assets.
|
||||
Cluster = []asset.WritableAsset{
|
||||
&cluster.TerraformVariables{},
|
||||
&kubeconfig.Admin{},
|
||||
&tls.JournalCertKey{},
|
||||
&cluster.Cluster{},
|
||||
&cluster.Metadata{},
|
||||
}
|
||||
)
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*OpenshiftMachineConfigOperator)(nil)
|
||||
|
||||
// OpenshiftMachineConfigOperator is the constant to represent contents of Openshift_MachineConfigOperator.yaml file
|
||||
type OpenshiftMachineConfigOperator struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *OpenshiftMachineConfigOperator) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *OpenshiftMachineConfigOperator) Generate(parents asset.Parents) error {
|
||||
t.fileName = openshiftMachineConfigOperatorFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := openshiftMachineConfigOperatorFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*OpenshiftClusterAPINamespace)(nil)
|
||||
|
||||
// OpenshiftClusterAPINamespace is the constant to represent contents of Openshift_ClusterApiNamespace.yaml file
|
||||
type OpenshiftClusterAPINamespace struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *OpenshiftClusterAPINamespace) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *OpenshiftClusterAPINamespace) Generate(parents asset.Parents) error {
|
||||
t.fileName = openshiftClusterAPINamespaceFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := openshiftClusterAPINamespaceFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*OpenshiftServiceCertSignerNamespace)(nil)
|
||||
|
||||
// OpenshiftServiceCertSignerNamespace is the constant to represent the contents of 09-openshift-service-signer-namespace.yaml
|
||||
type OpenshiftServiceCertSignerNamespace struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *OpenshiftServiceCertSignerNamespace) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *OpenshiftServiceCertSignerNamespace) Generate(parents asset.Parents) error {
|
||||
t.fileName = openshiftServiceCertSignerNamespaceFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := openshiftServiceCertSignerNamespaceFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ var _ asset.WritableAsset = (*CVOOverrides)(nil)
|
||||
// with resources already owned by other operators.
|
||||
// This files can be dropped when the overrides list becomes empty.
|
||||
type CVOOverrides struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -35,14 +34,14 @@ func (t *CVOOverrides) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *CVOOverrides) Generate(parents asset.Parents) error {
|
||||
t.fileName = cVOOverridesFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := cVOOverridesFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*EtcdServiceKubeSystem)(nil)
|
||||
|
||||
// EtcdServiceKubeSystem is the constant to represent contents of etcd-service.yaml file
|
||||
type EtcdServiceKubeSystem struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *EtcdServiceKubeSystem) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *EtcdServiceKubeSystem) Generate(parents asset.Parents) error {
|
||||
t.fileName = etcdServiceKubeSystemFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := etcdServiceKubeSystemFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*HostEtcdServiceEndpointsKubeSystem)(nil)
|
||||
|
||||
// HostEtcdServiceEndpointsKubeSystem is the constant to represent contents of etcd-service-endpoints.yaml.template file.
|
||||
type HostEtcdServiceEndpointsKubeSystem struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *HostEtcdServiceEndpointsKubeSystem) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *HostEtcdServiceEndpointsKubeSystem) Generate(parents asset.Parents) error {
|
||||
t.fileName = hostEtcdServiceEndpointsKubeSystemFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := hostEtcdServiceEndpointsKubeSystemFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*HostEtcdServiceKubeSystem)(nil)
|
||||
|
||||
// HostEtcdServiceKubeSystem is the constant to represent contents of etcd-service.yaml file
|
||||
type HostEtcdServiceKubeSystem struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *HostEtcdServiceKubeSystem) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *HostEtcdServiceKubeSystem) Generate(parents asset.Parents) error {
|
||||
t.fileName = hostEtcdServiceKubeSystemFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := hostEtcdServiceKubeSystemFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*KubeCloudConfig)(nil)
|
||||
|
||||
// KubeCloudConfig is the constant to represent contents of kube_cloudconfig.yaml file
|
||||
type KubeCloudConfig struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *KubeCloudConfig) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *KubeCloudConfig) Generate(parents asset.Parents) error {
|
||||
t.fileName = kubeCloudConfigFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := kubeCloudConfigFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*KubeSystemConfigmapEtcdServingCA)(nil)
|
||||
|
||||
// KubeSystemConfigmapEtcdServingCA is the constant to represent contents of kube-system-configmap-etcd-serving-ca.yaml.template file.
|
||||
type KubeSystemConfigmapEtcdServingCA struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *KubeSystemConfigmapEtcdServingCA) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *KubeSystemConfigmapEtcdServingCA) Generate(parents asset.Parents) error {
|
||||
t.fileName = kubeSystemConfigmapEtcdServingCAFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := kubeSystemConfigmapEtcdServingCAFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*KubeSystemConfigmapRootCA)(nil)
|
||||
|
||||
// KubeSystemConfigmapRootCA is the constant to represent contents of kube-system-configmap-root-ca.yaml.template file.
|
||||
type KubeSystemConfigmapRootCA struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *KubeSystemConfigmapRootCA) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *KubeSystemConfigmapRootCA) Generate(parents asset.Parents) error {
|
||||
t.fileName = kubeSystemConfigmapRootCAFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := kubeSystemConfigmapRootCAFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*KubeSystemSecretEtcdClient)(nil)
|
||||
|
||||
// KubeSystemSecretEtcdClient is the constant to represent contents of kube-system-secret-etcd-client.yaml.template file.
|
||||
type KubeSystemSecretEtcdClient struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *KubeSystemSecretEtcdClient) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *KubeSystemSecretEtcdClient) Generate(parents asset.Parents) error {
|
||||
t.fileName = kubeSystemSecretEtcdClientFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := kubeSystemSecretEtcdClientFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*MachineConfigServerTLSSecret)(nil)
|
||||
|
||||
// MachineConfigServerTLSSecret is the constant to represent contents of machine_configservertlssecret.yaml.template file
|
||||
type MachineConfigServerTLSSecret struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *MachineConfigServerTLSSecret) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *MachineConfigServerTLSSecret) Generate(parents asset.Parents) error {
|
||||
t.fileName = machineConfigServerTLSSecretFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := machineConfigServerTLSSecretFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*OpenshiftServiceCertSignerSecret)(nil)
|
||||
|
||||
// OpenshiftServiceCertSignerSecret is the constant to represent the contents of openshift-service-signer-secret.yaml.template
|
||||
type OpenshiftServiceCertSignerSecret struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *OpenshiftServiceCertSignerSecret) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *OpenshiftServiceCertSignerSecret) Generate(parents asset.Parents) error {
|
||||
t.fileName = openshiftServiceCertSignerSecretFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := openshiftServiceCertSignerSecretFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*Pull)(nil)
|
||||
|
||||
// Pull is the constant to represent contents of pull.yaml.template file
|
||||
type Pull struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *Pull) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *Pull) Generate(parents asset.Parents) error {
|
||||
t.fileName = pullFileName
|
||||
data, err := content.GetBootkubeTemplate(t.fileName)
|
||||
fileName := pullFileName
|
||||
data, err := content.GetBootkubeTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*BindingDiscovery)(nil)
|
||||
|
||||
// BindingDiscovery is the variable/constant representing the contents of the respective file
|
||||
type BindingDiscovery struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *BindingDiscovery) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *BindingDiscovery) Generate(parents asset.Parents) error {
|
||||
t.fileName = bindingDiscoveryFileName
|
||||
data, err := content.GetOpenshiftTemplate(t.fileName)
|
||||
fileName := bindingDiscoveryFileName
|
||||
data, err := content.GetOpenshiftTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*CloudCredsSecret)(nil)
|
||||
|
||||
// CloudCredsSecret is the constant to represent contents of corresponding yaml file
|
||||
type CloudCredsSecret struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *CloudCredsSecret) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *CloudCredsSecret) Generate(parents asset.Parents) error {
|
||||
t.fileName = cloudCredsSecretFileName
|
||||
data, err := content.GetOpenshiftTemplate(t.fileName)
|
||||
fileName := cloudCredsSecretFileName
|
||||
data, err := content.GetOpenshiftTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
infraCRDfilename = "cluster-infrastructure-crd.yaml"
|
||||
infraCRDFilename = "cluster-infrastructure-crd.yaml"
|
||||
)
|
||||
|
||||
var _ asset.WritableAsset = (*InfrastructureCRD)(nil)
|
||||
@@ -17,7 +17,6 @@ var _ asset.WritableAsset = (*InfrastructureCRD)(nil)
|
||||
// InfrastructureCRD is the custom resource definition for the openshift/api
|
||||
// Infrastructure type.
|
||||
type InfrastructureCRD struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -33,14 +32,13 @@ func (t *InfrastructureCRD) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *InfrastructureCRD) Generate(parents asset.Parents) error {
|
||||
t.fileName = infraCRDfilename
|
||||
data, err := content.GetOpenshiftTemplate(t.fileName)
|
||||
data, err := content.GetOpenshiftTemplate(infraCRDFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, infraCRDFilename),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
@@ -54,7 +52,7 @@ func (t *InfrastructureCRD) Files() []*asset.File {
|
||||
|
||||
// Load returns the asset from disk.
|
||||
func (t *InfrastructureCRD) Load(f asset.FileFetcher) (bool, error) {
|
||||
file, err := f.FetchByName(filepath.Join(content.TemplateDir, infraCRDfilename))
|
||||
file, err := f.FetchByName(filepath.Join(content.TemplateDir, infraCRDFilename))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*KubeadminPasswordSecret)(nil)
|
||||
|
||||
// KubeadminPasswordSecret is the constant to represent contents of kubeadmin-password-secret.yaml.template file
|
||||
type KubeadminPasswordSecret struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *KubeadminPasswordSecret) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *KubeadminPasswordSecret) Generate(parents asset.Parents) error {
|
||||
t.fileName = kubeadminPasswordSecretFileName
|
||||
data, err := content.GetOpenshiftTemplate(t.fileName)
|
||||
fileName := kubeadminPasswordSecretFileName
|
||||
data, err := content.GetOpenshiftTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ var _ asset.WritableAsset = (*RoleCloudCredsSecretReader)(nil)
|
||||
|
||||
// RoleCloudCredsSecretReader is the variable to represent contents of corresponding file
|
||||
type RoleCloudCredsSecretReader struct {
|
||||
fileName string
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
@@ -32,14 +31,14 @@ func (t *RoleCloudCredsSecretReader) Name() string {
|
||||
|
||||
// Generate generates the actual files by this asset
|
||||
func (t *RoleCloudCredsSecretReader) Generate(parents asset.Parents) error {
|
||||
t.fileName = roleCloudCredsSecretReaderFileName
|
||||
data, err := content.GetOpenshiftTemplate(t.fileName)
|
||||
fileName := roleCloudCredsSecretReaderFileName
|
||||
data, err := content.GetOpenshiftTemplate(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.FileList = []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(content.TemplateDir, t.fileName),
|
||||
Filename: filepath.Join(content.TemplateDir, fileName),
|
||||
Data: []byte(data),
|
||||
},
|
||||
}
|
||||
|
||||
2
pkg/asset/templates/doc.go
Normal file
2
pkg/asset/templates/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package templates deals with creating template assets that will be used by other assets
|
||||
package templates
|
||||
@@ -1,126 +0,0 @@
|
||||
// Package templates deals with creating template assets that will be used by other assets
|
||||
package templates
|
||||
|
||||
import (
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
"github.com/openshift/installer/pkg/asset/templates/content/bootkube"
|
||||
"github.com/openshift/installer/pkg/asset/templates/content/openshift"
|
||||
)
|
||||
|
||||
var _ asset.WritableAsset = (*Templates)(nil)
|
||||
|
||||
// Templates generates the dependent unrendered template files
|
||||
type Templates struct {
|
||||
FileList []*asset.File
|
||||
}
|
||||
|
||||
// Name returns a human friendly name for the templates asset
|
||||
func (m *Templates) Name() string {
|
||||
return "Common Templates"
|
||||
}
|
||||
|
||||
// Dependencies returns all of the dependencies directly needed by a
|
||||
// Templates asset.
|
||||
func (m *Templates) Dependencies() []asset.Asset {
|
||||
return []asset.Asset{
|
||||
&bootkube.KubeCloudConfig{},
|
||||
&bootkube.MachineConfigServerTLSSecret{},
|
||||
&bootkube.OpenshiftServiceCertSignerSecret{},
|
||||
&bootkube.Pull{},
|
||||
&bootkube.CVOOverrides{},
|
||||
&bootkube.HostEtcdServiceEndpointsKubeSystem{},
|
||||
&bootkube.KubeSystemConfigmapEtcdServingCA{},
|
||||
&bootkube.KubeSystemConfigmapRootCA{},
|
||||
&bootkube.KubeSystemSecretEtcdClient{},
|
||||
&bootkube.OpenshiftMachineConfigOperator{},
|
||||
&bootkube.OpenshiftClusterAPINamespace{},
|
||||
&bootkube.OpenshiftServiceCertSignerNamespace{},
|
||||
&bootkube.EtcdServiceKubeSystem{},
|
||||
&bootkube.HostEtcdServiceKubeSystem{},
|
||||
&openshift.BindingDiscovery{},
|
||||
&openshift.CloudCredsSecret{},
|
||||
&openshift.KubeadminPasswordSecret{},
|
||||
&openshift.RoleCloudCredsSecretReader{},
|
||||
&openshift.InfrastructureCRD{},
|
||||
&openshift.NetworkCRDs{},
|
||||
}
|
||||
}
|
||||
|
||||
// Generate generates the respective operator config.yml files
|
||||
func (m *Templates) Generate(dependencies asset.Parents) error {
|
||||
kubeCloudConfig := &bootkube.KubeCloudConfig{}
|
||||
machineConfigServerTLSSecret := &bootkube.MachineConfigServerTLSSecret{}
|
||||
openshiftServiceCertSignerSecret := &bootkube.OpenshiftServiceCertSignerSecret{}
|
||||
pull := &bootkube.Pull{}
|
||||
cVOOverrides := &bootkube.CVOOverrides{}
|
||||
hostEtcdServiceEndpointsKubeSystem := &bootkube.HostEtcdServiceEndpointsKubeSystem{}
|
||||
kubeSystemConfigmapEtcdServingCA := &bootkube.KubeSystemConfigmapEtcdServingCA{}
|
||||
kubeSystemConfigmapRootCA := &bootkube.KubeSystemConfigmapRootCA{}
|
||||
kubeSystemSecretEtcdClient := &bootkube.KubeSystemSecretEtcdClient{}
|
||||
openshiftMachineConfigOperator := &bootkube.OpenshiftMachineConfigOperator{}
|
||||
openshiftClusterAPINamespace := &bootkube.OpenshiftClusterAPINamespace{}
|
||||
openshiftServiceCertSignerNamespace := &bootkube.OpenshiftServiceCertSignerNamespace{}
|
||||
etcdServiceKubeSystem := &bootkube.EtcdServiceKubeSystem{}
|
||||
hostEtcdServiceKubeSystem := &bootkube.HostEtcdServiceKubeSystem{}
|
||||
|
||||
bindingDiscovery := &openshift.BindingDiscovery{}
|
||||
cloudCredsSecret := &openshift.CloudCredsSecret{}
|
||||
kubeadminPasswordSecret := &openshift.KubeadminPasswordSecret{}
|
||||
roleCloudCredsSecretReader := &openshift.RoleCloudCredsSecretReader{}
|
||||
infrastructure := &openshift.InfrastructureCRD{}
|
||||
|
||||
dependencies.Get(
|
||||
kubeCloudConfig,
|
||||
machineConfigServerTLSSecret,
|
||||
openshiftServiceCertSignerSecret,
|
||||
pull,
|
||||
cVOOverrides,
|
||||
hostEtcdServiceEndpointsKubeSystem,
|
||||
kubeSystemConfigmapEtcdServingCA,
|
||||
kubeSystemConfigmapRootCA,
|
||||
kubeSystemSecretEtcdClient,
|
||||
openshiftMachineConfigOperator,
|
||||
openshiftClusterAPINamespace,
|
||||
openshiftServiceCertSignerNamespace,
|
||||
etcdServiceKubeSystem,
|
||||
hostEtcdServiceKubeSystem,
|
||||
bindingDiscovery,
|
||||
cloudCredsSecret,
|
||||
kubeadminPasswordSecret,
|
||||
roleCloudCredsSecretReader,
|
||||
infrastructure)
|
||||
|
||||
m.FileList = []*asset.File{}
|
||||
m.FileList = append(m.FileList, kubeCloudConfig.Files()...)
|
||||
m.FileList = append(m.FileList, machineConfigServerTLSSecret.Files()...)
|
||||
m.FileList = append(m.FileList, openshiftServiceCertSignerSecret.Files()...)
|
||||
m.FileList = append(m.FileList, pull.Files()...)
|
||||
m.FileList = append(m.FileList, cVOOverrides.Files()...)
|
||||
m.FileList = append(m.FileList, hostEtcdServiceEndpointsKubeSystem.Files()...)
|
||||
m.FileList = append(m.FileList, kubeSystemConfigmapEtcdServingCA.Files()...)
|
||||
m.FileList = append(m.FileList, kubeSystemConfigmapRootCA.Files()...)
|
||||
m.FileList = append(m.FileList, kubeSystemSecretEtcdClient.Files()...)
|
||||
m.FileList = append(m.FileList, openshiftMachineConfigOperator.Files()...)
|
||||
m.FileList = append(m.FileList, openshiftClusterAPINamespace.Files()...)
|
||||
m.FileList = append(m.FileList, openshiftServiceCertSignerNamespace.Files()...)
|
||||
m.FileList = append(m.FileList, etcdServiceKubeSystem.Files()...)
|
||||
m.FileList = append(m.FileList, hostEtcdServiceKubeSystem.Files()...)
|
||||
|
||||
m.FileList = append(m.FileList, bindingDiscovery.Files()...)
|
||||
m.FileList = append(m.FileList, cloudCredsSecret.Files()...)
|
||||
m.FileList = append(m.FileList, kubeadminPasswordSecret.Files()...)
|
||||
m.FileList = append(m.FileList, roleCloudCredsSecretReader.Files()...)
|
||||
m.FileList = append(m.FileList, infrastructure.Files()...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Files returns the files generated by the asset.
|
||||
func (m *Templates) Files() []*asset.File {
|
||||
return m.FileList
|
||||
}
|
||||
|
||||
// Load returns the manifests asset from disk.
|
||||
func (m *Templates) Load(f asset.FileFetcher) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user