github.com/nilium/gitlab-runner@v12.5.0+incompatible/cache/cache.go (about)

     1  package cache
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"path"
     7  	"path/filepath"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"github.com/sirupsen/logrus"
    12  
    13  	"gitlab.com/gitlab-org/gitlab-runner/common"
    14  )
    15  
    16  var createAdapter = CreateAdapter
    17  
    18  func getCacheConfig(build *common.Build) *common.CacheConfig {
    19  	if build == nil || build.Runner == nil || build.Runner.Cache == nil {
    20  		return nil
    21  	}
    22  
    23  	return build.Runner.Cache
    24  }
    25  
    26  func generateBaseObjectName(build *common.Build, config *common.CacheConfig) string {
    27  	runnerSegment := ""
    28  	if !config.GetShared() {
    29  		runnerSegment = path.Join("runner", build.Runner.ShortDescription())
    30  	}
    31  
    32  	return path.Join(config.GetPath(), runnerSegment, "project", strconv.Itoa(build.JobInfo.ProjectID))
    33  }
    34  
    35  func generateObjectName(build *common.Build, config *common.CacheConfig, key string) (string, error) {
    36  	if key == "" {
    37  		return "", nil
    38  	}
    39  
    40  	basePath := generateBaseObjectName(build, config)
    41  	path := path.Join(basePath, key)
    42  
    43  	relative, err := filepath.Rel(basePath, path)
    44  	if err != nil {
    45  		return "", fmt.Errorf("cache path correctness check failed with: %v", err)
    46  	}
    47  
    48  	if strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
    49  		return "", fmt.Errorf("computed cache path outside of project bucket. Please remove `../` from cache key")
    50  	}
    51  
    52  	return path, nil
    53  }
    54  
    55  func onAdapter(build *common.Build, key string, handler func(adapter Adapter) *url.URL) *url.URL {
    56  	config := getCacheConfig(build)
    57  	if config == nil {
    58  		logrus.Warning("Cache config not defined. Skipping cache operation.")
    59  		return nil
    60  	}
    61  
    62  	objectName, err := generateObjectName(build, config, key)
    63  	if err != nil {
    64  		logrus.WithError(err).Error("Error while generating cache bucket.")
    65  		return nil
    66  	}
    67  
    68  	if objectName == "" {
    69  		logrus.Warning("Empty cache key. Skipping adapter selection.")
    70  		return nil
    71  	}
    72  
    73  	adapter, err := createAdapter(config, build.GetBuildTimeout(), objectName)
    74  	if err != nil {
    75  		logrus.WithError(err).Error("Could not create cache adapter")
    76  	}
    77  
    78  	if adapter == nil {
    79  		return nil
    80  	}
    81  
    82  	return handler(adapter)
    83  }
    84  
    85  func GetCacheDownloadURL(build *common.Build, key string) *url.URL {
    86  	return onAdapter(build, key, func(adapter Adapter) *url.URL {
    87  		return adapter.GetDownloadURL()
    88  	})
    89  }
    90  
    91  func GetCacheUploadURL(build *common.Build, key string) *url.URL {
    92  	return onAdapter(build, key, func(adapter Adapter) *url.URL {
    93  		return adapter.GetUploadURL()
    94  	})
    95  }