-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a5ce96d
Showing
1,469 changed files
with
139,142 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Logs | ||
logs | ||
*.log | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directory | ||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env node | ||
|
||
var program = require('commander'); | ||
|
||
program | ||
.version('0.0.1') | ||
.description('Build a NPM package compatible with AWS Lambda using AWS Lambda.') | ||
.command('configure', 'Configure Thaumaturgy with your AWS Credentials.') | ||
.command('deploy', 'Deploy the Thaumaturgy builder lambda function to AWS Lambda.') | ||
.command('build <packages>', "Build NPM packages using Thaumaturge in AWS Lambda. See 'thaumaturgy help build'.") | ||
.parse(process.argv); | ||
|
||
if (!process.argv.slice(2).length) { | ||
program.outputHelp(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
#!/usr/bin/env node | ||
|
||
var program = require('commander'); | ||
var osenv = require('osenv'); | ||
var fs = require('fs'); | ||
var AWS = require('aws-sdk'); | ||
var Promise = require('bluebird'); | ||
|
||
var description = "Build NPM packages using Thaumaturgy in AWS Lambda." + | ||
"\n Package list should be in a space-separated list of packages in the same format as a package.json file." + | ||
"\n\n Examples:" + "\n\n thaumaturgy build mkdirp:^0.5.1" + | ||
"\n thaumaturgy build mysql2:0.15.8 mongodb:~2.0.45" + | ||
"\n thaumaturgy build redis:latest --download /tmp/redis.zip" + | ||
"\n thaumaturgy build --file package.json"; | ||
|
||
program | ||
.option('-f, --file [path]', 'build all dependencies in a package.json file') | ||
.option('-d, --download [path]', 'download build package from S3 and store at [path]') | ||
.description(description) | ||
.parse(process.argv); | ||
|
||
// Make sure we can read their thaumaturgy config file. | ||
var workDir = osenv.home() + '/.thaumaturgy'; | ||
var config; | ||
try { | ||
config = JSON.parse(fs.readFileSync(workDir + '/config.json')); | ||
} catch (err) { | ||
console.error("Could not read configuration. Run 'thaumaturgy configure' first."); | ||
process.exit(1); | ||
} | ||
|
||
// Make sure they've actually deployed thaumaturgy to AWS Lambda. | ||
if (typeof config.lambdaArn === 'undefined') { | ||
console.error("Thaumaturgy does not seem to have been deployed to AWS Lambda yet. Run 'thaumaturgy deploy'."); | ||
process.exit(1); | ||
} | ||
|
||
|
||
var packages = {}; | ||
|
||
|
||
// Get the list of packages, either from the command line or the specified file. | ||
if (!program.file){ // Command line | ||
var packageList = program.args; | ||
|
||
// Check their package list to make sure they're valid. | ||
if (!validPackages(packageList)) { | ||
process.exit(1); | ||
} | ||
|
||
// Turn the list of packages into an object | ||
packageList.forEach(function(package){ | ||
var pieces = package.split(':'); | ||
|
||
//Could be a url, which has a : we don't want to split, so rejoin | ||
pieces = [pieces.shift(), pieces.join(':')]; | ||
packages[pieces[0]] = pieces[1]; | ||
}); | ||
console.log("Invoking Thaumaturgy Lambda in AWS with packages %s.", packageList.join(' ')); | ||
|
||
} else { // Read dependencies from package.json-type file | ||
|
||
var dependencies; | ||
try { | ||
var packagejson = JSON.parse(fs.readFileSync(program.file)); | ||
dependencies = packagejson.dependencies; | ||
} catch (err ){ | ||
console.log('Could not read file at',program.file); | ||
process.exit(1); | ||
} | ||
packages = dependencies; | ||
|
||
console.log("Invoking Thaumaturgy Lambda in AWS for dependencies in", program.file); | ||
} | ||
|
||
AWS.config.update({ | ||
accessKeyId: config.awsAccessKey, | ||
secretAccessKey: config.awsSecretAccessKey, | ||
region: 'us-east-1' | ||
}); | ||
|
||
var lambda = new AWS.Lambda(); | ||
|
||
var params = { | ||
FunctionName : 'Thaumaturgy', | ||
Payload : JSON.stringify({ | ||
bucket : config.s3Bucket, | ||
packages : packages | ||
}) | ||
} | ||
|
||
lambda.invoke(params, function(err, data ){ | ||
if (err) { | ||
console.error("Thaumaturgy reported an error:"); | ||
console.error(err); | ||
process.exit(1); | ||
} | ||
else { | ||
console.log('Build completed successfully.'); | ||
|
||
if ( program.download ){ | ||
console.log('Downloading.') | ||
var s3 = new AWS.S3(); | ||
|
||
var params = { | ||
Bucket : config.s3Bucket, | ||
Key : 'thaumaturgy.zip' | ||
} | ||
|
||
var file = fs.createWriteStream(program.download); | ||
var pipe = s3.getObject(params).createReadStream().pipe(file); | ||
pipe.on('error', function(err){ | ||
console.error('An error occurred downloading the file.'); | ||
console.error(err); | ||
process.exit(1); | ||
}) | ||
pipe.on('finish', function(){ | ||
console.log('Download complete. File at', program.download); | ||
}); | ||
} else { | ||
console.log('Results at: s3://' + config.s3Bucket + '/thaumaturgy.zip'); | ||
process.exit(0); | ||
} | ||
} | ||
}); | ||
|
||
|
||
|
||
// Make sure list is in a valid package.json dependencies format. | ||
function validPackages(packageList) { | ||
var valid = true; | ||
|
||
packageList.forEach(function(package) { | ||
if (package.indexOf(':') == -1) { | ||
console.error(package + ' is not valid. Missing a :'); | ||
valid = false; | ||
} | ||
var pieces = package.split(':'); | ||
|
||
//Could be a url, which has a : we don't want to split, so rejoin | ||
pieces = [pieces.shift(), pieces.join(':')]; | ||
|
||
var version = pieces[1]; | ||
|
||
//console.log(version); | ||
if (!isValidVersionRange(version)) { | ||
console.error(package + ' does not have a valid version.'); | ||
valid = false; | ||
} | ||
}); | ||
return valid; | ||
} | ||
|
||
function isValidVersionRange(v) { | ||
return (/^[\^<>=~]{0,2}[0-9.x]+/).test(v) || | ||
/^https*:\/\/[a-z.\-0-9]+/.test(v) || | ||
v == "*" || | ||
v === "" || | ||
v.indexOf("git") === 0 || | ||
v === "latest" || | ||
false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#!/usr/bin/env node | ||
|
||
var prompt = require('prompt'); | ||
var fs = require('fs'); | ||
var osenv = require('osenv'); | ||
var path = require('path'); | ||
var mkdirp = require('mkdirp'); | ||
|
||
var credentials = {}; | ||
var schema = { | ||
properties: { | ||
'awsAccessKey': { | ||
required: true, | ||
pattern : /^[a-zA-Z0-9]{20}$/, // 20 alphanumeric characters | ||
description: 'AWS Access Key ID:'.cyan, | ||
message: 'That does not seem to be a valid AWS Access Key.' | ||
}, | ||
'awsSecretAccessKey': { | ||
required: true, | ||
pattern : /^[a-zA-Z0-9/+=]{40}$/, // 40 base64 characters | ||
description: 'AWS Secret Access Key:'.cyan, | ||
message: 'That does not seem to be a valid AWS Secret Access Key.' | ||
}, | ||
'roleArn' :{ | ||
required : true, | ||
description: 'AWS Role ARN:'.cyan, | ||
pattern : /^arn:aws:iam.*/, | ||
message : 'That does not look like a valid AWS ARN. Should start with arn:aws:iam' | ||
}, | ||
's3Bucket' :{ | ||
required : true, | ||
description: 'S3 Bucket:'.cyan | ||
}, | ||
'npmVersion' :{ | ||
required : true, | ||
description: 'NPM Version (2 or 3):'.cyan, | ||
enum: ['2', '3'], | ||
message : 'Must be version 2 or 3' | ||
} | ||
} | ||
} | ||
|
||
prompt.message = ''; | ||
prompt.delimiter = ''; | ||
prompt.start(); | ||
prompt.get(schema, function(err, options) { | ||
|
||
if (err) { | ||
console.error('\nConfiguration stopped.'); | ||
} | ||
else { | ||
var workDir = osenv.home() + '/.thaumaturgy'; | ||
mkdirp.sync(workDir); | ||
console.log('Created dirctory: ' + workDir); | ||
fs.writeFileSync(workDir + '/config.json',JSON.stringify(options,null,4)); | ||
console.log('Wrote file: ' + workDir + '/config.json') | ||
console.log('Thaumaturgy configure complete.') | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#!/usr/bin/env node | ||
|
||
var prompt = require('prompt'); | ||
var fs = require('fs'); | ||
var osenv = require('osenv'); | ||
var path = require('path'); | ||
var archiver = require('archiver'); | ||
var mkdirp = require('mkdirp'); | ||
var AWS = require('aws-sdk'); | ||
var Promise = require('bluebird'); | ||
|
||
var workDir = osenv.home() + '/.thaumaturgy'; | ||
var buildDir = workDir + '/build'; | ||
|
||
var config; | ||
try { | ||
config = JSON.parse(fs.readFileSync(workDir + '/config.json')); | ||
} catch (err){ | ||
console.error("Could not read configuration. Run 'thaumaturgy configure' first."); | ||
process.exit(1); | ||
} | ||
|
||
build() | ||
.then(deploy) | ||
.then(function(deployResults){ | ||
config.lambdaArn = deployResults.FunctionArn; | ||
fs.writeFileSync(workDir + '/config.json',JSON.stringify(config,null,4)); | ||
console.log('Thaumaturgy Lambda deployed to AWS Lambda. Ready to build packages.') | ||
}) | ||
.catch(function(e){ | ||
console.error(e); | ||
}); | ||
|
||
function build(){ | ||
return new Promise( function( resolve, reject ){ | ||
console.log('Creating Thaumaturgy Lambda zip file.'); | ||
console.log('Using NPM %s.', config.npmVersion); | ||
|
||
mkdirp.sync(buildDir) | ||
|
||
var output = fs.createWriteStream(buildDir + '/thaumaturgy.zip'); | ||
var archive = archiver.create('zip', {}); // or archiver('zip', {}); | ||
archive.pipe(output); | ||
|
||
output.on('close', function() { | ||
console.log('Thaumaturgy Lambda zip file built.'); | ||
resolve(); | ||
}); | ||
|
||
archive.on('error', function(err) { | ||
reject(err); | ||
}); | ||
|
||
var basePath = path.join(__dirname, '..'); | ||
|
||
archive.directory(basePath + '/lib/npm' + config.npmVersion,'node_modules/npm'); | ||
archive.directory(basePath + '/node_modules/nopt','node_modules/nopt'); | ||
archive.directory(basePath + '/node_modules/archiver','node_modules/archiver'); | ||
archive.file(basePath + '/package.json', { name : 'package.json'}); | ||
archive.file(basePath + '/index.js', { name : 'index.js'}); | ||
archive.finalize(); | ||
}); | ||
} | ||
|
||
function deploy(){ | ||
console.log('Deploying Thaumaturgy Lambda to AWS Lambda.'); | ||
|
||
AWS.config.update({ | ||
accessKeyId: config.awsAccessKey, | ||
secretAccessKey: config.awsSecretAccessKey, | ||
region: 'us-east-1' | ||
}); | ||
|
||
var lambda = new AWS.Lambda(); | ||
|
||
if (config.lambdaArn) { // update lambda | ||
var params = { | ||
FunctionName: 'Thaumaturgy', | ||
ZipFile: fs.readFileSync(buildDir + '/thaumaturgy.zip') | ||
} | ||
return new Promise(function(resolve, reject) { | ||
lambda.updateFunctionCode(params, function(err, data) { | ||
if (err) reject(err); | ||
else resolve(data); | ||
}); | ||
}); | ||
} else { //new lambda | ||
var params = { | ||
FunctionName: 'Thaumaturgy', | ||
Handler: 'index.handler', | ||
Role: config.roleArn, | ||
Runtime: 'nodejs', | ||
MemorySize : 512, | ||
Timeout : 60, | ||
Code: { | ||
ZipFile: fs.readFileSync(buildDir + '/thaumaturgy.zip') | ||
} | ||
} | ||
return new Promise(function(resolve, reject) { | ||
lambda.createFunction(params, function(err, data) { | ||
if (err) reject(err); | ||
else resolve(data); | ||
}); | ||
}); | ||
} | ||
} |
Oops, something went wrong.