From 46e7e91046da78b7dd49a6a8b6742f49c5fef1ee Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Wed, 17 Feb 2016 15:23:15 +0100 Subject: [PATCH] Run post build hook with `/bin/sh -ic` We need either `/bin/bash -c` or `/bin/sh -ic` to make our supported SCL-powered images to work properly. That's due to a hack to auto-enable SCLs: https://github.com/openshift/sti-base/blob/8d95148/Dockerfile#L23-L29 In CentOS and RHEL images, `/bin/sh` is a symlink to `/bin/bash`. In that case, the ENV environment variable is only evaluated when the shell is started in interactive mode, which happens when there's and attached tty (not the case for post build hook) or when the `-i` argument is passed explicitly. Making the shell interactive with `-i` is ugly, but is the only solution we know so far without requiring Bash. --- .../application-template-dockerbuild.json | 3 +++ .../application-template-pullspecbuild.json | 3 +++ .../sample-app/application-template-stibuild.json | 3 +++ pkg/build/api/types.go | 15 ++++++++++----- pkg/build/api/v1/types.go | 15 ++++++++++----- pkg/build/api/v1beta3/types.go | 15 ++++++++++----- pkg/build/builder/common.go | 7 ++++++- 7 files changed, 45 insertions(+), 16 deletions(-) diff --git a/examples/sample-app/application-template-dockerbuild.json b/examples/sample-app/application-template-dockerbuild.json index 08e99b5ca6e1..ca50735409d3 100644 --- a/examples/sample-app/application-template-dockerbuild.json +++ b/examples/sample-app/application-template-dockerbuild.json @@ -144,6 +144,9 @@ "name": "origin-ruby-sample:latest" } }, + "postCommit": { + "script": "bundle exec rake test" + }, "resources": {} }, "status": { diff --git a/examples/sample-app/application-template-pullspecbuild.json b/examples/sample-app/application-template-pullspecbuild.json index de7fc5aeb042..7fa70da4e075 100644 --- a/examples/sample-app/application-template-pullspecbuild.json +++ b/examples/sample-app/application-template-pullspecbuild.json @@ -136,6 +136,9 @@ "name": "origin-ruby-sample:latest" } }, + "postCommit": { + "script": "bundle exec rake test" + }, "resources": {} }, "status": { diff --git a/examples/sample-app/application-template-stibuild.json b/examples/sample-app/application-template-stibuild.json index e8f06e86073f..d82a0047bfbe 100644 --- a/examples/sample-app/application-template-stibuild.json +++ b/examples/sample-app/application-template-stibuild.json @@ -146,6 +146,9 @@ "name": "origin-ruby-sample:latest" } }, + "postCommit": { + "script": "bundle exec rake test" + }, "resources": {} }, "status": { diff --git a/pkg/build/api/types.go b/pkg/build/api/types.go index 56e8394472e4..7b5b21d370f4 100644 --- a/pkg/build/api/types.go +++ b/pkg/build/api/types.go @@ -441,7 +441,7 @@ type SourceBuildStrategy struct { // The above is a convenient form which is equivalent to: // // BuildPostCommitSpec{ -// Command: []string{"/bin/sh", "-c"}, +// Command: []string{"/bin/sh", "-ic"}, // Args: []string{"rake test --verbose"}, // } // @@ -486,7 +486,7 @@ type SourceBuildStrategy struct { // the fields are specified, the hook is not executed. type BuildPostCommitSpec struct { // Command is the command to run. It may not be specified with Script. - // This might be needed if the image doesn't have "/bin/sh", or if you + // This might be needed if the image doesn't have `/bin/sh`, or if you // do not want to use a shell. In all other cases, using Script might be // more convenient. Command []string @@ -494,11 +494,16 @@ type BuildPostCommitSpec struct { // Script or the Docker image's default entrypoint. The arguments are // placed immediately after the command to be run. Args []string - // Script is a shell script to be run with `/bin/sh -c`. It may not be + // Script is a shell script to be run with `/bin/sh -ic`. It may not be // specified with Command. Use Script when a shell script is appropriate // to execute the post build hook, for example for running unit tests - // with "rake test". If you need control over the image entrypoint, or - // if the image does not have "/bin/sh", use Command and/or Args. + // with `rake test`. If you need control over the image entrypoint, or + // if the image does not have `/bin/sh`, use Command and/or Args. + // The `-i` flag is needed to support CentOS and RHEL images that use + // Software Collections (SCL), in order to have the appropriate + // collections enabled in the shell. E.g., in the Ruby image, this is + // necessary to make `ruby`, `bundle` and other binaries available in + // the PATH. Script string } diff --git a/pkg/build/api/v1/types.go b/pkg/build/api/v1/types.go index 408717a3aab2..dd1e90f83b86 100644 --- a/pkg/build/api/v1/types.go +++ b/pkg/build/api/v1/types.go @@ -424,7 +424,7 @@ type SourceBuildStrategy struct { // The above is a convenient form which is equivalent to: // // BuildPostCommitSpec{ -// Command: []string{"/bin/sh", "-c"}, +// Command: []string{"/bin/sh", "-ic"}, // Args: []string{"rake test --verbose"}, // } // @@ -469,7 +469,7 @@ type SourceBuildStrategy struct { // the fields are specified, the hook is not executed. type BuildPostCommitSpec struct { // Command is the command to run. It may not be specified with Script. - // This might be needed if the image doesn't have "/bin/sh", or if you + // This might be needed if the image doesn't have `/bin/sh`, or if you // do not want to use a shell. In all other cases, using Script might be // more convenient. Command []string `json:"command,omitempty" description:"command to be executed in a container running the build output image replacing the image's entrypoint"` @@ -477,11 +477,16 @@ type BuildPostCommitSpec struct { // Script or the Docker image's default entrypoint. The arguments are // placed immediately after the command to be run. Args []string `json:"args,omitempty" description:"arguments to command, script or the default image entrypoint"` - // Script is a shell script to be run with `/bin/sh -c`. It may not be + // Script is a shell script to be run with `/bin/sh -ic`. It may not be // specified with Command. Use Script when a shell script is appropriate // to execute the post build hook, for example for running unit tests - // with "rake test". If you need control over the image entrypoint, or - // if the image does not have "/bin/sh", use Command and/or Args. + // with `rake test`. If you need control over the image entrypoint, or + // if the image does not have `/bin/sh`, use Command and/or Args. + // The `-i` flag is needed to support CentOS and RHEL images that use + // Software Collections (SCL), in order to have the appropriate + // collections enabled in the shell. E.g., in the Ruby image, this is + // necessary to make `ruby`, `bundle` and other binaries available in + // the PATH. Script string `json:"script,omitempty" description:"shell script to be executed in a container running the build output image"` } diff --git a/pkg/build/api/v1beta3/types.go b/pkg/build/api/v1beta3/types.go index cbe960922f3e..54f511f68946 100644 --- a/pkg/build/api/v1beta3/types.go +++ b/pkg/build/api/v1beta3/types.go @@ -411,7 +411,7 @@ type SourceBuildStrategy struct { // The above is a convenient form which is equivalent to: // // BuildPostCommitSpec{ -// Command: []string{"/bin/sh", "-c"}, +// Command: []string{"/bin/sh", "-ic"}, // Args: []string{"rake test --verbose"}, // } // @@ -456,7 +456,7 @@ type SourceBuildStrategy struct { // the fields are specified, the hook is not executed. type BuildPostCommitSpec struct { // Command is the command to run. It may not be specified with Script. - // This might be needed if the image doesn't have "/bin/sh", or if you + // This might be needed if the image doesn't have `/bin/sh`, or if you // do not want to use a shell. In all other cases, using Script might be // more convenient. Command []string `json:"command,omitempty" description:"command to be executed in a container running the build output image replacing the image's entrypoint"` @@ -464,11 +464,16 @@ type BuildPostCommitSpec struct { // Script or the Docker image's default entrypoint. The arguments are // placed immediately after the command to be run. Args []string `json:"args,omitempty" description:"arguments to command, script or the default image entrypoint"` - // Script is a shell script to be run with `/bin/sh -c`. It may not be + // Script is a shell script to be run with `/bin/sh -ic`. It may not be // specified with Command. Use Script when a shell script is appropriate // to execute the post build hook, for example for running unit tests - // with "rake test". If you need control over the image entrypoint, or - // if the image does not have "/bin/sh", use Command and/or Args. + // with `rake test`. If you need control over the image entrypoint, or + // if the image does not have `/bin/sh`, use Command and/or Args. + // The `-i` flag is needed to support CentOS and RHEL images that use + // Software Collections (SCL), in order to have the appropriate + // collections enabled in the shell. E.g., in the Ruby image, this is + // necessary to make `ruby`, `bundle` and other binaries available in + // the PATH. Script string `json:"script,omitempty" description:"shell script to be executed in a container running the build output image"` } diff --git a/pkg/build/builder/common.go b/pkg/build/builder/common.go index 9b079b887dc5..9ccd9360c369 100644 --- a/pkg/build/builder/common.go +++ b/pkg/build/builder/common.go @@ -135,7 +135,12 @@ func execPostCommitHook(client DockerClient, postCommitSpec api.BuildPostCommitS glog.V(4).Infof("Post commit hook spec: %+v", postCommitSpec) if script != "" { - command = []string{"/bin/sh", "-c"} + // The `-i` flag is needed to support CentOS and RHEL images + // that use Software Collections (SCL), in order to have the + // appropriate collections enabled in the shell. E.g., in the + // Ruby image, this is necessary to make `ruby`, `bundle` and + // other binaries available in the PATH. + command = []string{"/bin/sh", "-ic"} args = append([]string{script, command[0]}, args...) }