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

Create and deploy simple openscad api #228

Merged
merged 2 commits into from
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ dist
dist-babel
node_modules
yarn-error.log
web/public/mockServiceWorker.js
web/public/CADWorker/*

# serverless related ignores, see api/src/docker/openscad/Dockerfile for aws-lambda-rie info
.serverless
aws-lambda-rie
22 changes: 22 additions & 0 deletions api/src/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Serverless

We're using the serverless from work for deployment

```
sls deploy
```
But Kurt Hutten credentials for deployment, though if you wanted to set your own account you could deploy to that if you wanted to test.

## testing changes locally

Honestly it's a pain in the neck, for a number of reasons.

You'll need to have Docker installed

Because of the way the docker containers to be deployed as lambdas on aws are somewhat specialised for the purpose we're using `docker-compose` to spin one up for each function/endpoint. But more work needs to be done to get this to work with the app locally.

```bash
docker-compose up --build
Copy link
Owner Author

@Irev-Dev Irev-Dev Mar 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the lambda functions needed are suposed to run in aws-land they can't be used directly, so I plan on making a dev only docker container that does a bit of aws emulation so that we can use them locally. I started doing this with with the docker-compose file, but I think it will make more sense to get this bit of work done when I start actually iterating on the openscad api (atm it's very simple).

It's not great to be writing dev only code (emulating aws), and the serverless framework I'm using does have a offline plugin that I've used before, but doesn't seem to like docker lambdas.

```
The first time you run the, when it has to build the main image it will take some time, but launching again will be quicker.

20 changes: 20 additions & 0 deletions api/src/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
services:
openscad-health:
build: ./openscad/.
image: openscad
command: openscad.health
ports:
- "5051:8080"
openscad-render:
image: openscad
# build: ./openscad/.
command: openscad.render
ports:
- "5052:8080"
openscad-export:
image: openscad
# build: ./openscad/.
command: openscad.exportstl
ports:
- "5053:8080"

44 changes: 44 additions & 0 deletions api/src/docker/openscad/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM public.ecr.aws/lts/ubuntu:20.04_stable

ARG DEBIAN_FRONTEND=noninteractive

## install things needed to run openscad (xvfb is an important one)
RUN apt-get update -qq
# double check this below, I'm not sure we need inkscape etc
RUN apt-get -y -qq install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates xvfb imagemagick unzip inkscape
RUN apt-get update -qq
RUN apt-get install -y -qq openscad
RUN apt-get install -y curl

# install node 14, (maybe I should put the .sh file into version control?)
RUN curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should commit this bash script I think. TODO

RUN bash nodesource_setup.sh
RUN apt-get install -y nodejs

# Install aws-lambda-cpp build dependencies, this is for the post install script in aws-lambda-ric (in package.json)
RUN apt-get update && \
apt-get install -y \
g++ \
make \
cmake \
unzip \
automake autoconf libtool \
libcurl4-openssl-dev

# Add the lambda emulator for local dev, (see entrypoint.sh for where it's used),
# I have the file locally (gitignored) to speed up build times (as it downloads everytime),
# but you can use the http version of the below ADD command or download it yourself from that url.
ADD aws-lambda-rie /usr/local/bin/aws-lambda-rie
# ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/download/v1.0/aws-lambda-rie /usr/local/bin/aws-lambda-rie
RUN ["chmod", "+x", "/usr/local/bin/aws-lambda-rie"]

WORKDIR /var/task/
COPY package*.json /var/task/
RUN npm install

COPY *.js /var/task/
COPY entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]

ENTRYPOINT ["sh", "/entrypoint.sh"]
CMD [ "openscad.render" ]
6 changes: 6 additions & 0 deletions api/src/docker/openscad/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
/usr/local/bin/aws-lambda-rie /usr/bin/npx aws-lambda-ric $1
else
/usr/bin/npx aws-lambda-ric $1
fi
95 changes: 95 additions & 0 deletions api/src/docker/openscad/openscad.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
const { runScad, stlExport } = require('./runScad')
const middy = require('middy')
const { cors } = require('middy/middlewares')

const health = async () => {
console.log('Health endpoint')
return {
statusCode: 200,
body: 'ok',
}
}

// cors true does not seem to work in serverless.yml, perhaps docker lambdas aren't covered by that config
// special lambda just for responding to options requests
const preflightOptions = (req, _context, callback) => {
const response = {
statusCode: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': '*',
},
}
callback(null, response)
}

const render = async (req, _context, callback) => {
_context.callbackWaitsForEmptyEventLoop = false
const eventBody = Buffer.from(req.body, 'base64').toString('ascii')
console.log(eventBody, 'eventBody')
const { file, settings } = JSON.parse(eventBody)
const { error, result, tempFile } = await runScad({ file, settings })
if (error) {
const response = {
statusCode: 400,
body: JSON.stringify({ error, tempFile }),
}
callback(null, response)
} else {
console.log(`got result in route: ${result}, file is: ${tempFile}`)
const fs = require('fs')
const image = fs.readFileSync(`/tmp/${tempFile}/output.png`, {
encoding: 'base64',
})
console.log(image, 'encoded image')
const response = {
statusCode: 200,
headers: {
'content-type': 'image/png',
},
body: image,
isBase64Encoded: true,
}
callback(null, response)
}
}

const exportstl = async (req, _context, callback) => {
_context.callbackWaitsForEmptyEventLoop = false
const eventBody = Buffer.from(req.body, 'base64').toString('ascii')
console.log(eventBody, 'eventBody')
const { file } = JSON.parse(eventBody)
const { error, result, tempFile } = await stlExport({ file })
if (error) {
const response = {
statusCode: 400,
body: { error, tempFile },
}
callback(null, response)
} else {
console.log(`got result in route: ${result}, file is: ${tempFile}`)
const fs = require('fs')
const stl = fs.readFileSync(`/tmp/${tempFile}/output.stl`, {
encoding: 'base64',
})
console.log('encoded stl', stl)
const response = {
statusCode: 200,
headers: {
'content-type': 'application/stl',
},
body: stl,
isBase64Encoded: true,
}
console.log('callback fired')
callback(null, response)
}
}

module.exports = {
health: middy(health).use(cors()),
exportstl: middy(exportstl).use(cors()),
render: middy(render).use(cors()),
preflightOptions,
}
Loading