Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust invoker playbook to pull docker images when a prefix and tag is specified. #3680

Merged
merged 1 commit into from
Jun 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions ansible/files/runtimes.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
{
"kind": "nodejs",
"image": {
"name": "nodejsaction"
"prefix": "openwhisk",
"name": "nodejsaction",
"tag": "latest"
},
"deprecated": true
},
{
"kind": "nodejs:6",
"default": true,
"image": {
"name": "nodejs6action"
"prefix": "openwhisk",
"name": "nodejs6action",
"tag": "latest"
},
"deprecated": false,
"stemCells": [{
Expand All @@ -24,7 +28,9 @@
"kind": "nodejs:8",
"default": false,
"image": {
"name": "action-nodejs-v8"
"prefix": "openwhisk",
"name": "action-nodejs-v8",
"tag": "latest"
},
"deprecated": false
}
Expand All @@ -33,22 +39,28 @@
{
"kind": "python",
"image": {
"name": "python2action"
"prefix": "openwhisk",
"name": "python2action",
"tag": "latest"
},
"deprecated": false
},
{
"kind": "python:2",
"default": true,
"image": {
"name": "python2action"
"prefix": "openwhisk",
"name": "python2action",
"tag": "latest"
},
"deprecated": false
},
{
"kind": "python:3",
"image": {
"name": "python3action"
"prefix": "openwhisk",
"name": "python3action",
"tag": "latest"
},
"deprecated": false
}
Expand All @@ -57,29 +69,37 @@
{
"kind": "swift",
"image": {
"name": "swiftaction"
"prefix": "openwhisk",
"name": "swiftaction",
"tag": "latest"
},
"deprecated": true
},
{
"kind": "swift:3",
"image": {
"name": "swift3action"
"prefix": "openwhisk",
"name": "swift3action",
"tag": "latest"
},
"deprecated": true
},
{
"kind": "swift:3.1.1",
"image": {
"name": "action-swift-v3.1.1"
"prefix": "openwhisk",
"name": "action-swift-v3.1.1",
"tag": "latest"
},
"deprecated": false
},
{
"kind": "swift:4.1",
"default": true,
"image": {
"name": "action-swift-v4.1"
"prefix": "openwhisk",
"name": "action-swift-v4.1",
"tag": "latest"
},
"deprecated": false
}
Expand All @@ -89,7 +109,9 @@
"kind": "java",
"default": true,
"image": {
"name": "java8action"
"prefix": "openwhisk",
"name": "java8action",
"tag": "latest"
},
"deprecated": false,
"attached": {
Expand All @@ -106,14 +128,18 @@
"default": true,
"deprecated": false,
"image": {
"name": "action-php-v7.1"
"prefix": "openwhisk",
"name": "action-php-v7.1",
"tag": "latest"
}
}
]
},
"blackboxes": [
{
"name": "dockerskeleton"
"prefix": "openwhisk",
"name": "dockerskeleton",
"tag": "latest"
}
]
}
19 changes: 11 additions & 8 deletions ansible/group_vars/all
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ whisk:
date: "{{ansible_date_time.iso8601}}"

##
# list of supported runtimes (see whisk.core.entity.ExecManifest for schema).
# briefly:
# defaultImagePrefix: the default image prefix when not given explicitly
# defaultImageTag: the default image tag
# runtimes: set of language runtime families grouped by language (e.g., nodejs, python)
# blackboxes: list of pre-populated docker action images as "name" with optional "prefix" and "tag"
# bypassPullForLocalImages: optional, if true, allow images with a prefix that matches {{ docker.image.prefix }}
# to skip docker pull in invoker even if the image is not part of the blackbox set
# configuration parameters related to support runtimes (see whisk.core.entity.ExecManifest for schema of the manifest).
# briefly the parameters are:
#
# runtimes_registry: optional registry (with trailing slack) where to pull docker images from for runtimes and backbox images
#
# skip_pull_runtimes: this will skip pulling the images to the invoker (images must exist there somehow)
#
# runtimes_manifest: set of language runtime families grouped by language (e.g., nodejs, python) and blackbox images to pre-pull
#
# runtimes_bypass_pull_for_local_images: optional, if true, allow images with a prefix that matches
# {{ runtimes_local_image_prefix }} to skip docker pull in invoker even if the image is not part of the blackbox set
#
runtimesManifest: "{{ runtimes_manifest | default(lookup('file', openwhisk_home ~ '/ansible/files/runtimes.json') | from_json) }}"

Expand Down
30 changes: 18 additions & 12 deletions ansible/roles/invoker/tasks/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,28 @@
retries: "{{ docker.pull.retries }}"
delay: "{{ docker.pull.delay }}"

- name: "pull runtime action images with tag {{docker.image.tag}}"
shell: "docker pull {{docker_registry}}{{docker.image.prefix}}/{{item}}:{{docker.image.tag}}"
with_items: "{{ runtimesManifest.runtimes.values() | sum(start=[]) | selectattr('deprecated', 'equalto',false) | map(attribute='image.name') | list | unique }}"
when: docker_registry != ""
###
# 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()}}"
with_items: "{{ 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
retries: "{{ docker.pull.retries }}"
delay: "{{ docker.pull.delay }}"

- name: "pull blackboxes action images with tag {{docker.image.tag}}"
shell: "docker pull {{docker_registry}}{{docker.image.prefix}}/{{item.name}}:{{docker.image.tag}}"
###
# 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()}}"
with_items:
- "{{ runtimesManifest.blackboxes }}"
when: docker_registry != ""
when: skip_pull_runtimes is not defined or skip_pull_runtimes == True
retries: "{{ docker.pull.retries }}"
delay: "{{ docker.pull.delay }}"

Expand Down Expand Up @@ -179,14 +189,10 @@
"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_defaultImagePrefix": "{{ runtimes_default_image_prefix | default() }}"
"CONFIG_whisk_runtimes_defaultImageTag": "{{ runtimes_default_image_tag | default() }}"
"CONFIG_whisk_runtimes_bypassPullForLocalImages": "{{ runtimes_bypass_pull_for_local_images | default() }}"
"CONFIG_whisk_runtimes_localImagePrefix": "{{ runtimes_local_image_prefix | default() }}"
"DOCKER_REGISTRY": "{{ docker_registry }}"
"DOCKER_IMAGE_PREFIX": "{{ docker.image.prefix }}"
"DOCKER_IMAGE_TAG": "{{ docker.image.tag }}"
"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 }}"
Expand Down
2 changes: 0 additions & 2 deletions common/scala/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ whisk {
}
# action runtimes configuration
runtimes {
default-image-prefix = "openwhisk"
default-image-tag = "latest"
bypass-pull-for-local-images = false
local-image-prefix = "whisk"
}
Expand Down
10 changes: 2 additions & 8 deletions common/scala/src/main/scala/whisk/core/WhiskConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,9 @@ class WhiskConfig(requiredProperties: Map[String, String],
}

val servicePort = this(WhiskConfig.servicePort)
val dockerRegistry = this(WhiskConfig.dockerRegistry)
val dockerEndpoint = this(WhiskConfig.dockerEndpoint)
val dockerPort = this(WhiskConfig.dockerPort)

val dockerImagePrefix = this(WhiskConfig.dockerImagePrefix)
val dockerImageTag = this(WhiskConfig.dockerImageTag)

val invokerName = this(WhiskConfig.invokerName)

val wskApiHost = this(WhiskConfig.wskApiProtocol) + "://" + this(WhiskConfig.wskApiHostname) + ":" + this(
Expand All @@ -77,6 +73,7 @@ class WhiskConfig(requiredProperties: Map[String, String],
val dbPrefix = this(WhiskConfig.dbPrefix)
val mainDockerEndpoint = this(WhiskConfig.mainDockerEndpoint)

val runtimesRegistry = this(WhiskConfig.runtimesRegistry)
val runtimesManifest = this(WhiskConfig.runtimesManifest)
val actionInvokePerMinuteLimit = this(WhiskConfig.actionInvokePerMinuteLimit)
val actionInvokeConcurrentLimit = this(WhiskConfig.actionInvokeConcurrentLimit)
Expand Down Expand Up @@ -149,7 +146,6 @@ object WhiskConfig {
}

val servicePort = "port"
val dockerRegistry = "docker.registry"
val dockerPort = "docker.port"

val dockerEndpoint = "main.docker.endpoint"
Expand All @@ -163,9 +159,6 @@ object WhiskConfig {

val whiskVersion = Map(whiskVersionDate -> null, whiskVersionBuildno -> null)

val dockerImagePrefix = "docker.image.prefix"
val dockerImageTag = "docker.image.tag"

val invokerName = "invoker.name"

val wskApiProtocol = "whisk.api.host.proto"
Expand Down Expand Up @@ -194,6 +187,7 @@ object WhiskConfig {
val kafkaHosts = Map(kafkaHostList -> null)
val zookeeperHosts = Map(zookeeperHostList -> null)

val runtimesRegistry = "runtimes.registry"
val runtimesManifest = "runtimes.manifest"

val actionSequenceMaxLimit = "limits.actions.sequence.maxLength"
Expand Down
32 changes: 13 additions & 19 deletions common/scala/src/main/scala/whisk/core/entity/ExecManifest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,20 @@ protected[core] object ExecManifest {
* @return Runtimes instance
*/
protected[entity] def runtimes(config: JsObject, runtimeManifestConfig: RuntimeManifestConfig): Try[Runtimes] = Try {

val prefix = runtimeManifestConfig.defaultImagePrefix
val tag = runtimeManifestConfig.defaultImageTag

val runtimes = config.fields
.get("runtimes")
.map(_.convertTo[Map[String, Set[RuntimeManifest]]].map {
case (name, versions) =>
RuntimeFamily(name, versions.map { mf =>
val img = ImageName(mf.image.name, mf.image.prefix.orElse(prefix), mf.image.tag.orElse(tag))
val img = ImageName(mf.image.name, mf.image.prefix, mf.image.tag)
mf.copy(image = img)
})
}.toSet)

val blackbox = config.fields
.get("blackboxes")
.map(_.convertTo[Set[ImageName]].map { image =>
ImageName(image.name, image.prefix.orElse(prefix), image.tag.orElse(tag))
ImageName(image.name, image.prefix, image.tag)
})

val bypassPullForLocalImages = runtimeManifestConfig.bypassPullForLocalImages
Expand All @@ -100,16 +96,14 @@ protected[core] object ExecManifest {
}

/**
* Misc options related to runtime manifests
* @param defaultImagePrefix the default image prefix when not given explicitly
* @param defaultImageTag the default image tag
* Misc options related to runtime manifests.
*
* @param bypassPullForLocalImages if true, allow images with a prefix that matches localImagePrefix
* to skip docker pull in invoker even if the image is not part of the blackbox set
* to skip docker pull on invoker even if the image is not part of the blackbox set;
* this is useful for testing with local images that aren't published to the runtimes registry
* @param localImagePrefix image prefix for bypassPullForLocalImages
*/
protected[core] case class RuntimeManifestConfig(defaultImagePrefix: Option[String] = None,
defaultImageTag: Option[String] = None,
bypassPullForLocalImages: Option[Boolean] = None,
protected[core] case class RuntimeManifestConfig(bypassPullForLocalImages: Option[Boolean] = None,
localImagePrefix: Option[String] = None)

/**
Expand Down Expand Up @@ -159,18 +153,18 @@ protected[core] object ExecManifest {
}

/**
* The internal name of the image for an action kind. It overrides
* the prefix with an internal name. Optionally overrides tag.
* The internal name of the image for an action kind relative to a registry.
*/
def localImageName(registry: String, prefix: String, tagOverride: Option[String] = None): String = {
def localImageName(registry: String): String = {
val r = Option(registry)
.filter(_.nonEmpty)
.map { reg =>
if (reg.endsWith("/")) reg else reg + "/"
}
.getOrElse("")
val p = Option(prefix).filter(_.nonEmpty).map(_ + "/").getOrElse("")
r + p + name + ":" + tagOverride.orElse(tag).getOrElse(ImageName.defaultImageTag)
val p = prefix.filter(_.nonEmpty).map(_ + "/").getOrElse("")
val t = tag.filter(_.nonEmpty).map(":" + _).getOrElse("")
r + p + name + t
}

/**
Expand All @@ -190,7 +184,7 @@ protected[core] object ExecManifest {
}

protected[core] object ImageName {
protected val defaultImageTag = "latest"
private val defaultImageTag = "latest"
private val componentRegex = """([a-z0-9._-]+)""".r
private val tagRegex = """([\w.-]{0,128})""".r

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class MesosContainerFactory(config: WhiskConfig,
val image = if (userProvidedImage) {
actionImage.publicImageName
} else {
actionImage.localImageName(config.dockerRegistry, config.dockerImagePrefix, Some(config.dockerImageTag))
actionImage.localImageName(config.runtimesRegistry)
}
val constraintStrings = if (userProvidedImage) {
mesosConfig.blackboxConstraints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class DockerContainerFactory(instance: InstanceId,
val image = if (userProvidedImage) {
actionImage.publicImageName
} else {
actionImage.localImageName(config.dockerRegistry, config.dockerImagePrefix, Some(config.dockerImageTag))
actionImage.localImageName(config.runtimesRegistry)
}

DockerContainer.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class KubernetesContainerFactory(label: String, config: WhiskConfig)(implicit ac
val image = if (userProvidedImage) {
actionImage.publicImageName
} else {
actionImage.localImageName(config.dockerRegistry, config.dockerImagePrefix, Some(config.dockerImageTag))
actionImage.localImageName(config.runtimesRegistry)
}

KubernetesContainer.create(
Expand Down
5 changes: 2 additions & 3 deletions core/invoker/src/main/scala/whisk/core/invoker/Invoker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,11 @@ object Invoker {
* An object which records the environment variables required for this component to run.
*/
def requiredProperties =
Map(servicePort -> 8080.toString(), dockerRegistry -> null, dockerImagePrefix -> null) ++
Map(servicePort -> 8080.toString, invokerName -> "", runtimesRegistry -> "") ++
ExecManifest.requiredProperties ++
kafkaHosts ++
zookeeperHosts ++
wskApiHost ++ Map(dockerImageTag -> "latest") ++
Map(invokerName -> "")
wskApiHost

def main(args: Array[String]): Unit = {
Kamon.start()
Expand Down
Loading