-
Couldn't load subscription status.
- Fork 23
Swift 4 support #1
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
Changes from all commits
b52b8af
eb03006
4957a94
a1ff269
d1ced84
5aa2d9c
07f943c
5fc90cd
33b2f8a
0cdaf55
4f3420f
b1a0df4
3d0a4a2
23251e1
9873a0d
5a67ac9
7900278
b0c0f0e
6902520
42b533e
f091f4f
e980952
f1b673f
1d3fe12
2a878d2
d4f7f3b
0665def
ac4727a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,10 +2,158 @@ | |
| [](https://travis-ci.org/apache/incubator-openwhisk-runtime-swift) | ||
|
|
||
|
|
||
| ### Give it a try today | ||
| ### Simple swift action hello.swift | ||
| The traditional support for dictionary still works: | ||
| ```swift | ||
| func main(args: [String:Any]) -> [String:Any] { | ||
| if let name = args["name"] as? String { | ||
| return [ "greeting" : "Hello \(name)!" ] | ||
| } else { | ||
| return [ "greeting" : "Hello swif4!" ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Packaging an action as a Swift executable using Swift 4 | ||
|
|
||
| When you create an OpenWhisk Swift action with a Swift source file, it has to be compiled into a binary before the action is run. Once done, subsequent calls to the action are much faster until the container holding your action is purged. This delay is known as the cold-start delay. | ||
|
|
||
| To avoid the cold-start delay, you can compile your Swift file into a binary and then upload to OpenWhisk in a zip file. As you need the OpenWhisk scaffolding, the easiest way to create the binary is to build it within the same environment as it will be run in. These are the steps: | ||
|
|
||
| - Run an interactive Swift action container. | ||
| ``` | ||
| docker run --rm -it -v "$(pwd):/owexec" openwhisk/action-swift-v4 bash | ||
| ``` | ||
| This puts you in a bash shell within the Docker container. | ||
|
|
||
| - Copy the source code and prepare to build it. | ||
| ``` | ||
| cp /owexec/hello.swift /swift4Action/spm-build/Sources/Action/main.swift | ||
| ``` | ||
| ``` | ||
| cat /swift4Action/epilogue.swift >> /swift4Action/spm-build/Sources/Action/main.swift | ||
| ``` | ||
| ``` | ||
| echo '_run_main(mainFunction:main)' >> /swift4Action/spm-build/Sources/Action/main.swift | ||
| ``` | ||
| Copy any additional source files to `/swift4Action/spm-build/Sources/Action/` | ||
|
|
||
|
|
||
| - (Optional) Create the `Package.swift` file to add dependencies. | ||
| ```swift | ||
| // swift-tools-version:4.0 | ||
| // The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
|
||
| import PackageDescription | ||
|
|
||
| let package = Package( | ||
| name: "Action", | ||
| products: [ | ||
| .executable( | ||
| name: "Action", | ||
| targets: ["Action"] | ||
| ) | ||
| ], | ||
| dependencies: [ | ||
| .package(url: "https://github.com/IBM-Swift/SwiftyRequest.git", .upToNextMajor(from: "1.0.0")) | ||
| ], | ||
| targets: [ | ||
| .target( | ||
| name: "Action", | ||
| dependencies: ["SwiftyRequest"], | ||
| path: "." | ||
| ) | ||
|
|
||
| ``` | ||
| As you can see this example adds `SwiftyRequest` dependencies. | ||
|
|
||
| Notice that now with swift:4 is no longer required to include `CCurl`, `Kitura-net` and `SwiftyJSON` in your own `Package.swift`. | ||
| You are free now to use no dependencies, or add the combination that you want with the versions you want. | ||
|
|
||
| - Copy Package.swift to spm-build directory | ||
| ``` | ||
| cp /owexec/Package.swift /swift4Action/spm-build/Package.swift | ||
| ``` | ||
|
|
||
| - Change to the spm-build directory. | ||
| ``` | ||
| cd /swift4Action/spm-build | ||
| ``` | ||
|
|
||
| - Compile your Swift Action. | ||
| ``` | ||
| swift build -c release | ||
| ``` | ||
|
|
||
| - Create the zip archive. | ||
| ``` | ||
| zip /owexec/hello.zip .build/release/Action | ||
| ``` | ||
|
|
||
| - Exit the Docker container. | ||
| ``` | ||
| exit | ||
| ``` | ||
|
|
||
| This has created hello.zip in the same directory as hello.swift. | ||
|
|
||
| - Upload it to OpenWhisk with the action name helloSwifty: | ||
| ``` | ||
| wsk action update helloSwiftly hello.zip openwhisk/action-swift-v4 | ||
| ``` | ||
|
|
||
| - To check how much faster it is, run | ||
| ``` | ||
| wsk action invoke helloSwiftly --blocking | ||
| ``` | ||
|
|
||
| ### Migrating from Swift 3 to Swift 4 | ||
|
|
||
| ### Helper compile.sh helper script | ||
| When compiling and packaging your swift 4 now there are a couple of differences | ||
| All your source code needs to be copy to `/swift4Action/spm-build/Sources/Action/` instead of `/swift3Action/spm-build/` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: |
||
| You Package.swift needs to have the first line with a comment indicating swift4 tooling and format | ||
| ``` | ||
| // swift-tools-version:4.0 | ||
| ``` | ||
| For swift 4 you need specify additional information in Package.swift such as `products` with executable name `Action` and `targets` | ||
|
|
||
| You can take a look at the helper script [tools/build/compile.sh](tools/build/compile.sh) to compile and zip your Actions. | ||
| Having a project directory `Hello` under a directory `actions` like the following: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: |
||
| ``` | ||
| actions/Hello/Package.swift | ||
| actions/Hello/Sources/main.swift | ||
| ``` | ||
| Change to the parent directory then run the compile script specify the project directory, the kind `swift:3.1.1` or `swift:4` and any swiftc build flags like the following: | ||
| ``` | ||
| cd actions/ | ||
| incubator-runtime-swift/tools/build/compile.sh Hello swift:4 -v | ||
| ``` | ||
| This will produce a zip `build/swift4/Hello.zip` | ||
|
|
||
| ### SwiftyJSON using single source action file | ||
| If you have a swift:3.1.1 action not compile, just as source using the `SwiftyJSON` package, you need to precompile your action and specify the version of SwiftyJSON you wan to use for swift:4 kind action. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| Take into account that tarting with Swift 4 there is better support to manage JSON data natively. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| Note: This is only applicable to the base image provided for the Swift 4 runtime, other downstream such as IBM Cloud Functions extending this image might provide additional SDK and packages including `SwiftyJSON` and IBM Watson SDK, check the vendor documentation for more specific information about packages and versions. | ||
|
|
||
| ### Building the Swift4 Image | ||
| ``` | ||
| ./gradlew core:swift4Action:distDocker | ||
| ``` | ||
| This will produce the image `whisk/action-swift-v4` | ||
|
|
||
| Build and Push image | ||
| ``` | ||
| docker login | ||
| ./gradlew core:swift4Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io | ||
| ``` | ||
|
|
||
|
|
||
| ### Using Swift 3.1.1 | ||
| To use as a docker action | ||
| ``` | ||
| wsk action update myAction myAction.jar --docker openwhisk/action-swift-v3.1.1:1.0.0 | ||
| wsk action update myAction myAction.swift --docker openwhisk/action-swift-v3.1.1:1.0.0 | ||
| ``` | ||
| This works on any deployment of Apache OpenWhisk | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Apache OpenWhisk Swift 4 Runtime Container | ||
|
|
||
| ## 1.0.0 | ||
| Initial swift 4 image | ||
|
|
||
| Swift 4 runtime version: | ||
| - [4.0.3](https://hub.docker.com/r/ibmcom/swift-ubuntu/tags/4.0.3/) | ||
|
|
||
| Packages included: | ||
| - No packages included, use Package.swift and pre-compile action. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Dockerfile for swift actions, overrides and extends ActionRunner from actionProxy | ||
| # This Dockerfile is partially based on: https://github.com/IBM-Swift/swift-ubuntu-docker/blob/master/swift-development/Dockerfile | ||
| FROM ibmcom/swift-ubuntu:4.0 | ||
|
|
||
| # Set WORKDIR | ||
| WORKDIR / | ||
|
|
||
| # Upgrade and install basic Python dependencies | ||
| RUN apt-get -y update \ | ||
| && apt-get -y install --fix-missing python2.7 python-gevent python-flask zip | ||
|
|
||
| # Add the action proxy | ||
| RUN mkdir -p /actionProxy | ||
| ADD actionproxy.py /actionProxy | ||
|
|
||
| # Add files needed to build and run action | ||
| RUN mkdir -p /swift4Action/spm-build/Sources/Action | ||
| ADD epilogue.swift /swift4Action | ||
| ADD buildandrecord.py /swift4Action | ||
| ADD swift4runner.py /swift4Action | ||
| ADD spm-build/Package.swift /swift4Action/spm-build | ||
| ADD spm-build/_Whisk.swift /swift4Action/spm-build/Sources/Action | ||
|
|
||
| # Build | ||
| RUN touch /swift4Action/spm-build/Sources/Action/main.swift | ||
| RUN python /swift4Action/buildandrecord.py && rm /swift4Action/spm-build/.build/release/Action | ||
| #RUN cd /swift4Action/spm-build; swift build -v -c release; rm /swift4Action/spm-build/.build/release/Action | ||
| ENV FLASK_PROXY_PORT 8080 | ||
| EXPOSE 8080 | ||
|
|
||
| CMD ["/bin/bash", "-c", "cd /swift4Action && PYTHONIOENCODING='utf-8' python -u swift4runner.py"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| ext.dockerImageName = 'action-swift-v4' | ||
| apply from: '../../gradle/docker.gradle' | ||
| distDocker.dependsOn 'copyProxy' | ||
| distDocker.finalizedBy('cleanup') | ||
|
|
||
| task copyProxy(type: Copy) { | ||
| from '../actionProxy/actionproxy.py' | ||
| into '.' | ||
| } | ||
|
|
||
| task cleanup(type: Delete) { | ||
| delete 'actionproxy.py' | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| """Python to generate build script. | ||
|
|
||
| /* | ||
| * 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. | ||
| */ | ||
| """ | ||
| from __future__ import print_function | ||
| import os | ||
| import sys | ||
| from subprocess import check_output | ||
|
|
||
| # Settings | ||
| COMPILE_PREFIX = "/usr/bin/swiftc -module-name Action " | ||
| LINKER_PREFIX = "/usr/bin/swiftc -target 'x86_64-unknown-linux' -sdk / -L '/swift4Action/spm-build/.build/x86_64-unknown-linux/release' -o '/swift4Action/spm-build/.build/x86_64-unknown-linux/release/Action' -module-name Action -emit-executable -Xlinker '-rpath=$ORIGIN'" | ||
| GENERATED_BUILD_SCRIPT = "/swift4Action/spm-build/swiftbuildandlink.sh" | ||
| SPM_DIRECTORY = "/swift4Action/spm-build" | ||
| BUILD_COMMAND = ["swift", "build", "-v", "-c", "release"] | ||
|
|
||
| # Build Swift package and capture step trace | ||
| print("Building action") | ||
| out = check_output(BUILD_COMMAND, cwd=SPM_DIRECTORY) | ||
| print("action built. Decoding compile and link commands") | ||
|
|
||
| # Look for compile and link commands in step trace | ||
| compileCommand = None | ||
| linkCommand = None | ||
|
|
||
| buildInstructions = out.decode("utf-8").splitlines() | ||
|
|
||
| for instruction in buildInstructions: | ||
| if instruction.startswith(COMPILE_PREFIX): | ||
| compileCommand = instruction | ||
|
|
||
| # add flag to quiet warnings | ||
| compileCommand += " -suppress-warnings" | ||
|
|
||
| elif instruction.startswith(LINKER_PREFIX): | ||
| linkCommand = instruction | ||
|
|
||
| # if found, create build script, otherwise exit with error | ||
| if compileCommand is not None and linkCommand is not None: | ||
| print("Generated OpenWhisk Compile command: %s" % compileCommand) | ||
| print("=========") | ||
| print("Generated OpenWhisk Link command: %s" % linkCommand) | ||
|
|
||
| with open(GENERATED_BUILD_SCRIPT, "a") as buildScript: | ||
| buildScript.write("#!/bin/bash\n") | ||
| buildScript.write("echo \"Compiling\"\n") | ||
| buildScript.write("%s\n" % compileCommand) | ||
| buildScript.write("swiftStatus=$?\n") | ||
| buildScript.write("echo swiftc status is $swiftStatus\n") | ||
| buildScript.write("if [[ \"$swiftStatus\" -eq \"0\" ]]; then\n") | ||
| buildScript.write("echo \"Linking\"\n") | ||
| buildScript.write("%s\n" % linkCommand) | ||
| buildScript.write("else\n") | ||
| buildScript.write(">2& echo \"Action did not compile\"\n") | ||
| buildScript.write("exit 1\n") | ||
| buildScript.write("fi") | ||
|
|
||
| os.chmod(GENERATED_BUILD_SCRIPT, 0o777) | ||
| sys.exit(0) | ||
| else: | ||
| print("Cannot generate build script: compile or link command not found") | ||
| sys.exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo:
couple of differences.