github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/structs/config/artifact.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"time"
     7  
     8  	"github.com/dustin/go-humanize"
     9  	"github.com/hashicorp/nomad/helper/pointer"
    10  )
    11  
    12  // ArtifactConfig is the configuration specific to the Artifact stanza
    13  type ArtifactConfig struct {
    14  	// HTTPReadTimeout is the duration in which a download must complete or
    15  	// it will be canceled. Defaults to 30m.
    16  	HTTPReadTimeout *string `hcl:"http_read_timeout"`
    17  
    18  	// HTTPMaxSize is the maximum size of an artifact that will be downloaded.
    19  	// Defaults to 100GB.
    20  	HTTPMaxSize *string `hcl:"http_max_size"`
    21  
    22  	// GCSTimeout is the duration in which a GCS operation must complete or
    23  	// it will be canceled. Defaults to 30m.
    24  	GCSTimeout *string `hcl:"gcs_timeout"`
    25  
    26  	// GitTimeout is the duration in which a git operation must complete or
    27  	// it will be canceled. Defaults to 30m.
    28  	GitTimeout *string `hcl:"git_timeout"`
    29  
    30  	// HgTimeout is the duration in which an hg operation must complete or
    31  	// it will be canceled. Defaults to 30m.
    32  	HgTimeout *string `hcl:"hg_timeout"`
    33  
    34  	// S3Timeout is the duration in which an S3 operation must complete or
    35  	// it will be canceled. Defaults to 30m.
    36  	S3Timeout *string `hcl:"s3_timeout"`
    37  
    38  	// DisableFilesystemIsolation will turn off the security feature where the
    39  	// artifact downloader can write only to the task sandbox directory, and can
    40  	// read only from specific locations on the host filesystem.
    41  	DisableFilesystemIsolation *bool `hcl:"disable_filesystem_isolation"`
    42  
    43  	// SetEnvironmentVariables is a comma-separated list of environment
    44  	// variable names to inherit from the Nomad Client and set in the artifact
    45  	// download sandbox process.
    46  	SetEnvironmentVariables *string `hcl:"set_environment_variables"`
    47  }
    48  
    49  func (a *ArtifactConfig) Copy() *ArtifactConfig {
    50  	if a == nil {
    51  		return nil
    52  	}
    53  	return &ArtifactConfig{
    54  		HTTPReadTimeout:            pointer.Copy(a.HTTPReadTimeout),
    55  		HTTPMaxSize:                pointer.Copy(a.HTTPMaxSize),
    56  		GCSTimeout:                 pointer.Copy(a.GCSTimeout),
    57  		GitTimeout:                 pointer.Copy(a.GitTimeout),
    58  		HgTimeout:                  pointer.Copy(a.HgTimeout),
    59  		S3Timeout:                  pointer.Copy(a.S3Timeout),
    60  		DisableFilesystemIsolation: pointer.Copy(a.DisableFilesystemIsolation),
    61  		SetEnvironmentVariables:    pointer.Copy(a.SetEnvironmentVariables),
    62  	}
    63  }
    64  
    65  func (a *ArtifactConfig) Merge(o *ArtifactConfig) *ArtifactConfig {
    66  	switch {
    67  	case a == nil:
    68  		return o.Copy()
    69  	case o == nil:
    70  		return a.Copy()
    71  	default:
    72  		return &ArtifactConfig{
    73  			HTTPReadTimeout:            pointer.Merge(a.HTTPReadTimeout, o.HTTPReadTimeout),
    74  			HTTPMaxSize:                pointer.Merge(a.HTTPMaxSize, o.HTTPMaxSize),
    75  			GCSTimeout:                 pointer.Merge(a.GCSTimeout, o.GCSTimeout),
    76  			GitTimeout:                 pointer.Merge(a.GitTimeout, o.GitTimeout),
    77  			HgTimeout:                  pointer.Merge(a.HgTimeout, o.HgTimeout),
    78  			S3Timeout:                  pointer.Merge(a.S3Timeout, o.S3Timeout),
    79  			DisableFilesystemIsolation: pointer.Merge(a.DisableFilesystemIsolation, o.DisableFilesystemIsolation),
    80  			SetEnvironmentVariables:    pointer.Merge(a.SetEnvironmentVariables, o.SetEnvironmentVariables),
    81  		}
    82  	}
    83  }
    84  
    85  func (a *ArtifactConfig) Equal(o *ArtifactConfig) bool {
    86  	if a == nil || o == nil {
    87  		return a == o
    88  	}
    89  	switch {
    90  	case !pointer.Eq(a.HTTPReadTimeout, o.HTTPReadTimeout):
    91  		return false
    92  	case !pointer.Eq(a.HTTPMaxSize, o.HTTPMaxSize):
    93  		return false
    94  	case !pointer.Eq(a.GCSTimeout, o.GCSTimeout):
    95  		return false
    96  	case !pointer.Eq(a.GitTimeout, o.GitTimeout):
    97  		return false
    98  	case !pointer.Eq(a.HgTimeout, o.HgTimeout):
    99  		return false
   100  	case !pointer.Eq(a.S3Timeout, o.S3Timeout):
   101  		return false
   102  	case !pointer.Eq(a.DisableFilesystemIsolation, o.DisableFilesystemIsolation):
   103  		return false
   104  	case !pointer.Eq(a.SetEnvironmentVariables, o.SetEnvironmentVariables):
   105  		return false
   106  	}
   107  	return true
   108  }
   109  
   110  func (a *ArtifactConfig) Validate() error {
   111  	if a == nil {
   112  		return fmt.Errorf("artifact must not be nil")
   113  	}
   114  
   115  	if a.HTTPReadTimeout == nil {
   116  		return fmt.Errorf("http_read_timeout must be set")
   117  	}
   118  	if v, err := time.ParseDuration(*a.HTTPReadTimeout); err != nil {
   119  		return fmt.Errorf("http_read_timeout not a valid duration: %w", err)
   120  	} else if v < 0 {
   121  		return fmt.Errorf("http_read_timeout must be > 0")
   122  	}
   123  
   124  	if a.HTTPMaxSize == nil {
   125  		return fmt.Errorf("http_max_size must be set")
   126  	}
   127  	if v, err := humanize.ParseBytes(*a.HTTPMaxSize); err != nil {
   128  		return fmt.Errorf("http_max_size not a valid size: %w", err)
   129  	} else if v > math.MaxInt64 {
   130  		return fmt.Errorf("http_max_size must be < %d but found %d", int64(math.MaxInt64), v)
   131  	}
   132  
   133  	if a.GCSTimeout == nil {
   134  		return fmt.Errorf("gcs_timeout must be set")
   135  	}
   136  	if v, err := time.ParseDuration(*a.GCSTimeout); err != nil {
   137  		return fmt.Errorf("gcs_timeout not a valid duration: %w", err)
   138  	} else if v < 0 {
   139  		return fmt.Errorf("gcs_timeout must be > 0")
   140  	}
   141  
   142  	if a.GitTimeout == nil {
   143  		return fmt.Errorf("git_timeout must be set")
   144  	}
   145  	if v, err := time.ParseDuration(*a.GitTimeout); err != nil {
   146  		return fmt.Errorf("git_timeout not a valid duration: %w", err)
   147  	} else if v < 0 {
   148  		return fmt.Errorf("git_timeout must be > 0")
   149  	}
   150  
   151  	if a.HgTimeout == nil {
   152  		return fmt.Errorf("hg_timeout must be set")
   153  	}
   154  	if v, err := time.ParseDuration(*a.HgTimeout); err != nil {
   155  		return fmt.Errorf("hg_timeout not a valid duration: %w", err)
   156  	} else if v < 0 {
   157  		return fmt.Errorf("hg_timeout must be > 0")
   158  	}
   159  
   160  	if a.S3Timeout == nil {
   161  		return fmt.Errorf("s3_timeout must be set")
   162  	}
   163  	if v, err := time.ParseDuration(*a.S3Timeout); err != nil {
   164  		return fmt.Errorf("s3_timeout not a valid duration: %w", err)
   165  	} else if v < 0 {
   166  		return fmt.Errorf("s3_timeout must be > 0")
   167  	}
   168  
   169  	if a.DisableFilesystemIsolation == nil {
   170  		return fmt.Errorf("disable_filesystem_isolation must be set")
   171  	}
   172  
   173  	if a.SetEnvironmentVariables == nil {
   174  		return fmt.Errorf("set_environment_variables must be set")
   175  	}
   176  
   177  	return nil
   178  }
   179  
   180  func DefaultArtifactConfig() *ArtifactConfig {
   181  	return &ArtifactConfig{
   182  		// Read timeout for HTTP operations. Must be long enough to
   183  		// accommodate large/slow downloads.
   184  		HTTPReadTimeout: pointer.Of("30m"),
   185  
   186  		// Maximum download size. Must be large enough to accommodate
   187  		// large downloads.
   188  		HTTPMaxSize: pointer.Of("100GB"),
   189  
   190  		// Timeout for GCS operations. Must be long enough to
   191  		// accommodate large/slow downloads.
   192  		GCSTimeout: pointer.Of("30m"),
   193  
   194  		// Timeout for Git operations. Must be long enough to
   195  		// accommodate large/slow clones.
   196  		GitTimeout: pointer.Of("30m"),
   197  
   198  		// Timeout for Hg operations. Must be long enough to
   199  		// accommodate large/slow clones.
   200  		HgTimeout: pointer.Of("30m"),
   201  
   202  		// Timeout for S3 operations. Must be long enough to
   203  		// accommodate large/slow downloads.
   204  		S3Timeout: pointer.Of("30m"),
   205  
   206  		// Toggle for disabling filesystem isolation, where available.
   207  		DisableFilesystemIsolation: pointer.Of(false),
   208  
   209  		// No environment variables are inherited from Client by default.
   210  		SetEnvironmentVariables: pointer.Of(""),
   211  	}
   212  }