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  }