balena-cli
Version:
The official balena Command Line Interface
164 lines • 5.51 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeviceAPI = void 0;
const _ = require("lodash");
const request = require("request");
const helpers_1 = require("../helpers");
const ApiErrors = require("./errors");
const deviceEndpoints = {
setTargetState: 'v2/local/target-state',
getTargetState: 'v2/local/target-state',
getDeviceInformation: 'v2/local/device-info',
logs: 'v2/local/logs',
ping: 'ping',
version: 'v2/version',
status: 'v2/state/status',
containerId: 'v2/containerId',
};
class DeviceAPI {
constructor(logger, addr, port = 48484) {
this.logger = logger;
this.deviceAddress = `http://${addr}:${port}/`;
}
async setTargetState(state) {
const url = this.getUrlForAction('setTargetState');
return DeviceAPI.promisifiedRequest({
method: 'POST',
url,
json: true,
body: state,
}, this.logger);
}
async getTargetState() {
const url = this.getUrlForAction('getTargetState');
return DeviceAPI.promisifiedRequest({
method: 'GET',
url,
json: true,
}, this.logger).then((body) => {
return body.state;
});
}
async getDeviceInformation() {
const url = this.getUrlForAction('getDeviceInformation');
return DeviceAPI.promisifiedRequest({
method: 'GET',
url,
json: true,
}, this.logger).then((body) => {
return body.info;
});
}
async getContainerId(serviceName) {
const url = this.getUrlForAction('containerId');
const body = await DeviceAPI.promisifiedRequest({
method: 'GET',
url,
json: true,
qs: {
serviceName,
},
}, this.logger);
if (body.status !== 'success') {
throw new ApiErrors.DeviceAPIError('Non-successful response from supervisor containerId endpoint');
}
return body.containerId;
}
async ping() {
const url = this.getUrlForAction('ping');
return DeviceAPI.promisifiedRequest({
method: 'GET',
url,
}, this.logger);
}
getVersion() {
const url = this.getUrlForAction('version');
return DeviceAPI.promisifiedRequest({
method: 'GET',
url,
json: true,
}).then((body) => {
if (body.status !== 'success') {
throw new ApiErrors.DeviceAPIError('Non-successful response from supervisor version endpoint');
}
return body.version;
});
}
getStatus() {
const url = this.getUrlForAction('status');
return DeviceAPI.promisifiedRequest({
method: 'GET',
url,
json: true,
}).then((body) => {
if (body.status !== 'success') {
throw new ApiErrors.DeviceAPIError('Non-successful response from supervisor status endpoint');
}
return _.omit(body, 'status');
});
}
getLogStream() {
const url = this.getUrlForAction('logs');
return new Promise((resolve, reject) => {
const req = request.get(url);
req.on('error', reject).on('response', async (res) => {
if (res.statusCode !== 200) {
reject(new ApiErrors.DeviceAPIError('Non-200 response from log streaming endpoint'));
return;
}
try {
res.socket.setKeepAlive(true, 1000);
}
catch (error) {
reject(error);
}
resolve(res);
});
});
}
getUrlForAction(action) {
return `${this.deviceAddress}${deviceEndpoints[action]}`;
}
static async promisifiedRequest(opts, logger) {
if (logger != null) {
let url = null;
if (_.isObject(opts) && opts.url != null) {
url = opts.url;
}
else if (typeof opts === 'string') {
url = opts;
}
if (url != null) {
logger.logDebug(`Sending request to ${url}`);
}
}
const doRequest = async () => {
return await new Promise((resolve, reject) => {
return request(opts, (err, response, body) => {
if (err) {
return reject(err);
}
switch (response.statusCode) {
case 200:
return resolve(body);
case 400:
return reject(new ApiErrors.BadRequestDeviceAPIError(body.message));
case 503:
return reject(new ApiErrors.ServiceUnavailableAPIError(body.message));
default:
return reject(new ApiErrors.DeviceAPIError(body.message));
}
});
});
};
return await (0, helpers_1.retry)({
func: doRequest,
initialDelayMs: 2000,
maxAttempts: 6,
label: `Supervisor API (${opts.method} ${opts.url})`,
});
}
}
exports.DeviceAPI = DeviceAPI;
exports.default = DeviceAPI;
//# sourceMappingURL=api.js.map
;