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

parse env_variables from settings.json meteor-google-cloud property #9

Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ $RECYCLE.BIN/
*.msm
*.msp
# Windows shortcuts
*.lnk
*.lnk
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Yes, announced in February 5, 2019, [more info](https://cloud.google.com/blog/pr

**4. Do I get auto healing?** Yes.

**5. Can I add the environment variables to the `settings.json?`** Yes. Just create add a property `env_variables` to `meteor-google-cloud`. It will prefer those over the ones in your `app.yaml`.
## Support

We welcome any questions, contributions or bug reports in the GitHub [issue tracker](https://github.com/EducationLink/meteor-google-cloud/issues).
Expand Down
11 changes: 9 additions & 2 deletions dist/lib/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ function compileBundle() {
dir = _ref.dir,
_ref$workingDir = _ref.workingDir,
workingDir = _ref$workingDir === void 0 ? _tmp.default.dirSync().name : _ref$workingDir,
ci = _ref.ci;
ci = _ref.ci,
keep = _ref.keep;

var customMeteorProjectDirShellEx = `cd ${dir} &&`;

Expand All @@ -30,7 +31,13 @@ function compileBundle() {

_winston.default.debug(`generate meteor build at ${workingDir}`);

_shelljs.default.exec(`rm -rf ${workingDir}`);
if (!keep) {
_winston.default.debug(`removing ${workingDir}`);

_shelljs.default.exec(`rm -rf ${workingDir}`);
} else {
_winston.default.debug(`keeping ${workingDir}, if it exists`);
}

_shelljs.default.exec(`${dir ? customMeteorProjectDirShellEx : ''} meteor build ${workingDir} ${ci ? '--allow-superuser' : ''} --directory --server-only --architecture os.linux.x86_64`); // Cleanup broken symlinks

Expand Down
32 changes: 20 additions & 12 deletions dist/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
pkg: _package.default
}).notify(); // Configure CLI

_commander.default.description(_package.default.description).version(`v${_package.default.version}`, '-v, --version').option('-i, --init', 'init necessary files on your repo').option('-b, --build-only', 'build bundle only').option('-s, --settings <path>', 'path to settings file (settings.json)').option('-c, --app <path>', 'path to app.yaml config file').option('-d, --docker <path>', 'path to Dockerfile file').option('-p, --project <path>', 'path of the directory of your Meteor project').option('-v, --verbose', 'enable verbose mode').option('-q, --quiet', 'enable quite mode').option('-ci, --ci', 'add --allow-superuser flag in meteor commands for running in CI').option('-o, --output-dir <path>', 'build files output directory').parse(process.argv); // Pretty print logs
_commander.default.description(_package.default.description).version(`v${_package.default.version}`, '-v, --version').option('-i, --init', 'init necessary files on your repo').option('-b, --build-only', 'build bundle only').option('-s, --settings <path>', 'path to settings file (settings.json)').option('-c, --app <path>', 'path to app.yaml config file').option('-d, --docker <path>', 'path to Dockerfile file').option('-p, --project <path>', 'path of the directory of your Meteor project').option('-v, --verbose', 'enable verbose mode').option('-q, --quiet', 'enable quite mode').option('-ci, --ci', 'add --allow-superuser flag in meteor commands for running in CI').option('-o, --output-dir <path>', 'build files output directory').option('-k, --keep-output-dir', 'do not remove the output directory before start').parse(process.argv); // Pretty print logs


_winston.default.cli(); // Terminate on shelljs errors
Expand All @@ -72,7 +72,7 @@ function _startup() {
_startup = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee() {
var settingsFile, appFile, dockerFile, outputDir, _compileBundle, workingDir, appEngine;
var settingsFile, appFile, dockerFile, outputDir, env, _compileBundle, workingDir, appEngine;

return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
Expand Down Expand Up @@ -101,39 +101,47 @@ function _startup() {
settingsFile = (0, _validation.validateSettings)(_commander.default.settings);
appFile = (0, _validation.validateApp)(_commander.default.app);
dockerFile = (0, _validation.getDocker)(_commander.default.docker);
outputDir = _commander.default.outputDir; // Create Meteor bundle
outputDir = _commander.default.outputDir;
/*
Validate that either settingsFile[meteor-google-cloud].env_variables
or appFile.env_variables contains the needed variables
*/

env = (0, _validation.validateEnv)(settingsFile, appFile); // Create Meteor bundle

_compileBundle = (0, _bundle.default)({
dir: _commander.default.project,
workingDir: outputDir,
ci: _commander.default.ci
ci: _commander.default.ci,
keep: _commander.default.keepOutputDir
}), workingDir = _compileBundle.workingDir; // Set up GCP App Engine instance

appEngine = new _google.default({
settingsFile,
appFile,
dockerFile,
workingDir,
ci: _commander.default.ci
ci: _commander.default.ci,
env
});
appEngine.prepareBundle(); // If --build-only flag was passed, exit

if (!(_commander.default.buildOnly === true)) {
_context.next = 17;
_context.next = 18;
break;
}

process.exit(0);
return _context.abrupt("return");

case 17:
case 18:
appEngine.deployBundle();
process.exit(0);
_context.next = 26;
_context.next = 27;
break;

case 21:
_context.prev = 21;
case 22:
_context.prev = 22;
_context.t0 = _context["catch"](0);

_tmp.default.setGracefulCleanup();
Expand All @@ -142,12 +150,12 @@ function _startup() {

process.exit(1);

case 26:
case 27:
case "end":
return _context.stop();
}
}
}, _callee, null, [[0, 21]]);
}, _callee, null, [[0, 22]]);
}));
return _startup.apply(this, arguments);
}
26 changes: 19 additions & 7 deletions dist/lib/google.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ var _winston = _interopRequireDefault(require("winston"));

var _jsYaml = _interopRequireDefault(require("js-yaml"));

var _fs = _interopRequireDefault(require("fs"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
Expand All @@ -47,7 +49,8 @@ function () {
dockerFile = _ref.dockerFile,
appFile = _ref.appFile,
workingDir = _ref.workingDir,
ci = _ref.ci;
ci = _ref.ci,
env = _ref.env;

_classCallCheck(this, AppEngineInstance);

Expand All @@ -57,6 +60,7 @@ function () {
this.workingDir = workingDir;
this.googleCloudSettings = settingsFile['meteor-google-cloud'];
this.ci = ci;
this.env = env;
}

_createClass(AppEngineInstance, [{
Expand All @@ -65,7 +69,9 @@ function () {
// We add the Meteor settings now to avoid it being compiled to YAML
var compactSettings = JSON.stringify(this.meteorSettings || {}, null, 0) // It will remove all non-printable characters.
// This are all characters NOT within the ASCII HEX space 0x20-0x7E.
.replace(/[^\x20-\x7E]/gmi, '').replace(/[\n\r]+/g, ''); // We will use shell sed command to replace the variables
.replace(/[^\x20-\x7E]/gmi, '').replace(/[\n\r]+/g, ''); // make sure the env_variables are set

this.appSettings.env_variables = this.env; // We will use shell sed command to replace the variables

Object.assign(this.appSettings.env_variables, {
METEOR_SETTINGS: '{{ METEOR_SETTINGS }}'
Expand All @@ -77,6 +83,8 @@ function () {

_shelljs.default.sed('-i', '{{ METEOR_SETTINGS }}', `'${compactSettings}'`, `${this.workingDir}/bundle/app.yaml`);

_winston.default.debug(`the following app.yaml will be used:\n${JSON.stringify(_jsYaml.default.safeLoad(_fs.default.readFileSync(`${this.workingDir}/bundle/app.yaml`)))}`);

var nodeVersion = _shelljs.default.exec(`meteor node -v ${this.ci ? '--allow-superuser' : ''}`, {
silent: true
}).stdout.trim();
Expand All @@ -93,6 +101,8 @@ function () {
var docker = this.dockerFile.replace('{{ nodeVersion }}', nodeVersion).replace('{{ npmVersion }}', npmVersion);

_shelljs.default.exec(`echo '${docker}' >${this.workingDir}/bundle/Dockerfile`);

_winston.default.debug(`the following Dockerfile will be used:\n${JSON.stringify(_jsYaml.default.safeLoad(_fs.default.readFileSync(`${this.workingDir}/bundle/Dockerfile`)))}`);
}
}, {
key: "deployBundle",
Expand All @@ -110,13 +120,15 @@ function () {

settings = this.googleCloudSettings;
flags = Object.keys(settings).map(function (key) {
var value = settings[key]; // Only some flags actually require a value (e.g. stop-previous-version)
if (key !== 'env_variables') {
var value = settings[key]; // Only some flags actually require a value (e.g. stop-previous-version)

if (value) {
return `--${key}=${settings[key]}`;
}
if (value) {
return `--${key}=${settings[key]}`;
}

return `--${key}`;
return `--${key}`;
}
}).join(' ');

_winston.default.debug(`set flags for deploy: ${flags}`);
Expand Down
38 changes: 33 additions & 5 deletions dist/lib/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exports.validateMeteor = validateMeteor;
exports.validateSettings = validateSettings;
exports.validateApp = validateApp;
exports.getDocker = getDocker;
exports.validateEnv = validateEnv;

var _fs = _interopRequireDefault(require("fs"));

Expand Down Expand Up @@ -148,11 +149,7 @@ function validateApp(filePath) {
}).optional().unknown(true),
network: _joi.default.object({
session_affinity: _joi.default.boolean()
}),
env_variables: _joi.default.object({
ROOT_URL: _joi.default.string(),
MONGO_URL: _joi.default.string()
}).unknown(true)
})
}).unknown(true); // allow unknown keys (at the top level) for extra settings
// (https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions)
// Ensure settings app yaml follows schema
Expand Down Expand Up @@ -205,4 +202,35 @@ function getDocker(filePath) {
}

return dockerFile;
}

function validateEnv(settings, app) {
_winston.default.debug('check either settings.json or app.yaml contain the required env');

var appSchema = _joi.default.object({
env_variables: _joi.default.object({
ROOT_URL: _joi.default.string(),
MONGO_URL: _joi.default.string()
}).unknown(true)
}).unknown(true);

var settingsValidation = _joi.default.validate(settings, _joi.default.object({
'meteor-google-cloud': appSchema
}).unknown(true), {
presence: 'required'
});

var appValidation = _joi.default.validate(app, appSchema, {
presence: 'required'
});

if (settingsValidation.error === null) {
return settings['meteor-google-cloud'].env_variables;
}

if (appValidation.error === null) {
return app.env_variables;
}

throw new Error('neither app.yaml, nor settings.json did contain the env_variables');
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions examples/example_with_env_in_settings/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM gcr.io/google_appengine/nodejs
RUN install_node {{ nodeVersion }}
RUN npm install npm@{{ npmVersion }}
RUN node -v
RUN npm -v
COPY . /app/
RUN (cd programs/server && npm install --unsafe-perm)
CMD node main.js
22 changes: 22 additions & 0 deletions examples/example_with_env_in_settings/app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
runtime: custom
service: my-service-name
env: flex
threadsafe: true
zones:
- us-east1-b
- us-east1-c
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
network:
session_affinity: true
automatic_scaling:
max_num_instances: 2
skip_files:
- ^(.*/)?\.dockerignore$
- ^(.*/)?\yarn-error.log$
- ^(.*/)?\.git$
- ^(.*/)?\.hg$
- ^(.*/)?\.svn$

12 changes: 12 additions & 0 deletions examples/example_with_env_in_settings/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"public": {},
"private": {},
"meteor-google-cloud": {
"project": "",
"stop-previous-version": "",
"env_variables": {
"MONGO_URL": "mongodb://user:[email protected]",
"ROOT_URL": "https://example.de"
}
}
}
Loading