
Cet article poursuit la série de notes traduites sur OpenWhisk par Priti Desai . Aujourd'hui, nous examinerons des exemples de déploiement de fonctions Zip, de dépendances GitHub, et décrirons également plus en détail la synchronisation des objets entre le client et le serveur OpenWhisk.
Fonctions Zip
OpenWhisk prend en charge la création de fonctions à partir d'un seul fichier source, comme cela a été [montré précédemment] (). Il prend également en charge la création d'une fonction à l'aide de plusieurs fichiers avec le code source et un ensemble de packages dont dépend la fonction. Ce cas d'utilisation des fonctions est appelé fonction zip. Essayons de déployer une fonction zip à l'aide de wskdeploy
.
Première étape
Créez un fichier manifeste:
packages: zipaction: actions: my-zip-action: function: actions/my-zip-action runtime: nodejs:6 inputs: name: Amy
Nous pensons que my-zip-action
a une telle structure de répertoires qui contient le code source de la fonction:
$ ls actions/my-zip-action index.js package.json
Le contenu du fichier 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;
Le contenu du fichier 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" } }
Deuxième étape
Exécutez npm install pour installer le format de chaîne:
cd actions/my-action npm install --production
Étape trois
Développez la fonction zip:
./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.
Nous avons déployé la fonction zip my-zip-action avec le string-format
module dépendant. Lorsque vous spécifiez un répertoire dans le manifeste avec la clé de function
, une archive zip est créée à partir de ce répertoire, ainsi qu'une fonction à partir de cette archive, vous n'avez donc pas besoin de la rechercher dans le système de fichiers. Après le déploiement, vous pouvez travailler avec la nouvelle fonction de la même manière qu'avec les autres fonctions.
Inclure et exclure des fichiers dans les fonctions zip
OpenWhisk vous permet de créer une fonction à l'aide d'une archive zip contenant un nombre illimité de fichiers pour la fonction, y compris toutes ses dépendances. Le déploiement prend en charge la spécification dans la function
répertoire avec des fichiers pour que la fonction fonctionne. Une archive sera créée à partir du contenu du répertoire, à partir de laquelle la fonction sera déjà déployée.
Inclusion de fichiers
Auparavant, il était possible de spécifier une clé d' include
, qui fonctionne de la même manière que l' import
dans les langages de programmation, ce qui permettait, par exemple, à plusieurs fonctions de référencer la même bibliothèque avec du code:
$ 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
Vous pouvez voir le fichier index.js
dans le répertoire de index.js
, ainsi qu'un autre index.js
dans le répertoire de utils.js
, et les deux se réfèrent à utils.js
situé dans common/
.
Le contenu du fichier index.js situé dans 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;
Le contenu du fichier index.js situé dans 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;
La clé d' include
contient une liste de fichiers ou de répertoires qui doivent être inclus dans la fonction. Chaque élément de cette liste doit avoir une source
et / ou une destination
, par exemple:
include: - [source] - [source, destination]
Remarques:
source
contient le chemin relatif du répertoire contenant manimanifest.yaml
. destination
implique le chemin relatif du répertoire de fonctions, par exemple actions/greeting1
et actions/greeting2
dans l'exemple suivant.- Si la
destination
pas spécifiée, on considère qu'elle sera identique à la source
.
Le contenu du fichier manifeste:
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
œuvres avec diverses combinaisons de source
et de destination
:
include: - [actions/common/utils.js]
Avec cette entrée, utils.js
sera copié dans actions/greeting/actions/common/utils.js
, et index.js
peut s'y référer comme ceci:
var utils = require('./actions/common/utils.js')
include: - ["actions/common/utils.js", "./common/myUtils.js"]
Avec cette définition, utils.js
sera placé le long du chemin actions/greeting/common/myUtils.js
, et index.js
s'y référera comme ceci:
var utils = require('./common/myUtils.js')
include
d'une autre manière:
include: - ["actions/common/utils.js", "./common/utility/utils.js"]
Dans ce cas, utils.js
sera copié dans actions/greeting/common/utility/utils.js
, avec un lien depuis index.js
:
var utils = require('./common/utility/utils.js')
include
avec le symbole *
:
include: - ["actions/common/*.js", "./common/"]
Dans cette version, utils.js
ainsi que d'autres fichiers avec l'extension .js
seront copiés dans le répertoire actions/greeting/common/
, et dans index.js
ces fichiers seront connectés comme ceci:
var utils = require('./common/utils.js')
Inclusion d'annuaire
Dans include
vous pouvez spécifier un répertoire qui sera copié récursivement à l'emplacement spécifié avant d'être inclus dans l'archive. Par exemple, libs`` ,
index.js
-
libs`` ,
accueil3 / `` '':
$ 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
Le contenu de index.js dans le répertoire 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;
Le contenu du fichier manifeste:
packages: zipactionwithinclude: actions: greeting3: function: actions/greeting3 runtime: nodejs:6 include: - ["actions/libs/*", "libs/"]
Dans cet exemple, le répertoire libs
est entièrement récursivement copié dans actions/greeting3/libs/
.
Connexion des répertoires avec le symbole *
:
include: - ["actions/libs/*/utils.js", "libs/"]
Avec cette écriture, tous les sous-répertoires contenant utils.js
seront copiés à partir des libs
. Les liens depuis index.js
ressembleront à ceci:
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"]
Avec cette entrée, tous les sous-répertoires correspondant au masque et contenant utils.js
seront copiés. L'accès depuis index.js
sera comme ceci:
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/"]
Cet exemple indique explicitement où tout sera copié. L'accès à partir de index.js
sera le même que dans l'exemple précédent.
Exception
Le mot-clé exclude
peut être utilisé comme une liste de fichiers et de répertoires, il est autorisé d'utiliser un masque sous la forme d'un caractère *
. Exemple d'utilisation:
exclude: - actions/common/*.js - actions/libs/*/utils.js
Un exemple courant de partage include
et 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"]
Fonctions avec les dépendances GitHub
OpenWhisk prend en charge les dépendances, vous pouvez donc décrire les autres packages OpenWhisk dont dépend notre projet. Avec ces dépendances, OpenWhisk déploiera également automatiquement les packages dépendants. Tout package avec manifest.yaml
et \ ou deployment.yaml
peut être considéré comme un package dépendant, qui peut être spécifié dans le manifeste de notre projet. Vous pouvez décrire une telle dépendance dans le manifeste dans la section des 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
Dans cet exemple, helloworlds
est un package externe hébergé sur le référentiel GitHub à https://github.com/apache/incubator-openwhisk-test . Le package helloworlds
sera déployé en fonction de ses fichiers à déployer dans le packages/helloworlds
lorsque vous déploierez notre projet RootProject
. Il est également possible de changer le nom du package dépendant, par exemple, au lieu de helloworlds
définissez 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
Vous pouvez ajouter plusieurs dépendances à plusieurs packages:
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
Comment fonctionne la synchronisation des projets OpenWhisk entre le client et le serveur
Pour répondre, vous devez démarrer le déploiement en mode de managed deployment
. Dans ce mode, OpenWhisk déploie tous les objets du manifeste et attache également une description cachée à chacun d'eux, le soi-disant managed
. Cette description ressemble à ceci:
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
Ici, OpenWhisk est une chaîne constante et "\ 0" est le caractère NULL. size_of_manifest_file et contents_of_manifest_file dépendent du fichier. La séquence de déploiement du même projet en mode de managed deployment
calcule un nouveau __OW_PROJECT_HASH
sur le client pour chaque objet et le compare avec l'objet __OW_PROJECT_HASH
du même projet sur le serveur. Il existe plusieurs options ci-dessous.
Option 1 : si __OW_PROJECT_HASH
correspond sur le client et le serveur, c'est-à-dire s'il n'y a aucune modification du projet côté client, le projet sur le serveur reste tel quel, sauf pour le déploiement via wskdeploy
nouveaux objets à partir du manifeste pour recevoir les modifications dans le fichier deployment.yaml
.
Option 2 : si __OW_PROJECT_HASH
ne correspond pas, c'est-à-dire s'il y a des changements côté client, wskdeploy
déploie tous les objets du manifeste, puis les met à jour __OW_PROJECT_HASH
sur le serveur. wskdeploy
également tous les objets: y compris les fonctions, les séquences et les __OW_PROJECT_NAME
conditionnelles qui ont le même __OW_PROJECT_NAME
, c'est-à-dire appartenant au même projet mais ayant un __OW_PROJECT_HASH
différent, car ils pourraient être supprimés du manifeste sur le client. Le nom du projet dans le manifeste est requis pour synchroniser le projet entre le client et le serveur:
project: name: MyProjectName packages: package1: ....
Les objets d'OpenWhisk qui font partie du projet mais qui sont déployés à l'aide d'autres outils ou outils d'automatisation restent inchangés lorsqu'ils sont supprimés du projet. Ils sont considérés comme des objets externes et ne sont donc pas remplacés. Vous pouvez wskdeploy
un tel projet à l'aide de wskdeploy
, en le dirigeant vers le fichier manifeste, qui contient uniquement le nom du projet:
project: name: MyProjectName
Examinons un exemple de projet pour comprendre le managed deployment
. Dans ce référentiel, vous pouvez voir le projet avec divers manifestes qui montrent le managed deployment
.
Première étape
Déployez MyFirstManagedProject
utilisant le mode de managed deployment
:
$wskdeploy -m tests/src/integration/managed-deployment/manifest.yaml --managed Deployment completed successfully.

Liste des objets déployés sur un serveur OpenWhisk

Description de la propriété
Deuxième étape
Nous synchronisons le client et le serveur - nous supprimons ManagedPackage-2:
./wskdeploy -m tests/src/integration/managed-deployment/00-manifest-minus-second-package.yaml --managed Deployment completed successfully.

Liste des objets après suppression dans MyFirstManagedProject
Étape trois
Nous synchronisons le client et le serveur - nous supprimons la séquence ManagedSequence-2:
./wskdeploy -m tests/src/integration/managed-deployment/01-manifest-minus-sequence-2.yaml --managed Deployment completed successfully.

Liste des objets après suppression
Quatrième étape
Supprimez la fonction Helloworld-3:
./wskdeploy -m tests/src/integration/managed-deployment/02-manifest-minus-action-3.yaml --managed Deployment completed successfully.

Liste des objets après suppression
Cinquième étape
Supprimer ManagedPackage-1:
./wskdeploy -m tests/src/integration/managed-deployment/04-manifest-minus-package.yaml --managed Deployment completed successfully.

Autres objets dans MyFirstManagedProject
Autres articles de cycle
Informatique sans serveur basée sur OpenWhisk, partie 1
Informatique sans serveur basée sur OpenWhisk, partie 2
Informatique sans serveur basée sur OpenWhisk, partie 3
Informatique sans serveur basée sur OpenWhisk, partie 4