github.com/hashicorp/go-getter/v2@v2.2.2/get_smb_mount.go (about)

     1  package getter
     2  
     3  import (
     4  	"context"
     5  	"net/url"
     6  	"os"
     7  	"path/filepath"
     8  	"runtime"
     9  )
    10  
    11  // SmbMountGetter is a Getter implementation that will download an artifact from
    12  // a shared folder using the file system using FileGetter implementation.
    13  // For Unix and MacOS users, the Getter will look for usual system specific mount paths such as:
    14  // /Volumes/ for MacOS
    15  // /run/user/1000/gvfs/smb-share:server=<hostIP>,share=<path> for Unix
    16  type SmbMountGetter struct{}
    17  
    18  func (g *SmbMountGetter) Mode(ctx context.Context, u *url.URL) (Mode, error) {
    19  	if u.Host == "" || u.Path == "" {
    20  		return 0, new(smbPathError)
    21  	}
    22  
    23  	prefix, path := g.findPrefixAndPath(u)
    24  	u.Path = prefix + path
    25  
    26  	return new(FileGetter).Mode(ctx, u)
    27  }
    28  
    29  func (g *SmbMountGetter) Get(ctx context.Context, req *Request) error {
    30  	if req.u.Host == "" || req.u.Path == "" {
    31  		return new(smbPathError)
    32  	}
    33  
    34  	prefix, path := g.findPrefixAndPath(req.u)
    35  	req.u.Path = prefix + path
    36  
    37  	return new(FileGetter).Get(ctx, req)
    38  }
    39  
    40  func (g *SmbMountGetter) GetFile(ctx context.Context, req *Request) error {
    41  	if req.u.Host == "" || req.u.Path == "" {
    42  		return new(smbPathError)
    43  	}
    44  
    45  	prefix, path := g.findPrefixAndPath(req.u)
    46  	req.u.Path = prefix + path
    47  
    48  	return new(FileGetter).GetFile(ctx, req)
    49  }
    50  
    51  func (g *SmbMountGetter) findPrefixAndPath(u *url.URL) (string, string) {
    52  	var prefix, path string
    53  	switch runtime.GOOS {
    54  	case "windows":
    55  		prefix = string(os.PathSeparator) + string(os.PathSeparator)
    56  		path = filepath.Join(u.Host, u.Path)
    57  	case "darwin":
    58  		prefix = string(os.PathSeparator)
    59  		path = filepath.Join("Volumes", u.Path)
    60  	}
    61  	return prefix, path
    62  }
    63  
    64  func (g *SmbMountGetter) Detect(req *Request) (bool, error) {
    65  	if runtime.GOOS == "linux" {
    66  		// Linux has the smbclient command which is a safer approach to retrieve an artifact from a samba shared folder.
    67  		// Therefore, this should be used instead of looking in the file system.
    68  		return false, nil
    69  	}
    70  	if len(req.Src) == 0 {
    71  		return false, nil
    72  	}
    73  
    74  	if req.Forced != "" {
    75  		// There's a getter being Forced
    76  		if !g.validScheme(req.Forced) {
    77  			// Current getter is not the Forced one
    78  			// Don't use it to try to download the artifact
    79  			return false, nil
    80  		}
    81  	}
    82  	isForcedGetter := req.Forced != "" && g.validScheme(req.Forced)
    83  
    84  	u, err := url.Parse(req.Src)
    85  	if err == nil && u.Scheme != "" {
    86  		if isForcedGetter {
    87  			// Is the Forced getter and source is a valid url
    88  			return true, nil
    89  		}
    90  		if g.validScheme(u.Scheme) {
    91  			return true, nil
    92  		}
    93  		// Valid url with a scheme that is not valid for current getter
    94  		return false, nil
    95  	}
    96  
    97  	return false, nil
    98  }
    99  
   100  func (g *SmbMountGetter) validScheme(scheme string) bool {
   101  	return scheme == "smb"
   102  }