balena-cli
Version:
The official balena Command Line Interface
200 lines (196 loc) • 8.53 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const errors_1 = require("../../errors");
const cf = require("../../utils/common-flags");
const lazy_1 = require("../../utils/lazy");
const messages_1 = require("../../utils/messages");
class EnvSetCmd extends core_1.Command {
async run() {
const { args: params, flags: options } = await this.parse(EnvSetCmd);
const cmd = this;
if (!options.fleet && !options.device) {
throw new errors_1.ExpectedError('Either the --fleet or the --device option must be specified');
}
const { checkLoggedIn } = await Promise.resolve().then(() => require('../../utils/patterns'));
await checkLoggedIn();
if (params.value == null) {
params.value = process.env[params.name];
if (params.value == null) {
throw new errors_1.ExpectedError(`Value not found for environment variable: ${params.name}`);
}
else if (!options.quiet) {
cmd.warn(`Using ${params.name}=${params.value} from CLI process environment`);
}
}
const balena = (0, lazy_1.getBalenaSdk)();
const reservedPrefixes = await getReservedPrefixes(balena);
const isConfigVar = reservedPrefixes.some((prefix) => params.name.startsWith(prefix));
if (options.service) {
if (isConfigVar) {
throw new errors_1.ExpectedError((0, lazy_1.stripIndent) `
Configuration variables prefixed with "${reservedPrefixes.join('" or "')}" cannot be set per service.
Hint: remove the --service option or rename the variable.
`);
}
await setServiceVars(balena, params, options);
return;
}
const varType = isConfigVar ? 'configVar' : 'envVar';
if (options.fleet) {
for (const appSlug of await resolveFleetSlugs(balena, options.fleet)) {
try {
await balena.models.application[varType].set(appSlug, params.name, params.value);
}
catch (err) {
console.error(`${err.message}, fleet: ${appSlug}`);
process.exitCode = 1;
}
}
}
else if (options.device) {
for (const device of options.device.split(',')) {
try {
await balena.models.device[varType].set(device, params.name, params.value);
}
catch (err) {
console.error(`${err.message}, device: ${device}`);
process.exitCode = 1;
}
}
}
}
}
EnvSetCmd.aliases = ['env add'];
EnvSetCmd.deprecateAliases = true;
EnvSetCmd.description = (0, lazy_1.stripIndent) `
Add or update env or config variable to fleets, devices or services.
Add or update an environment or config variable to one or more fleets, devices or
services, as selected by the respective command-line options. Either the
--fleet or the --device option must be provided, and either may be be
used alongside the --service option to define a service-specific variable.
(A service corresponds to a Docker image/container in a microservices fleet.)
When the --service option is used in conjunction with the --device option,
the service variable applies to the selected device only. Otherwise, it
applies to all devices of the selected fleet. If the --service option is
omitted, the variable applies to all services.
If VALUE is omitted, the CLI will attempt to use the value of the environment
variable of same name in the CLI process' environment. In this case, a warning
message will be printed. Use \`--quiet\` to suppress it.
'BALENA_' or 'RESIN_' are reserved variable name prefixes used to identify
"configuration variables". Configuration variables control balena platform
features and are treated specially by balenaOS and the balena supervisor
running on devices. They are also stored differently in the balenaCloud API
database. Configuration variables cannot be set for specific services,
therefore the --service option cannot be used when the variable name starts
with a reserved prefix. When defining custom fleet variables, please avoid
these reserved prefixes.
${messages_1.applicationIdInfo.split('\n').join('\n\t\t')}
`;
EnvSetCmd.examples = [
'$ balena env set TERM --fleet MyFleet',
'$ balena env set EDITOR vim -f myorg/myfleet',
'$ balena env set EDITOR vim --fleet MyFleet,MyFleet2',
'$ balena env set EDITOR vim --fleet MyFleet --service MyService',
'$ balena env set EDITOR vim --fleet MyFleet,MyFleet2 --service MyService,MyService2',
'$ balena env set EDITOR vim --device 7cf02a6',
'$ balena env set EDITOR vim --device 7cf02a6,d6f1433',
'$ balena env set EDITOR vim --device 7cf02a6 --service MyService',
'$ balena env set EDITOR vim --device 7cf02a6,d6f1433 --service MyService,MyService2',
];
EnvSetCmd.args = {
name: core_1.Args.string({
required: true,
description: 'environment or config variable name',
}),
value: core_1.Args.string({
required: false,
description: "variable value; if omitted, use value from this process' environment",
}),
};
EnvSetCmd.strict = false;
EnvSetCmd.flags = {
fleet: { ...cf.fleet, exclusive: ['device'] },
device: { ...cf.device, exclusive: ['fleet'] },
quiet: cf.quiet,
service: cf.service,
};
exports.default = EnvSetCmd;
async function resolveFleetSlugs(balena, fleetOption) {
const fleetSlugs = [];
const { getFleetSlug } = await Promise.resolve().then(() => require('../../utils/sdk'));
for (const appNameOrSlug of fleetOption.split(',')) {
try {
fleetSlugs.push(await getFleetSlug(balena, appNameOrSlug));
}
catch (err) {
console.error(`${err.message}, fleet: ${appNameOrSlug}`);
process.exitCode = 1;
}
}
return fleetSlugs;
}
async function setServiceVars(sdk, params, options) {
if (options.fleet) {
for (const appSlug of await resolveFleetSlugs(sdk, options.fleet)) {
for (const service of options.service.split(',')) {
try {
const serviceId = await getServiceIdForApp(sdk, appSlug, service);
await sdk.models.service.var.set(serviceId, params.name, params.value);
}
catch (err) {
console.error(`${err.message}, fleet: ${appSlug}`);
process.exitCode = 1;
}
}
}
}
else if (options.device) {
const { getDeviceAndAppFromUUID } = await Promise.resolve().then(() => require('../../utils/cloud'));
for (const uuid of options.device.split(',')) {
let device;
let app;
try {
[device, app] = await getDeviceAndAppFromUUID(sdk, uuid, ['id'], ['slug']);
}
catch (err) {
console.error(`${err.message}, device: ${uuid}`);
process.exitCode = 1;
continue;
}
for (const service of options.service.split(',')) {
try {
const serviceId = await getServiceIdForApp(sdk, app.slug, service);
await sdk.models.device.serviceVar.set(device.id, serviceId, params.name, params.value);
}
catch (err) {
console.error(`${err.message}, service: ${service}`);
process.exitCode = 1;
}
}
}
}
}
async function getServiceIdForApp(sdk, appSlug, serviceName) {
let serviceId;
const services = await sdk.models.service.getAllByApplication(appSlug, {
$select: 'id',
$filter: { service_name: serviceName },
});
if (services.length > 0) {
serviceId = services[0].id;
}
if (serviceId === undefined) {
throw new errors_1.ExpectedError(`Cannot find service ${serviceName} for fleet ${appSlug}`);
}
return serviceId;
}
async function getReservedPrefixes(balena) {
const settings = await balena.settings.getAll();
const response = await balena.request.send({
baseUrl: settings.apiUrl,
url: '/config/vars',
});
return response.body.reservedNamespaces;
}
//# sourceMappingURL=set.js.map
;