Informatique sans serveur basée sur OpenWhisk, partie 3


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 :


  • juste source :

 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 avec renommer:

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


  • exemple 1:

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

  • exemple 2:

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

  • exemple 3:

 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

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


All Articles