bitbucket.org/Aishee/synsec@v0.0.0-20210414005726-236fc01a153d/pkg/cwhub/install.go (about)

     1  package cwhub
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"bitbucket.org/Aishee/synsec/pkg/csconfig"
     9  	"github.com/pkg/errors"
    10  	log "github.com/sirupsen/logrus"
    11  )
    12  
    13  //DisableItem to disable an item managed by the hub, removes the symlink if purge is true
    14  func DisableItem(hub *csconfig.Hub, target Item, purge bool, force bool) (Item, error) {
    15  	var tdir = hub.ConfigDir
    16  	var hdir = hub.HubDir
    17  
    18  	syml, err := filepath.Abs(tdir + "/" + target.Type + "/" + target.Stage + "/" + target.FileName)
    19  	if err != nil {
    20  		return Item{}, err
    21  	}
    22  	if target.Local {
    23  		return target, fmt.Errorf("%s isn't managed by hub. Please delete manually", target.Name)
    24  	}
    25  
    26  	if target.Tainted && !force {
    27  		return target, fmt.Errorf("%s is tainted, use '--force' to overwrite", target.Name)
    28  	}
    29  
    30  	/*for a COLLECTIONS, disable sub-items*/
    31  	if target.Type == COLLECTIONS {
    32  		var tmp = [][]string{target.Parsers, target.PostOverflows, target.Scenarios, target.Collections}
    33  		for idx, ptr := range tmp {
    34  			ptrtype := ItemTypes[idx]
    35  			for _, p := range ptr {
    36  				if val, ok := hubIdx[ptrtype][p]; ok {
    37  					hubIdx[ptrtype][p], err = DisableItem(hub, val, purge, force)
    38  					if err != nil {
    39  						return target, errors.Wrap(err, fmt.Sprintf("while disabling %s", p))
    40  					}
    41  				} else {
    42  					log.Errorf("Referred %s %s in collection %s doesn't exist.", ptrtype, p, target.Name)
    43  				}
    44  			}
    45  		}
    46  	}
    47  
    48  	stat, err := os.Lstat(syml)
    49  	if os.IsNotExist(err) {
    50  		if !purge && !force { //we only accept to "delete" non existing items if it's a purge
    51  			return target, fmt.Errorf("can't delete %s : %s doesn't exist", target.Name, syml)
    52  		}
    53  	} else {
    54  		//if it's managed by hub, it's a symlink to csconfig.GConfig.hub.HubDir / ...
    55  		if stat.Mode()&os.ModeSymlink == 0 {
    56  			log.Warningf("%s (%s) isn't a symlink, can't disable", target.Name, syml)
    57  			return target, fmt.Errorf("%s isn't managed by hub", target.Name)
    58  		}
    59  		hubpath, err := os.Readlink(syml)
    60  		if err != nil {
    61  			return target, errors.Wrap(err, "while reading symlink")
    62  		}
    63  		absPath, err := filepath.Abs(hdir + "/" + target.RemotePath)
    64  		if err != nil {
    65  			return target, errors.Wrap(err, "while abs path")
    66  		}
    67  		if hubpath != absPath {
    68  			log.Warningf("%s (%s) isn't a symlink to %s", target.Name, syml, absPath)
    69  			return target, fmt.Errorf("%s isn't managed by hub", target.Name)
    70  		}
    71  
    72  		//remove the symlink
    73  		if err = os.Remove(syml); err != nil {
    74  			return target, errors.Wrap(err, "while removing symlink")
    75  		}
    76  		log.Infof("Removed symlink [%s] : %s", target.Name, syml)
    77  	}
    78  	target.Installed = false
    79  
    80  	if purge {
    81  		hubpath := hdir + "/" + target.RemotePath
    82  		//if purge, disable hub file
    83  		if err = os.Remove(hubpath); err != nil {
    84  			return target, errors.Wrap(err, "while removing file")
    85  		}
    86  		target.Downloaded = false
    87  		log.Infof("Removed source file [%s] : %s", target.Name, hubpath)
    88  	}
    89  	hubIdx[target.Type][target.Name] = target
    90  	return target, nil
    91  }
    92  
    93  func EnableItem(hub *csconfig.Hub, target Item) (Item, error) {
    94  	var tdir = hub.ConfigDir
    95  	var hdir = hub.HubDir
    96  	var err error
    97  	parent_dir := filepath.Clean(tdir + "/" + target.Type + "/" + target.Stage + "/")
    98  	/*create directories if needed*/
    99  	if target.Installed {
   100  		if target.Tainted {
   101  			return target, fmt.Errorf("%s is tainted, won't enable unless --force", target.Name)
   102  		}
   103  		if target.Local {
   104  			return target, fmt.Errorf("%s is local, won't enable", target.Name)
   105  		}
   106  		/* if it's a collection, check sub-items even if the collection file itself is up-to-date */
   107  		if target.UpToDate && target.Type != COLLECTIONS {
   108  			log.Tracef("%s is installed and up-to-date, skip.", target.Name)
   109  			return target, nil
   110  		}
   111  	}
   112  	if _, err := os.Stat(parent_dir); os.IsNotExist(err) {
   113  		log.Printf("%s doesn't exist, create", parent_dir)
   114  		if err := os.MkdirAll(parent_dir, os.ModePerm); err != nil {
   115  			return target, errors.Wrap(err, "while creating directory")
   116  		}
   117  	}
   118  
   119  	/*install sub-items if it's a collection*/
   120  	if target.Type == COLLECTIONS {
   121  		var tmp = [][]string{target.Parsers, target.PostOverflows, target.Scenarios, target.Collections}
   122  		for idx, ptr := range tmp {
   123  			ptrtype := ItemTypes[idx]
   124  			for _, p := range ptr {
   125  				if val, ok := hubIdx[ptrtype][p]; ok {
   126  					hubIdx[ptrtype][p], err = EnableItem(hub, val)
   127  					if err != nil {
   128  						return target, errors.Wrap(err, fmt.Sprintf("while installing %s", p))
   129  					}
   130  				} else {
   131  					return target, fmt.Errorf("required %s %s of %s doesn't exist, abort.", ptrtype, p, target.Name)
   132  				}
   133  			}
   134  		}
   135  	}
   136  
   137  	if _, err := os.Lstat(parent_dir + "/" + target.FileName); os.IsNotExist(err) {
   138  		//tdir+target.RemotePath
   139  		srcPath, err := filepath.Abs(hdir + "/" + target.RemotePath)
   140  		if err != nil {
   141  			return target, errors.Wrap(err, "while getting source path")
   142  		}
   143  		dstPath, err := filepath.Abs(parent_dir + "/" + target.FileName)
   144  		if err != nil {
   145  			return target, errors.Wrap(err, "while getting destination path")
   146  		}
   147  		err = os.Symlink(srcPath, dstPath)
   148  		if err != nil {
   149  			return target, errors.Wrap(err, fmt.Sprintf("while creating symlink from %s to %s", srcPath, dstPath))
   150  		}
   151  		log.Printf("Enabled %s : %s", target.Type, target.Name)
   152  	} else {
   153  		log.Printf("%s already exists.", parent_dir+"/"+target.FileName)
   154  		return target, nil
   155  	}
   156  	target.Installed = true
   157  	hubIdx[target.Type][target.Name] = target
   158  	return target, nil
   159  }