1
0
mirror of https://github.com/openshift/source-to-image.git synced 2026-02-05 12:44:54 +01:00

Add support for .sti/environment file

This commit is contained in:
Michal Fojtik
2015-02-24 16:00:43 +01:00
parent 1f10fc6006
commit d2e8a4602c
6 changed files with 130 additions and 2 deletions

View File

@@ -40,6 +40,18 @@ image:
Additionally for the best user experience and optimized sti operation we suggest image
to have `/bin/sh` and tar command inside.
Users can also set extra environment variables in the application source code,
which are passed to the build and the `assemble` script consumes them. All
environment variables are also present in the output application image. These
variables are defined in `.sti/environment` file inside the application sources.
The format of this file is a simple key-value, for example:
```
FOO=bar
```
In this case, the value of `FOO` environment variable will be set to `bar`.
For detailed description of the requirements and the scripts along with examples see
[builder_image.md](https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md)
@@ -51,6 +63,7 @@ For detailed description of the requirements and the scripts along with examples
1. `sti` creates a container based on the build image and passes it a tar file that contains:
1. The application source in `src`
1. The build artifacts in `artifacts` (if applicable - see [incremental builds](#incremental-builds))
1. `sti` sets the environment variables from `.sti/environment` (optional)
1. `sti` starts the container and runs its `assemble` script
1. `sti` waits for the container to finish
1. `sti` commits the container, setting the CMD for the output image to be the `run` script and tagging the image with the name provided.

View File

@@ -9,6 +9,11 @@ const (
SaveArtifacts = "save-artifacts"
// Usage is the name of the script responsible for printing the builder image's short info.
Usage = "usage"
// Environment contains list of key value pairs that will be set during the
// STI build. Users can use this file to provide extra configuration
// depending on the builder image used.
Environment = "environment"
)
const (

View File

@@ -13,6 +13,7 @@ import (
"github.com/openshift/source-to-image/pkg/build/strategies/sti"
"github.com/openshift/source-to-image/pkg/docker"
"github.com/openshift/source-to-image/pkg/git"
"github.com/openshift/source-to-image/pkg/scripts"
"github.com/openshift/source-to-image/pkg/tar"
"github.com/openshift/source-to-image/pkg/util"
)
@@ -124,6 +125,12 @@ func (b *OnBuild) CreateDockerfile(request *api.Request) error {
if err != nil {
return err
}
env, err := scripts.GetEnvironment(request)
if err != nil {
glog.V(1).Infof("Environment: %v", err)
} else {
buffer.WriteString(scripts.ConvertEnvironmentToDocker(env))
}
// If there is an assemble script present, run it as part of the build process
// as the last thing.
if b.hasAssembleScript(request) {

View File

@@ -209,10 +209,17 @@ func (b *STI) PostExecute(containerID string, location string) error {
}
}
env, err := scripts.GetEnvironment(b.request)
if err != nil {
glog.V(1).Infof("No .sti/environment provided (%v)", err)
}
buildEnv := append(scripts.ConvertEnvironment(env), b.generateConfigEnv()...)
cmd := []string{}
opts := docker.CommitContainerOptions{
Command: append(cmd, filepath.Join(location, api.Run)),
Env: b.generateConfigEnv(),
Env: buildEnv,
ContainerID: containerID,
Repository: b.request.Tag,
}
@@ -296,6 +303,13 @@ func (b *STI) Save(request *api.Request) (err error) {
func (b *STI) Execute(command string, request *api.Request) error {
glog.V(2).Infof("Using image name %s", request.BaseImage)
env, err := scripts.GetEnvironment(request)
if err != nil {
glog.V(1).Infof("No .sti/environment provided (%v)", err)
}
buildEnv := append(scripts.ConvertEnvironment(env), b.generateConfigEnv()...)
uploadDir := filepath.Join(request.WorkingDir, "upload")
tarFileName, err := b.tar.CreateTarFile(request.WorkingDir, uploadDir)
if err != nil {
@@ -329,7 +343,7 @@ func (b *STI) Execute(command string, request *api.Request) error {
ScriptsURL: request.ScriptsURL,
Location: request.Location,
Command: command,
Env: b.generateConfigEnv(),
Env: buildEnv,
PostExec: b.postExecutor,
}
if !request.LayeredBuild {

View File

@@ -0,0 +1,73 @@
package scripts
import (
"bufio"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/golang/glog"
"github.com/openshift/source-to-image/pkg/api"
)
// Environment represents a single environment variable definition
type Environment struct {
Name string
Value string
}
// GetEnvironment gets the .sti/environment file located in the sources and
// parse it into []environment
func GetEnvironment(request *api.Request) ([]Environment, error) {
envPath := filepath.Join(request.WorkingDir, api.Source, ".sti", api.Environment)
if _, err := os.Stat(envPath); os.IsNotExist(err) {
return nil, errors.New("no evironment file found in application sources")
}
f, err := os.Open(envPath)
if err != nil {
return nil, errors.New("unable to read .sti/environment file")
}
defer f.Close()
result := []Environment{}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
s := scanner.Text()
// Allow for comments in environment file
if strings.HasPrefix(s, "#") {
continue
}
parts := strings.SplitN(s, "=", 2)
if len(parts) != 2 {
continue
}
e := Environment{
Name: strings.TrimSpace(parts[0]),
Value: strings.TrimSpace(parts[1]),
}
glog.V(1).Infof("Setting '%s' to '%s'", e.Name, e.Value)
result = append(result, e)
}
return result, scanner.Err()
}
// ConvertEnvironment converts the []Environment to "key=val" strings
func ConvertEnvironment(env []Environment) (result []string) {
for _, e := range env {
result = append(result, fmt.Sprintf("%s=%s", e.Name, e.Value))
}
return
}
// ConvertEnvironmentToDocker converts the []Environment into Dockerfile format
func ConvertEnvironmentToDocker(env []Environment) (result string) {
for _, e := range env {
result += fmt.Sprintf("ENV %s %s\n", e.Name, e.Value)
}
return
}

View File

@@ -0,0 +1,16 @@
package scripts
import "testing"
func TestConvertEnvironment(t *testing.T) {
env := []Environment{
{"FOO", "BAR"},
}
result := ConvertEnvironment(env)
if len(result) != 1 {
t.Errorf("Expected 1 item, got %d", len(result))
}
if result[0] != "FOO=BAR" {
t.Errorf("Expected FOO=BAR, got %v", result)
}
}