github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/agent/tools/symlinks.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package tools
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/juju/errors"
    11  	"github.com/juju/utils/symlink"
    12  
    13  	"github.com/juju/juju/juju/names"
    14  )
    15  
    16  // EnsureSymlinks creates a symbolic link to jujud within dir for each
    17  // command. If the commands already exist, this operation does nothing.
    18  // If dir is a symbolic link, it will be dereferenced first.
    19  func EnsureSymlinks(jujuDir, dir string, commands []string) (err error) {
    20  	logger.Infof("ensure jujuc symlinks in %s", dir)
    21  	defer func() {
    22  		if err != nil {
    23  			err = errors.Annotatef(err, "cannot initialize commands in %q", dir)
    24  		}
    25  	}()
    26  	isSymlink, err := symlink.IsSymlink(jujuDir)
    27  	if err != nil {
    28  		return err
    29  	}
    30  	if isSymlink {
    31  		link, err := symlink.Read(jujuDir)
    32  		if err != nil {
    33  			return err
    34  		}
    35  		if !filepath.IsAbs(link) {
    36  			logger.Infof("%s is relative", link)
    37  			link = filepath.Join(filepath.Dir(dir), link)
    38  		}
    39  		jujuDir = link
    40  		logger.Infof("was a symlink, now looking at %s", jujuDir)
    41  	}
    42  
    43  	jujudPath := filepath.Join(jujuDir, names.Jujud)
    44  	logger.Debugf("jujud path %s", jujudPath)
    45  	for _, name := range commands {
    46  		// The link operation fails when the target already exists,
    47  		// so this is a no-op when the command names already
    48  		// exist.
    49  		err := symlink.New(jujudPath, filepath.Join(dir, name))
    50  		if err != nil && !os.IsExist(err) {
    51  			return err
    52  		}
    53  	}
    54  	return nil
    55  }