Skip to content

Commit

Permalink
Add prebuild/postbuild script
Browse files Browse the repository at this point in the history
  • Loading branch information
keimoon committed Feb 27, 2018
1 parent c1b22d2 commit f77daea
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 8 deletions.
38 changes: 34 additions & 4 deletions buildtree/buildtree.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

// BuildTree is a build tree
type BuildTree struct {
rootDir string
rootNodes []*buildNode
allNodes map[string]*buildNode
credentials map[string]*credentialConfig
Expand All @@ -28,6 +29,8 @@ type buildNode struct {
name string
tag string
depend string
preBuild string
postBuild string
children []*buildNode
dirty bool
forceBuild bool
Expand Down Expand Up @@ -79,18 +82,21 @@ func readBuildTree(configFilePath string, fileContent []byte, variableMap map[st
if err != nil {
return nil, err
}
configFileFolder := filepath.Dir(configFilePath)
buildTree := &BuildTree{
rootDir: filepath.Join(configFileFolder, buildConfig.RootDir),
rootNodes: []*buildNode{},
allNodes: make(map[string]*buildNode),
credentials: make(map[string]*credentialConfig),
}
configFileFolder := filepath.Dir(configFilePath)
for _, buildNodeConfig := range buildConfig.Build {
node := &buildNode{
buildRoot: utils.ResolveDir(filepath.Join(configFileFolder, buildConfig.RootDir), buildNodeConfig.From),
buildRoot: utils.ResolveDir(buildTree.rootDir, buildNodeConfig.From),
name: utils.FormatDockerName(buildNodeConfig.Name),
tag: buildNodeConfig.Tag,
depend: utils.FormatDockerName(buildNodeConfig.Depend),
preBuild: buildNodeConfig.PreBuild,
postBuild: buildNodeConfig.PostBuild,
children: []*buildNode{},
dirty: false,
forceBuild: buildNodeConfig.ForceBuild,
Expand Down Expand Up @@ -313,7 +319,7 @@ func (t *BuildTree) buildNodeAndChildren(node *buildNode) error {
fmt.Printf("====> Skipping %s\n", node.name)
} else {
fmt.Printf("====> Building %s:%s\n", node.name, node.tag)
err := utils.DockerBuild(node.name, node.tag, node.buildRoot)
err := t.buildNode(node, node.tag)
if err != nil {
return err
}
Expand All @@ -333,7 +339,7 @@ func (t *BuildTree) tryBuildNodeAndChildren(node *buildNode) error {
} else {
randomTag := fmt.Sprintf("%s-%d", node.tag, time.Now().UnixNano())
fmt.Printf("====> Building %s:%s\n", node.name, randomTag)
err := utils.DockerBuild(node.name, randomTag, node.buildRoot)
err := t.buildNode(node, randomTag)
if err != nil {
return err
}
Expand All @@ -352,6 +358,30 @@ func (t *BuildTree) tryBuildNodeAndChildren(node *buildNode) error {
return nil
}

func (t *BuildTree) buildNode(node *buildNode, tag string) error {
if node.preBuild != "" {
err := utils.RunShellCommand(t.resolveShellCommandPath(t.rootDir, node.preBuild))
if err != nil {
return err
}
}
err := utils.DockerBuild(node.name, tag, node.buildRoot)
if node.postBuild != "" {
utils.RunShellCommand(t.resolveShellCommandPath(t.rootDir, node.postBuild))
}
return err
}

func (t *BuildTree) resolveShellCommandPath(buildRoot, command string) string {
if strings.HasPrefix(command, "/") {
return command
}
if strings.HasPrefix(command, "./") || strings.HasPrefix(command, "../") {
return buildRoot + "/" + command
}
return command
}

func (t *BuildTree) pushNodeAndChildren(node *buildNode) error {
if !t.needBuild(node) {
fmt.Printf("====> Skipping %s\n", node.name)
Expand Down
34 changes: 30 additions & 4 deletions buildtree/buildtree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package buildtree

import (
"os"
"os/exec"
"path/filepath"
"sort"
"testing"

"github.com/anduintransaction/doriath/utils"
"github.com/palantir/stacktrace"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -76,7 +78,7 @@ credentials:
}

func (s *BuildTreeTestSuite) TestBuildTreeHappyPath() {
if !s.checkIntegTestEnable() {
if !s.checkDockerhubTestEnable() {
s.T().Log("Skipping test happy path")
return
}
Expand Down Expand Up @@ -189,7 +191,7 @@ func (s *BuildTreeTestSuite) TestMismatchTag() {
}

func (s *BuildTreeTestSuite) TestMissingProvidedImage() {
if !s.checkIntegTestEnable() {
if !s.checkDockerhubTestEnable() {
s.T().Log("Skipping test missing provided image")
return
}
Expand All @@ -202,7 +204,7 @@ func (s *BuildTreeTestSuite) TestMissingProvidedImage() {
}

func (s *BuildTreeTestSuite) TestOutdateTag() {
if !s.checkIntegTestEnable() {
if !s.checkDockerhubTestEnable() {
s.T().Log("Skipping test outdate tag")
return
}
Expand All @@ -214,7 +216,26 @@ func (s *BuildTreeTestSuite) TestOutdateTag() {
require.True(s.T(), ok)
}

func (s *BuildTreeTestSuite) checkIntegTestEnable() bool {
func (s *BuildTreeTestSuite) TestPrePostBuild() {
if !s.checkDockerTestEnable() {
s.T().Log("Skipping testing pre-post build")
return
}
rootFolder := filepath.Join(s.resourceFolder, "pre-and-post-build")
buildTree, err := ReadBuildTreeFromFile(filepath.Join(rootFolder, "doriath.yml"), map[string]string{})
require.Nil(s.T(), err, "build tree must be readable")
err = buildTree.Prepare()
require.Nil(s.T(), err, "build tree must be able to be prepared")
err = buildTree.Build()
require.Nil(s.T(), err, "build tree must be able to be built")
cmd := exec.Command("docker", "run", "--rm", "node1:1.0")
output, err := cmd.Output()
require.Nil(s.T(), err, "docker must run successfully")
require.Equal(s.T(), "42\n", string(output))
utils.RunShellCommand("docker rmi node1:1.0")
}

func (s *BuildTreeTestSuite) checkDockerhubTestEnable() bool {
dockerhubTestEnv := os.Getenv("DOCKERHUB_TEST_ENABLE")
if dockerhubTestEnv == "1" || dockerhubTestEnv == "true" {
if os.Getenv("DOCKERHUB_USERNAME") == "" {
Expand All @@ -228,6 +249,11 @@ func (s *BuildTreeTestSuite) checkIntegTestEnable() bool {
return false
}

func (s *BuildTreeTestSuite) checkDockerTestEnable() bool {
dockerTestEnv := os.Getenv("DOCKER_TEST_ENABLE")
return dockerTestEnv == "1" || dockerTestEnv == "true"
}

type buildNodeForTestData struct {
buildRoot string
name string
Expand Down
1 change: 1 addition & 0 deletions test-resources/pre-and-post-build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node1/data
8 changes: 8 additions & 0 deletions test-resources/pre-and-post-build/doriath.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root_dir: .
build:
- name: node1
tag: 1.0
from: ./node1
prebuild: ./scripts/prebuild.sh
postbuild: ./scripts/postbuild.sh
forcebuild: true
6 changes: 6 additions & 0 deletions test-resources/pre-and-post-build/node1/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM ubuntu:16.04

ADD run.sh /opt/run.sh
ADD data /opt/data

CMD exec /opt/run.sh
3 changes: 3 additions & 0 deletions test-resources/pre-and-post-build/node1/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

cat /opt/data
4 changes: 4 additions & 0 deletions test-resources/pre-and-post-build/scripts/postbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

here=`cd $(dirname $BASH_SOURCE); pwd`
rm -f $here/../node1/data
4 changes: 4 additions & 0 deletions test-resources/pre-and-post-build/scripts/prebuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

here=`cd $(dirname $BASH_SOURCE); pwd`
echo 42 > $here/../node1/data
8 changes: 8 additions & 0 deletions utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,11 @@ func (s StringSet) Exists(value string) bool {
_, ok := s[value]
return ok
}

// RunShellCommand runs a command under bash shell
func RunShellCommand(command string) error {
cmd := exec.Command("sh", "-c", command)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

0 comments on commit f77daea

Please sign in to comment.