HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-19
1 Эта статья продолжает цикл переводных заметок об OpenWhisk от автора <a>Priti Desai</a>. Сегодня рассмотрим примеры развертывания Zip-функций, зависимости GitHub, а также подробнее опишем синхронизацию объектов между клиентом и сервером OpenWhisk.<h2>Zip-функции</h2>
1 Эта статья продолжает цикл переводных заметок об OpenWhisk от автора <a>Priti Desai</a>. Сегодня рассмотрим примеры развертывания Zip-функций, зависимости GitHub, а также подробнее опишем синхронизацию объектов между клиентом и сервером OpenWhisk.<h2>Zip-функции</h2>
2 OpenWhisk поддерживает создание функции из единственного файла с исходным кодом, как это было [показано ранее](). Он же поддерживает создание функции с использованием нескольких файлов с исходным кодом и набором пакетов, от которых функция зависит. Этот вариант использования функций называется zip-функцией. Давайте попробуем развернуть zip-функцию с помощью wskdeploy.<h3>Шаг первый</h3>
2 OpenWhisk поддерживает создание функции из единственного файла с исходным кодом, как это было [показано ранее](). Он же поддерживает создание функции с использованием нескольких файлов с исходным кодом и набором пакетов, от которых функция зависит. Этот вариант использования функций называется zip-функцией. Давайте попробуем развернуть zip-функцию с помощью wskdeploy.<h3>Шаг первый</h3>
3 Создаем файл-манифест:<blockquote><em>packages:</em></blockquote><blockquote><em> zipaction:</em></blockquote><blockquote><em> actions:</em></blockquote><blockquote><em> my-zip-action:</em></blockquote><blockquote><em> function: actions/my-zip-action</em></blockquote><blockquote><em> runtime: nodejs:6</em></blockquote><blockquote><em> inputs:</em></blockquote><blockquote><em> name: Amy</em></blockquote>Считаем, что my-zip-action имеет такую структуру каталога, содержащую исходный код функции:<blockquote><em>$ ls actions/my-zip-action</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote>Содержимое файла <strong>index.js</strong>:<blockquote><em>function helloworld(params) {</em></blockquote><blockquote><em> var format = require('string-format');</em></blockquote><blockquote><em> var name = params.name || 'Stranger';</em></blockquote><blockquote><em> payload = format('Hello, {}!', name)</em></blockquote><blockquote><em> return { message: payload };</em></blockquote><blockquote><em>}</em></blockquote><blockquote><em>exports.main = helloworld;</em></blockquote>Содержимое файла <strong>package.json</strong>:<blockquote><em>{</em></blockquote><blockquote><em> </em><em>"</em><em>name": "my-zip-action",</em></blockquote><blockquote><em> "description": "Node OpenWhisk zip action to demo Whisk Deploy",</em></blockquote><blockquote><em> "license": "Apache-2.0",</em></blockquote><blockquote><em> "version": "1.0.0",</em></blockquote><blockquote><em> "main": "index.js",</em></blockquote><blockquote><em> "dependencies": {</em></blockquote><blockquote><em> "string-format": "0.5.0"</em></blockquote><blockquote><em> }</em></blockquote><blockquote><em>}</em></blockquote><h3>Шаг второй</h3>
3 Создаем файл-манифест:<blockquote><em>packages:</em></blockquote><blockquote><em> zipaction:</em></blockquote><blockquote><em> actions:</em></blockquote><blockquote><em> my-zip-action:</em></blockquote><blockquote><em> function: actions/my-zip-action</em></blockquote><blockquote><em> runtime: nodejs:6</em></blockquote><blockquote><em> inputs:</em></blockquote><blockquote><em> name: Amy</em></blockquote>Считаем, что my-zip-action имеет такую структуру каталога, содержащую исходный код функции:<blockquote><em>$ ls actions/my-zip-action</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote>Содержимое файла <strong>index.js</strong>:<blockquote><em>function helloworld(params) {</em></blockquote><blockquote><em> var format = require('string-format');</em></blockquote><blockquote><em> var name = params.name || 'Stranger';</em></blockquote><blockquote><em> payload = format('Hello, {}!', name)</em></blockquote><blockquote><em> return { message: payload };</em></blockquote><blockquote><em>}</em></blockquote><blockquote><em>exports.main = helloworld;</em></blockquote>Содержимое файла <strong>package.json</strong>:<blockquote><em>{</em></blockquote><blockquote><em> </em><em>"</em><em>name": "my-zip-action",</em></blockquote><blockquote><em> "description": "Node OpenWhisk zip action to demo Whisk Deploy",</em></blockquote><blockquote><em> "license": "Apache-2.0",</em></blockquote><blockquote><em> "version": "1.0.0",</em></blockquote><blockquote><em> "main": "index.js",</em></blockquote><blockquote><em> "dependencies": {</em></blockquote><blockquote><em> "string-format": "0.5.0"</em></blockquote><blockquote><em> }</em></blockquote><blockquote><em>}</em></blockquote><h3>Шаг второй</h3>
4 Запускаем npm install для установки string-format:<blockquote><em>cd actions/my-action</em></blockquote><blockquote><em>npm install --production</em></blockquote><h3>Шаг третий</h3>
4 Запускаем npm install для установки string-format:<blockquote><em>cd actions/my-action</em></blockquote><blockquote><em>npm install --production</em></blockquote><h3>Шаг третий</h3>
5 Разворачиваем zip-функцию:<a>Скопировать код</a><p>Мы развернули zip-функцию <strong>my-zip-action</strong> с зависимым модулем string-format. При указании каталога в манифесте по ключу function создается zip-архив из этого каталога, а также - функция из этого архива, так что не надо искать его по файловой системе. После развертывания можно работать с новой функцией точно так же, как и с другими функциями.</p>
5 Разворачиваем zip-функцию:<a>Скопировать код</a><p>Мы развернули zip-функцию <strong>my-zip-action</strong> с зависимым модулем string-format. При указании каталога в манифесте по ключу function создается zip-архив из этого каталога, а также - функция из этого архива, так что не надо искать его по файловой системе. После развертывания можно работать с новой функцией точно так же, как и с другими функциями.</p>
6 <h2>Include и exclude для файлов в zip-функциях</h2>
6 <h2>Include и exclude для файлов в zip-функциях</h2>
7 OpenWhisk позволяет создавать функцию с использованием zip-архива, содержащего любое количество файлов для функции, в т.ч. все ее зависимости. Развертывание поддерживает указание в function каталога с файлами для работы функции. Из содержимого каталога будет создан архив, из которого уже будет развернута функция.<h3>Включение файлов</h3>
7 OpenWhisk позволяет создавать функцию с использованием zip-архива, содержащего любое количество файлов для функции, в т.ч. все ее зависимости. Развертывание поддерживает указание в function каталога с файлами для работы функции. Из содержимого каталога будет создан архив, из которого уже будет развернута функция.<h3>Включение файлов</h3>
8 Ранее была представлена возможность указать ключ include, работающий примерно так же, как import в языках программирования, что позволило, к примеру, нескольким функциям ссылаться на одну общую библиотеку с кодом:<blockquote><em>$ cd actions/</em></blockquote><blockquote><em>$ ls -1 ./</em></blockquote><blockquote><em>common/</em></blockquote><blockquote><em>greeting1/</em></blockquote><blockquote><em>greeting2/</em></blockquote><blockquote><em>manifest.yaml</em></blockquote><blockquote><em>$ ls -1 common/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 greeting1/</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote><blockquote><em>$ ls -1 greeting2/</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote>Можно видеть файл index.js в каталоге greeting1, а также еще один index.js в каталоге greeting2, и оба ссылаются на utils.js, расположенный в common/.<p>Содержимое файла index.js, расположенного в actions/greeting1/:</p>
8 Ранее была представлена возможность указать ключ include, работающий примерно так же, как import в языках программирования, что позволило, к примеру, нескольким функциям ссылаться на одну общую библиотеку с кодом:<blockquote><em>$ cd actions/</em></blockquote><blockquote><em>$ ls -1 ./</em></blockquote><blockquote><em>common/</em></blockquote><blockquote><em>greeting1/</em></blockquote><blockquote><em>greeting2/</em></blockquote><blockquote><em>manifest.yaml</em></blockquote><blockquote><em>$ ls -1 common/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 greeting1/</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote><blockquote><em>$ ls -1 greeting2/</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote>Можно видеть файл index.js в каталоге greeting1, а также еще один index.js в каталоге greeting2, и оба ссылаются на utils.js, расположенный в common/.<p>Содержимое файла index.js, расположенного в actions/greeting1/:</p>
9 <a>Скопировать код</a><p>Содержимое файла index.js, расположенного в actions/greeting2/:</p>
9 <a>Скопировать код</a><p>Содержимое файла index.js, расположенного в actions/greeting2/:</p>
10 <a>Скопировать код</a><p>Внутри ключа include содержится список файлов или каталогов, которые должны быть включены в функцию. Каждый элемент этого списка должен иметь source и\или destination, к примеру:</p>
10 <a>Скопировать код</a><p>Внутри ключа include содержится список файлов или каталогов, которые должны быть включены в функцию. Каждый элемент этого списка должен иметь source и\или destination, к примеру:</p>
11 <blockquote><em>include:</em></blockquote><blockquote><em> - [source]</em></blockquote><blockquote><em> - [source, destination]</em></blockquote>Примечания:<ul><li>source содержит относительный путь от каталога, содержащего manimanifest.yaml. destination подразумевает относительный путь от каталога с функцией, к примеру actions/greeting1 и actions/greeting2 в следующем примере.</li>
11 <blockquote><em>include:</em></blockquote><blockquote><em> - [source]</em></blockquote><blockquote><em> - [source, destination]</em></blockquote>Примечания:<ul><li>source содержит относительный путь от каталога, содержащего manimanifest.yaml. destination подразумевает относительный путь от каталога с функцией, к примеру actions/greeting1 и actions/greeting2 в следующем примере.</li>
12 <li>Если параметр destination не задается - считается что он будет такой же, как и source.</li>
12 <li>Если параметр destination не задается - считается что он будет такой же, как и source.</li>
13 </ul>Содержимое файла-манифеста:<a>Скопировать код</a><p>include работает с различными сочетаниями source и destination:</p>
13 </ul>Содержимое файла-манифеста:<a>Скопировать код</a><p>include работает с различными сочетаниями source и destination:</p>
14 <ul><li>просто source:</li>
14 <ul><li>просто source:</li>
15 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - [actions/common/utils.js]</em></blockquote>При такой записи utils.js будет скопирован в actions/greeting/actions/common/utils.js, а index.js может сослаться на него так:<blockquote><em>var utils = require('./actions/common/utils.js')</em></blockquote><ul><li>include с переименованием:</li>
15 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - [actions/common/utils.js]</em></blockquote>При такой записи utils.js будет скопирован в actions/greeting/actions/common/utils.js, а index.js может сослаться на него так:<blockquote><em>var utils = require('./actions/common/utils.js')</em></blockquote><ul><li>include с переименованием:</li>
16 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/common/utils.js", "./common/myUtils.js"]</em></blockquote>С таким определением utils.js будет помещен по пути actions/greeting/common/myUtils.js, а index.js будет ссылаться на него так:<blockquote><em>var utils = require('./common/myUtils.js')</em></blockquote><ul><li>include с другим путём:</li>
16 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/common/utils.js", "./common/myUtils.js"]</em></blockquote>С таким определением utils.js будет помещен по пути actions/greeting/common/myUtils.js, а index.js будет ссылаться на него так:<blockquote><em>var utils = require('./common/myUtils.js')</em></blockquote><ul><li>include с другим путём:</li>
17 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/common/utils.js", "./common/utility/utils.js"]</em></blockquote>В таком случае utils.js будет скопирован в actions/greeting/common/utility/utils.js, со ссылкой из index.js:<blockquote><em>var utils = require('./common/utility/utils.js')</em></blockquote><ul><li>include с символом *:</li>
17 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/common/utils.js", "./common/utility/utils.js"]</em></blockquote>В таком случае utils.js будет скопирован в actions/greeting/common/utility/utils.js, со ссылкой из index.js:<blockquote><em>var utils = require('./common/utility/utils.js')</em></blockquote><ul><li>include с символом *:</li>
18 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/common/*.js", "./common/"]</em></blockquote>В этом варианте utils.js вместе с другими файлами с расширением .js будет скопирован в каталог actions/greeting/common/, а в index.js эти файлы будут подключаться так:<blockquote><em>var utils = require('./common/utils.js')</em></blockquote><h3>Включение каталогов</h3>
18 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/common/*.js", "./common/"]</em></blockquote>В этом варианте utils.js вместе с другими файлами с расширением .js будет скопирован в каталог actions/greeting/common/, а в index.js эти файлы будут подключаться так:<blockquote><em>var utils = require('./common/utils.js')</em></blockquote><h3>Включение каталогов</h3>
19 В include можно прописать каталог, который будет рекурсивно скопирован в указанное место перед включением в архив. Например libs`` содержит список библиотек, на которые ссылаетсяindex.jsв подкаталогеgreeting3/```:<blockquote><em>$ cd actions/</em></blockquote><blockquote><em>$ ls -1</em></blockquote><blockquote><em>libs/</em></blockquote><blockquote><em>greeting3/</em></blockquote><blockquote><em>manifest.yaml</em></blockquote><blockquote><em>$ ls -1 libs/</em></blockquote><blockquote><em>lib1/</em></blockquote><blockquote><em>lib2/</em></blockquote><blockquote><em>lib3/</em></blockquote><blockquote><em>$ ls -1 libs/lib1/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 libs/lib2/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 libs/lib3/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 greeting3/</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote>Содержимое index.js в каталоге actions/greeting3/:<a>Скопировать код</a><p>Содержимое файла-манифеста:</p>
19 В include можно прописать каталог, который будет рекурсивно скопирован в указанное место перед включением в архив. Например libs`` содержит список библиотек, на которые ссылаетсяindex.jsв подкаталогеgreeting3/```:<blockquote><em>$ cd actions/</em></blockquote><blockquote><em>$ ls -1</em></blockquote><blockquote><em>libs/</em></blockquote><blockquote><em>greeting3/</em></blockquote><blockquote><em>manifest.yaml</em></blockquote><blockquote><em>$ ls -1 libs/</em></blockquote><blockquote><em>lib1/</em></blockquote><blockquote><em>lib2/</em></blockquote><blockquote><em>lib3/</em></blockquote><blockquote><em>$ ls -1 libs/lib1/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 libs/lib2/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 libs/lib3/</em></blockquote><blockquote><em>utils.js</em></blockquote><blockquote><em>$ ls -1 greeting3/</em></blockquote><blockquote><em>index.js</em></blockquote><blockquote><em>package.json</em></blockquote>Содержимое index.js в каталоге actions/greeting3/:<a>Скопировать код</a><p>Содержимое файла-манифеста:</p>
20 <blockquote><em>packages:</em></blockquote><blockquote><em> zipactionwithinclude:</em></blockquote><blockquote><em> actions:</em></blockquote><blockquote><em> greeting3:</em></blockquote><blockquote><em> function: actions/greeting3</em></blockquote><blockquote><em> runtime: nodejs:6</em></blockquote><blockquote><em> include:</em></blockquote><blockquote><em> - ["actions/libs/*", "libs/"]</em></blockquote>В этом примере каталог libs целиком рекурсивно копируется в actions/greeting3/libs/.<p>Подключение каталогов с символом *:</p>
20 <blockquote><em>packages:</em></blockquote><blockquote><em> zipactionwithinclude:</em></blockquote><blockquote><em> actions:</em></blockquote><blockquote><em> greeting3:</em></blockquote><blockquote><em> function: actions/greeting3</em></blockquote><blockquote><em> runtime: nodejs:6</em></blockquote><blockquote><em> include:</em></blockquote><blockquote><em> - ["actions/libs/*", "libs/"]</em></blockquote>В этом примере каталог libs целиком рекурсивно копируется в actions/greeting3/libs/.<p>Подключение каталогов с символом *:</p>
21 <ul><li>пример 1:</li>
21 <ul><li>пример 1:</li>
22 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/libs/*/utils.js", "libs/"]</em></blockquote>При таком написании будут скопированы из libs все подкаталоги, содержащие utils.js. Ссылки из index.js будут выглядеть так:<blockquote><em>var lib1 = require('./libs/lib1/utils.js')</em></blockquote><blockquote><em>var lib2 = require('./libs/lib2/utils.js')</em></blockquote><blockquote><em>var lib3 = require('./libs/lib3/utils.js')</em></blockquote><ul><li>пример 2:</li>
22 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/libs/*/utils.js", "libs/"]</em></blockquote>При таком написании будут скопированы из libs все подкаталоги, содержащие utils.js. Ссылки из index.js будут выглядеть так:<blockquote><em>var lib1 = require('./libs/lib1/utils.js')</em></blockquote><blockquote><em>var lib2 = require('./libs/lib2/utils.js')</em></blockquote><blockquote><em>var lib3 = require('./libs/lib3/utils.js')</em></blockquote><ul><li>пример 2:</li>
23 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/*/*/utils.js"]</em></blockquote>При такой записи будут скопированы все подкаталоги, подходящие под маску и содержащие utils.js. Доступ из index.js будет таким:<blockquote><em>var lib1 = require('./actions/libs/lib1/utils.js')</em></blockquote><blockquote><em>var lib2 = require('./actions/libs/lib2/utils.js')</em></blockquote><blockquote><em>var lib3 = require('./actions/libs/lib3/utils.js')</em></blockquote><ul><li>пример 3:</li>
23 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/*/*/utils.js"]</em></blockquote>При такой записи будут скопированы все подкаталоги, подходящие под маску и содержащие utils.js. Доступ из index.js будет таким:<blockquote><em>var lib1 = require('./actions/libs/lib1/utils.js')</em></blockquote><blockquote><em>var lib2 = require('./actions/libs/lib2/utils.js')</em></blockquote><blockquote><em>var lib3 = require('./actions/libs/lib3/utils.js')</em></blockquote><ul><li>пример 3:</li>
24 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/*/*/utils.js", "actions/"]</em></blockquote>В этом примере явно указано, куда все скопируется. Доступ из index.js будет таким же, как и в предыдущем примере.<h2>Исключение</h2>
24 </ul><blockquote><em>include:</em></blockquote><blockquote><em> - ["actions/*/*/utils.js", "actions/"]</em></blockquote>В этом примере явно указано, куда все скопируется. Доступ из index.js будет таким же, как и в предыдущем примере.<h2>Исключение</h2>
25 Ключевое слово exclude может использоваться в виде списка файлов и каталогов, разрешено использовать маску в виде символа *. Пример использования:<blockquote><em>exclude:</em></blockquote><blockquote><em> - actions/common/*.js</em></blockquote><blockquote><em> - actions/libs/*/utils.js</em></blockquote>Общий пример совместного использования include и exclude:<a>Скопировать код</a><h2>Функции с GitHub зависимостями</h2>
25 Ключевое слово exclude может использоваться в виде списка файлов и каталогов, разрешено использовать маску в виде символа *. Пример использования:<blockquote><em>exclude:</em></blockquote><blockquote><em> - actions/common/*.js</em></blockquote><blockquote><em> - actions/libs/*/utils.js</em></blockquote>Общий пример совместного использования include и exclude:<a>Скопировать код</a><h2>Функции с GitHub зависимостями</h2>
26 OpenWhisk поддерживает зависимости, так что можно описать другие пакеты OpenWhisk, от которых зависит наш проект. При наличии таких зависимостей OpenWhisk автоматически развернет и зависимые пакеты. Любой пакет с manifest.yaml и\или deployment.yaml можно рассматривать как зависимый пакет, который может быть указан в манифесте нашего проекта. Можно описать такую зависимость в манифесте в разделе dependencies:<a>Скопировать код</a><p>В этом примере helloworlds является внешним пакетом, размещенным в репозитории GitHub по адресу <a>https://github.com/apache/incubator-openwhisk-test</a>. Пакет helloworlds будет развернут, исходя из его файлов для развертывания в каталоге packages/helloworlds - при развертывании нашего проекта RootProject. Также есть возможность смены имени зависимого пакета, например вместо helloworlds задать ChildProject:</p>
26 OpenWhisk поддерживает зависимости, так что можно описать другие пакеты OpenWhisk, от которых зависит наш проект. При наличии таких зависимостей OpenWhisk автоматически развернет и зависимые пакеты. Любой пакет с manifest.yaml и\или deployment.yaml можно рассматривать как зависимый пакет, который может быть указан в манифесте нашего проекта. Можно описать такую зависимость в манифесте в разделе dependencies:<a>Скопировать код</a><p>В этом примере helloworlds является внешним пакетом, размещенным в репозитории GitHub по адресу <a>https://github.com/apache/incubator-openwhisk-test</a>. Пакет helloworlds будет развернут, исходя из его файлов для развертывания в каталоге packages/helloworlds - при развертывании нашего проекта RootProject. Также есть возможность смены имени зависимого пакета, например вместо helloworlds задать ChildProject:</p>
27 <a>Скопировать код</a><p>Можно добавить несколько зависимостей к нескольким пакетам:</p>
27 <a>Скопировать код</a><p>Можно добавить несколько зависимостей к нескольким пакетам:</p>
28 <a>Скопировать код</a><h2>Как работает синхронизация проектов OpenWhisk между клиентом и сервером</h2>
28 <a>Скопировать код</a><h2>Как работает синхронизация проектов OpenWhisk между клиентом и сервером</h2>
29 Для ответа надо запустить развертывание в режиме managed deployment. В этом режиме OpenWhisk производит развертывание всех объектов из манифеста, а также присоединяет к каждому из них скрытое описание, т.н. managed. Это описание можно посмотреть<a>по ссылке.</a><p><strong>Вариант 1</strong>: Если __OW_PROJECT_HASH совпадает на клиенте и сервере, т.е. если нет изменений проекта на клиентской стороне, то проект на сервере остается как есть, за исключением развертывания через wskdeploy новых объектов из манифеста для получения любых изменений в файле deployment.yaml.</p>
29 Для ответа надо запустить развертывание в режиме managed deployment. В этом режиме OpenWhisk производит развертывание всех объектов из манифеста, а также присоединяет к каждому из них скрытое описание, т.н. managed. Это описание можно посмотреть<a>по ссылке.</a><p><strong>Вариант 1</strong>: Если __OW_PROJECT_HASH совпадает на клиенте и сервере, т.е. если нет изменений проекта на клиентской стороне, то проект на сервере остается как есть, за исключением развертывания через wskdeploy новых объектов из манифеста для получения любых изменений в файле deployment.yaml.</p>
30 <p><strong>Вариант 2</strong>: Если __OW_PROJECT_HASH не совпадает, т.е. имеются изменения на стороне клиента, то wskdeploy выполняет развертывание всех объектов из манифеста, а затем обновляет их __OW_PROJECT_HASH на сервере. Также wskdeploy выполняет поиск всех объектов: включая функции, последовательности и условные срабатывания, у которых такой же __OW_PROJECT_NAME, - т.е. принадлежащих тому же проекту, но имеющих другой __OW_PROJECT_HASH, поскольку они могли быть удалены из манифеста на клиенте. Имя проекта в манифесте является обязательным для синхронизации проекта между клиентом и сервером:</p>
30 <p><strong>Вариант 2</strong>: Если __OW_PROJECT_HASH не совпадает, т.е. имеются изменения на стороне клиента, то wskdeploy выполняет развертывание всех объектов из манифеста, а затем обновляет их __OW_PROJECT_HASH на сервере. Также wskdeploy выполняет поиск всех объектов: включая функции, последовательности и условные срабатывания, у которых такой же __OW_PROJECT_NAME, - т.е. принадлежащих тому же проекту, но имеющих другой __OW_PROJECT_HASH, поскольку они могли быть удалены из манифеста на клиенте. Имя проекта в манифесте является обязательным для синхронизации проекта между клиентом и сервером:</p>
31 <blockquote><em>project:</em></blockquote><blockquote><em> name: MyProjectName</em></blockquote><blockquote><em> packages:</em></blockquote><blockquote><em> package1:</em></blockquote><blockquote><em> ....</em></blockquote>Объекты в OpenWhisk, являющиеся частью проекта, но для которых выполняется развертывание с использованием других инструментов или средств автоматизации, остаются неизменными при их удалении из проекта. Они считаются внешними объектами и поэтому не перезаписываются. Развернуть такой проект можно с помощью wskdeploy, направляя его на файл манифеста, в котором есть только имя проекта:<blockquote><em>project:</em></blockquote><blockquote><em> name: MyProjectName</em></blockquote>Давайте посмотрим на пример проекта для понимания managed deployment. В <a>этом репозитории</a> можно посмотреть проект с различными манифестами, которые показывают managed deployment.<h3>Шаг первый</h3>
31 <blockquote><em>project:</em></blockquote><blockquote><em> name: MyProjectName</em></blockquote><blockquote><em> packages:</em></blockquote><blockquote><em> package1:</em></blockquote><blockquote><em> ....</em></blockquote>Объекты в OpenWhisk, являющиеся частью проекта, но для которых выполняется развертывание с использованием других инструментов или средств автоматизации, остаются неизменными при их удалении из проекта. Они считаются внешними объектами и поэтому не перезаписываются. Развернуть такой проект можно с помощью wskdeploy, направляя его на файл манифеста, в котором есть только имя проекта:<blockquote><em>project:</em></blockquote><blockquote><em> name: MyProjectName</em></blockquote>Давайте посмотрим на пример проекта для понимания managed deployment. В <a>этом репозитории</a> можно посмотреть проект с различными манифестами, которые показывают managed deployment.<h3>Шаг первый</h3>
32 Выполняем развертывание MyFirstManagedProject, используя режим managed deployment:<blockquote><em>$wskdeploy -m tests/src/integration/managed-deployment/manifest.yaml --managed</em></blockquote><blockquote><em>Deployment completed successfully.</em></blockquote>Список объектов, развернутых на сервере OpenWhiskОписание объекта<h3>Шаг второй</h3>
32 Выполняем развертывание MyFirstManagedProject, используя режим managed deployment:<blockquote><em>$wskdeploy -m tests/src/integration/managed-deployment/manifest.yaml --managed</em></blockquote><blockquote><em>Deployment completed successfully.</em></blockquote>Список объектов, развернутых на сервере OpenWhiskОписание объекта<h3>Шаг второй</h3>
33 Синхронизируем клиент и сервер - удаляем ManagedPackage-<a>2: https://xpaste.pro/p/5xm4eUso</a>Список объектов после удаления в MyFirstManagedProject<h3>Шаг третий</h3>
33 Синхронизируем клиент и сервер - удаляем ManagedPackage-<a>2: https://xpaste.pro/p/5xm4eUso</a>Список объектов после удаления в MyFirstManagedProject<h3>Шаг третий</h3>
34 Синхронизируем клиент и сервер - удаляем последовательность ManagedSequence-<a>2: https://xpaste.pro/p/0E82P8r4</a>Список объектов после удаления<h3>Шаг четвертый</h3>
34 Синхронизируем клиент и сервер - удаляем последовательность ManagedSequence-<a>2: https://xpaste.pro/p/0E82P8r4</a>Список объектов после удаления<h3>Шаг четвертый</h3>
35 Удаляем функцию Helloworld-3: <a>https://xpaste.pro/p/xjm1tvPT</a>Список объектов после удаления<h3>Шаг пятый</h3>
35 Удаляем функцию Helloworld-3: <a>https://xpaste.pro/p/xjm1tvPT</a>Список объектов после удаления<h3>Шаг пятый</h3>
36 Удаляем ManagedPackage-1: <a>https://xpaste.pro/p/JZAfllFV</a>Остальные объекты в MyFirstManagedProject<h3>Другие статьи цикла</h3>
36 Удаляем ManagedPackage-1: <a>https://xpaste.pro/p/JZAfllFV</a>Остальные объекты в MyFirstManagedProject<h3>Другие статьи цикла</h3>
37 <a>Бессерверные вычисления на основе OpenWhisk, часть 1</a><a>Бессерверные вычисления на основе OpenWhisk, часть 2</a><a>Бессерверные вычисления на основе OpenWhisk, часть 4</a>
37 <a>Бессерверные вычисления на основе OpenWhisk, часть 1</a><a>Бессерверные вычисления на основе OpenWhisk, часть 2</a><a>Бессерверные вычисления на основе OpenWhisk, часть 4</a>