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 }