Serverloses Rechnen basierend auf OpenWhisk, Teil 3


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 :


  • nur source :

 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') 

  • mit dem Symbol * :

 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 * :


  • Beispiel 1:

 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') 

  • Beispiel 2:

 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') 

  • Beispiel 3:

 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

Source: https://habr.com/ru/post/de479492/


All Articles