Skip to content

Commit

Permalink
add API for web publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
mnutt committed Nov 3, 2015
1 parent 3544cc7 commit 6edd37b
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 1 deletion.
25 changes: 25 additions & 0 deletions .sandstorm/compile_helper.sh
@@ -0,0 +1,25 @@
### Download & compile capnproto and the Sandstorm getPublicId helper.

# First, get capnproto from master and install it to
# /usr/local/bin. This requires a C++ compiler. We opt for clang
# because that's what Sandstorm is typically compiled with.
if [ ! -e /usr/local/bin/capnp ] ; then
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -q clang autoconf pkg-config libtool
cd /tmp
if [ ! -e capnproto ]; then git clone https://github.com/sandstorm-io/capnproto; fi
cd capnproto
git checkout master
cd c++
autoreconf -i
./configure
make -j2
sudo make install
fi

# Second, compile the small C++ program within
# /opt/app/sandstorm-integration.
if [ ! -e /opt/app/sandstorm-integration/getPublicId ] ; then
pushd /opt/app/sandstorm-integration
make
fi
### All done.
2 changes: 2 additions & 0 deletions .sandstorm/sandstorm-files.list
Expand Up @@ -612,6 +612,7 @@ opt/app/sample-files
opt/app/sample-files/Welcome to Davros.md
opt/app/sample-files/space.jpg
opt/app/sample-files/voyager.jpg
opt/app/sandstorm-integration/bin/getPublicId
opt/app/server
opt/app/server/api-ws.js
opt/app/server/api.js
Expand All @@ -624,6 +625,7 @@ opt/app/server/dav/notify.js
opt/app/server/dav/root-delete.js
opt/app/server/dav/statvfs-shim.js
opt/app/server/index.js
opt/app/server/publishing.js
opt/app/server/sandstorm_permissions.js
opt/app/tests
opt/app/tests/.jshintrc
Expand Down
3 changes: 3 additions & 0 deletions .sandstorm/setup.sh
Expand Up @@ -22,3 +22,6 @@
export DEBIAN_FRONTEND=noninteractive
curl -sL https://deb.nodesource.com/setup_node_4.x | bash -
apt-get install -y iojs git-core g++

# Compile a small helper to get a publicId
/opt/app/.sandstorm/compile_helper.sh
2 changes: 2 additions & 0 deletions sandstorm-integration/.gitignore
@@ -0,0 +1,2 @@
tmp
bin
24 changes: 24 additions & 0 deletions sandstorm-integration/Makefile
@@ -0,0 +1,24 @@
# You may override the following vars on the command line to suit
# your config.
CXX=clang++
CXXFLAGS=-O2 -Wall

# You generally should not modify these.
CXXFLAGS2=-std=c++1y -Itmp $(CXXFLAGS)

.PHONY: all clean

all: bin/getPublicId

clean:
rm -rf bin tmp

bin/getPublicId: tmp/genfiles getPublicId.c++
@mkdir -p bin
@$(CXX) getPublicId.c++ tmp/sandstorm/*.capnp.c++ -o bin/getPublicId -static $(CXXFLAGS2) `pkg-config capnp-rpc --cflags --libs`

tmp/genfiles: /opt/sandstorm/latest/usr/include/sandstorm/*.capnp
@echo "generating capnp files..."
@mkdir -p tmp
@capnp compile --src-prefix=/opt/sandstorm/latest/usr/include -oc++:tmp /opt/sandstorm/latest/usr/include/sandstorm/*.capnp
@touch tmp/genfiles
75 changes: 75 additions & 0 deletions sandstorm-integration/getPublicId.c++
@@ -0,0 +1,75 @@
// Sandstorm - Personal Cloud Sandbox
// Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors
//

// Hack around stdlib bug with C++14.
#include <initializer_list> // force libstdc++ to include its config
#undef _GLIBCXX_HAVE_GETS // correct broken config
// End hack.

#include <kj/main.h>
#include <kj/debug.h>
#include <kj/async-io.h>
#include <kj/async-unix.h>
#include <kj/io.h>
#include <capnp/rpc-twoparty.h>
#include <capnp/rpc.capnp.h>
#include <capnp/ez-rpc.h>
#include <sandstorm/sandstorm-http-bridge.capnp.h>
#include <unistd.h>

#include <sandstorm/hack-session.capnp.h>

namespace sandstorm {

class GetPublicIdMain {
public:
GetPublicIdMain(kj::ProcessContext& context): context(context) { }

kj::MainFunc getMain() {
return kj::MainBuilder(context, "GetPublicId version: 0.0.2",
"Runs the getPublicId command from hack-session.capnp. "
"Outputs the return arguments as separate lines on stdout.")
.expectArg("<sessionId>", KJ_BIND_METHOD(*this, setSessionId))
.callAfterParsing(KJ_BIND_METHOD(*this, run))
.build();
}

kj::MainBuilder::Validity setSessionId(kj::StringPtr id) {
sessionId = kj::heapString(id);
return true;
}

kj::MainBuilder::Validity run() {
capnp::EzRpcClient client("unix:/tmp/sandstorm-api");
SandstormHttpBridge::Client restorer = client.getMain<SandstormHttpBridge>();

auto request = restorer.getSessionContextRequest();
request.setId(sessionId);
auto session = request.send().getContext().castAs<HackSessionContext>();

kj::Promise<void> promise = session.getPublicIdRequest().send().then([](auto result) {
auto publicId = result.getPublicId();
auto hostname = result.getHostname();
auto autoUrl = result.getAutoUrl();
auto isDemoUser = result.getIsDemoUser();
kj::String msg = kj::str(publicId, "\n", hostname, "\n", autoUrl, "\n",
isDemoUser ? "true" : "false", "\n");
kj::FdOutputStream(STDOUT_FILENO).write(msg.begin(), msg.size());
}, [] (auto e) {
auto desc = e.getDescription();
kj::FdOutputStream(STDOUT_FILENO).write(desc.begin(), desc.size());
});

promise.wait(client.getWaitScope());
return true;
}

private:
kj::ProcessContext& context;
kj::String sessionId;
};

} // namespace sandstorm

KJ_MAIN(sandstorm::GetPublicIdMain)
6 changes: 5 additions & 1 deletion server/index.js
Expand Up @@ -12,7 +12,7 @@ var api = require('./api');
var apiWs = require('./api-ws');
var dav = require('./dav');
var morgan = require('morgan');

var publishing = require('./publishing');
var sandstormPermissions = require('./sandstorm_permissions');


Expand All @@ -33,6 +33,10 @@ module.exports = function(app, options) {
var uploadServer = api.upload(root);
app.use('/api/upload', uploadServer);

app.get('/api/publish/info', publishing.getInfo);
app.post('/api/publish', publishing.publish);
app.post('/api/unpublish', publishing.unpublish);

// Log proxy requests
app.use(morgan('dev'));
};
49 changes: 49 additions & 0 deletions server/publishing.js
@@ -0,0 +1,49 @@
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;

var destination = '/var/www';
var source = path.relative(path.dirname(destination), process.env.STORAGE_PATH);

exports.unpublish = function(req, res, next) {
fs.unlink(destination, function(err) {
if(err) { throw(err); }
res.json({success: true});
});
};

exports.getInfo = function(req, res, next) {
fs.stat(destination, function(err, stat) {
if(stat) {
var sessionId = req.headers['x-sandstorm-session-id'];
exec("./sandstorm-integration/bin/getPublicId " + sessionId, function(err, stdout, stderr) {
if(err) {
throw(err);
}

var lines = stdout.split("\n");

var data = {
publicId: lines[0],
autoUrl: lines[2]
};

res.json(data);
});
} else {
res.json({});
}
});
};

exports.publish = function(req, res, next) {
fs.unlink(destination, function(err) {
fs.symlink(source, destination, function(err) {
if(err) {
throw(err);
}

exports.getInfo(req, res, next);
});
});
};

0 comments on commit 6edd37b

Please sign in to comment.