From 1b0e36432234bb545211235473657e58c10a4361 Mon Sep 17 00:00:00 2001 From: Pagan Gazzard Date: Mon, 4 Aug 2014 12:10:36 +0100 Subject: [PATCH] Enable spawning a tty.js tunnel. --- bin/enter.sh | 1 + deps.sh | 2 +- package.json | 5 ++++- src/api.coffee | 13 +++++++++++++ src/enterContainer.sh | 11 +++++++++++ src/tty.coffee | 25 +++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 bin/enter.sh create mode 100644 src/enterContainer.sh create mode 100644 src/tty.coffee diff --git a/bin/enter.sh b/bin/enter.sh new file mode 100644 index 00000000..15fa182e --- /dev/null +++ b/bin/enter.sh @@ -0,0 +1 @@ +nsenter --target $(docker inspect --format '{{.State.Pid}}' $1) --mount --uts --ipc --net --pid bash \ No newline at end of file diff --git a/deps.sh b/deps.sh index be509fa0..6f7a7d1a 100644 --- a/deps.sh +++ b/deps.sh @@ -11,4 +11,4 @@ fi # System dependencies apt-get -q update -apt-get install -qqy openvpn libsqlite3-dev +apt-get install -qqy openvpn libsqlite3-dev socat diff --git a/package.json b/package.json index ea0dc76b..fb8a018b 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "scripts": { "preinstall": "bash deps.sh", "postinstall": "bash postinstall.sh", + "prestart": "cp bin/enter.sh /data/enter.sh && chmod +x /data/enter.sh", "start": "./entry.sh" }, "dependencies": { @@ -17,11 +18,13 @@ "knex": "~0.5.1", "lodash": "~2.4.1", "mixpanel": "0.0.20", + "ngrok": "~0.1.97", "ping": "0.1.8", "pubnub": "~3.6.4", "request": "~2.22.0", "resin-platform-api": "git+ssh://git@bitbucket.org:rulemotion/resin-platform-api.git#v0.2.3", - "sqlite3": "~2.1.19" + "sqlite3": "~2.1.19", + "tty.js": "~0.2.13" }, "engines": { "node": "0.10.22" diff --git a/src/api.coffee b/src/api.coffee index aa242acd..2bc0ad68 100644 --- a/src/api.coffee +++ b/src/api.coffee @@ -4,8 +4,10 @@ utils = require './utils' express = require 'express' application = require './application' supervisor = require './supervisor-update' +tty = require './tty' api = express() +api.use(express.bodyParser()) api.post '/v1/blink', (req, res) -> utils.mixpanelTrack('Device blink') @@ -25,4 +27,15 @@ api.post '/v1/update-supervisor', (req, res) -> supervisor.update() res.send(204) +api.post '/v1/spawn-tty', (req, res) -> + appId = req.body.appId + utils.mixpanelTrack('Spawn tty', appId) + if !appId? + res.send(400, 'Missing app id') + tty.start(appId) + .then (url) -> + res.send(200, url) + .catch (err) -> + res.send(404, err) + module.exports = api diff --git a/src/enterContainer.sh b/src/enterContainer.sh new file mode 100644 index 00000000..c80ba267 --- /dev/null +++ b/src/enterContainer.sh @@ -0,0 +1,11 @@ +SOCKET_NAME=test-${1}-${2}-${3} +HOST_DATA_PATH=/resin-data/resin-supervisor +HOST_SOCKET=${HOST_DATA_PATH}/${SOCKET_NAME} +SUPERVISOR_SOCKET_PATH=/data + +echo " + rm -f ${HOST_SOCKET} + socat UNIX-LISTEN:${HOST_SOCKET} EXEC:'${HOST_DATA_PATH}/enter.sh ${1}',pty,setsid,setpgid,stderr,ctty & + exit +" | socat UNIX:${SUPERVISOR_SOCKET_PATH}/host - +socat UNIX:${SUPERVISOR_SOCKET_PATH}/${SOCKET_NAME} -,raw,echo=0 diff --git a/src/tty.coffee b/src/tty.coffee new file mode 100644 index 00000000..319cbf3a --- /dev/null +++ b/src/tty.coffee @@ -0,0 +1,25 @@ +Promise = require 'bluebird' +ngrok = Promise.promisifyAll require 'ngrok' +tty = Promise.promisifyAll require 'tty.js' +knex = require './db' + +# socat UNIX:/data/host -,raw,echo=0 + +apps = {} +nextPort = 81 +exports.start = (appId) -> + apps[appId] ?= Promise.rejected() + return apps[appId] = apps[appId].catch -> + port = nextPort++ + knex('app').select().where({appId}) + .then ([app]) -> + if !app? + throw new Error('App not found') + tty.createServer + shell: './src/enterContainer.sh' + shellArgs: do -> + i = 0 + return (session) -> [app.containerId, session.id, i++] + .listenAsync(port, null) + .then -> + ngrok.connectAsync(port)