Skip to content
This repository has been archived by the owner on Nov 15, 2022. It is now read-only.

Commit

Permalink
Merge pull request #445 from containscafeine/add_imagestreams
Browse files Browse the repository at this point in the history
add ImageStreams support
  • Loading branch information
kadel authored Nov 20, 2017
2 parents cd5297c + 83b819c commit 4ccf7ea
Show file tree
Hide file tree
Showing 8 changed files with 341 additions and 1 deletion.
17 changes: 17 additions & 0 deletions docs/examples/imagestreams/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Image Streams

An image stream can be used to automatically perform an action, such as updating a deployment when a new image is created.

Like most of the Kedge constructs, the `ImageStreamSpec` and `ObjectMeta` have been merged at the same YAML level.

A valid OpenShift `ImageStream` resource can be specified at the root level of the Kedge spec in a field called `imageStreams` like we see in [is.yml](is.yml):

```yaml
name: webapp
imageStreams:
- tags:
- from:
kind: DockerImage
name: centos/httpd-24-centos7:2.4
name: "2.4"
```
22 changes: 22 additions & 0 deletions docs/examples/imagestreams/is.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
controller: DeploymentConfig
name: webapp
containers:
- image: ""
triggers:
- imageChangeParams:
automatic: true
containerNames:
- webapp
from:
kind: ImageStreamTag
name: webapp:2.4
type: ImageChange
services:
- portMappings:
- "8080"
imageStreams:
- tags:
- from:
kind: DockerImage
name: centos/httpd-24-centos7:2.4
name: "2.4"
65 changes: 65 additions & 0 deletions docs/file-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ routes:
- <routeObject>
secrets:
- <secret>
imageStreams:
- <imageStreamObject>
includeResources:
- <includeResources>
```
Expand All @@ -141,6 +143,7 @@ Each "app" (Kedge file) is a Kubernetes <a target="_blank" href="https://kuberne
| ingresses | array of [ingress object](#ingressobject) | no | [ingress object](#ingressobject) object |
| routes | array of [route object](#routeobject) | no | [route object](#routeobject) object |
| secrets | array of [secret](#secret) | no | [secret](#secret) object |
| imageStreams | array of [imageStream object](#imagestreamobject) | no | [imageStream object](#imagestreamobject) object |
| includeResources | array of [includeResources](#includeResources) | no |


Expand Down Expand Up @@ -314,6 +317,18 @@ secrets:
| array of [secret](#secret) | no | [secret](#secret) object |



## imageStreams

```yaml
imageStreams:
- <imageStreamObject>
```

| Type | Required | Description |
|----------------------------------|--------------|------|
| array of [imageStream Object](#imagestreamobject) | no | [imageStream Object](#imagestreamobject) object |

## includeResources

```yaml
Expand Down Expand Up @@ -869,6 +884,56 @@ secrets:
Anything [EnvVarSource Spec](https://kubernetes.io/docs/api-reference/v1.8/#envvarsource-v1-core) from Kubernetes can be included within the Kedge file.


## imageStreamObject

```yaml
imageStreams:
- <imageStreamObject>
```

> Example

```yaml
name: rubyapp
imageStreams:
- name: rubystream
dockerImageRepository: "docker.io/openshift/ruby-20-centos7"
```

<aside class="notice">
Each "imageStreamObject" is an OpenShift <a target="_blank" href="https://docs.openshift.org/latest/rest_api/apis-image.openshift.io/v1.ImageStream.html#object-schema">ImageStream Spec</a> with additional Kedge-specific keys.
</aside>


| Type | Required | Description |
|----------------------------------|--------------|------|
| name | string | yes | The name of the ImageStream |


### name

```yaml
name: wordpress
```

| Type | Required | Description |
|----------|--------------|-------|
| string | yes | The name of the ImageStream |

### OpenShift extension

> Example extending `imageStreams` with OpenShift ImageStream Spec

```yaml
name: webapp
imageStreams:
- tags:
- from:
kind: DockerImage
name: centos/httpd-24-centos7:latest
name: "2.4"
```

## includeResources

```yaml
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func CreateArtifacts(paths []string, generate bool, args ...string) error {
for _, runtimeObject := range ros {
switch runtimeObject.GetObjectKind().GroupVersionKind().Kind {
// If there is at least one OpenShift resource use oc
case "DeploymentConfig", "Route":
case "DeploymentConfig", "Route", "ImageStream":
useOC = true
break
}
Expand Down
48 changes: 48 additions & 0 deletions pkg/spec/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strings"

log "github.com/Sirupsen/logrus"
image_v1 "github.com/openshift/origin/pkg/image/apis/image/v1"
os_route_v1 "github.com/openshift/origin/pkg/route/apis/route/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api_v1 "k8s.io/kubernetes/pkg/api/v1"
Expand Down Expand Up @@ -125,6 +126,26 @@ func fixSecrets(secrets []SecretMod, appName string) ([]SecretMod, error) {
return secrets, nil
}

func fixImageStreams(imageStreams []ImageStreamSpecMod, appName string) ([]ImageStreamSpecMod, error) {

// auto populate name only if one ImageStream is specified without any name
if len(imageStreams) == 1 && imageStreams[0].Name == "" {
imageStreams[0].ObjectMeta.Name = appName
}

for i, is := range imageStreams {
if is.Name == "" {
return nil, fmt.Errorf("please specify name for app.imageStreams[%d]", i)
}

is.ObjectMeta.Labels = addKeyValueToMap(appLabelKey, appName, is.ObjectMeta.Labels)

// this should be the last statement in this for loop
imageStreams[i] = is
}
return imageStreams, nil
}

func fixIngresses(ingresses []IngressSpecMod, appName string) ([]IngressSpecMod, error) {

// auto populate name only if one ingress is specified without any name
Expand Down Expand Up @@ -217,6 +238,12 @@ func (cf *ControllerFields) fixControllerFields() error {
return errors.Wrap(err, "unable to fix secrets")
}

// fix imageStreams
cf.ImageStreams, err = fixImageStreams(cf.ImageStreams, cf.Name)
if err != nil {
return errors.Wrap(err, "unable to fix imageStreams")
}

// fix ingresses
cf.Ingresses, err = fixIngresses(cf.Ingresses, cf.Name)
if err != nil {
Expand Down Expand Up @@ -400,6 +427,19 @@ func (app *ControllerFields) createSecrets() ([]runtime.Object, error) {
return secrets, nil
}

func (app *ControllerFields) createImageStreams() ([]runtime.Object, error) {
var imageStreams []runtime.Object

for _, is := range app.ImageStreams {
imageStream := &image_v1.ImageStream{
ObjectMeta: is.ObjectMeta,
Spec: is.ImageStreamSpec,
}
imageStreams = append(imageStreams, imageStream)
}
return imageStreams, nil
}

// CreateK8sObjects, if given object DeploymentSpecMod, this function reads
// them and returns kubernetes objects as list of runtime.Object
// If the deployment is using field 'includeResources' then it will
Expand Down Expand Up @@ -431,6 +471,11 @@ func (app *ControllerFields) CreateK8sObjects() ([]runtime.Object, []string, err
return nil, nil, errors.Wrap(err, "Unable to create Kubernetes Secrets")
}

iss, err := app.createImageStreams()
if err != nil {
return nil, nil, errors.Wrap(err, "unable to create OpenShift ImageStreams")
}

app.PodSpec.Containers, err = populateContainers(app.Containers, app.ConfigMaps, app.Secrets)
if err != nil {
return nil, nil, errors.Wrapf(err, "deployment %q", app.Name)
Expand Down Expand Up @@ -486,6 +531,9 @@ func (app *ControllerFields) CreateK8sObjects() ([]runtime.Object, []string, err
objects = append(objects, secs...)
log.Debugf("app: %s, secret: %s\n", app.Name, spew.Sprint(secs))

objects = append(objects, iss...)
log.Debugf("app: %s, imageStreams: %s\n", app.Name, spew.Sprint(iss))

objects = append(objects, configMap...)
log.Debugf("app: %s, configMap: %s\n", app.Name, spew.Sprint(configMap))

Expand Down
Loading

0 comments on commit 4ccf7ea

Please sign in to comment.