Skip to content

Commit

Permalink
Merge pull request #1 from rhd-gitops-example/pr-to-js-outter
Browse files Browse the repository at this point in the history
2.1.0 to share schema with 2.0.0
  • Loading branch information
jaideepr97 authored Jul 17, 2020
2 parents 3220820 + 6a1b8a7 commit 7ad6864
Show file tree
Hide file tree
Showing 22 changed files with 390 additions and 1,524 deletions.
16 changes: 9 additions & 7 deletions docs/proposals/odo-deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
## Abstract
Add a new command (verb) to build a production-like/slim container image for the project and deploy the built image on the target platform.

There is an existing proposal for adding on outer-loop information (including support for multiple strategies for building and deploying the projects) to Devfile 2.1.0:
There is an existing proposal for adding on outer-loop information (including support for multiple strategies for building and deploying the projects) to Devfile v2.0.0/v2.1.0:
https://github.com/devfile/kubernetes-api/issues/49

It would be useful to start the design/development of a simpler version of `odo deploy` with devfile 2.0.0 that covers:
It would be useful to start the design/development of a simpler version of `odo deploy` with devfile v2.0.0/v2.1.0 that covers:
- single build strategy - Dockerfile built using `BuildConfig` or `Kaniko`.
- single deployment strategy - Kubernetes manifest deployed using `kubectl`.

Expand Down Expand Up @@ -49,7 +49,7 @@ This deployment is equivalent to a development version of your production and wi

#### Pre-requisites:
- The implementation would be under the experimental flag.
- Only supported for Devfile v2.0.0 components.
- Only supported for Devfile v2.0.0/v2.1.0 components.
- Only supported for Kubernetes/OpenShift targets.

#### odo deploy
Expand All @@ -71,13 +71,15 @@ This command will delete any resources created by odo deploy.

### Devfile

For the initial implementation, we could use devfile v2.0.0 and capture basic outer-loop information as `metadata` on the devfile. `odo` could look for specific keys, while other tools like Che could ignore them.
For the initial implementation, we could use devfile v2.0.0/v2.1.0 and capture basic outer-loop information as `metadata` on the devfile. `odo` could look for specific keys, while other tools like Che could ignore them.

For example:
```
metadata:
alpha.build-dockerfile: <URI>
alpha.deployment-manifest: <URI>
component:
- dockerfile:
dockerfilePath: <URI>
```

### Dockerfile
Expand All @@ -100,7 +102,7 @@ Examples:
This command will perform the following actions:

#### Input validation
- Check if the devfile is v2.0.0 and that it specifies the expected outer-loop metadata.
- Check if the devfile is v2.0.0/v2.1.0 and that it specifies the expected outer-loop metadata.
- If not provided, display a meaningful error message.
- Validate all arguments passed by the user.
- If argument values are invalid, display a meaningful error message.
Expand Down Expand Up @@ -145,4 +147,4 @@ This command will perform the following actions:

- If a devfile does not provide deployment manifest, odo can perhaps create a manifest in the way it does for inner-loop. This will mean devfile creators do not need to provide a deployment manifest if they do not care so much about the deployment aspect.

- Once `odo link` and service binding is supported by odo and devfiles v2, we could use the same service binding information for `odo deploy`.
- Once `odo link` and service binding is supported by odo and devfiles v2.0.0/v2.1.0, we could use the same service binding information for `odo deploy`.
1 change: 1 addition & 0 deletions pkg/devfile/adapters/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type DeployParameters struct {
EnvSpecificInfo envinfo.EnvSpecificInfo // EnvSpecificInfo contains infomation of env.yaml file
Tag string // Tag refers to the image tag of the image being built
ManifestSource []byte // Source of the manifest file
DeploymentPort int // Port to be used in deployment manifest
}

// PushParameters is a struct containing the parameters to be used when pushing to a devfile component
Expand Down
71 changes: 45 additions & 26 deletions pkg/devfile/adapters/kubernetes/component/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"fmt"
"io"
"os"
"os/signal"
"path/filepath"
"reflect"
"strconv"
"strings"
"syscall"
"time"

"github.com/openshift/odo/pkg/exec"
Expand All @@ -31,7 +33,6 @@ import (
"github.com/openshift/odo/pkg/devfile/adapters/kubernetes/storage"
"github.com/openshift/odo/pkg/devfile/adapters/kubernetes/utils"
versionsCommon "github.com/openshift/odo/pkg/devfile/parser/data/common"
"github.com/openshift/odo/pkg/envinfo"
"github.com/openshift/odo/pkg/kclient"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/machineoutput"
Expand Down Expand Up @@ -84,6 +85,10 @@ func (a Adapter) runBuildConfig(client *occlient.Client, parameters common.Build
Name: buildName,
}

controlC := make(chan os.Signal)
signal.Notify(controlC, os.Interrupt, syscall.SIGTERM)
go a.terminateBuild(controlC, client, commonObjectMeta)

_, err = client.CreateDockerBuildConfigWithBinaryInput(commonObjectMeta, dockerfilePath, parameters.Tag, []corev1.EnvVar{})
if err != nil {
return err
Expand Down Expand Up @@ -114,21 +119,30 @@ func (a Adapter) runBuildConfig(client *occlient.Client, parameters common.Build
var cmdOutput string
// This Go routine will automatically pipe the output from WaitForBuildToFinish to
// our logger.
go func() {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()

if log.IsDebug() {
_, err := fmt.Fprintln(os.Stdout, line)
if err != nil {
log.Errorf("Unable to print to stdout: %v", err)
// We pass the controlC os.Signal in order to output the logs within the terminateBuild
// function if the process is interrupted by the user performing a ^C. If we didn't pass it
// The Scanner would consume the log, and only output it if there was an err within this
// func.
go func(controlC chan os.Signal) {
select {
case <-controlC:
return
default:
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()

if log.IsDebug() {
_, err := fmt.Fprintln(os.Stdout, line)
if err != nil {
log.Errorf("Unable to print to stdout: %v", err)
}
}
}

cmdOutput += fmt.Sprintln(line)
cmdOutput += fmt.Sprintln(line)
}
}
}()
}(controlC)

s := log.Spinner("Waiting for build to complete")
if err := client.WaitForBuildToFinish(bc.Name, writer); err != nil {
Expand All @@ -137,9 +151,26 @@ func (a Adapter) runBuildConfig(client *occlient.Client, parameters common.Build
}

s.End(true)
// Stop listening for a ^C so it doesnt perform terminateBuild during any later stages
signal.Stop(controlC)
return
}

// terminateBuild is triggered if the user performs a ^C action within the terminal during the build phase
// of the deploy.
// It cleans up the resources created for the build, as the defer function would not be reached.
// The subsequent deploy would fail if these resources are not cleaned up.
func (a Adapter) terminateBuild(c chan os.Signal, client *occlient.Client, commonObjectMeta metav1.ObjectMeta) {
_ = <-c

log.Info("\nBuild process interrupted, terminating build, this might take a few seconds")
err := client.DeleteBuildConfig(commonObjectMeta)
if err != nil {
log.Info("\n", err.Error())
}
os.Exit(0)
}

// Build image for devfile project
func (a Adapter) Build(parameters common.BuildParameters) (err error) {
client, err := occlient.New()
Expand All @@ -159,18 +190,6 @@ func (a Adapter) Build(parameters common.BuildParameters) (err error) {
return errors.New("unable to build image, only Openshift BuildConfig build is supported")
}

func determinePort(envSpecificInfo envinfo.EnvSpecificInfo) string {
// Determine port to use from first non-Docker route in env.yaml)
deploymentPort := ""
for _, localURL := range envSpecificInfo.GetURL() {
if localURL.Kind != envinfo.DOCKER {
deploymentPort = strconv.Itoa(localURL.Port)
break
}
}
return deploymentPort
}

func substitueYamlVariables(baseYaml []byte, yamlSubstitutions map[string]string) []byte {
// TODO: Provide a better way to do the substitution in the manifest file(s)
for key, value := range yamlSubstitutions {
Expand Down Expand Up @@ -254,7 +273,7 @@ func (a Adapter) Deploy(parameters common.DeployParameters) (err error) {
yamlSubstitutions := map[string]string{
"CONTAINER_IMAGE": parameters.Tag,
"COMPONENT_NAME": applicationName,
"PORT": determinePort(parameters.EnvSpecificInfo),
"PORT": strconv.Itoa(parameters.DeploymentPort),
}

// Build a yaml decoder with the unstructured Scheme
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package version210
package version200

import (
"testing"
Expand All @@ -21,7 +21,7 @@ func TestGetCommands(t *testing.T) {

}

func getTestDevfileData() (testDevfile Devfile210, commands []common.DevfileCommand) {
func getTestDevfileData() (testDevfile Devfile200, commands []common.DevfileCommand) {

command := "ls -la"
component := "alias1"
Expand All @@ -46,7 +46,7 @@ func getTestDevfileData() (testDevfile Devfile210, commands []common.DevfileComm
},
}

testDevfileobj := Devfile210{
testDevfileobj := Devfile200{
Commands: execCommands,
}

Expand Down
41 changes: 36 additions & 5 deletions pkg/devfile/parser/data/2.0.0/devfileJsonSchema200.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,8 @@ const JsonSchema200 = `{
"CheEditor",
"Volume",
"ChePlugin",
"Custom"
"Custom",
"Dockerfile"
],
"type": "string"
},
Expand All @@ -634,6 +635,40 @@ const JsonSchema200 = `{
"name"
],
"type": "object"
},
"Dockerfile":{
"description":"Dockerfile component",
"properties":{
"name":{
"description":"Mandatory name that allows referencing the dockerfile component",
"type":"string"
},
"source":{
"sourceDir":{
"description":"path of source directory to establish build context",
"type":"string"
},
"location":{
"description":"location of the source code repostory",
"type":"string"
},
"type":"object"
},
"dockerfilePath":{
"description":"path to dockerfile",
"type":"string"
},
"destination":{
"description":"path to registry where the build image is to be pushed",
"type":"string"
}
},
"required":[
"name",
"dockerfilePath",
"source"
],
"type":"object"
}
},
"type": "object"
Expand Down Expand Up @@ -849,10 +884,6 @@ const JsonSchema200 = `{
"type": "string",
"description": "Optional devfile name"
},
"alpha.build-dockerfile": {
"type":"string",
"description": "Optional URL to remote Dockerfile"
},
"alpha.deployment-manifest": {
"type":"string",
"description": "Optional URL to remote Deployment Manifest"
Expand Down
28 changes: 28 additions & 0 deletions pkg/devfile/parser/data/2.0.0/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ type Component struct {

// Allows specifying the definition of a volume shared by several other components
Volume *Volume `json:"volume,omitempty"`

// Allows specifying a dockerfile to initiate build
Dockerfile *Dockerfile `json:"dockerfile,omitempty"`
}

// Composite Composite command that allows executing several sub-commands either sequentially or concurrently
Expand Down Expand Up @@ -408,3 +411,28 @@ type Zip struct {
// Part of project to populate in the working directory.
SparseCheckoutDir string `json:"sparseCheckoutDir,omitempty"`
}

// Dockerfile Component is for dockerfile image build
type Dockerfile struct {
// Mandatory name that allows referencing the Volume component in Container volume mounts or inside a parent
Name string `json:"name"`

// Mandatory path to source code
Source *Source `json:"source"`

//Mandatory path to dockerfile
DockerfilePath string `json:"dockerfilePath"`

//Mandatory destination to registry to push built image
Destination string `json:"destination,omitempty"`
}

// Source represents source code for Dockerfile Component
type Source struct {
//Mandatory path to local source directory folder
SourceDir string `json:"sourceDir"`

//Mandatory path to source repository hosted locally or on cloud
Location string `json:"location"`
}

53 changes: 0 additions & 53 deletions pkg/devfile/parser/data/2.1.0/components.go

This file was deleted.

Loading

0 comments on commit 7ad6864

Please sign in to comment.