Skip to content
This repository was archived by the owner on Dec 17, 2024. It is now read-only.

Commit ac624ea

Browse files
committed
add support for --native actions
Fixes #871
1 parent ec12908 commit ac624ea

File tree

6 files changed

+166
-11
lines changed

6 files changed

+166
-11
lines changed

app/content/js/ui.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,14 +1417,28 @@ const ui = (function() {
14171417
const code = sidecar.querySelector('.action-content .action-source')
14181418

14191419
if (entity.exec.kind === 'blackbox') {
1420-
// show the image name
1421-
const clicky = document.createElement('a')
1422-
clicky.className = 'clickable clickable-blatant'
1423-
code.appendChild(document.createTextNode('dockerhub image: '))
1424-
code.appendChild(clicky)
1425-
clicky.innerText = entity.exec.image
1426-
clicky.setAttribute('href', `https://hub.docker.com/r/${entity.exec.image}`)
1427-
clicky.setAttribute('target', '_blank')
1420+
if (entity.exec.image) {
1421+
if (entity.exec.code) {
1422+
// then this is a dockerskeleton
1423+
// that attaches some code; we can
1424+
// show the code
1425+
code.appendChild(document.createTextNode(entity.exec.code))
1426+
hljs.highlightBlock(code)
1427+
1428+
} else {
1429+
// otherwise, just show the image name
1430+
const clicky = document.createElement('a')
1431+
clicky.className = 'clickable clickable-blatant'
1432+
code.appendChild(document.createTextNode('dockerhub image: '))
1433+
code.appendChild(clicky)
1434+
clicky.innerText = entity.exec.image
1435+
clicky.setAttribute('href', `https://hub.docker.com/r/${entity.exec.image}`)
1436+
clicky.setAttribute('target', '_blank')
1437+
}
1438+
} else {
1439+
// ?? not sure what this case is; blackbox without an image name?
1440+
code.appendChild(document.createTextNode('blackbox action'))
1441+
}
14281442

14291443
} else if (entity.exec.code) {
14301444
//

app/plugins/ui/commands/openwhisk-core.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ const synonymsFn = (type,T) => synonyms[T || 'entities'][type].concat([type]) //
152152

153153
const booleans = {
154154
actions: {
155-
create: ['sequence', 'docker', 'copy', 'web']
155+
create: ['sequence', 'docker', 'native', 'copy', 'web']
156156
}
157157
}
158158
booleans.actions.update = booleans.actions.create
@@ -568,7 +568,7 @@ specials.actions = {
568568
// for action create, or update and the user gave a
569569
// positional param... find the input file
570570
if (options.docker) {
571-
// blackbox action!
571+
// blackbox action
572572
options.action.exec.kind = 'blackbox'
573573
options.action.exec.image = argv[0]
574574

@@ -594,6 +594,12 @@ specials.actions = {
594594
options.action.annotations.push({ key: 'binary', value: true })
595595
}
596596

597+
if (options.native) {
598+
// native code blackbox action
599+
options.action.exec.kind = 'blackbox'
600+
options.action.exec.image = 'openwhisk/dockerskeleton'
601+
}
602+
597603
eventBus.emit('/action/update', { file: filepath, action: { name: options.name, namespace: options.namespace } })
598604

599605
// set the default kind

app/plugins/ui/commands/openwhisk-usage.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ const actionMix = params.concat(annotations).concat(limits).concat([
8484
{ name: '--kind', allowed: ['nodejs', 'python', 'swift', 'php'], allowedIsPrefixMatch: true, defaultValue: 'nodejs', docs: 'the action runtime' },
8585
{ name: '--sequence', boolean: true, example: 'a1,a2,a3', docs: 'create a sequence of the given actions' },
8686
{ name: '--copy', boolean: true, advanced: true, docs: 'copy the action named by the second parameter to a new action named by the first' },
87-
{ name: '--docker', boolean: true, docs: 'create a blackbox action from a dockerhub image' },
87+
{ name: '--docker', boolean: true, docs: 'use a dockerhub image for the action' },
88+
{ name: '--native', boolean: true, docs: 'use a shell script or Linux binary for the action' },
8889
{ name: '--web', boolean: true, docs: 'web export the action' },
8990
{ name: '--content-type', hidden: true }
9091
])

tests/data/flip.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
# install jq if it does not exist
4+
if [ ! -f /usr/bin/jq ]; then
5+
apk update && apk add jq
6+
fi
7+
8+
# determine number of flips
9+
N=`echo "$@" | jq '."n"'`
10+
11+
# total count of heads and tails
12+
HEADS=0
13+
TAILS=0
14+
15+
for i in `seq 1 $N`; do
16+
echo -n "flipping coin..."
17+
if [ $(( RANDOM % 2 )) == 0 ]; then
18+
echo "HEADS"; HEADS=$(( HEADS + 1 ))
19+
else
20+
echo "TAILS"; TAILS=$(( TAILS + 1 ))
21+
fi
22+
done
23+
24+
echo "{\"trials\": $N, \"heads\": $HEADS, \"tails\": $TAILS}"

tests/lib/ui.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ exports.sidecar = {
198198
.then(actualSource => assert.equal(actualSource.replace(/\s+/g, ''), expectedSource.replace(/\s+/g, '')))
199199
.then(() => app),
200200

201+
expectResult: expectedResult => app => app.client.getText(selectors.SIDECAR_ACTIVATION_RESULT)
202+
.then(exports.expectStruct(expectedResult))
203+
.then(() => app),
204+
205+
expectResultSubset: expectedResult => app => app.client.getText(selectors.SIDECAR_ACTIVATION_RESULT)
206+
.then(exports.expectSubset(expectedResult))
207+
.then(() => app),
208+
201209
expectBadge: badge => app => app.client.waitUntil(() => app.client.getText(selectors.SIDECAR_BADGES)
202210
.then(badges => badges.indexOf(badge) >= 0))
203211
.then(() => app),
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2018 IBM Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const common = require('../../../lib/common'),
18+
openwhisk = require('../../../lib/openwhisk'),
19+
ui = require('../../../lib/ui'),
20+
fs = require('fs'),
21+
assert = require('assert'),
22+
keys = ui.keys,
23+
cli = ui.cli,
24+
sidecar = ui.sidecar,
25+
flip = 'flip'
26+
27+
const removeWhitespace = txt => txt.replace(/\s/g, '')
28+
29+
describe('blackbox actions from a shell script', function() {
30+
before(common.before(this))
31+
after(common.after(this))
32+
33+
it('should have an active repl', () => cli.waitForRepl(this.app))
34+
35+
const expectedFlipSource = removeWhitespace(fs.readFileSync('./data/flip.sh').toString())
36+
37+
it('should create a blackbox action', () => cli.do(`wsk action create --native ${flip} ./data/flip.sh`, this.app)
38+
.then(cli.expectOK)
39+
.then(sidecar.expectOpen)
40+
.then(sidecar.expectShowing(flip))
41+
.then(() => this.app.client.getText(ui.selectors.SIDECAR_ACTION_SOURCE))
42+
.then(removeWhitespace)
43+
.then(txt => assert.equal(txt, expectedFlipSource))
44+
.catch(common.oops(this)))
45+
46+
const N1 = 3
47+
it(`should invoke the native action with implicit entity`, () => cli.do(`invoke -p n ${N1}`, this.app)
48+
.then(cli.expectOK)
49+
.then(sidecar.expectOpen)
50+
.then(sidecar.expectShowing(flip))
51+
.then(sidecar.expectResultSubset({
52+
trials: N1
53+
}))
54+
.catch(common.oops(this)))
55+
56+
const N2 = 4
57+
it(`should invoke (again) the native action with implicit entity`, () => cli.do(`invoke -p n ${N2}`, this.app)
58+
.then(cli.expectOK)
59+
.then(sidecar.expectOpen)
60+
.then(sidecar.expectShowing(flip))
61+
.then(sidecar.expectResultSubset({
62+
trials: N2
63+
}))
64+
.catch(common.oops(this)))
65+
66+
it('should update a blackbox action variant 1', () => cli.do(`wsk action update --native ${flip} ./data/flip.sh`, this.app)
67+
.then(cli.expectOK)
68+
.then(sidecar.expectOpen)
69+
.then(sidecar.expectShowing(flip))
70+
.then(() => this.app.client.getText(ui.selectors.SIDECAR_ACTION_SOURCE))
71+
.then(removeWhitespace)
72+
.then(txt => assert.equal(txt, expectedFlipSource))
73+
.catch(common.oops(this)))
74+
75+
it('should update a blackbox action variant 2', () => cli.do(`wsk action update ${flip} --native ./data/flip.sh`, this.app)
76+
.then(cli.expectOK)
77+
.then(sidecar.expectOpen)
78+
.then(sidecar.expectShowing(flip))
79+
.then(() => this.app.client.getText(ui.selectors.SIDECAR_ACTION_SOURCE))
80+
.then(removeWhitespace)
81+
.then(txt => assert.equal(txt, expectedFlipSource))
82+
.catch(common.oops(this)))
83+
84+
it('should update a blackbox action variant 3', () => cli.do(`wsk action update ${flip} ./data/flip.sh --native`, this.app)
85+
.then(cli.expectOK)
86+
.then(sidecar.expectOpen)
87+
.then(sidecar.expectShowing(flip))
88+
.then(() => this.app.client.getText(ui.selectors.SIDECAR_ACTION_SOURCE))
89+
.then(removeWhitespace)
90+
.then(txt => assert.equal(txt, expectedFlipSource))
91+
.catch(common.oops(this)))
92+
93+
const N3 = 5
94+
it(`should invoke (again) the native action, now with explicit`, () => cli.do(`invoke ${flip} -p n ${N3}`, this.app)
95+
.then(cli.expectOK)
96+
.then(sidecar.expectOpen)
97+
.then(sidecar.expectShowing(flip))
98+
.then(sidecar.expectResultSubset({
99+
trials: N3
100+
}))
101+
.catch(common.oops(this)))
102+
})

0 commit comments

Comments
 (0)