Skip to content

Commit 96e3339

Browse files
committed
Python Container Definition
1 parent ce6dcbc commit 96e3339

File tree

14 files changed

+447
-1
lines changed

14 files changed

+447
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,5 @@ ENV/
9999

100100
# mypy
101101
.mypy_cache/
102+
103+
.gradle/**

.travis.yml

Whitespace-only changes.

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,35 @@
1-
# runtime-python3
1+
# local development
2+
```
3+
./gradlew python3:distDocker
4+
docker login
5+
./gradlew python3:distDocker -PdockerImagePrefix=<YourDockerId> -PdockerRegistry=docker.io
6+
cd $OPENWHISK_HOME
7+
bin/wskdev teardown -t <currentEnvironmentName>
8+
cd ansible/environments/
9+
ln -s /path/to/runtime-python3/ansible/environments/local ./local-ibm-py
10+
cd ..
11+
ansible-playbook -i environments/local-ibm-py setup.yml
12+
ansible-playbook -i environments/local-ibm-py couchdb.yml -e mode=clean
13+
ansible-playbook -i environments/local-ibm-py couchdb.yml
14+
ansible-playbook -i environments/local-ibm-py initdb.yml
15+
ansible-playbook -i environments/local-ibm-py wipe.yml
16+
cd $OPENWHISK_HOME
17+
./gradlew distDocker
18+
cd ansible
19+
ansible-playbook -i environments/local-ibm-py openwhisk.yml -e mode=clean
20+
ansible-playbook -i environments/local-ibm-py openwhisk.yml
21+
ansible-playbook -i environments/local-ibm-py postdeploy.yml
22+
23+
```
24+
25+
Create a python action and put it in file `test.py`:
26+
```
27+
def main(args):
28+
return {"message":"Successfully called Simple Python Action"}
29+
```
30+
31+
Run:
32+
```
33+
wsk -i action create test test.py --kind "python-ibm:3"
34+
wsk -i action invoke test -b
35+
```
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
whisk_version_name: local
2+
config_root_dir: /tmp
3+
whisk_logs_dir: /tmp/wsklogs
4+
docker_registry: ""
5+
docker_dns: ""
6+
7+
db_prefix: whisk_local_
8+
9+
# Auto lookup to find the db credentials
10+
db_provider: "{{ lookup('ini', 'db_provider section=db_creds file={{ playbook_dir }}/db_local.ini') }}"
11+
db_username: "{{ lookup('ini', 'db_username section=db_creds file={{ playbook_dir }}/db_local.ini') }}"
12+
db_password: "{{ lookup('ini', 'db_password section=db_creds file={{ playbook_dir }}/db_local.ini') }}"
13+
db_protocol: "{{ lookup('ini', 'db_protocol section=db_creds file={{ playbook_dir }}/db_local.ini') }}"
14+
db_host: "{{ lookup('ini', 'db_host section=db_creds file={{ playbook_dir }}/db_local.ini') }}"
15+
db_port: "{{ lookup('ini', 'db_port section=db_creds file={{ playbook_dir }}/db_local.ini') }}"
16+
17+
# API GW connection configuration
18+
apigw_auth_user: ""
19+
apigw_auth_pwd: ""
20+
apigw_host_v2: "http://{{ groups['apigateway']|first }}:{{apigateway.port.api}}/v2"
21+
22+
controller_arguments: '-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=1098'
23+
invoker_arguments: "{{ controller_arguments }}"
24+
25+
invoker_allow_multiple_instances: true
26+
27+
runtimes_manifest:
28+
defaultImagePrefix: "openwhisk"
29+
defaultImageTag: "latest"
30+
runtimes:
31+
nodejs:
32+
- kind: "nodejs:6"
33+
default: true
34+
image:
35+
name: "nodejs6action"
36+
deprecated: false
37+
python:
38+
- kind: "python"
39+
image:
40+
name: "python2action"
41+
deprecated: false
42+
- kind: "python:2"
43+
default: true
44+
image:
45+
name: "python2action"
46+
deprecated: false
47+
- kind: "python:3"
48+
image:
49+
name: "python3action"
50+
deprecated: false
51+
- kind: "python-ibm:3"
52+
default: false
53+
image:
54+
name: "action-python-ibm-3"
55+
deprecated: false
56+
blackboxes:
57+
- name: "dockerskeleton"

ansible/environments/local/hosts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; the first parameter in a host is the inventory_hostname
2+
3+
; used for local actions only
4+
ansible ansible_connection=local
5+
6+
[edge]
7+
172.17.0.1 ansible_host=172.17.0.1 ansible_connection=local
8+
9+
[controllers]
10+
controller0 ansible_host=172.17.0.1 ansible_connection=local
11+
12+
[kafka]
13+
172.17.0.1 ansible_host=172.17.0.1 ansible_connection=local
14+
15+
[invokers]
16+
invoker0 ansible_host=172.17.0.1 ansible_connection=local
17+
18+
; db group is only used if db_provider is CouchDB
19+
[db]
20+
172.17.0.1 ansible_host=172.17.0.1 ansible_connection=local
21+
22+
[redis]
23+
172.17.0.1 ansible_host=172.17.0.1 ansible_connection=local
24+
25+
[apigateway]
26+
172.17.0.1 ansible_host=172.17.0.1 ansible_connection=local

build.gradle

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
buildscript {
2+
repositories {
3+
jcenter()
4+
}
5+
dependencies {
6+
classpath "cz.alenkacz:gradle-scalafmt:${gradle.scalafmt.version}"
7+
}
8+
}
9+
10+
subprojects {
11+
apply plugin: 'scalafmt'
12+
scalafmt.configFilePath = gradle.scalafmt.config
13+
}

gradle/docker.gradle

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import groovy.time.*
2+
3+
/**
4+
* Utility to build docker images based in gradle projects
5+
*
6+
* This extends gradle's 'application' plugin logic with a 'distDocker' task which builds
7+
* a docker image from the Dockerfile of the project that applies this file. The image
8+
* is automatically tagged and pushed if a tag and/or a registry is given.
9+
*
10+
* Parameters that can be set on project level:
11+
* - dockerImageName (required): The name of the image to build (e.g. controller)
12+
* - dockerRegistry (optional): The registry to push to
13+
* - dockerImageTag (optional, default 'latest'): The tag for the image
14+
* - dockerImagePrefix (optional, default 'whisk'): The prefix for the image,
15+
* 'controller' becomes 'whisk/controller' per default
16+
* - dockerTimeout (optional, default 840): Timeout for docker operations in seconds
17+
* - dockerRetries (optional, default 3): How many times to retry docker operations
18+
* - dockerBinary (optional, default 'docker'): The binary to execute docker commands
19+
* - dockerBuildArgs (options, default ''): Project specific custom docker build arguments
20+
* - dockerHost (optional): The docker host to run commands on, default behaviour is
21+
* docker's own DOCKER_HOST environment variable
22+
*/
23+
24+
ext {
25+
dockerRegistry = project.hasProperty('dockerRegistry') ? dockerRegistry + '/' : ''
26+
dockerImageTag = project.hasProperty('dockerImageTag') ? dockerImageTag : 'latest'
27+
dockerImagePrefix = project.hasProperty('dockerImagePrefix') ? dockerImagePrefix : 'whisk'
28+
dockerTimeout = project.hasProperty('dockerTimeout') ? dockerTimeout.toInteger() : 840
29+
dockerRetries = project.hasProperty('dockerRetries') ? dockerRetries.toInteger() : 3
30+
dockerBinary = project.hasProperty('dockerBinary') ? [dockerBinary] : ['docker']
31+
dockerBuildArg = ['build']
32+
}
33+
ext.dockerTaggedImageName = dockerRegistry + dockerImagePrefix + '/' + dockerImageName + ':' + dockerImageTag
34+
35+
if(project.hasProperty('dockerHost')) {
36+
dockerBinary += ['--host', project.dockerHost]
37+
}
38+
39+
if(project.hasProperty('dockerBuildArgs')) {
40+
dockerBuildArgs.each { arg ->
41+
dockerBuildArg += ['--build-arg', arg]
42+
}
43+
}
44+
45+
task distDocker {
46+
doLast {
47+
def start = new Date()
48+
def cmd = dockerBinary + dockerBuildArg + ['-t', dockerImageName, project.buildscript.sourceFile.getParentFile().getAbsolutePath()]
49+
retry(cmd, dockerRetries, dockerTimeout)
50+
println("Building '${dockerImageName}' took ${TimeCategory.minus(new Date(), start)}")
51+
}
52+
}
53+
task tagImage {
54+
doLast {
55+
def versionString = (dockerBinary + ['-v']).execute().text
56+
def matched = (versionString =~ /(\d+)\.(\d+)\.(\d+)/)
57+
58+
def major = matched[0][1] as int
59+
def minor = matched[0][2] as int
60+
61+
def dockerCmd = ['tag']
62+
if(major == 1 && minor < 12) {
63+
dockerCmd += ['-f']
64+
}
65+
retry(dockerBinary + dockerCmd + [dockerImageName, dockerTaggedImageName], dockerRetries, dockerTimeout)
66+
}
67+
}
68+
69+
task pushImage {
70+
doLast {
71+
def cmd = dockerBinary + ['push', dockerTaggedImageName]
72+
retry(cmd, dockerRetries, dockerTimeout)
73+
}
74+
}
75+
pushImage.dependsOn tagImage
76+
pushImage.onlyIf { dockerRegistry != '' }
77+
distDocker.finalizedBy pushImage
78+
79+
def retry(cmd, retries, timeout) {
80+
println("${new Date()}: Executing '${cmd.join(" ")}'")
81+
def proc = cmd.execute()
82+
proc.consumeProcessOutput(System.out, System.err)
83+
proc.waitForOrKill(timeout * 1000)
84+
if(proc.exitValue() != 0) {
85+
def message = "${new Date()}: Command '${cmd.join(" ")}' failed with exitCode ${proc.exitValue()}"
86+
if(proc.exitValue() == 143) { // 143 means the process was killed (SIGTERM signal)
87+
message = "${new Date()}: Command '${cmd.join(" ")}' was killed after ${timeout} seconds"
88+
}
89+
90+
if(retries > 1) {
91+
println("${message}, ${retries-1} retries left, retrying...")
92+
retry(cmd, retries-1, timeout)
93+
}
94+
else {
95+
println("${message}, no more retries left, aborting...")
96+
throw new GradleException(message)
97+
}
98+
}
99+
}

gradle/wrapper/gradle-wrapper.jar

53.4 KB
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
zipStoreBase=GRADLE_USER_HOME
4+
zipStorePath=wrapper/dists
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip

0 commit comments

Comments
 (0)