blob: d7afdce03ff29aa0c2d7eb4a7e0d4a6b5dd8b477 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements; and to You under the Apache License, Version 2.0.
---
# This role installs invokers.
- import_tasks: docker_login.yml
- name: "pull invoker image with tag {{docker.image.tag}}"
shell: "docker pull {{docker_registry}}{{ docker.image.prefix }}/invoker:{{docker.image.tag}}"
when: docker_registry != ""
register: result
until: (result.rc == 0)
retries: "{{ docker.pull.retries }}"
delay: "{{ docker.pull.delay }}"
###
# This task assumes that the images are local to the invoker host already if there is no prefix or tag
# which is usually the case for a local deployment. A distributed deployment will specify the prefix, or tag
# to pull the images from the appropriate registry. If a runtimes_registry is optionally specified, pull images
# from there; this permits a (private) registry to be used for caching the images. The registry if specified
# must include a trailing '/'.
#
- name: "pull runtime action images per manifest"
shell: "docker pull {{runtimes_registry | default()}}{{item.prefix}}/{{item.name}}:{{item.tag | default()}}"
loop: "{{ runtimesManifest.runtimes.values() | sum(start=[]) | selectattr('deprecated', 'equalto',false) | map(attribute='image') | list | unique }}"
when: skip_pull_runtimes is not defined or skip_pull_runtimes != True
register: result
until: (result.rc == 0)
retries: "{{ docker.pull.retries }}"
delay: "{{ docker.pull.delay }}"
###
# See comment above for pulling other runtime images.
#
- name: "pull blackboxes action images per manifest"
shell: "docker pull {{runtimes_registry | default()}}{{item.prefix}}/{{item.name}}:{{item.tag | default()}}"
loop: "{{ runtimesManifest.blackboxes }}"
when: skip_pull_runtimes is not defined or skip_pull_runtimes != True
register: result
until: (result.rc == 0)
retries: "{{ docker.pull.retries }}"
delay: "{{ docker.pull.delay }}"
- name: "determine docker root dir on docker-machine"
uri: url="http://{{ ansible_host }}:{{ docker.port }}/info" return_content=yes
register: dockerInfo_output
when: environmentInformation.type == 'docker-machine'
- set_fact:
dockerInfo: "{{ dockerInfo_output['json'] }}"
when: environmentInformation.type == "docker-machine"
- name: "determine docker root dir"
shell: echo -e "GET http:/v1.24/info HTTP/1.0\r\n" | nc -U /var/run/docker.sock | grep "{"
args:
executable: /bin/bash
register: dockerInfo_output
when: environmentInformation.type != "docker-machine"
- set_fact:
dockerInfo: "{{ dockerInfo_output.stdout|from_json }}"
when: environmentInformation.type != "docker-machine"
- name: ensure invoker log directory is created with permissions
file:
path: "{{ whisk_logs_dir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}"
state: directory
mode: 0777
become: "{{ logs.dir.become }}"
- name: ensure invoker config directory is created with permissions
file:
path: "{{ invoker.confdir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}"
state: directory
mode: 0777
become: "{{ invoker.dir.become }}"
- name: "copy kafka truststore/keystore"
when: kafka.protocol == 'SSL'
copy:
src: "{{ openwhisk_home }}/ansible/roles/kafka/files/{{ kafka.ssl.keystore.name }}"
dest: "{{ invoker.confdir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}"
- name: check, that required databases exist
include_tasks: "{{ openwhisk_home }}/ansible/tasks/db/checkDb.yml"
vars:
dbName: "{{ item }}"
with_items:
- "{{ db.whisk.actions }}"
- "{{ db.whisk.activations }}"
- name: get running invoker information
uri: url="http://{{ ansible_host }}:{{ docker.port }}/containers/json?filters={{ '{"name":[ "invoker" ],"ancestor":[ "invoker" ]}' | urlencode }}" return_content=yes
register: invokerInfo_output
when: environmentInformation.type == "docker-machine"
- set_fact:
invokerInfo: "{{ invokerInfo_output['json'] }}"
when: environmentInformation.type == "docker-machine"
- name: "get invoker info"
shell: |
INFO=`echo -e "GET http:/v1.24/containers/json?filters={{ '{"name":[ "invoker" ],"ancestor":[ "invoker" ]}' | urlencode }} HTTP/1.0\r\n" | nc -U /var/run/docker.sock | grep "{"`
if [ -z "$INFO" ]; then
echo []
else
echo $INFO
fi
args:
executable: /bin/bash
register: invokerInfo_output
when: environmentInformation.type != "docker-machine"
- set_fact:
invokerInfo: "{{ invokerInfo_output.stdout|from_json }}"
when: environmentInformation.type != "docker-machine"
- name: determine if more than one invoker is running
fail:
msg: "more than one invoker is running"
when: not invoker.allowMultipleInstances and invokerInfo|length > 1
- name: determine if index of invoker is same with index of inventory host
fail:
msg: "invoker index is invalid. expected: /invoker{{ groups['invokers'].index(inventory_hostname) }} found: {{ item.Names[0] }}"
with_items: "{{ invokerInfo }}"
when: not invoker.allowMultipleInstances and item.Names[0] != "/invoker{{ groups['invokers'].index(inventory_hostname) }}"
- name: copy jmxremote password file
when: jmx.enabled
template:
src: "jmxremote.password.j2"
dest: "{{ invoker.confdir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}/jmxremote.password"
mode: 0777
- name: copy jmxremote access file
when: jmx.enabled
template:
src: "jmxremote.access.j2"
dest: "{{ invoker.confdir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}/jmxremote.access"
mode: 0777
- name: add additional jvm params if jmxremote is enabled
when: jmx.enabled
set_fact:
invoker_args: "{{ invoker.arguments }} {{ invoker.jmxremote.jvmArgs }}"
- name: prepare invoker ports
set_fact:
ports_to_expose: ["{{ invoker.port + groups['invokers'].index(inventory_hostname) }}:8080"]
- name: expose additional ports if jmxremote is enabled
when: jmx.enabled
set_fact:
ports_to_expose: "{{ ports_to_expose }} + [ \"{{ jmx.basePortInvoker + groups['invokers'].index(inventory_hostname) }}:{{ jmx.basePortInvoker + groups['invokers'].index(inventory_hostname) }}\" ] + [ \"{{ jmx.rmiBasePortInvoker + groups['invokers'].index(inventory_hostname) }}:{{ jmx.rmiBasePortInvoker + groups['invokers'].index(inventory_hostname) }}\" ]"
- name: prepare invoker env
set_fact:
invoker_env:
"JAVA_OPTS": "-Xmx{{ invoker.heap }} -XX:+CrashOnOutOfMemoryError -XX:+UseGCOverheadLimit -XX:ErrorFile=/logs/java_error.log"
"INVOKER_OPTS": "{{ invoker_args | default(invoker.arguments) }}"
"JMX_REMOTE": "{{ jmx.enabled }}"
"COMPONENT_NAME": "invoker{{ groups['invokers'].index(inventory_hostname) }}"
"PORT": 8080
"KAFKA_HOSTS": "{{ kafka_connect_string }}"
"CONFIG_whisk_kafka_replicationFactor": "{{ kafka.replicationFactor | default() }}"
"CONFIG_whisk_kafka_topics_invoker_retentionBytes": "{{ kafka_topics_invoker_retentionBytes | default() }}"
"CONFIG_whisk_kafka_topics_invoker_retentionMs": "{{ kafka_topics_invoker_retentionMS | default() }}"
"CONFIG_whisk_kakfa_topics_invoker_segmentBytes": "{{ kafka_topics_invoker_segmentBytes | default() }}"
"CONFIG_whisk_kafka_common_securityProtocol": "{{ kafka.protocol }}"
"CONFIG_whisk_kafka_common_sslTruststoreLocation": "/conf/{{ kafka.ssl.keystore.name }}"
"CONFIG_whisk_kafka_common_sslTruststorePassword": "{{ kafka.ssl.keystore.password }}"
"CONFIG_whisk_kafka_common_sslKeystoreLocation": "/conf/{{ kafka.ssl.keystore.name }}"
"CONFIG_whisk_kafka_common_sslKeystorePassword": "{{ kafka.ssl.keystore.password }}"
"CONFIG_whisk_userEvents_enabled": "{{ user_events }}"
"ZOOKEEPER_HOSTS": "{{ zookeeper_connect_string }}"
"CONFIG_whisk_couchdb_protocol": "{{ db_protocol }}"
"CONFIG_whisk_couchdb_host": "{{ db_host }}"
"CONFIG_whisk_couchdb_port": "{{ db_port }}"
"CONFIG_whisk_couchdb_username": "{{ db_username }}"
"CONFIG_whisk_couchdb_password": "{{ db_password }}"
"CONFIG_whisk_couchdb_provider": "{{ db_provider }}"
"CONFIG_whisk_couchdb_databases_WhiskAuth": "{{ db.whisk.auth }}"
"CONFIG_whisk_couchdb_databases_WhiskEntity": "{{ db.whisk.actions }}"
"CONFIG_whisk_couchdb_databases_WhiskActivation": "{{ db.whisk.activations }}"
"DB_WHISK_ACTIONS": "{{ db.whisk.actions }}"
"DB_WHISK_ACTIVATIONS": "{{ db.whisk.activations }}"
"DB_WHISK_AUTHS": "{{ db.whisk.auth }}"
"CONFIG_whisk_db_actionsDdoc": "{{ db_whisk_actions_ddoc | default() }}"
"CONFIG_whisk_db_activationsDdoc": "{{ db_whisk_activations_ddoc | default() }}"
"CONFIG_whisk_db_activationsFilterDdoc": "{{ db_whisk_activations_filter_ddoc | default() }}"
"WHISK_API_HOST_PROTO": "{{ whisk_api_host_proto | default('https') }}"
"WHISK_API_HOST_PORT": "{{ whisk_api_host_port | default('443') }}"
"WHISK_API_HOST_NAME": "{{ whisk_api_host_name | default(groups['edge'] | first) }}"
"RUNTIMES_REGISTRY": "{{ runtimes_registry | default('') }}"
"RUNTIMES_MANIFEST": "{{ runtimesManifest | to_json }}"
"CONFIG_whisk_runtimes_bypassPullForLocalImages": "{{ runtimes_bypass_pull_for_local_images | default() }}"
"CONFIG_whisk_runtimes_localImagePrefix": "{{ runtimes_local_image_prefix | default() }}"
"CONFIG_whisk_containerFactory_containerArgs_network": "{{ invoker_container_network_name | default('bridge') }}"
"INVOKER_CONTAINER_POLICY": "{{ invoker_container_policy_name | default()}}"
"CONFIG_whisk_containerPool_numCore": "{{ invoker.numcore }}"
"CONFIG_whisk_containerPool_coreShare": "{{ invoker.coreshare }}"
"CONFIG_whisk_docker_containerFactory_useRunc": "{{ invoker.useRunc }}"
"INVOKER_NAME": "{{ groups['invokers'].index(inventory_hostname) }}"
"WHISK_LOGS_DIR": "{{ whisk_logs_dir }}"
"METRICS_KAMON": "{{ metrics.kamon.enabled }}"
"METRICS_KAMON_TAGS": "{{ metrics.kamon.tags }}"
"METRICS_LOG": "{{ metrics.log.enabled }}"
"CONFIG_kamon_statsd_hostname": "{{ metrics.kamon.host }}"
"CONFIG_kamon_statsd_port": "{{ metrics.kamon.port }}"
"CONFIG_whisk_spi_LogStoreProvider": "{{ userLogs.spi }}"
"CONFIG_logback_log_level": "{{ invoker.loglevel }}"
"CONFIG_whisk_memory_min": "{{ limit_action_memory_min | default() }}"
"CONFIG_whisk_memory_max": "{{ limit_action_memory_max | default() }}"
"CONFIG_whisk_memory_std": "{{ limit_action_memory_std | default() }}"
"CONFIG_whisk_timeLimit_min": "{{ limit_action_time_min | default() }}"
"CONFIG_whisk_timeLimit_max": "{{ limit_action_time_max | default() }}"
"CONFIG_whisk_timeLimit_std": "{{ limit_action_time_std | default() }}"
"CONFIG_whisk_activation_payload_max": "{{ limit_activation_payload | default() }}"
"CONFIG_whisk_transactions_header": "{{ transactions.header }}"
- name: extend invoker dns env
set_fact:
invoker_env: "{{ invoker_env | default({}) | combine( {'CONFIG_whisk_containerFactory_containerArgs_dnsServers_' ~ item.0: item.1} ) }}"
with_indexed_items: "{{ (invoker_container_network_dns_servers | default()).split(' ')}}"
- name: merge extra env variables
set_fact:
invoker_env: "{{ invoker_env | combine(invoker.extraEnv) }}"
- name: set invoker volumes
set_fact:
volumes: "/sys/fs/cgroup:/sys/fs/cgroup,/run/runc:/run/runc,\
{{ whisk_logs_dir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}:/logs,\
{{ invoker.confdir }}/invoker{{ groups['invokers'].index(inventory_hostname) }}:/conf,\
{{ dockerInfo['DockerRootDir'] }}/containers/:/containers,\
{{ docker_sock | default('/var/run/docker.sock') }}:/var/run/docker.sock"
- name: define options when deploying invoker on Ubuntu
set_fact:
volumes: "{{ volumes|default('') }},/usr/lib/x86_64-linux-gnu/libapparmor.so.1:/usr/lib/x86_64-linux-gnu/libapparmor.so.1"
when: ansible_distribution == "Ubuntu"
- name: start invoker using docker cli
docker_container:
userns_mode: "host"
pid_mode: "host"
privileged: "yes"
name: invoker{{ groups['invokers'].index(inventory_hostname) }}
hostname: "invoker{{ groups['invokers'].index(inventory_hostname) }}"
restart_policy: "{{ docker.restart.policy }}"
image: "{{ docker_registry }}{{ docker.image.prefix }}/invoker:{{ docker.image.tag }}"
state: started
recreate: true
env: "{{ invoker_env }}"
volumes: "{{ volumes }}"
ports: "{{ ports_to_expose }}"
command: /bin/sh -c "exec /init.sh {{ groups['invokers'].index(inventory_hostname) }} >> /logs/invoker{{ groups['invokers'].index(inventory_hostname) }}_logs.log 2>&1"
- name: wait until Invoker is up and running
uri:
url: "http://{{ ansible_host }}:{{ invoker.port + groups['invokers'].index(inventory_hostname) }}/ping"
register: result
until: result.status == 200
retries: 12
delay: 5