Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions commands/operator-sdk/cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"log"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/operator-framework/operator-sdk/commands/operator-sdk/cmd/cmdutil"
Expand Down Expand Up @@ -144,14 +145,20 @@ func buildFunc(cmd *cobra.Command, args []string) {
cmdError.ExitWithError(cmdError.ExitBadArgs, fmt.Errorf("build command needs exactly 1 argument"))
}

cmdutil.MustInProjectRoot()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command breaks support for Ansible Operator because config/config.yaml doesn't exist in our project. Why doesn't this function look for the Dockerfile instead? It would verify we are in the project root and be agnostic to the type of operator.

goBuildEnv := append(os.Environ(), "GOOS=linux", "GOARCH=amd64", "CGO_ENABLED=0")
wd, err := os.Getwd()
if err != nil {
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("could not identify current working directory: %v", err))
}

// Don't need to buld go code if Ansible Operator
if mainExists() {
bcmd := exec.Command(build)
bcmd.Env = append(os.Environ(), fmt.Sprintf("TEST_LOCATION=%v", testLocationBuild))
bcmd.Env = append(bcmd.Env, fmt.Sprintf("ENABLE_TESTS=%v", enableTests))
o, err := bcmd.CombinedOutput()
buildCmd := exec.Command("go", "build", "-o", filepath.Join(wd, "tmp/_output/bin", filepath.Base(wd)), filepath.Join(cmdutil.GetCurrPkg(), "cmd", filepath.Base(wd)))
buildCmd.Env = goBuildEnv
o, err := buildCmd.CombinedOutput()
if err != nil {
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to build: (%v)", string(o)))
log.Fatalf("failed to build operator binary: %v (%v)", err, string(o))
}
fmt.Fprintln(os.Stdout, string(o))
}
Expand All @@ -173,6 +180,18 @@ func buildFunc(cmd *cobra.Command, args []string) {
fmt.Fprintln(os.Stdout, string(o))

if enableTests {
buildTestCmd := exec.Command("go", "test", "-c", "-o", filepath.Join(wd, "tmp/_output/bin", filepath.Base(wd)+"-test"), testLocationBuild+"/...")
buildTestCmd.Env = goBuildEnv
o, err := buildTestCmd.CombinedOutput()
if err != nil {
log.Fatalf("failed to build test binary: %v (%v)", err, string(o))
}
fmt.Fprintln(os.Stdout, string(o))
// if a user is using an older sdk repo as their library, make sure they have required build files
_, err = os.Stat("tmp/build/test-framework/Dockerfile")
if err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a logging to indicate that you are missing the tmp/build/test-framework/Dockerfile and you are going to tmp/build/test-framework/Dockerfile

Copy link
Copy Markdown
Contributor

@fanminshi fanminshi Oct 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

offline discussion: generator already prints out the file it is going to generate. so we don't need to add extra a logging statement.

generator.RenderTestingContainerFiles(filepath.Join(wd, "tmp/build"), filepath.Base(wd))
}
testDbcmd := exec.Command("docker", "build", ".", "-f", "tmp/build/test-framework/Dockerfile", "-t", image, "--build-arg", "NAMESPACEDMAN="+namespacedManBuild, "--build-arg", "BASEIMAGE="+baseImageName)
o, err = testDbcmd.CombinedOutput()
if err != nil {
Expand Down
24 changes: 24 additions & 0 deletions commands/operator-sdk/cmd/cmdutil/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
package cmdutil

import (
"errors"
"fmt"
gobuild "go/build"
"io/ioutil"
"os"
"path/filepath"
"strings"

cmdError "github.com/operator-framework/operator-sdk/commands/operator-sdk/error"
"github.com/operator-framework/operator-sdk/pkg/generator"
Expand Down Expand Up @@ -49,3 +53,23 @@ func GetConfig() *generator.Config {
}
return c
}

// GetCurrPkg returns the current directory's import path
// e.g: "github.com/example-inc/app-operator"
func GetCurrPkg() string {
gopath := os.Getenv("GOPATH")
if len(gopath) == 0 {
gopath = gobuild.Default.GOPATH
}
goSrc := filepath.Join(gopath, "src")

wd, err := os.Getwd()
if err != nil {
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to get working directory: (%v)", err))
}
if !strings.HasPrefix(filepath.Dir(wd), goSrc) {
cmdError.ExitWithError(cmdError.ExitError, errors.New("must run from gopath"))
}
currPkg := strings.Replace(wd, goSrc+string(filepath.Separator), "", 1)
return currPkg
}
22 changes: 8 additions & 14 deletions pkg/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,22 +503,10 @@ func (g *Generator) renderVersion() error {
}

func renderBuildFiles(buildDir, repoPath, projectName, operatorType string, generatePlaybook bool) error {
buf := &bytes.Buffer{}
bTd := tmplData{
ProjectName: projectName,
RepoPath: repoPath,
}

var dockerFileTmplName string
switch operatorType {
case goOperatorType:
dockerFileTmplName = dockerFileTmpl
if err := renderFile(buf, "tmp/build/build.sh", buildTmpl, bTd); err != nil {
return err
}
if err := writeFileAndPrint(filepath.Join(buildDir, build), buf.Bytes(), defaultExecFileMode); err != nil {
return err
}
case ansibleOperatorType:
dockerFileTmplName = dockerFileAnsibleTmpl
}
Expand All @@ -532,11 +520,17 @@ func renderBuildFiles(buildDir, repoPath, projectName, operatorType string, gene
return err
}

return RenderTestingContainerFiles(buildDir, projectName)
}

func RenderTestingContainerFiles(buildDir, projectName string) error {
dTd := tmplData{
ProjectName: projectName,
}
if err := renderWriteFile(filepath.Join(buildDir, "test-framework", testingDockerfile), "tmp/build/test-framework/Dockerfile", testingDockerFileTmpl, dTd); err != nil {
return err
}

buf = &bytes.Buffer{}
buf := &bytes.Buffer{}
if err := renderFile(buf, filepath.Join(buildDir, goTest), goTestScript, tmplData{}); err != nil {
return err
}
Expand Down
15 changes: 0 additions & 15 deletions pkg/generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,21 +593,6 @@ COPY watches.yaml ${HOME}/watches.yaml

func TestGenBuild(t *testing.T) {
buf := &bytes.Buffer{}
bTd := tmplData{
ProjectName: appProjectName,
RepoPath: appRepoPath,
}
if err := renderFile(buf, "tmp/build/build.sh", buildTmpl, bTd); err != nil {
t.Error(err)
return
}
if buildExp != buf.String() {
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(buildExp, buf.String(), false)
t.Errorf("\nTest failed. Below is the diff of the expected vs actual results.\nRed text is missing and green text is extra.\n\n" + dmp.DiffPrettyText(diffs))
}

buf = &bytes.Buffer{}
dTd := tmplData{
ProjectName: appProjectName,
}
Expand Down
24 changes: 0 additions & 24 deletions pkg/generator/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,30 +551,6 @@ deepcopy \
{{.APIDirName}}:{{.Version}} \
--go-header-file "./tmp/codegen/boilerplate.go.txt"
`
const buildTmpl = `#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail

if ! which go > /dev/null; then
echo "golang needs to be installed"
exit 1
fi

BIN_DIR="$(pwd)/tmp/_output/bin"
mkdir -p ${BIN_DIR}
PROJECT_NAME="{{.ProjectName}}"
REPO_PATH="{{.RepoPath}}"
BUILD_PATH="${REPO_PATH}/cmd/${PROJECT_NAME}"
TEST_PATH="${REPO_PATH}/${TEST_LOCATION}"
echo "building "${PROJECT_NAME}"..."
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o ${BIN_DIR}/${PROJECT_NAME} $BUILD_PATH
if $ENABLE_TESTS ; then
echo "building "${PROJECT_NAME}-test"..."
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c -o ${BIN_DIR}/${PROJECT_NAME}-test $TEST_PATH
fi
`

const goTestScript = `#!/bin/sh

Expand Down