apache / openwhisk

Apache OpenWhisk is an open source serverless cloud platform
https://openwhisk.apache.org/
Apache License 2.0
6.5k stars 1.16k forks source link

support choice of node.js runtime for an action #17

Closed sjfink closed 8 years ago

sjfink commented 8 years ago

Right now javascript actions run with node 0.12.9.

We need to support newer versions of node.js.

As upgrading base software will be an ongoing issue, we should design a solution to allow users to choose either "latest" or a backlevel configuration for an action.

markusthoemmes commented 8 years ago

As a first step, how about we use node images from https://hub.docker.com/_/node/ for our NodeJSAction containers (as their baseimage). Then, we'ld have at least 2 different NodeJSAction containers built:

additionally we could have

Tags in the node Dockerhub repository are very nicely structured and support semantic versioning very well.

sjfink commented 8 years ago

@markusthoemmes I think we have a decision to make on the correct schema here. I see at least two choices:

I think either could work, but since this will be an API change, let's try to get it right the first time?

As for pulling base images from dockerhub, seems reasonable as an implementation choice.

markusthoemmes commented 8 years ago

Well pulling them from Dockerhub is only an implementation detail, which keeps us from maintaining the node version themselves.

I think both your suggestions are needed.

  1. The actions needs to tell the invoker which version of node it wants to use, hence which image it needs to use to start the container (that's the field you described). This is needed regardless of any implementation details, right?
  2. Invoker pulls the appropriate image, which it does by the naming scheme proposed by myself.

In fact, there would be another possibility to the second step: We could install multiple node versions into the NodeJSAction container and use something like nvm to choose the right version on runtime. That'll be a single more bloated image vs. one image for each node version.

Note: Instead of using another parameter to the action code itself, npm supports engine requirements. This could be an option aswell (in the future maybe).

Edit: While this issue is related to node only, we need to take other runtimes into account as well. One might want to use a different version of everything. Since it might not be too easy to implement a "multi-version all-in-one" image there, I'ld vote for the "one image per version" approach.

vinodmut commented 8 years ago

Is this related more broadly to the runtime environment in addition to the runtime version?

For example, not just Python 3, but a Python 3 "data science" environment that would come with NumPy, SciPy, etc.

jthomas commented 8 years ago

If you're thinking about the future Node.js images for openwhisk, you might want to compare compilation and execution time when using a Node.js image that bases from Alpine linux. They are tiny in comparison to the official Node.js images which base from Debian.

REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
node                 4                   14c6b4a1f30b        19 hours ago        643.7 MB
mhart/alpine-node    4                   ff9852bfb8ce        22 hours ago        36.04 MB
jthomas commented 8 years ago

Digging around more, it looks like the official Node.js images will soon support Alpine Linux out of the box https://github.com/nodejs/docker-node/issues/46

sjfink commented 8 years ago

I propose the following plan to implement this support. This plan makes no changes to the API but will introduce a new flag in the CLI.

The basic strategy is that each new version of a runtime is identified by a unique string, and all runtime versions are peers -- there is no hierarchy. So in particular, we currently have runtimes named "nodejs", "swift", and "docker" (and "python" when we handle the PR).

Step 1 will be to simply introduce a new runtime "swift3" which is logically a peer of all the other variants. This requires no API change.

Step 2 will be to add a -type flag to wsk action create. So wsk action create x.swift will create a "swift" action, but wsk action create -type "swift3" x.swift creates a "swift3" action.

That's basically it for the short term, and will satisfy our short term needs (modulo UI support).

In the medium term, we would rename our current runtimes to "nodejs0.12.9", "swift2.2", and "python3.3" (or whatever), and then define aliases such as "nodejs" -> latest version of nodejs we support. So "nodejs" would change it's meaning to mean "the latest version supported in the system".

That's basically it. Please comment if you have an opinion.

perryibm commented 8 years ago

Fine with me but to confirm.....

In both the short-term and medium-term of the proposal, the invoker will pull a distinct image from our registry for each runtime (or runtime + version). The use of dockerhub registry for creating our images is a build-time step detail for how things get into our registry.

markusthoemmes commented 8 years ago

+1 as it's the most predictable approach.

Need to keep in mind semantic versioning though. In which granularity do we update? That's probably dependent on the runtime itself.

A parseable naming-approach would be good aswell. For example we could follow docker's :tag approach to then have nodejs:4, nodejs:5 and so on, while nodejs:latest would be a placeholder for the latest and greatest.

csantanapr commented 8 years ago

FYI: a build of node6 it's out and will become LTS in Oct/2016

domdom82 commented 8 years ago

The short-term solution is fine with me.

We will eventually have the discussion about supported packages on the runtime though. Also keep in mind that we will have versions on the packages, too. So you can have the same node version but with different versions of express, request or other npm packages.

On CloudFoundry we have the notion of package.json descriptors that pull the required packages upfront. We could do similar things in a "bootstrapping" phase of a user container that does not get charged by time (msec), maybe only a fixed value per activation itself. Of course that means the first time the action is run you get a longer waiting period.

sjfink commented 8 years ago

Assigning to Jason as per request from Billy.

csantanapr commented 8 years ago

@jasonpet As part of enabling Node6 then we get Promises programing model natively Take a look at the following items:

It would be good to have @jthomas help review once you have something working.