Skip to content

Commit

Permalink
create is working
Browse files Browse the repository at this point in the history
  • Loading branch information
maarteNNNN authored and jondubois committed Aug 21, 2022
1 parent d0ed753 commit a809603
Show file tree
Hide file tree
Showing 10 changed files with 1,583 additions and 11 deletions.
195 changes: 195 additions & 0 deletions bin/actions/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
const fs = require('fs-extra');
const { spawn } = require('child_process');
const YAML = require('yamljs');

const { destDir, fileExistsSync, appDir, getSCCWorkerDeploymentDefPath, sanitizeYAML } = require('../lib');

const copyDirRecursive = (src, dest, opts) => {
try {
fs.copySync(src, dest);
return true;
} catch (e) {
opts.errorLog(
'Failed to create necessary files. Please check your permissions and try again.',
);
}
return false;
};

const createSuccess = (destinationDir, opts) => {
console.log(
'Installing app dependencies using npm. This could take a while...',
);

const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const options = {
cwd: destinationDir,
maxBuffer: Infinity,
};

const npmProcess = spawn(npmCommand, ['install'], options);

npmProcess.stdout.on('data', (data) => {
process.stdout.write(data);
});

npmProcess.stderr.on('data', (data) => {
process.stderr.write(data);
});

npmProcess.on('close', (code) => {
if (code) {
opts.errorLog(`Failed to install npm dependencies. Exited with code ${code}.`);
} else {
try {
fs.writeFileSync(
clientFileDestPath,
fs.readFileSync(clientFileSourcePath),
);
opts.successLog(
`SocketCluster app "${destinationDir}" was setup successfully.`,
);
} catch (err) {
opts.errorLog(
`Failed to copy file from "${clientFileSourcePath}" to "${clientFileDestPath}" - Try copying it manually.`,
code,
);
}
}
});

npmProcess.stdin.end();
};

const setupMessage = function () {
console.log('Creating app structure...');
};

const confirmReplaceSetup = function (confirm, destinationDir, opts) {
const rmdirRecursive = function (dirname) {
try {
fs.removeSync(dirname);
return true;
} catch (e) {
opts.errorLog(
`Failed to remove existing directory at ${dirPath}. This directory may be used by another program or you may not have the permission to remove it.`,
);
}
return false;
};

if (confirm) {
setupMessage();
if (
rmdirRecursive(destinationDir) &&
copyDirRecursive(appDir, destinationDir, opts)
) {
createSuccess();
} else {
this.errorLog();
}
} else {
this.errorLog('SocketCluster "create" action was aborted.');
}
};

const create = async function (app) {
const destinationDir = destDir(app);

let transformK8sConfigs = function () {
return new Promise((resolve, reject) => {
let kubernetesTargetDir = destinationDir + '/kubernetes';
let kubeConfSCCWorker = getSCCWorkerDeploymentDefPath(
kubernetesTargetDir,
);
try {
let kubeConfContentSCCWorker = fs.readFileSync(kubeConfSCCWorker, {
encoding: 'utf8',
});
let deploymentConfSCCWorker = YAML.parse(kubeConfContentSCCWorker);

deploymentConfSCCWorker.spec.template.spec.volumes = [
{
name: 'app-src-volume',
emptyDir: {},
},
];

let containers = deploymentConfSCCWorker.spec.template.spec.containers;
let templateSpec = deploymentConfSCCWorker.spec.template.spec;

if (!templateSpec.initContainers) {
templateSpec.initContainers = [];
}
let initContainers = templateSpec.initContainers;
let appSrcContainerIndex;
containers.forEach((value, index) => {
if (value && value.name == 'scc-worker') {
appSrcContainerIndex = index;
return;
}
});
if (!containers[appSrcContainerIndex].volumeMounts) {
containers[appSrcContainerIndex].volumeMounts = [];
}
containers[appSrcContainerIndex].volumeMounts.push({
mountPath: '/usr/src/app',
name: 'app-src-volume',
});
initContainers.push({
name: 'app-src-container',
image: '', // image name will be generated during deployment
volumeMounts: [
{
mountPath: '/usr/dest',
name: 'app-src-volume',
},
],
command: ['cp', '-a', '/usr/src/.', '/usr/dest/'],
});
let formattedYAMLString = sanitizeYAML(
YAML.stringify(deploymentConfSCCWorker, Infinity, 2),
);
fs.writeFileSync(kubeConfSCCWorker, formattedYAMLString);
} catch (err) {
reject(err);
}
resolve();
});
};

if (app) {
if (fileExistsSync(destinationDir)) {
if (this.argv.force) {
confirmReplaceSetup(true, destinationDir, this);
} else {
let message = `There is already a directory at ${destinationDir}. Do you want to overwrite it?`;
if(await this.promptConfirm(message, { default: true }, confirmReplaceSetup)) {
createSuccess(destinationDir, this)
};
}
} else {
setupMessage();
if (copyDirRecursive(appDir, destinationDir, this)) {
try {
await transformK8sConfigs();
createSuccess(destinationDir);
} catch (err) {
this.errorLog(
`Failed to format Kubernetes configs. Failed to create SocketCluster app. ${err}`,
);
}
} else {
this.errorLog('Failed to create SocketCluster app.');
}
}
} else {
this.errorLog(
'The "create" command requires a valid <appname> as argument.',
);
showCorrectUsage();
process.exit();
}
};

module.exports = { create };
114 changes: 114 additions & 0 deletions bin/actions/docker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const dockerStop = async function () {
let appName = arg1;
if (!appName) {
let appPath = '.';
let pkg = parsePackageFile(appPath);
appName = pkg.name;
}
try {
execSync(`docker stop ${appName}`);
execSync(`docker rm ${appName}`);
this.successLog(`App '${appName}' was stopped.`);
} catch (e) {
this.errorLog(`Failed to stop app '${appName}'.`);
}
process.exit();
};

const dockerRestart = async function () {
let appName = arg1;
if (!appName) {
let appPath = '.';
let pkg = parsePackageFile(appPath);
appName = pkg.name;
}
try {
execSync(`docker stop ${appName}`, { stdio: 'ignore' });
this.successLog(`App '${appName}' was stopped.`);
} catch (e) {}
try {
execSync(`docker start ${appName}`);
this.successLog(`App '${appName}' is running.`);
} catch (e) {
this.errorLog(`Failed to start app '${appName}'.`);
}
process.exit();
};

const dockerRun = async function () {
let appPath = arg1 || '.';
let absoluteAppPath = path.resolve(appPath);
let pkg = parsePackageFile(appPath);
let appName = pkg.name;

let portNumber = Number(argv.p) || 8000;
let envVarList;
if (argv.e === undefined) {
envVarList = [];
} else if (!Array.isArray(argv.e)) {
envVarList = [argv.e];
} else {
envVarList = argv.e;
}
let envFlagList = envVarList.map((value) => {
return `-e "${value}"`;
});
let envFlagString = envFlagList.join(' ');
if (envFlagList.length > 0) {
envFlagString += ' ';
}

try {
execSync(`docker stop ${appName}`, { stdio: 'ignore' });
execSync(`docker rm ${appName}`, { stdio: 'ignore' });
} catch (e) {}

let dockerCommand =
`docker run -d -p ${portNumber}:8000 -v ${absoluteAppPath}:/usr/src/app/ ` +
`${envFlagString}--name ${appName} socketcluster/socketcluster:v${scVersion} `;
try {
execSync(dockerCommand, { stdio: 'inherit' });
this.successLog(
`App "${appName}" is running at http://localhost:${portNumber}`,
);
} catch (e) {
this.errorLog(`Failed to start app "${appName}".`);
}
process.exit();
};

const dockerList = async function () {
let command = exec(`docker ps${commandRawArgsString}`, (err) => {
if (err) {
this.errorLog(`Failed to list active containers. ` + err);
}
process.exit();
});
command.stdout.pipe(process.stdout);
command.stderr.pipe(process.stderr);
};

const dockerLogs = async function () {
let appName = arg1;
if (!appName) {
let appPath = '.';
let pkg = parsePackageFile(appPath);
appName = pkg.name;
}
let command = exec(`docker logs ${appName}${commandRawArgsString}`, (err) => {
if (err) {
this.errorLog(`Failed to get logs for '${appName}' app. ` + err);
}
process.exit();
});
command.stdout.pipe(process.stdout);
command.stderr.pipe(process.stderr);
};

module.exports = {
dockerRestart,
dockerRun,
dockerStop,
dockerList,
dockerLogs,
};
9 changes: 9 additions & 0 deletions bin/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const create = require('./create');
const docker = require('./docker');
const k8s = require('./k8s');

module.exports = {
...create,
...docker,
...k8s,
};
Loading

0 comments on commit a809603

Please sign in to comment.