alwaysai
Version:
The alwaysAI command-line interface (CLI)
242 lines • 9.13 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.installVenv = exports.buildDocker = exports.appInstallComponent = exports.APP_IGNORE_FILES = void 0;
const fs_1 = require("fs");
const alwayscli_1 = require("@alwaysai/alwayscli");
const docker_1 = require("../docker");
const user_1 = require("../user");
const app_check_component_1 = require("./app-check-component");
const app_clean_component_1 = require("./app-clean-component");
const app_configure_component_1 = require("./app-configure-component");
const target_1 = require("./target");
const app_install_models_component_1 = require("./models/app-install-models-component");
const constants_1 = require("../../constants");
const util_1 = require("../../util");
const app_1 = require("../../core/app");
const infrastructure_1 = require("../../infrastructure");
const general_1 = require("../general");
const paths_1 = require("../../paths");
exports.APP_IGNORE_FILES = ['models', 'node_modules', '.git', 'venv'];
async function appInstallComponent(props) {
const { yes, clean, pull, source, models, docker, venv, excludes } = props;
const steps = [];
// When any flag is set, only add steps determined by flags
if ([source, models, docker, venv].some((element) => element === true)) {
if (source) {
steps.push('source');
}
if (models) {
steps.push('models');
}
if (docker) {
steps.push('docker');
}
if (venv) {
steps.push('venv');
}
}
else {
// Otherwise, add all steps
steps.push(...['source', 'models', 'docker', 'venv']);
}
await (0, user_1.checkUserIsLoggedInComponent)({ yes });
try {
await (0, app_check_component_1.appCheckComponent)();
}
catch (err) {
if (yes) {
throw new alwayscli_1.CliUsageError(`App is not properly configured. Did you run \`${constants_1.ALWAYSAI_CLI_EXECUTABLE_NAME} app configure\`?`);
}
else {
await (0, app_configure_component_1.appConfigureComponent)({ yes });
}
}
const targetJsonFile = (0, app_1.TargetJsonFile)();
const targetHostSpawner = targetJsonFile.readHostSpawner();
const targetCfg = targetJsonFile.read();
const sourceSpawner = (0, util_1.JsSpawner)();
switch (targetCfg.targetProtocol) {
case 'native:':
case 'docker:': {
if (clean) {
await (0, app_clean_component_1.appCleanComponent)({ yes });
}
break;
}
case 'ssh+docker:': {
const { targetHostname, targetPath } = targetCfg;
await (0, general_1.findOrWritePrivateKeyFileComponent)({ yes });
await (0, general_1.connectBySshComponent)({ targetHostname });
if (clean) {
await (0, app_clean_component_1.appCleanComponent)({ yes });
}
await (0, target_1.createTargetDirectoryComponent)({ targetHostname, targetPath });
const projectDevice = targetCfg.deviceId;
let getDevice;
try {
getDevice = await (0, infrastructure_1.getDeviceByUuid)({
uuid: projectDevice
});
}
catch (error) {
util_1.logger.error((0, util_1.stringifyError)(error));
throw new alwayscli_1.CliTerseError('Device does not exist in the selected project.');
}
const hardwareId = await (0, app_1.getTargetHardwareUuid)((0, util_1.SshSpawner)({ targetHostname }));
if (hardwareId !== getDevice.hardware_ids) {
throw new alwayscli_1.CliTerseError(`Target device does not match the one selected. Please run ${constants_1.ALWAYSAI_CLI_EXECUTABLE_NAME} app configure again.`);
}
break;
}
default:
}
if (steps.includes('source')) {
await installSource({
targetCfg,
sourceSpawner,
targetHostSpawner,
excludes
});
}
if (steps.includes('docker')) {
await buildDocker({
targetCfg,
targetJsonFile,
targetHostSpawner,
pull
});
}
if (steps.includes('models')) {
await installModels({ targetJsonFile });
}
if (steps.includes('venv')) {
await installVenv({
targetCfg,
sourceSpawner,
targetJsonFile
});
}
}
exports.appInstallComponent = appInstallComponent;
async function installSource(props) {
const { targetCfg, sourceSpawner, targetHostSpawner } = props;
switch (targetCfg.targetProtocol) {
case 'ssh+docker:': {
const { targetHostname, targetPath } = targetCfg;
const busyboxSpawner = (0, util_1.SshDockerSpawner)({
targetHostname,
targetPath,
dockerImageId: constants_1.DOCKER_TEST_IMAGE_ID
});
const excludes = props.excludes
? props.excludes.concat(exports.APP_IGNORE_FILES)
: exports.APP_IGNORE_FILES;
await (0, util_1.runWithSpinner)(async () => {
await (0, util_1.copyFiles)(sourceSpawner, busyboxSpawner, excludes);
util_1.logger.debug(await targetHostSpawner.run({
exe: 'docker',
args: [
'run',
'--rm',
'--workdir',
'/app',
'--volume',
'$(pwd):/app',
constants_1.DOCKER_TEST_IMAGE_ID,
'chown',
'-R',
'$(id -u ${USER}):$(id -g ${USER})',
'/app'
],
cwd: '.'
}));
}, [], 'Copy application to target');
break;
}
default:
}
}
async function buildDocker(props) {
const { targetCfg, targetJsonFile, targetHostSpawner, pull } = props;
switch (targetCfg.targetProtocol) {
case 'docker:':
case 'ssh+docker:': {
const targetHardware = targetCfg.targetHardware;
const dockerImageId = await (0, docker_1.buildDockerImageComponent)({
targetHostSpawner,
targetHardware,
pullBaseImage: pull
});
targetCfg.dockerImageId = dockerImageId;
targetJsonFile.update((targetCfg) => {
switch (targetCfg.targetProtocol) {
case 'docker:':
case 'ssh+docker:': {
targetCfg.dockerImageId = dockerImageId;
break;
}
case 'native:':
default: {
throw new alwayscli_1.CliTerseError(`Invalid target protocol (${targetCfg.targetProtocol})! ${constants_1.PLEASE_REPORT_THIS_ERROR_MESSAGE}`);
}
}
});
}
}
}
exports.buildDocker = buildDocker;
async function installModels(props) {
const { targetJsonFile } = props;
const targetSpawner = targetJsonFile.readHostSpawner();
await (0, app_install_models_component_1.appInstallModelsComponent)(targetSpawner);
}
async function installVenv(props) {
const { targetCfg, sourceSpawner, targetJsonFile } = props;
const pythonVenvPaths = await (0, app_1.getPythonVenvPaths)({ targetCfg });
let targetSpawner;
switch (targetCfg.targetProtocol) {
case 'native:': {
targetSpawner = sourceSpawner;
break;
}
case 'docker:':
case 'ssh+docker:': {
targetSpawner = targetJsonFile.readContainerSpawner({
ignoreTargetHardware: true
});
break;
}
default:
throw new alwayscli_1.CliTerseError(`Invalid target protocol(${targetCfg})! ${constants_1.PLEASE_REPORT_THIS_ERROR_MESSAGE}`);
}
const spinner = (0, util_1.Spinner)('Create python virtual environment');
try {
const installed = await (0, app_1.createPythonVenv)({
targetSpawner,
pythonVenvPaths,
logger: util_1.logger
});
if (installed === false) {
spinner.succeed('Found python virtual environment');
}
else {
spinner.succeed();
}
}
catch (exception) {
spinner.fail();
throw exception;
}
if ((0, fs_1.existsSync)(paths_1.PYTHON_REQUIREMENTS_FILE_NAME)) {
await (0, util_1.runWithSpinner)(app_1.installPythonReqs, [
{
reqFilePath: paths_1.PYTHON_REQUIREMENTS_FILE_NAME,
targetSpawner,
pythonVenvPaths,
logger: util_1.logger
}
], 'Install python dependencies');
}
}
exports.installVenv = installVenv;
//# sourceMappingURL=app-install-component.js.map