Creating local folder as part of "site create"
Changing .action to .execute for better async support
This commit is contained in:
Родитель
d77c99427b
Коммит
225f24509d
|
@ -152,6 +152,46 @@ function enableNestedCommands(command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
commander.Command.prototype.execute = function (fn) {
|
||||||
|
var self = this;
|
||||||
|
return self.action(function () {
|
||||||
|
log.info('Executing command ' + self.fullName().bold);
|
||||||
|
|
||||||
|
try {
|
||||||
|
var args = [];
|
||||||
|
for (var i = 0; i != arguments.length; ++i) {
|
||||||
|
args.push(arguments[i]);
|
||||||
|
}
|
||||||
|
args.push(callback);
|
||||||
|
fn.apply(this, args);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
function callback(err) {
|
||||||
|
if (err) {
|
||||||
|
if (err.message) {
|
||||||
|
log.error(err.message);
|
||||||
|
//log.verbose('stack', err.stack);
|
||||||
|
log.json('silly', err);
|
||||||
|
}
|
||||||
|
else if (err.Message) {
|
||||||
|
log.error(err.Message);
|
||||||
|
log.json('verbose', err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.exit('error', self.fullName().bold + ' command ' + 'failed'.red.bold, -1);
|
||||||
|
} else {
|
||||||
|
cli.exit('info', self.fullName().bold + ' command ' + 'OK'.green.bold, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enableNestedCommands(cli);
|
enableNestedCommands(cli);
|
||||||
|
|
||||||
|
@ -237,7 +277,7 @@ function harvestPlugins() {
|
||||||
var results = fs.readdirSync(scanPath);
|
var results = fs.readdirSync(scanPath);
|
||||||
|
|
||||||
results = results.filter(function (filePath) {
|
results = results.filter(function (filePath) {
|
||||||
if (filePath.substring(0,5) === 'tmp--') {
|
if (filePath.substring(0, 5) === 'tmp--') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (filePath.substring(filePath.length - 4) === '_.js') {
|
if (filePath.substring(filePath.length - 4) === '_.js') {
|
||||||
|
@ -255,12 +295,12 @@ function harvestPlugins() {
|
||||||
results = results.filter(function (filePath) {
|
results = results.filter(function (filePath) {
|
||||||
return fs.statSync(filePath).isFile();
|
return fs.statSync(filePath).isFile();
|
||||||
});
|
});
|
||||||
|
|
||||||
// load modules
|
// load modules
|
||||||
results = results.map(function (filePath) {
|
results = results.map(function (filePath) {
|
||||||
return require(filePath);
|
return require(filePath);
|
||||||
});
|
});
|
||||||
|
|
||||||
// look for exports.init
|
// look for exports.init
|
||||||
results = results.filter(function (entry) {
|
results = results.filter(function (entry) {
|
||||||
return entry.init !== undefined;
|
return entry.init !== undefined;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
if (!require('streamline/module')(module)) return;
|
if (!require('streamline/module')(module)) return;
|
||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var crypto = require('crypto');
|
||||||
var pfx2pem = require('../../util/certificates/pkcs').pfx2pem;
|
var pfx2pem = require('../../util/certificates/pkcs').pfx2pem;
|
||||||
var Channel = require('../channel');
|
var Channel = require('../channel');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
@ -47,47 +49,18 @@ exports.init = function (cli) {
|
||||||
site.command('list')
|
site.command('list')
|
||||||
.description('List your web sites.')
|
.description('List your web sites.')
|
||||||
.option('-s, --subscription <id>', 'use the subscription id')
|
.option('-s, --subscription <id>', 'use the subscription id')
|
||||||
.action(function (options) {
|
.execute(function (options, _) {
|
||||||
execute('site list', function(_) {
|
var parameters = {
|
||||||
var parameters = {
|
subscription: cli.category('account').lookupSubscriptionId(options.subscription)
|
||||||
subscription: cli.category('account').lookupSubscriptionId(options.subscription)
|
};
|
||||||
};
|
|
||||||
|
|
||||||
var spaces = site.doSpacesGet(parameters, _);
|
var spaces = site.doSpacesGet(parameters, _);
|
||||||
var sites = site.doSitesGet(parameters, _);
|
var sites = site.doSitesGet(parameters, _);
|
||||||
|
|
||||||
log.table(sites, function (row, site) {
|
log.table(sites, function (row, site) {
|
||||||
row.cell('Name', site.Name);
|
row.cell('Name', site.Name);
|
||||||
row.cell('State', site.State);
|
row.cell('State', site.State);
|
||||||
row.cell('Host names', clean(site).HostNames);
|
row.cell('Host names', clean(site).HostNames);
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
site.command('show <name>')
|
|
||||||
.description('Show details for a web sites.')
|
|
||||||
.option('-s, --subscription <id>', 'use the subscription id')
|
|
||||||
.action(function (name, options) {
|
|
||||||
|
|
||||||
execute('site show', function(_) {
|
|
||||||
var parameters = {
|
|
||||||
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
|
||||||
site: {
|
|
||||||
name: name
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
log.info('Showing details for site');
|
|
||||||
log.verbose('Parameters', parameters);
|
|
||||||
|
|
||||||
var siteData = site.doSiteGet(parameters, _);
|
|
||||||
var configData = site.doSiteConfigGet(parameters, _);
|
|
||||||
var repositoryData = site.doRepositoryGet(parameters, _);
|
|
||||||
|
|
||||||
logEachData('Site', siteData);
|
|
||||||
logEachData('Config', configData);
|
|
||||||
log.data('Repository', clean(repositoryData));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -95,51 +68,67 @@ exports.init = function (cli) {
|
||||||
cli.choose(data, function(x) {callback(null,x);});
|
cli.choose(data, function(x) {callback(null,x);});
|
||||||
}
|
}
|
||||||
|
|
||||||
function execute(command, impl, _) {
|
|
||||||
log.info('Executing command ' + command.bold);
|
|
||||||
try {
|
|
||||||
impl(_);
|
|
||||||
cli.exit('info', command.bold + ' command ' + 'OK'.green.bold, 0);
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
logError(err);
|
|
||||||
cli.exit('error', command.bold + ' command ' + 'failed'.red.bold, -1);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
site.command('create <name>')
|
site.command('create <name>')
|
||||||
.description('Create a new web site and local directory.')
|
.description('Create a new web site and local directory.')
|
||||||
.option('-s, --subscription <id>', 'use the subscription id')
|
.option('-s, --subscription <id>', 'use the subscription id')
|
||||||
.option('--location <location>', 'the geographic region to create the website')
|
.option('--location <location>', 'the geographic region to create the website')
|
||||||
.option('--hostname <hostname>', 'custom host name to use')
|
.option('--hostname <hostname>', 'custom host name to use')
|
||||||
.action(function (name, options) {
|
.execute(function (name, options, _) {
|
||||||
execute('site create', function(_) {
|
var context = {
|
||||||
|
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
||||||
var context = {
|
site: {
|
||||||
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
name: name,
|
||||||
site: {
|
webspace: options.location,
|
||||||
name: name,
|
hostname: options.hostname
|
||||||
webspace: options.location,
|
|
||||||
hostname: options.hostname
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (context.site.webspace === undefined) {
|
|
||||||
log.help('Choose a region');
|
|
||||||
context.site.webspace = regions[choose(regionPrompts, _)].webspace;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
site.doSitesPost(context, _);
|
if (context.site.webspace === undefined) {
|
||||||
site.doRepositoryPost(context, _);
|
log.help('Choose a region');
|
||||||
var repo = site.doRepositoryGet(context, _);
|
context.site.webspace = regions[choose(regionPrompts, _)].webspace;
|
||||||
|
}
|
||||||
|
|
||||||
log.help('To start adding content to the website, type in the following:');
|
site.doSitesPost(context, _);
|
||||||
log.help(' git init');
|
site.doRepositoryPost(context, _);
|
||||||
log.help(' git add .');
|
var repo = site.doRepositoryGet(context, _);
|
||||||
log.help(' git commit -m "initial commit"');
|
|
||||||
log.help(' git remote add azure ' + repo + context.site.name + '.git');
|
log.info('Creating local folder', name);
|
||||||
log.help(' git push azure master');
|
fs.mkdir(name, _);
|
||||||
});
|
process.chdir(name);
|
||||||
|
site.initConfig({name:name});
|
||||||
|
|
||||||
|
log.help('To start adding content to the website, type in the following:');
|
||||||
|
log.help(' cd ' + name);
|
||||||
|
log.help(' git init');
|
||||||
|
log.help(' git add .');
|
||||||
|
log.help(' git commit -m "initial commit"');
|
||||||
|
log.help(' git remote add azure ' + repo + context.site.name + '.git');
|
||||||
|
log.help(' git push azure master');
|
||||||
|
});
|
||||||
|
|
||||||
|
site.command('show <name>')
|
||||||
|
.description('Show details for a web sites.')
|
||||||
|
.option('-s, --subscription <id>', 'use the subscription id')
|
||||||
|
.execute(function (name, options, _) {
|
||||||
|
var context = {
|
||||||
|
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
||||||
|
site: {
|
||||||
|
name: name
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
lookupSiteWebSpace(context, _);
|
||||||
|
|
||||||
|
log.info('Showing details for site');
|
||||||
|
log.verbose('Parameters', context);
|
||||||
|
|
||||||
|
var siteData = site.doSiteGet(context, _);
|
||||||
|
var configData = site.doSiteConfigGet(context, _);
|
||||||
|
var repositoryData = site.doRepositoryGet(context, _);
|
||||||
|
|
||||||
|
logEachData('Site', siteData);
|
||||||
|
logEachData('Config', configData);
|
||||||
|
log.data('Repository', clean(repositoryData));
|
||||||
});
|
});
|
||||||
|
|
||||||
function lookupSiteWebSpace(context, _) {
|
function lookupSiteWebSpace(context, _) {
|
||||||
|
@ -159,99 +148,170 @@ exports.init = function (cli) {
|
||||||
site.command('delete <name>')
|
site.command('delete <name>')
|
||||||
.description('Delete a web site.')
|
.description('Delete a web site.')
|
||||||
.option('-s, --subscription <id>', 'use the subscription id')
|
.option('-s, --subscription <id>', 'use the subscription id')
|
||||||
.action(function (name, options) {
|
.execute(function (name, options, _) {
|
||||||
execute('site delete', function(_) {
|
var context = {
|
||||||
var context = {
|
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
||||||
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
site: {
|
||||||
site: {
|
name: name
|
||||||
name: name
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
lookupSiteWebSpace(context, _);
|
lookupSiteWebSpace(context, _);
|
||||||
|
|
||||||
var result = getChannel()
|
var result = getChannel()
|
||||||
.path(context.subscription)
|
.path(context.subscription)
|
||||||
.path('services/webspaces')
|
.path('services/webspaces')
|
||||||
.path(context.site.webspace)
|
.path(context.site.webspace)
|
||||||
.path('sites')
|
.path('sites')
|
||||||
.path(context.site.name)
|
.path(context.site.name)
|
||||||
.DELETE(_);
|
.DELETE(_);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
site.command('start <name>')
|
site.command('start <name>')
|
||||||
.description('Start a web site.')
|
.description('Start a web site.')
|
||||||
.option('-s, --subscription <id>', 'use the subscription id')
|
.option('-s, --subscription <id>', 'use the subscription id')
|
||||||
.action(function (name, options) {
|
.execute(function (name, options, _) {
|
||||||
execute('site start', function(_) {
|
var context = {
|
||||||
|
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
||||||
var context = {
|
site: {
|
||||||
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
name: name
|
||||||
site: {
|
}
|
||||||
name: name
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lookupSiteWebSpace(context, _);
|
lookupSiteWebSpace(context, _);
|
||||||
|
|
||||||
var result = getChannel()
|
var result = getChannel()
|
||||||
.path(context.subscription)
|
.path(context.subscription)
|
||||||
.path('services/webspaces')
|
.path('services/webspaces')
|
||||||
.path(context.site.webspace)
|
.path(context.site.webspace)
|
||||||
.path('sites')
|
.path('sites')
|
||||||
.path(context.site.name)
|
.path(context.site.name)
|
||||||
.header('Content-Type', 'application/xml')
|
.header('Content-Type', 'application/xml')
|
||||||
.POST(function (req) {
|
.POST(function (req) {
|
||||||
req.write('<Site xmlns="http://schemas.microsoft.com/windowsazure">');
|
req.write('<Site xmlns="http://schemas.microsoft.com/windowsazure">');
|
||||||
req.write('<State>');
|
req.write('<State>');
|
||||||
req.write('Running');
|
req.write('Running');
|
||||||
req.write('</State>');
|
req.write('</State>');
|
||||||
req.write('</Site>');
|
req.write('</Site>');
|
||||||
|
|
||||||
req.end();
|
req.end();
|
||||||
}, _);
|
}, _);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
site.command('stop <name>')
|
site.command('stop <name>')
|
||||||
.description('Stop a web site.')
|
.description('Stop a web site.')
|
||||||
.option('-s, --subscription <id>', 'use the subscription id')
|
.option('-s, --subscription <id>', 'use the subscription id')
|
||||||
.action(function (name, options) {
|
.execute(function (name, options, _) {
|
||||||
execute('site start', function(_) {
|
var context = {
|
||||||
|
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
||||||
var context = {
|
site: {
|
||||||
subscription: cli.category('account').lookupSubscriptionId(options.subscription),
|
name: name
|
||||||
site: {
|
}
|
||||||
name: name
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lookupSiteWebSpace(context, _);
|
lookupSiteWebSpace(context, _);
|
||||||
|
|
||||||
var result = getChannel()
|
var result = getChannel()
|
||||||
.path(context.subscription)
|
.path(context.subscription)
|
||||||
.path('services/webspaces')
|
.path('services/webspaces')
|
||||||
.path(context.site.webspace)
|
.path(context.site.webspace)
|
||||||
.path('sites')
|
.path('sites')
|
||||||
.path(context.site.name)
|
.path(context.site.name)
|
||||||
.header('Content-Type', 'application/xml')
|
.header('Content-Type', 'application/xml')
|
||||||
.POST(function (req) {
|
.POST(function (req) {
|
||||||
req.write('<Site xmlns="http://schemas.microsoft.com/windowsazure">');
|
req.write('<Site xmlns="http://schemas.microsoft.com/windowsazure">');
|
||||||
req.write('<State>');
|
req.write('<State>');
|
||||||
req.write('Stopped');
|
req.write('Stopped');
|
||||||
req.write('</State>');
|
req.write('</State>');
|
||||||
req.write('</Site>');
|
req.write('</Site>');
|
||||||
|
|
||||||
req.end();
|
req.end();
|
||||||
}, _);
|
}, _);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
// fundamental operations
|
// config and settings
|
||||||
|
|
||||||
|
site.findConfig = function() {
|
||||||
|
var scanFolder = process.cwd();
|
||||||
|
while(true) {
|
||||||
|
var azureFolder = path.join(scanFolder, '.azure');
|
||||||
|
|
||||||
|
// probe for config if azure folder exists
|
||||||
|
if (path.existsSync(azureFolder) &&
|
||||||
|
path.statSync(azureFolder).isDirectory()) {
|
||||||
|
|
||||||
|
// find a single .config file
|
||||||
|
var files = fs.readDirSync(azureFolder);
|
||||||
|
files = files.filter(function(filename){
|
||||||
|
return endsWith(filename, '.config');
|
||||||
|
});
|
||||||
|
|
||||||
|
// return full path if it exists
|
||||||
|
if (files.length == 1) {
|
||||||
|
return path.join(azureFolder, files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recurse upwards, or return null when that's no longer possible
|
||||||
|
try {
|
||||||
|
var parentFolder = path.dirname(scanFolder);
|
||||||
|
if (parentFolder === scanFolder || !path.exists(scanFolder)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
site.initConfig = function(config) {
|
||||||
|
var baseFolder = process.cwd();
|
||||||
|
var azureFolder = path.join(baseFolder, '.azure');
|
||||||
|
var baseName = crypto.randomBytes(16).toString('hex');
|
||||||
|
var configPath = path.join(azureFolder, baseName + '.config');
|
||||||
|
if (!path.exists(azureFolder)) {
|
||||||
|
log.silly('Creating folder', azureFolder);
|
||||||
|
fs.mkdirSync(azureFolder);
|
||||||
|
}
|
||||||
|
log.silly('Writing file', configPath);
|
||||||
|
var configText = JSON.stringify(config);
|
||||||
|
fs.writeFileSync(configPath, configText);
|
||||||
|
};
|
||||||
|
|
||||||
|
site.readConfig = function() {
|
||||||
|
var configPath = site.findConfig();
|
||||||
|
if (configPath === undefined) {
|
||||||
|
log.verbose('No site .azure/*.config file locate at current directory');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.silly('Reading file', configPath);
|
||||||
|
var configText = fs.readFileSync(configPath);
|
||||||
|
var config = JSON.parse(configText);
|
||||||
|
log.json('silly', 'Site config', config);
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
|
site.writeConfig = function(config) {
|
||||||
|
var configPath = site.findConfig();
|
||||||
|
if (configPath === undefined) {
|
||||||
|
log.verbose('No site .azure/*.config file locate at current directory');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.silly('Writing file', configPath);
|
||||||
|
var configText = JSON.stringify(config);
|
||||||
|
fs.writeFileSync(configPath, configText);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// remote api operations
|
||||||
|
|
||||||
site.doSitesPost = function (options, callback) {
|
site.doSitesPost = function (options, callback) {
|
||||||
log.info('Creating a new web site');
|
log.info('Creating a new web site');
|
||||||
|
@ -499,4 +559,7 @@ exports.init = function (cli) {
|
||||||
return isArray(testObject) ? testObject : typeof testObject === 'undefined' ? [] : [testObject];
|
return isArray(testObject) ? testObject : typeof testObject === 'undefined' ? [] : [testObject];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function endsWith(str, suffix) {
|
||||||
|
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче