gopkg.in/openshift/source-to-image.v1@v1.2.0/pkg/api/types.go (about) 1 package api 2 3 import ( 4 "errors" 5 "fmt" 6 "net/url" 7 "path/filepath" 8 "strings" 9 "time" 10 11 "github.com/openshift/source-to-image/pkg/scm/git" 12 utillog "github.com/openshift/source-to-image/pkg/util/log" 13 "github.com/openshift/source-to-image/pkg/util/user" 14 ) 15 16 var log = utillog.StderrLog 17 18 // invalidFilenameCharacters contains a list of character we consider malicious 19 // when injecting the directories into containers. 20 const invalidFilenameCharacters = `;*?"<>|%#$!+{}&[],"'` + "`" 21 22 const ( 23 // PullAlways means that we always attempt to pull the latest image. 24 PullAlways PullPolicy = "always" 25 26 // PullNever means that we never pull an image, but only use a local image. 27 PullNever PullPolicy = "never" 28 29 // PullIfNotPresent means that we pull if the image isn't present on disk. 30 PullIfNotPresent PullPolicy = "if-not-present" 31 32 // DefaultBuilderPullPolicy specifies the default pull policy to use 33 DefaultBuilderPullPolicy = PullIfNotPresent 34 35 // DefaultRuntimeImagePullPolicy specifies the default pull policy to use. 36 DefaultRuntimeImagePullPolicy = PullIfNotPresent 37 38 // DefaultPreviousImagePullPolicy specifies policy for pulling the previously 39 // build Docker image when doing incremental build 40 DefaultPreviousImagePullPolicy = PullIfNotPresent 41 ) 42 43 // Config contains essential fields for performing build. 44 type Config struct { 45 // DisplayName is a result image display-name label. This defaults to the 46 // output image name. 47 DisplayName string 48 49 // Description is a result image description label. The default is no 50 // description. 51 Description string 52 53 // BuilderImage describes which image is used for building the result images. 54 BuilderImage string 55 56 // BuilderImageVersion provides optional version information about the builder image. 57 BuilderImageVersion string 58 59 // BuilderBaseImageVersion provides optional version information about the builder base image. 60 BuilderBaseImageVersion string 61 62 // RuntimeImage specifies the image that will be a base for resulting image 63 // and will be used for running an application. By default, BuilderImage is 64 // used for building and running, but the latter may be overridden. 65 RuntimeImage string 66 67 // RuntimeImagePullPolicy specifies when to pull a runtime image. 68 RuntimeImagePullPolicy PullPolicy 69 70 // RuntimeAuthentication holds the authentication information for pulling the 71 // runtime Docker images from private repositories. 72 RuntimeAuthentication AuthConfig 73 74 // RuntimeArtifacts specifies a list of source/destination pairs that will 75 // be copied from builder to a runtime image. Source can be a file or 76 // directory. Destination must be a directory. Regardless whether it 77 // is an absolute or relative path, it will be placed into image's WORKDIR. 78 // Destination also can be empty or equals to ".", in this case it just 79 // refers to a root of WORKDIR. 80 // In case it's empty, S2I will try to get this list from 81 // io.openshift.s2i.assemble-input-files label on a RuntimeImage. 82 RuntimeArtifacts VolumeList 83 84 // DockerConfig describes how to access host docker daemon. 85 DockerConfig *DockerConfig 86 87 // DockerCfgPath provides the path to the .dockercfg file 88 DockerCfgPath string 89 90 // PullAuthentication holds the authentication information for pulling the 91 // Docker images from private repositories 92 PullAuthentication AuthConfig 93 94 // IncrementalAuthentication holds the authentication information for pulling the 95 // previous image from private repositories 96 IncrementalAuthentication AuthConfig 97 98 // DockerNetworkMode is used to set the docker network setting to --net=container:<id> 99 // when the builder is invoked from a container. 100 DockerNetworkMode DockerNetworkMode 101 102 // PreserveWorkingDir describes if working directory should be left after processing. 103 PreserveWorkingDir bool 104 105 // IgnoreSubmodules determines whether we will attempt to pull in submodules 106 // (via --recursive or submodule init) 107 IgnoreSubmodules bool 108 109 // Source URL describing the location of sources used to build the result image. 110 Source *git.URL 111 112 // Tag is a result image tag name. 113 Tag string 114 115 // BuilderPullPolicy specifies when to pull the builder image 116 BuilderPullPolicy PullPolicy 117 118 // PreviousImagePullPolicy specifies when to pull the previously build image 119 // when doing incremental build 120 PreviousImagePullPolicy PullPolicy 121 122 // Incremental describes whether to try to perform incremental build. 123 Incremental bool 124 125 // IncrementalFromTag sets an alternative image tag to look for existing 126 // artifacts. Tag is used by default if this is not set. 127 IncrementalFromTag string 128 129 // RemovePreviousImage describes if previous image should be removed after successful build. 130 // This applies only to incremental builds. 131 RemovePreviousImage bool 132 133 // Environment is a map of environment variables to be passed to the image. 134 Environment EnvironmentList 135 136 // EnvironmentFile provides the path to a file with list of environment 137 // variables. 138 EnvironmentFile string 139 140 // LabelNamespace provides the namespace under which the labels will be generated. 141 LabelNamespace string 142 143 // CallbackURL is a URL which is called upon successful build to inform about that fact. 144 CallbackURL string 145 146 // ScriptsURL is a URL describing where to fetch the S2I scripts from during build process. 147 // This url can be a reference within the builder image if the scheme is specified as image:// 148 ScriptsURL string 149 150 // Destination specifies a location where the untar operation will place its artifacts. 151 Destination string 152 153 // WorkingDir describes temporary directory used for downloading sources, scripts and tar operations. 154 WorkingDir string 155 156 // WorkingSourceDir describes the subdirectory off of WorkingDir set up during the repo download 157 // that is later used as the root for ignore processing 158 WorkingSourceDir string 159 160 // LayeredBuild describes if this is build which layered scripts and sources on top of BuilderImage. 161 LayeredBuild bool 162 163 // Operate quietly. Progress and assemble script output are not reported, only fatal errors. 164 // (default: false). 165 Quiet bool 166 167 // ForceCopy results in only the file SCM plugin being used (i.e. no `git clone`); allows for empty directories to be included 168 // in resulting image (since git does not support that). 169 // (default: false). 170 ForceCopy bool 171 172 // Specify a relative directory inside the application repository that should 173 // be used as a root directory for the application. 174 ContextDir string 175 176 // AllowedUIDs is a list of user ranges of users allowed to run the builder image. 177 // If a range is specified and the builder (or runtime) image uses a non-numeric 178 // user or a user that is outside the specified range, then the build fails. 179 AllowedUIDs user.RangeList 180 181 // AssembleUser specifies the user to run the assemble script in container 182 AssembleUser string 183 184 // RunImage will trigger a "docker run ..." invocation of the produced image so the user 185 // can see if it operates as he would expect 186 RunImage bool 187 188 // Usage allows for properly shortcircuiting s2i logic when `s2i usage` is invoked 189 Usage bool 190 191 // Injections specifies a list source/destination folders that are injected to 192 // the container that runs assemble. 193 // All files we inject will be truncated after the assemble script finishes. 194 Injections VolumeList 195 196 // CGroupLimits describes the cgroups limits that will be applied to any containers 197 // run by s2i. 198 CGroupLimits *CGroupLimits 199 200 // DropCapabilities contains a list of capabilities to drop when executing containers 201 DropCapabilities []string 202 203 // ScriptDownloadProxyConfig optionally specifies the http and https proxy 204 // to use when downloading scripts 205 ScriptDownloadProxyConfig *ProxyConfig 206 207 // ExcludeRegExp contains a string representation of the regular expression desired for 208 // deciding which files to exclude from the tar stream 209 ExcludeRegExp string 210 211 // BlockOnBuild prevents s2i from performing a docker build operation 212 // if one is necessary to execute ONBUILD commands, or to layer source code into 213 // the container for images that don't have a tar binary available, if the 214 // image contains ONBUILD commands that would be executed. 215 BlockOnBuild bool 216 217 // HasOnBuild will be set to true if the builder image contains ONBUILD instructions 218 HasOnBuild bool 219 220 // BuildVolumes specifies a list of volumes to mount to container running the 221 // build. 222 BuildVolumes []string 223 224 // Labels specify labels and their values to be applied to the resulting image. Label keys 225 // must have non-zero length. The labels defined here override generated labels in case 226 // they have the same name. 227 Labels map[string]string 228 229 // SourceInfo provides the info about the source to be built rather than relying 230 // on the Downloader to retrieve it. 231 SourceInfo *git.SourceInfo 232 233 // SecurityOpt are passed as options to the docker containers launched by s2i. 234 SecurityOpt []string 235 236 // KeepSymlinks indicates to copy symlinks as symlinks. Default behavior is to follow 237 // symlinks and copy files by content. 238 KeepSymlinks bool 239 240 // AsDockerfile indicates the path where the Dockerfile should be written instead of building 241 // a new image. 242 AsDockerfile string 243 244 // ImageWorkDir is the default working directory for the builder image. 245 ImageWorkDir string 246 247 // ImageScriptsURL is the default location to find the assemble/run scripts for a builder image. 248 // This url can be a reference within the builder image if the scheme is specified as image:// 249 ImageScriptsURL string 250 // AddHost Add a line to /etc/hosts for test purpose or private use in LAN. Its format is host:IP,muliple hosts can be added by using multiple --add-host 251 AddHost []string 252 253 // AssembleRuntimeUser specifies the user to run the assemble-runtime script in container 254 AssembleRuntimeUser string 255 } 256 257 // EnvironmentSpec specifies a single environment variable. 258 type EnvironmentSpec struct { 259 Name string 260 Value string 261 } 262 263 // EnvironmentList contains list of environment variables. 264 type EnvironmentList []EnvironmentSpec 265 266 // ProxyConfig holds proxy configuration. 267 type ProxyConfig struct { 268 HTTPProxy *url.URL 269 HTTPSProxy *url.URL 270 } 271 272 // CGroupLimits holds limits used to constrain container resources. 273 type CGroupLimits struct { 274 MemoryLimitBytes int64 275 CPUShares int64 276 CPUPeriod int64 277 CPUQuota int64 278 MemorySwap int64 279 Parent string 280 } 281 282 // VolumeSpec represents a single volume mount point. 283 type VolumeSpec struct { 284 // Source is a reference to the volume source. 285 Source string 286 // Destination is the path to mount the volume to - absolute or relative. 287 Destination string 288 // Keep indicates if the mounted data should be kept in the final image. 289 Keep bool 290 } 291 292 // VolumeList contains list of VolumeSpec. 293 type VolumeList []VolumeSpec 294 295 // DockerConfig contains the configuration for a Docker connection. 296 type DockerConfig struct { 297 // Endpoint is the docker network endpoint or socket 298 Endpoint string 299 300 // CertFile is the certificate file path for a TLS connection 301 CertFile string 302 303 // KeyFile is the key file path for a TLS connection 304 KeyFile string 305 306 // CAFile is the certificate authority file path for a TLS connection 307 CAFile string 308 309 // UseTLS indicates if TLS must be used 310 UseTLS bool 311 312 // TLSVerify indicates if TLS peer must be verified 313 TLSVerify bool 314 } 315 316 // AuthConfig is our abstraction of the Registry authorization information for whatever 317 // docker client we happen to be based on 318 type AuthConfig struct { 319 Username string 320 Password string 321 Email string 322 ServerAddress string 323 } 324 325 // ContainerConfig is the abstraction of the docker client provider (formerly go-dockerclient, now either 326 // engine-api or kube docker client) container.Config type that is leveraged by s2i or origin 327 type ContainerConfig struct { 328 Labels map[string]string 329 Env []string 330 } 331 332 // Image is the abstraction of the docker client provider (formerly go-dockerclient, now either 333 // engine-api or kube docker client) Image type that is leveraged by s2i or origin 334 type Image struct { 335 ID string 336 *ContainerConfig 337 Config *ContainerConfig 338 } 339 340 // Result structure contains information from build process. 341 type Result struct { 342 343 // Success describes whether the build was successful. 344 Success bool 345 346 // Messages is a list of messages from build process. 347 Messages []string 348 349 // WorkingDir describes temporary directory used for downloading sources, scripts and tar operations. 350 WorkingDir string 351 352 // ImageID describes resulting image ID. 353 ImageID string 354 355 // BuildInfo holds information about the result of a build. 356 BuildInfo BuildInfo 357 } 358 359 // BuildInfo contains information about the build process. 360 type BuildInfo struct { 361 // Stages contains details about each build stage. 362 Stages []StageInfo 363 364 // FailureReason is a camel case reason that is used by the machine to reply 365 // back to the OpenShift builder with information why any of the steps in the 366 // build failed. 367 FailureReason FailureReason 368 } 369 370 // StageInfo contains details about a build stage. 371 type StageInfo struct { 372 // Name is the identifier for each build stage. 373 Name StageName 374 375 // StartTime identifies when this stage started. 376 StartTime time.Time 377 378 // DurationMilliseconds identifies how long this stage ran. 379 DurationMilliseconds int64 380 381 // Steps contains details about each build step within a build stage. 382 Steps []StepInfo 383 } 384 385 // StageName is the identifier for each build stage. 386 type StageName string 387 388 // Valid StageNames 389 const ( 390 // StagePullImages pulls the docker images. 391 StagePullImages StageName = "PullImages" 392 393 //StageAssemble runs the assemble steps. 394 StageAssemble StageName = "Assemble" 395 396 // StageBuild builds the source. 397 StageBuild StageName = "Build" 398 399 // StageCommit commits the container. 400 StageCommit StageName = "CommitContainer" 401 402 // StageRetrieve retrieves artifacts. 403 StageRetrieve StageName = "RetrieveArtifacts" 404 ) 405 406 // StepInfo contains details about a build step. 407 type StepInfo struct { 408 // Name is the identifier for each build step. 409 Name StepName 410 411 // StartTime identifies when this step started. 412 StartTime time.Time 413 414 // DurationMilliseconds identifies how long this step ran. 415 DurationMilliseconds int64 416 } 417 418 // StepName is the identifier for each build step. 419 type StepName string 420 421 // Valid StepNames 422 const ( 423 // StepPullBuilderImage pulls the builder image. 424 StepPullBuilderImage StepName = "PullBuilderImage" 425 426 // StepPullPreviousImage pulls the previous image for an incremental build. 427 StepPullPreviousImage StepName = "PullPreviousImage" 428 429 // StepPullRuntimeImage pull the runtime image. 430 StepPullRuntimeImage StepName = "PullRuntimeImage" 431 432 // StepAssembleBuildScripts runs the assemble scripts. 433 StepAssembleBuildScripts StepName = "AssembleBuildScripts" 434 435 // StepBuildDockerImage builds the Docker image for layered builds. 436 StepBuildDockerImage StepName = "BuildDockerImage" 437 438 // StepCommitContainer commits the container to the builder image. 439 StepCommitContainer StepName = "CommitContainer" 440 441 // StepRetrievePreviousArtifacts restores archived artifacts from the previous build. 442 StepRetrievePreviousArtifacts StepName = "RetrievePreviousArtifacts" 443 ) 444 445 // StepFailureReason holds the type of failure that occurred during the build 446 // process. 447 type StepFailureReason string 448 449 // StepFailureMessage holds the detailed message of a failure. 450 type StepFailureMessage string 451 452 // FailureReason holds the type of failure that occurred during the build 453 // process. 454 type FailureReason struct { 455 Reason StepFailureReason 456 Message StepFailureMessage 457 } 458 459 // InstallResult structure describes the result of install operation 460 type InstallResult struct { 461 462 // Script describes which script this result refers to 463 Script string 464 465 // URL describes from where the script was taken 466 URL string 467 468 // Downloaded describes if download operation happened, this will be true for 469 // external scripts, but false for scripts from inside the image 470 Downloaded bool 471 472 // Installed describes if script was installed to upload directory 473 Installed bool 474 475 // Error describes last error encountered during install operation 476 Error error 477 478 // FailedSources is a list of sources that were attempted but failed 479 // when downloading this script 480 FailedSources []string 481 } 482 483 // DockerNetworkMode specifies the network mode setting for the docker container 484 type DockerNetworkMode string 485 486 const ( 487 // DockerNetworkModeHost places the container in the default (host) network namespace. 488 DockerNetworkModeHost DockerNetworkMode = "host" 489 // DockerNetworkModeBridge instructs docker to create a network namespace for this container connected to the docker0 bridge via a veth-pair. 490 DockerNetworkModeBridge DockerNetworkMode = "bridge" 491 // DockerNetworkModeContainerPrefix is the string prefix used by NewDockerNetworkModeContainer. 492 DockerNetworkModeContainerPrefix string = "container:" 493 // DockerNetworkModeNetworkNamespacePrefix is the string prefix used when sharing a namespace from a CRI-O container. 494 DockerNetworkModeNetworkNamespacePrefix string = "netns:" 495 ) 496 497 // NewDockerNetworkModeContainer creates a DockerNetworkMode value which instructs docker to place the container in the network namespace of an existing container. 498 // It can be used, for instance, to place the s2i container in the network namespace of the infrastructure container of a k8s pod. 499 func NewDockerNetworkModeContainer(id string) DockerNetworkMode { 500 return DockerNetworkMode(DockerNetworkModeContainerPrefix + id) 501 } 502 503 // PullPolicy specifies a type for the method used to retrieve the Docker image 504 type PullPolicy string 505 506 // String implements the String() function of pflags.Value so this can be used as 507 // command line parameter. 508 // This method is really used just to show the default value when printing help. 509 // It will not default the configuration. 510 func (p *PullPolicy) String() string { 511 if len(string(*p)) == 0 { 512 return string(DefaultBuilderPullPolicy) 513 } 514 return string(*p) 515 } 516 517 // Type implements the Type() function of pflags.Value interface 518 func (p *PullPolicy) Type() string { 519 return "string" 520 } 521 522 // Set implements the Set() function of pflags.Value interface 523 // The valid options are "always", "never" or "if-not-present" 524 func (p *PullPolicy) Set(v string) error { 525 switch v { 526 case "always": 527 *p = PullAlways 528 case "never": 529 *p = PullNever 530 case "if-not-present": 531 *p = PullIfNotPresent 532 default: 533 return fmt.Errorf("invalid value %q, valid values are: always, never or if-not-present", v) 534 } 535 return nil 536 } 537 538 // IsInvalidFilename verifies if the provided filename contains malicious 539 // characters. 540 func IsInvalidFilename(name string) bool { 541 return strings.ContainsAny(name, invalidFilenameCharacters) 542 } 543 544 // Set implements the Set() function of pflags.Value interface. 545 // This function parses the string that contains source:destination pair. 546 // When the destination is not specified, the source get copied into current 547 // working directory in container. 548 func (l *VolumeList) Set(value string) error { 549 volumes := strings.Split(value, ";") 550 newVols := make([]VolumeSpec, len(volumes)) 551 for i, v := range volumes { 552 spec, err := l.parseSpec(v) 553 if err != nil { 554 return err 555 } 556 newVols[i] = *spec 557 } 558 *l = append(*l, newVols...) 559 return nil 560 } 561 562 func (l *VolumeList) parseSpec(value string) (*VolumeSpec, error) { 563 if len(value) == 0 { 564 return nil, errors.New("invalid format, must be source:destination") 565 } 566 var mount []string 567 pos := strings.LastIndex(value, ":") 568 if pos == -1 { 569 mount = []string{value, ""} 570 } else { 571 mount = []string{value[:pos], value[pos+1:]} 572 } 573 mount[0] = strings.Trim(mount[0], `"'`) 574 mount[1] = strings.Trim(mount[1], `"'`) 575 s := &VolumeSpec{Source: filepath.Clean(mount[0]), Destination: filepath.ToSlash(filepath.Clean(mount[1]))} 576 if IsInvalidFilename(s.Source) || IsInvalidFilename(s.Destination) { 577 return nil, fmt.Errorf("invalid characters in filename: %q", value) 578 } 579 return s, nil 580 } 581 582 // String implements the String() function of pflags.Value interface. 583 func (l *VolumeList) String() string { 584 result := []string{} 585 for _, i := range *l { 586 result = append(result, strings.Join([]string{i.Source, i.Destination}, ":")) 587 } 588 return strings.Join(result, ",") 589 } 590 591 // Type implements the Type() function of pflags.Value interface. 592 func (l *VolumeList) Type() string { 593 return "string" 594 } 595 596 // Set implements the Set() function of pflags.Value interface. 597 func (e *EnvironmentList) Set(value string) error { 598 parts := strings.SplitN(value, "=", 2) 599 if len(parts) != 2 || len(parts[0]) == 0 { 600 return fmt.Errorf("invalid environment format %q, must be NAME=VALUE", value) 601 } 602 if strings.Contains(parts[1], ",") && strings.Contains(parts[1], "=") { 603 log.Warningf("DEPRECATED: Use multiple -e flags to specify multiple environment variables instead of comma (%q)", value) 604 } 605 *e = append(*e, EnvironmentSpec{ 606 Name: strings.TrimSpace(parts[0]), 607 Value: strings.TrimSpace(parts[1]), 608 }) 609 return nil 610 } 611 612 // String implements the String() function of pflags.Value interface. 613 func (e *EnvironmentList) String() string { 614 result := []string{} 615 for _, i := range *e { 616 result = append(result, strings.Join([]string{i.Name, i.Value}, "=")) 617 } 618 return strings.Join(result, ",") 619 } 620 621 // Type implements the Type() function of pflags.Value interface. 622 func (e *EnvironmentList) Type() string { 623 return "string" 624 } 625 626 // AsBinds converts the list of volume definitions to go-dockerclient compatible 627 // list of bind mounts. 628 func (l *VolumeList) AsBinds() []string { 629 result := make([]string, len(*l)) 630 for index, v := range *l { 631 result[index] = strings.Join([]string{v.Source, v.Destination}, ":") 632 } 633 return result 634 }