Skip to content

Commit

Permalink
[#27] Support ImageStream
Browse files Browse the repository at this point in the history
Add Spec.ApplicationSourceSpec to build the application image from a
Git repository using WildFly S2I images

Make Spec.ApplicationImage optional as the definition of
ApplicationSourceSpec allows an alternative.

Create ImageStream and BuildConfig resources to handle S2I builds

Use image.openshift.io/triggers annotation to trigger statefulset
update when the image stream changes

When a runtime image must be used, set
GALLEON_PROVISION_DEFAULT_FAT_SERVER to true only when
GALLEON_PROVISION_LAYERS is not defined.

ApplicationSourceSpec's GitHubWebHookSecret and GenericWebHookSecret
references secrets in the same namespace than the WildFlyServer resource.
These secrets must have a key named WebHookSecretKey whose value is used
to create the WebHook URL. If they are omitted from the spec, the
operator will automatically generate respective secrets.

Update references to WildFly 19 S2I Images

Signed-off-by: Jeff Mesnil <jmesnil@redhat.com>
  • Loading branch information
jmesnil committed Apr 6, 2020
1 parent bb6a09b commit 217ebbc
Show file tree
Hide file tree
Showing 109 changed files with 37,779 additions and 619 deletions.
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ $ kubectl apply -f deploy/crds/wildfly_v1alpha1_wildflyserver_crd.yaml
$ kubectl create -f deploy/operator.yaml
----

### Install a custom resource
### Install a custom resource from an existing Docker Image

An example of a custom resource of `WildFlyServer` is described in https://github.com/wildfly/wildfly-operator/blob/master/deploy/crds/quickstart-cr.yaml[quickstart-cr.yaml]:
An example of a custom resource of `WildFlyServer` is described in https://github.com/wildfly/wildfly-operator/blob/master/deploy/crds/quickstart-image.yaml[quickstart-image.yaml]:

[source,yaml]
----
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: wildfly.org/v1alpha1
kind: WildFlyServer
metadata:
name: quickstart
name: quickstart-image
spec:
applicationImage: "quay.io/wildfly-quickstarts/wildfly-operator-quickstart:18.0"
replicas: 2
replicas: 1
23 changes: 23 additions & 0 deletions deploy/crds/quickstart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: wildfly.org/v1alpha1
kind: WildFlyServer
metadata:
name: quickstart
spec:
applicationSource:
# The application will be built from the Web application at
# https://github.com/wildfly/quickstart/tree/19.0.0.Final/helloworld-rs
sourceRepository:
url: "https://github.com/wildfly/quickstart.git"
ref: "19.0.0.Final"
source2Image:
builderImage: "wildfly-centos7:19.0"
runtimeImage: "wildfly-runtime-centos7:19.0"
env:
# cloud-server provision a WildFly server that can runs JAX-RS application
- name: GALLEON_PROVISION_LAYERS
value: "cloud-server"
- name: MAVEN_ARGS
value: "install -pl org.wildfly.quickstarts:helloworld-rs -am "
- name: ARTIFACT_DIR
value: "helloworld-rs/target"
replicas: 1
168 changes: 167 additions & 1 deletion deploy/crds/wildfly.org_wildflyservers_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,173 @@ spec:
description: ApplicationImage is the name of the application image to
be deployed
type: string
applicationSource:
description: ApplicationSource contains the specification to build the
image from source code
properties:
source2Image:
description: Source2ImageSpec defines which S2I builder and runtime
images to use to build the application image
properties:
builderImage:
description: Image Stream Tag of the builder image
type: string
env:
description: Env contains environment variables for the containers
building the application image from the SourceRepository
items:
description: EnvVar represents an environment variable present
in a Container.
properties:
name:
description: Name of the environment variable. Must be
a C_IDENTIFIER.
type: string
value:
description: 'Variable references $(VAR_NAME) are expanded
using the previous defined environment variables in
the container and any service environment variables.
If a variable cannot be resolved, the reference in the
input string will be unchanged. The $(VAR_NAME) syntax
can be escaped with a double $$, ie: $$(VAR_NAME). Escaped
references will never be expanded, regardless of whether
the variable exists or not. Defaults to "".'
type: string
valueFrom:
description: Source for the environment variable's value.
Cannot be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
description: 'Name of the referent. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind,
uid?'
type: string
optional:
description: Specify whether the ConfigMap or
it's key must be defined
type: boolean
required:
- key
type: object
fieldRef:
description: 'Selects a field of the pod: supports
metadata.name, metadata.namespace, metadata.labels,
metadata.annotations, spec.nodeName, spec.serviceAccountName,
status.hostIP, status.podIP.'
properties:
apiVersion:
description: Version of the schema the FieldPath
is written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the
specified API version.
type: string
required:
- fieldPath
type: object
resourceFieldRef:
description: 'Selects a resource of the container:
only resources limits and requests (limits.cpu,
limits.memory, limits.ephemeral-storage, requests.cpu,
requests.memory and requests.ephemeral-storage)
are currently supported.'
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
description: Specifies the output format of the
exposed resources, defaults to "1"
type: string
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
secretKeyRef:
description: Selects a key of a secret in the pod's
namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind,
uid?'
type: string
optional:
description: Specify whether the Secret or it's
key must be defined
type: boolean
required:
- key
type: object
type: object
required:
- name
type: object
minItems: 1
type: array
namespace:
description: Namespace where the builder (and potentially runtime)
images streams are defined. If omitted, the "openshift" namespace
is used
type: string
runtimeImage:
description: Image Stream Tag of the runtime image. If omitted,
the application image will be built directly from the builder
image.
type: string
required:
- builderImage
type: object
sourceRepository:
description: SourceRepositorySpec defines the Git repository of
the application source code
properties:
contextDir:
description: Sub-directory where the source code for the application
exists
type: string
genericWebHookSecret:
description: Secret for Generic WebHook. This references a Secret
in the same namespace which has a key named WebHookSecretKey
whose value is supplied when invoking the webhook. If omitted,
a secret will be automatically generated.
type: string
gitHubWebHookSecret:
description: Secret for GitHub WebHook. This references a Secret
in the same namespace which has a key named WebHookSecretKey
whose value is supplied when invoking the webhook. If omitted,
a secret will be automatically generated.
type: string
ref:
description: Reference in the Git repository (can be a branch,
a tag or a SHA-1 checksum)
type: string
url:
description: URL of the Git repository
type: string
required:
- url
type: object
required:
- source2Image
- sourceRepository
type: object
configMaps:
description: ConfigMaps is a list of ConfigMaps in the same namespace
as the WildFlyServer object, which shall be mounted into the WildFlyServer
Expand Down Expand Up @@ -454,7 +621,6 @@ spec:
type: object
type: object
required:
- applicationImage
- replicas
type: object
status:
Expand Down
12 changes: 12 additions & 0 deletions deploy/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,15 @@ rules:
- routes
verbs:
- "*"
- apiGroups:
- image.openshift.io
resources:
- imagestreams
verbs:
- "*"
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
verbs:
- "*"
50 changes: 49 additions & 1 deletion doc/apis.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ It uses a `StatefulSet` with a pod spec that mounts the volume specified by `sto
[options="header,footer"]
|=======================
| Field | Description |Scheme| Required
| `applicationImage` | Name of the application image to be deployed | string | true
| `applicationImage` | Name of the application image to be deployed | string | false (if `applicationSource` is defined)
| `applicationSource` | spec to define the source of the application (OpenShift-only) | *<<applicationsourcespec>> | false (if `applicationImage` is defined)
| `replicas` | Replicas is the desired number of replicas for the application | int32 | true
| `standaloneConfigMap` | spec to specify how standalone configuration can be read from a `ConfigMap` | *<<standaloneconfigmapspec>> |false
| `storage` | Storage spec to specify how storage should be used. If omitted, an `EmptyDir` is used (that will not persist data across pod restart) | *<<storagespec>> |false
Expand All @@ -52,6 +53,53 @@ It uses a `StatefulSet` with a pod spec that mounts the volume specified by `sto
| `sessionAffinity`| If connections from the same client IP are passed to the same WildFlyServer instance/pod each time (false if omitted) | bool | false
|=======================
[[applicationsourcespec]]
## `ApplicationSourceSpec`
WARNING: Building the application from its source requires to run on OpenShift.
It uses https://github.com/wildfly/wildfly-s2i[WildFly Source-to-Image (S2I)] to create the application image from the source code
The Operator will configure OpenShift resources such as `ImageStream` and `BuildConfig` in order to build the application image.
[options="header,footer"]
|=======================
| Field | Description |Scheme| Required
| `sourceRepository` | The Git repository containing the code source of the application | *<<sourcerepositoryspec>> | true
| `source2Image` | Settings for the Source-to-Image (S2I) images used to build the application image | *<<source2imagespec>> | true
|=======================
[[sourcerepositoryspec]]
## `SourceRepositorySpec`
`SourceRepositorySpec` defines the Git repository containing the source code of the application.
[options="header,footer"]
|=======================
| Field | Description |Scheme| Required
| `url` | URL of the Git repository hosting the application code | string | true
| `ref` | Reference in the Git repository (can be a branch, a tag or a SHA-1 checksum) | string | false
| `contextDir` | Sub-directory where the source code for the application exists | string | false
| `gitHubWebHookSecret` | Secret for GitHub WebHook. This references a Secret in the same namespace which has a key named `WebHookSecretKey` whose value is supplied when invoking the webhook. If omitted, a secret will be automatically generated | string | false
| `genericWebHookSecret` | Secret for Generic WebHook. This references a Secret in the same namespace which has a key named `WebHookSecretKey` whose value is supplied when invoking the webhook. If omitted, a secret will be automatically generated | string | false
|=======================
[[source2imagespec]]
## `Source2ImageSpec`
`Source2ImagSpec` defines the specification to use Source-to-Image (S2I) to build the application image.
|=======================
| Field | Description | Scheme | Required
| `builderImage` | The image stream tag for the S2I Builder image | string | true
| `runtimeImage` | The image stream tag for the S2I Runtime image. If omitted, the application image is built directly from the S2I Builder image | string | false
| `namespace` | The namespace where the image streams for the S2I Builder and Runtime images are defined. If omitted, the Operator will use the `openshift` namespace | string| false
| `env` | List of environment variables used to build the application | []https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#envvar-v1-core[corev1.EnvVar] | false
|=======================
The `env` array can be used to configure the application building. These environment variables are passed to the `BuildConfig` resources and will be processed during the `S2I` build process. They will not be available in the application image
[[storagespec]]
## `StorageSpec`
Expand Down
66 changes: 66 additions & 0 deletions doc/user-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,72 @@ The `applicationImage` accepts different references to Docker image:
* a tag: `quay.io/wildfly-quickstarts/wildfly-operator-quickstart:18.0`
* a digest: `quay.io/wildfly-quickstarts/wildfly-operator-quickstart@sha256:0af38bc38be93116b6a1d86a9c78bd14cd527121970899d719baf78e5dc7bfd2`
[[source-repository]]
## Specify the Application Source

The WildFly Operator can also take as input the source code of the application and use https://github.com/openshift/source-to-image[OpenShift Source-to-Image (S2I)] to build the Java applications and create a Docker image from it.

[IMPORTANT]
====
This feature is available on OpenShift only.
It relies on OpenShift-specific resources such as `BuildConfig` and `ImageStreams` that are not available on a plain Kubernetes cluster.
====

[source,yaml]
.Example of application source configuration
----
apiVersion: wildfly.org/v1alpha1
kind: WildFlyServer
metadata:
name: quickstart
spec:
applicationSource:
# The application will be built from the Web application at
# https://github.com/wildfly/quickstart/tree/19.0.0.Final/helloworld-rs
sourceRepository:
url: "https://github.com/wildfly/quickstart.git"
ref: "19.0.0.Final"
source2Image:
builderImage: "wildfly-centos7:19.0"
runtimeImage: "wildfly-runtime-centos7:19.0"
env:
# cloud-server provision a WildFly server that can runs JAX-RS application
- name: GALLEON_PROVISION_LAYERS
value: "cloud-server"
- name: MAVEN_ARGS
value: "install -pl org.wildfly.quickstarts:helloworld-rs -am "
- name: ARTIFACT_DIR
value: "helloworld-rs/target"
replicas: 1
----

The application will be built from the project at https://github.com/wildfly/quickstart/tree/19.0.0.Final/helloworld-rs (`ref` corresponds to the branch or tag to checkout). The Git repository at https://github.com/wildfly/quickstart contains many Java application but we only want to build and run one of them from the module
`helloworld-rs`. We provide the `MAVEN_ARGS`and `ARTIFACT_DIR` environment variables to S2I to build only this Web application.

[NOTE]
====
To build the application image, the WildFly S2I images must be installed in the OpenShift cluster before the WildFly Operator deploys the application.
As an example, to install the WildFly 19 S2I images in the `openshift` cluster, you can run the commands:
[source,shell]
----
$ oc import-image wildfly/wildfly-centos7:19.0 --from=quay.io/wildfly/wildfly-centos7:19.0 -n openshift --confirm
$ oc import-image wildfly/wildfly-runtime-centos7:19.0 --from=quay.io/wildfly/wildfly-runtime-centos7:19.0 -n openshift --confirm
----
====

Once the application image is build and deployed, the Operator will install it on the OpenShift cluster and create a Route for it.
The application can then be accessed with:

[source,shell]
----
# you can check the route of the application with the command: oc get wfly/quickstart -o jsonpath='{.status.hosts[0]}'
$ curl $(oc get wfly/quickstart -o jsonpath='{.status.hosts[0]}')/helloworld-rs/rest/json
{"result":"Hello World!"}
----

[[size]]
## Specify the Size of the Application

Expand Down

0 comments on commit 217ebbc

Please sign in to comment.