github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/pkg/action/init.go (about)

     1  /*
     2  Copyright The Codefresh Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package action
    18  
    19  import (
    20  	"fmt"
    21  	"io/ioutil"
    22  	"log"
    23  	"os"
    24  	"path"
    25  	"path/filepath"
    26  	"regexp"
    27  	"strings"
    28  
    29  	"github.com/codefresh-io/kcfi/pkg/embeded/stage"
    30  
    31  	c "github.com/codefresh-io/kcfi/pkg/config"
    32  )
    33  
    34  const (
    35  	// AssetsDir - folder name where we save kubernetes and helm assets
    36  	AssetsDir = "assets"
    37  
    38  	kindCodefresh     = "codefresh"
    39  	kindK8sAgent      = "k8sAgent"
    40  	kindVenona        = "venona"
    41  	kindBackupManager = "backup-manager"
    42  
    43  	installerTypeOperator = "operator"
    44  	installerTypeHelm     = "helm"
    45  
    46  	operatorHelmReleaseName = "cf-onprem-operator"
    47  	operatorHelmChartName   = "codefresh-operator"
    48  
    49  	codefreshHelmReleaseName = "cf"
    50  )
    51  
    52  // CfInit is an action to create Codefresh config stage directory
    53  type CfInit struct {
    54  	ProductName string
    55  	StageDir    string
    56  }
    57  
    58  // NewCfInit creates object
    59  func NewCfInit(productName, stageDir string) *CfInit {
    60  	return &CfInit{
    61  		ProductName: productName,
    62  		StageDir:    stageDir,
    63  	}
    64  }
    65  
    66  // Run the action
    67  func (o *CfInit) Run() error {
    68  	var isValidProduct bool
    69  	for _, name := range StageDirsList() {
    70  		if o.ProductName == name {
    71  			isValidProduct = true
    72  			break
    73  		}
    74  	}
    75  	if !isValidProduct {
    76  		return fmt.Errorf("Unknown product %s", o.ProductName)
    77  	}
    78  
    79  	var err error
    80  	var restoreDir string
    81  	if len(o.StageDir) == 0 {
    82  		o.StageDir, err = os.Getwd()
    83  		if err != nil {
    84  			return err
    85  		}
    86  		restoreDir = path.Join(o.StageDir, o.ProductName)
    87  	} else {
    88  		restoreDir = o.StageDir
    89  	}
    90  
    91  	info("Creating stage directory %s\n", restoreDir)
    92  	if dirList, err := ioutil.ReadDir(restoreDir); err == nil && len(dirList) > 0 {
    93  		return fmt.Errorf("Directory %s is already exists and not empty", o.ProductName)
    94  	}
    95  	return restoreStageAssets(restoreDir, o.ProductName)
    96  }
    97  
    98  // restoreStageAssets restores an asset with replacing first folder under the given directory recursively
    99  func restoreStageAssets(dir, name string) error {
   100  	children, err := stage.AssetDir(name)
   101  	// File
   102  	if err != nil {
   103  		return restoreAsset(dir, name)
   104  	}
   105  	// Dir
   106  	for _, child := range children {
   107  		err = restoreStageAssets(dir, fmt.Sprintf("%s/%s", name, child))
   108  		if err != nil {
   109  			return err
   110  		}
   111  	}
   112  	return nil
   113  }
   114  
   115  // restoreAsset restores an asset under the given directory with removing first folder
   116  func restoreAsset(dir, name string) error {
   117  	data, err := stage.Asset(name)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	info, err := stage.AssetInfo(name)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	stageFileNameReplaceRe, _ := regexp.Compile(`^(.*?/)(.*$)$`)
   127  	stageFileName := stageFileNameReplaceRe.ReplaceAllString(name, "$2")
   128  	err = os.MkdirAll(_filePath(dir, filepath.Dir(stageFileName)), os.FileMode(0755))
   129  	if err != nil {
   130  		return err
   131  	}
   132  	err = ioutil.WriteFile(_filePath(dir, stageFileName), data, info.Mode())
   133  	if err != nil {
   134  		return err
   135  	}
   136  	err = os.Chtimes(_filePath(dir, stageFileName), info.ModTime(), info.ModTime())
   137  	if err != nil {
   138  		return err
   139  	}
   140  	return nil
   141  }
   142  
   143  func _filePath(dir, name string) string {
   144  	cannonicalName := strings.Replace(name, "\\", "/", -1)
   145  	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
   146  }
   147  
   148  // StageDirsList - returns list of registered staging dir
   149  func StageDirsList() []string {
   150  	var stageDirsList []string
   151  	var stageName string
   152  	stageDirsMap := make(map[string]int)
   153  	stageNameReplaceRe, _ := regexp.Compile(`^(.*?)/(.*$)$`)
   154  
   155  	for _, name := range stage.AssetNames() {
   156  		stageName = stageNameReplaceRe.ReplaceAllString(name, "$1")
   157  		if _, stageNameListed := stageDirsMap[stageName]; !stageNameListed {
   158  			stageDirsMap[stageName] = 1
   159  			stageDirsList = append(stageDirsList, stageName)
   160  		}
   161  	}
   162  	return stageDirsList
   163  }
   164  
   165  // GetAssetsDir - retur assets dir
   166  func GetAssetsDir(configFile string) string {
   167  	return path.Join(filepath.Dir(configFile), AssetsDir)
   168  }
   169  
   170  // TODO - use logger framework
   171  func info(format string, v ...interface{}) {
   172  	fmt.Printf(format+"\n", v...)
   173  }
   174  func debug(format string, v ...interface{}) {
   175  	if c.Debug {
   176  		format = fmt.Sprintf("[debug] %s\n", format)
   177  		log.Output(2, fmt.Sprintf(format, v...))
   178  	}
   179  }