balena-cli
Version:
The official balena Command Line Interface
69 lines • 3 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getContainerIdForService = getContainerIdForService;
exports.performLocalDeviceSSH = performLocalDeviceSSH;
const errors_1 = require("../../errors");
const lazy_1 = require("../lazy");
const ssh_1 = require("../ssh");
const deviceContainerEngineBinary = `$(if [ -f /usr/bin/balena ]; then echo "balena"; else echo "docker"; fi)`;
async function getContainerIdForService(opts) {
opts.cmd = `"${deviceContainerEngineBinary}" ps --format "{{.ID}} {{.Names}}"`;
if (opts.deviceUuid) {
opts.cmd = `host ${opts.deviceUuid} ${opts.cmd}`;
}
const psLines = (await (0, ssh_1.getRemoteCommandOutput)({ ...opts, stderr: 'inherit' })).stdout
.toString()
.split('\n')
.filter((l) => l);
const { escapeRegExp } = await Promise.resolve().then(() => require('lodash'));
const regex = new RegExp(`(?:^|\\/)${escapeRegExp(opts.service)}_\\d+_\\d+`);
const nameRegex = /(?:^|\/)([a-zA-Z0-9_-]+)_\d+_\d+(?:_.+)?$/;
const serviceNames = [];
const containerNames = [];
let containerId;
for (const psLine of psLines) {
const [cId, name] = psLine.split(' ');
if (cId && name) {
if (regex.test(name)) {
containerNames.push(name);
containerId = cId;
}
const match = name.match(nameRegex);
if (match) {
serviceNames.push(match[1]);
}
}
}
if (containerNames.length > 1) {
const [s, d] = [opts.service, opts.deviceUuid || opts.hostname];
throw new errors_1.ExpectedError((0, lazy_1.stripIndent) `
Found more than one container matching service name "${s}" on device "${d}":
${containerNames.join(', ')}
Use different service names to avoid ambiguity.
`);
}
if (!containerId) {
const [s, d] = [opts.service, opts.deviceUuid || opts.hostname];
throw new errors_1.ExpectedError(`Could not find a container matching service name "${s}" on device "${d}".${serviceNames.length > 0
? `\nAvailable services:\n\t${serviceNames.join('\n\t')}`
: ''}`);
}
return containerId;
}
async function performLocalDeviceSSH(opts) {
const username = await (0, ssh_1.findBestUsernameForDevice)(opts.hostname, opts.port);
let cmd = '';
if (opts.service) {
const containerId = await getContainerIdForService({
...opts,
service: opts.service,
username,
});
const shellCmd = `/bin/sh -c "if [ -e /bin/bash ]; then exec /bin/bash; else exec /bin/sh; fi"`;
const isTTY = !!opts.forceTTY || (await Promise.resolve().then(() => require('tty'))).isatty(0);
const ttyFlag = isTTY ? '-t' : '';
cmd = `${deviceContainerEngineBinary} exec -i ${ttyFlag} ${containerId} ${shellCmd}`;
}
await (0, ssh_1.runRemoteCommand)({ ...opts, cmd, username });
}
//# sourceMappingURL=ssh.js.map
;