blob: eea9a306e1934fccc642560b2fc5a17c944781e3 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
import kopf, logging, time, os
import openserverless.kube as kube
import openserverless.kustomize as kus
import openserverless.config as cfg
import openserverless.util as util
# Kinds whose version is this suffix are always preloaded, whether or not they
# are the default for their family. The system actions deployed by
# whisk_actions_deployer run on python:sys, so such images must be on the node
# before the first invocation.
ALWAYS_PRELOADED_SUFFIX = "sys"
def add_container(containers: list, container_name, runtime):
""" Append a preloader container entry for a runtime, if it has a usable image.
Images are preloaded whatever registry or organization they come from.
:param containers, the global containers array
:param container_name, the name that will be assigned for the containers preloader
:param runtime, the single runtime entry to add
"""
img = runtime['image']
if not img.get('tag'):
logging.warning(f"skipping runtime preloader for {container_name}: missing image tag")
return
container = {
"name": container_name,
"image": f"{img['prefix']}/{img['name']}:{img['tag']}"
}
containers.append(container)
def find_default_container(containers: list, container_name, runtime_list):
""" Scans for the inner runtime list and add an entry into the containers for the default one if any
:param containers, the global containers array
:param container_name, the name that will be assigned for the containers preloader
:param runtime_list the where to find for the default runtime if any
"""
for runtime in runtime_list:
if runtime['default']:
add_container(containers, container_name, runtime)
def find_always_preloaded_containers(containers: list, container_name, runtime_list):
""" Adds every `<family>:sys` kind, which is preloaded even when it is not the
default of its family. A kind already added as the default is not added twice.
:param containers, the global containers array
:param container_name, the family name, used to build the container name
:param runtime_list the runtime list where to look for the kinds
"""
for runtime in runtime_list:
kind = runtime.get('kind') or ''
if not kind.endswith(f":{ALWAYS_PRELOADED_SUFFIX}") or runtime.get('default'):
continue
name = kind.replace(':', '-').replace('.', '-')
if any(c['name'] == name for c in containers):
continue
add_container(containers, name, runtime)
def parse_runtimes(runtimes_as_json):
""" parse an openwhisk runtimes json and returns a stuitable data structure to customize the preloader jon
Every default kind is preloaded, plus every `<family>:sys` kind, whatever
registry or organization the image comes from.
:param runtimes_as_json a runtime json typically extracted from a config map
>>> import openserverless.testutil as tutil
>>> runtimes_as_json = tutil.load_sample_runtimes()
>>> data = parse_runtimes(runtimes_as_json)
>>> len(data['containers']) == 8
True
"""
data = {}
containers = list()
for name in runtimes_as_json["runtimes"]:
find_default_container(containers, name, runtimes_as_json["runtimes"][name])
find_always_preloaded_containers(containers, name, runtimes_as_json["runtimes"][name])
data['containers']=containers
return data