
Dieser Artikel setzt die Reihe der übersetzten Notizen zu OpenWhisk von Priti Desai fort . Heute werden Beispiele für die Bereitstellung von Zip-Funktionen und GitHub-Abhängigkeiten vorgestellt und die Synchronisation von Objekten zwischen dem Client und dem OpenWhisk-Server ausführlicher beschrieben.
Zip-Funktionen
OpenWhisk unterstützt das Erstellen von Funktionen aus einer einzelnen Quelldatei, wie es [früher gezeigt] war (). Es unterstützt auch die Erstellung einer Funktion unter Verwendung mehrerer Dateien mit Quellcode und einer Reihe von Paketen, von denen die Funktion abhängt. Dieser Anwendungsfall für Funktionen wird als Zip-Funktion bezeichnet. Versuchen wir, eine Zip-Funktion mit wskdeploy
.
Erster Schritt
Erstellen Sie eine Manifestdatei:
packages: zipaction: actions: my-zip-action: function: actions/my-zip-action runtime: nodejs:6 inputs: name: Amy
Wir glauben, dass my-zip-action
eine solche Verzeichnisstruktur hat, die den Quellcode der Funktion enthält:
$ ls actions/my-zip-action index.js package.json
Der Inhalt der Datei index.js :
function helloworld(params) { var format = require('string-format'); var name = params.name || 'Stranger'; payload = format('Hello, {}!', name) return { message: payload }; } exports.main = helloworld;
Der Inhalt der Datei package.json :
{ "name": "my-zip-action", "description": "Node OpenWhisk zip action to demo Whisk Deploy", "license": "Apache-2.0", "version": "1.0.0", "main": "index.js", "dependencies": { "string-format": "0.5.0" } }
Zweiter Schritt
Führen Sie npm install aus, um das Zeichenfolgenformat zu installieren:
cd actions/my-action npm install --production
Schritt drei
Erweitern Sie die Zip-Funktion:
./wskdeploy -i -p actions/my-zip-action/ ____ ___ _ _ _ _ _ /\ \ / _ \ _ __ ___ _ __ | | | | |__ (_)___| | __ /\ /__\ \ | | | | '_ \ / _ \ '_ \| | | | '_ \| / __| |/ / / \____ \ / | |_| | |_) | __/ | | | |/\| | | | | \__ \ < \ \ / \/ \___/| .__/ \___|_| |_|__/\__|_| |_|_|___/_|\_\ \___\/ |_| Packages: Name: zipaction bindings: * action: my-zip-action bindings: - name: name value: Amy Do you really want to deploy this? (y/N): y Deployment completed successfully.
Wir haben die zip-Funktion my-zip-action mit dem abhängigen Modul string-format
implementiert. Wenn Sie mit der function
ein Verzeichnis im Manifest angeben, wird ein Zip-Archiv aus diesem Verzeichnis und auch eine Funktion aus diesem Archiv erstellt, sodass Sie nicht im Dateisystem danach suchen müssen. Nach der Bereitstellung können Sie mit der neuen Funktion wie mit anderen Funktionen arbeiten.
Ein- und Ausschließen von Dateien in Zip-Funktionen
Mit OpenWhisk können Sie eine Funktion mithilfe eines ZIP-Archivs erstellen, das eine beliebige Anzahl von Dateien für die Funktion enthält, einschließlich all ihre Süchte. Die Bereitstellung unterstützt die Angabe function
Verzeichnisses mit Dateien in der Funktion, damit die Funktion funktioniert. Aus dem Inhalt des Verzeichnisses, aus dem die Funktion bereits bereitgestellt wird, wird ein Archiv erstellt.
Datei einbinden
Bisher war es möglich, einen include
Schlüssel anzugeben, der ähnlich funktioniert wie der import
in Programmiersprachen. So konnten beispielsweise mehrere Funktionen mit Code auf dieselbe Bibliothek verweisen:
$ cd actions/ $ ls -1 ./ common/ greeting1/ greeting2/ manifest.yaml $ ls -1 common/ utils.js $ ls -1 greeting1/ index.js package.json $ ls -1 greeting2/ index.js package.json
Sie können die Datei index.js
im Verzeichnis greeting1
sowie eine weitere index.js
im Verzeichnis greeting2
Beide verweisen auf utils.js
in common/
.
Der Inhalt der Datei index.js in actions/greeting1/
:
/** * Return a simple greeting message for someone. * * @param name A person's name. * @param place Where the person is from. */ var common = require('./common/utils.js') function main(params) { var name = params.name || params.payload || 'stranger'; var place = params.place || 'somewhere'; var hello = common.hello || 'Good Morning'; return {payload: hello + ', ' + name + ' from ' + place + '!'}; } exports.main = main;
Der Inhalt der Datei index.js in actions/greeting2/
:
/** * Return a simple greeting message for someone. * * @param name A person's name. * @param place Where the person is from. */ var common = require('./common/utils.js') function main(params) { var name = params.name || params.payload || 'stranger'; var place = params.place || 'somewhere'; var hello = common.hello || 'Good Evening'; return {payload: hello + ', ' + name + ' from ' + place + '!'}; } exports.main = main;
Innerhalb des include
Schlüssels befindet sich eine Liste von Dateien oder Verzeichnissen, die in die Funktion aufgenommen werden sollen. Jedes Element dieser Liste muss eine source
und / oder ein destination
, zum Beispiel:
include: - [source] - [source, destination]
Anmerkungen:
source
enthält den relativen Pfad aus dem Verzeichnis, das manimanifest.yaml
. destination
impliziert den relativen Pfad aus dem Funktionsverzeichnis, z. B. actions/greeting1
und actions/greeting2
im folgenden Beispiel.- Wenn kein
destination
angegeben wird, wird davon ausgegangen, dass es sich um die gleiche source
.
Der Inhalt der Manifestdatei:
packages: zipactionwithinclude: actions: greeting1: function: actions/greeting1 runtime: nodejs:6 include: - ["actions/common/utils.js", "common/utils.js"] greeting2: function: actions/greeting2 runtime: nodejs:6 include: - ["actions/common/utils.js", "common/utils.js"]
include
arbeitet mit verschiedenen Kombinationen von source
und destination
:
include: - [actions/common/utils.js]
Mit diesem Eintrag wird utils.js
nach actions/greeting/actions/common/utils.js
, und index.js
kann folgendermaßen darauf verweisen:
var utils = require('./actions/common/utils.js')
include
Umbenennen mit einbeziehen:
include: - ["actions/common/utils.js", "./common/myUtils.js"]
Mit dieser Definition wird utils.js
entlang des Pfads actions/greeting/common/myUtils.js
, und index.js
verweist folgendermaßen darauf:
var utils = require('./common/myUtils.js')
- auf andere Weise
include
:
include: - ["actions/common/utils.js", "./common/utility/utils.js"]
In diesem Fall wird utils.js
mit einem Link von index.js
nach actions/greeting/common/utility/utils.js
index.js
:
var utils = require('./common/utility/utils.js')
include: - ["actions/common/*.js", "./common/"]
In dieser Version werden utils.js
und andere Dateien mit der Erweiterung .js
in das Verzeichnis actions/greeting/common/
kopiert. In index.js
diese Dateien folgendermaßen verbunden:
var utils = require('./common/utils.js')
Verzeichniseinschluss
In include
Sie ein Verzeichnis angeben, das rekursiv an den angegebenen Speicherort kopiert wird, bevor es in das Archiv aufgenommen wird. Beispielsweise libs`` ,
,,, libs`` ,
index.js
greeting3 / `` 'verweist:
$ cd actions/ $ ls -1 libs/ greeting3/ manifest.yaml $ ls -1 libs/ lib1/ lib2/ lib3/ $ ls -1 libs/lib1/ utils.js $ ls -1 libs/lib2/ utils.js $ ls -1 libs/lib3/ utils.js $ ls -1 greeting3/ index.js package.json
Der Inhalt von index.js im Verzeichnis actions/greeting3/
:
/** * Return a simple greeting message for someone. * * @param name A person's name. * @param place Where the person is from. */ var lib1 = require('./libs/lib1/utils.js') var lib2 = require('./libs/lib2/utils.js') var lib3 = require('./libs/lib3/utils.js') function main(params) { var name = params.name || params.payload || 'stranger'; var place = params.place || 'somewhere'; var hello = lib1.hello || lib2.hello || lib3.hello || 'Hello'; return {payload: hello + ', ' + name + ' from ' + place + '!'}; } exports.main = main;
Der Inhalt der Manifestdatei:
packages: zipactionwithinclude: actions: greeting3: function: actions/greeting3 runtime: nodejs:6 include: - ["actions/libs/*", "libs/"]
In diesem Beispiel wird das Verzeichnis libs
vollständig rekursiv nach actions/greeting3/libs/
kopiert.
Verzeichnisse mit dem Symbol *
:
include: - ["actions/libs/*/utils.js", "libs/"]
Mit diesem Schreiben werden alle Unterverzeichnisse, die utils.js
enthalten, aus libs
kopiert. Links von index.js
sehen folgendermaßen aus:
var lib1 = require('./libs/lib1/utils.js') var lib2 = require('./libs/lib2/utils.js') var lib3 = require('./libs/lib3/utils.js')
include: - ["actions/*/*/utils.js"]
Mit diesem Eintrag werden alle Unterverzeichnisse kopiert, die der Maske entsprechen und utils.js
enthalten. Der Zugriff von index.js
folgendermaßen aus:
var lib1 = require('./actions/libs/lib1/utils.js') var lib2 = require('./actions/libs/lib2/utils.js') var lib3 = require('./actions/libs/lib3/utils.js')
include: - ["actions/*/*/utils.js", "actions/"]
In diesem Beispiel wird explizit angegeben, wo alles kopiert wird. Der Zugriff über index.js
erfolgt wie im vorherigen Beispiel.
Ausnahme
Das Schlüsselwort exclude
kann als Liste von Dateien und Verzeichnissen verwendet werden. Es ist zulässig, eine Maske in Form eines *
-Zeichens zu verwenden. Anwendungsbeispiel:
exclude: - actions/common/*.js - actions/libs/*/utils.js
Ein häufiges Beispiel für das Teilen von Inhalten und exclude
:
packages: zipactionwithexclude: actions: greeting1: function: actions runtime: nodejs:6 exclude: - actions/* include: - ["actions/common/utils.js", "common/utils.js"] - ["actions/index.js", "index.js"] - ["actions/package.json", "package.json"]
Funktioniert mit GitHub-Abhängigkeiten
OpenWhisk unterstützt Abhängigkeiten, sodass Sie die anderen OpenWhisk-Pakete beschreiben können, von denen unser Projekt abhängt. Mit diesen Abhängigkeiten stellt OpenWhisk automatisch auch abhängige Pakete bereit. Jedes Paket mit manifest.yaml
und \ oder deployment.yaml
kann als abhängiges Paket betrachtet werden, das im Manifest unseres Projekts angegeben werden kann. Sie können eine solche Abhängigkeit im Manifest im Abschnitt dependencies
:
packages: RootProject: dependencies: helloworlds: location: github.com/apache/incubator-openwhisk-test/packages/helloworlds triggers: trigger1: trigger2: rules: rule1: trigger: trigger1 action: helloworlds/hello-js rule2: trigger: trigger2 action: helloworlds/helloworld-js
In diesem Beispiel ist helloworlds
ein externes Paket, das im GitHub-Repository unter https://github.com/apache/incubator-openwhisk-test gehostet wird. Das helloworlds
Paket wird basierend auf seinen Dateien für die Bereitstellung im packages/helloworlds
- wenn Sie unser RootProject
Projekt RootProject
. Es ist auch möglich, den Namen des abhängigen Pakets zu helloworlds
Setzen ChildProject
beispielsweise anstelle von helloworlds
ChildProject
:
packages: RootProject: dependencies: ChildProject: location: github.com/apache/incubator-openwhisk-test/packages/helloworlds triggers: trigger1: trigger2: rules: rule1: trigger: trigger1 action: ChildProject/hello-js rule2: trigger: trigger2 action: ChildProject/helloworld-js
Sie können mehreren Paketen mehrere Abhängigkeiten hinzufügen:
packages: RootProject: dependencies: ChildProject1: location: github.com/apache/incubator-openwhisk-test/packages/helloworlds ChildProject2: location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk sequences: ChildProject1-series: actions: ChildProject1/hello-js, ChildProject1/helloworld-js ChildProject2-series: actions: ChildProject2/greeting, ChildProject2/httpGet triggers: trigger1: trigger2: rules: rule1: trigger: trigger1 action: ChildProject1-series rule2: trigger: trigger2 action: ChildProject2-series
Wie funktioniert die Synchronisation von OpenWhisk-Projekten zwischen Client und Server?
Um zu antworten, müssen Sie die Bereitstellung im managed deployment
starten. In diesem Modus stellt OpenWhisk alle Objekte aus dem Manifest bereit und fügt jedem eine versteckte Beschreibung hinzu, die so genannte managed
. Diese Beschreibung sieht folgendermaßen aus:
managed: __OW_PROJECT_NAME: MyProjectName __OW_PROJECT_HASH: SHA1("OpenWhisk " + <size_of_manifest_file> + "\0" + <contents_of_manifest_file>) __OW_FILE: Absolute path of manifest file on file system
Hier ist OpenWhisk eine konstante Zeichenfolge und "\ 0" ist das Nullzeichen. Größe_der_Manifestdatei und Inhalt_der_Manifestdatei sind dateiabhängig . Die Bereitstellungssequenz desselben Projekts im managed deployment
berechnet für jedes Objekt ein neues __OW_PROJECT_HASH
auf dem Client und vergleicht es mit dem __OW_PROJECT_HASH
Objekt aus demselben Projekt auf dem Server. Es gibt mehrere Optionen unten.
Option 1 : Wenn __OW_PROJECT_HASH
auf dem Client und dem Server __OW_PROJECT_HASH
, d. H. Wenn auf der Clientseite keine Änderungen am Projekt vorgenommen wurden, bleibt das Projekt auf dem Server unverändert, mit Ausnahme der Bereitstellung über wskdeploy
neuer Objekte aus dem Manifest, um Änderungen in der Datei deployment.yaml
zu erhalten.
Option 2 : Wenn __OW_PROJECT_HASH
nicht übereinstimmt, d. H. Wenn sich auf der Clientseite Änderungen ergeben, stellt wskdeploy
alle Objekte aus dem Manifest __OW_PROJECT_HASH
und aktualisiert sie dann __OW_PROJECT_HASH
auf dem Server. wskdeploy
auch wskdeploy
allen Objekten: einschließlich Funktionen, Sequenzen und bedingten __OW_PROJECT_NAME
, die denselben __OW_PROJECT_NAME
, d. H. Sie gehören zum selben Projekt, haben jedoch ein anderes __OW_PROJECT_HASH
, da sie auf dem Client aus dem Manifest entfernt werden könnten. Der Projektname im Manifest ist erforderlich, um das Projekt zwischen Client und Server zu synchronisieren:
project: name: MyProjectName packages: package1: ....
Objekte in OpenWhisk, die Teil des Projekts sind, aber mithilfe anderer Tools oder Automatisierungstools bereitgestellt werden, bleiben unverändert, wenn sie aus dem Projekt entfernt werden. Sie gelten als externe Objekte und werden daher nicht überschrieben. Sie können ein solches Projekt mit wskdeploy
und es in die Manifestdatei leiten, die nur den Projektnamen enthält:
project: name: MyProjectName
Schauen wir uns ein Beispielprojekt an, um die managed deployment
zu verstehen. In diesem Repository sehen Sie das Projekt mit verschiedenen Manifesten, die die managed deployment
.
Erster Schritt
MyFirstManagedProject
managed deployment
Bereitstellungsmodus MyFirstManagedProject
:
$wskdeploy -m tests/src/integration/managed-deployment/manifest.yaml --managed Deployment completed successfully.

Liste der auf einem OpenWhisk-Server bereitgestellten Objekte

Eigenschaft Beschreibung
Zweiter Schritt
Wir synchronisieren den Client und den Server - wir löschen ManagedPackage-2:
./wskdeploy -m tests/src/integration/managed-deployment/00-manifest-minus-second-package.yaml --managed Deployment completed successfully.

Liste der Objekte nach dem Löschen in MyFirstManagedProject
Schritt drei
Wir synchronisieren den Client und den Server - wir löschen die Sequenz ManagedSequence-2:
./wskdeploy -m tests/src/integration/managed-deployment/01-manifest-minus-sequence-2.yaml --managed Deployment completed successfully.

Liste der Objekte nach dem Löschen
Vierter Schritt
Löschen Sie die Helloworld-3-Funktion:
./wskdeploy -m tests/src/integration/managed-deployment/02-manifest-minus-action-3.yaml --managed Deployment completed successfully.

Liste der Objekte nach dem Löschen
Fünfter Schritt
ManagedPackage-1 löschen:
./wskdeploy -m tests/src/integration/managed-deployment/04-manifest-minus-package.yaml --managed Deployment completed successfully.

Andere Objekte in MyFirstManagedProject
Andere Fahrradartikel
Serverloses Rechnen basierend auf OpenWhisk, Teil 1
Serverloses Rechnen basierend auf OpenWhisk, Teil 2
Serverloses Rechnen basierend auf OpenWhisk, Teil 3
Serverloses Rechnen basierend auf OpenWhisk, Teil 4