mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 05:37:51 +00:00
Convert lib/utils/qemu.coffee to javascript
Change-type: patch
This commit is contained in:
parent
8be56ef092
commit
9f59b6dde5
@ -1,105 +0,0 @@
|
|||||||
###*
|
|
||||||
# @license
|
|
||||||
# Copyright 2017-2019 Balena Ltd.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
###
|
|
||||||
|
|
||||||
Promise = require('bluebird')
|
|
||||||
{ getBalenaSdk } = require('./lazy')
|
|
||||||
|
|
||||||
exports.QEMU_VERSION = QEMU_VERSION = 'v4.0.0-balena'
|
|
||||||
exports.QEMU_BIN_NAME = QEMU_BIN_NAME = 'qemu-execve'
|
|
||||||
|
|
||||||
exports.qemuPathInContext = (context) ->
|
|
||||||
path = require('path')
|
|
||||||
binDir = path.join(context, '.balena')
|
|
||||||
binPath = path.join(binDir, QEMU_BIN_NAME)
|
|
||||||
path.relative(context, binPath)
|
|
||||||
|
|
||||||
exports.copyQemu = (context, arch) ->
|
|
||||||
path = require('path')
|
|
||||||
fs = require('mz/fs')
|
|
||||||
# Create a hidden directory in the build context, containing qemu
|
|
||||||
binDir = path.join(context, '.balena')
|
|
||||||
binPath = path.join(binDir, QEMU_BIN_NAME)
|
|
||||||
|
|
||||||
Promise.resolve(fs.mkdir(binDir))
|
|
||||||
.catch(code: 'EEXIST', ->)
|
|
||||||
.then ->
|
|
||||||
getQemuPath(arch)
|
|
||||||
.then (qemu) ->
|
|
||||||
new Promise (resolve, reject) ->
|
|
||||||
read = fs.createReadStream(qemu)
|
|
||||||
write = fs.createWriteStream(binPath)
|
|
||||||
|
|
||||||
read
|
|
||||||
.on('error', reject)
|
|
||||||
.pipe(write)
|
|
||||||
.on('error', reject)
|
|
||||||
.on('finish', resolve)
|
|
||||||
.then ->
|
|
||||||
fs.chmod(binPath, '755')
|
|
||||||
.then ->
|
|
||||||
path.relative(context, binPath)
|
|
||||||
|
|
||||||
exports.getQemuPath = getQemuPath = (arch) ->
|
|
||||||
balena = getBalenaSdk()
|
|
||||||
path = require('path')
|
|
||||||
fs = require('mz/fs')
|
|
||||||
|
|
||||||
balena.settings.get('binDirectory')
|
|
||||||
.then (binDir) ->
|
|
||||||
Promise.resolve(fs.mkdir(binDir))
|
|
||||||
.catch(code: 'EEXIST', ->)
|
|
||||||
.then ->
|
|
||||||
path.join(binDir, "#{QEMU_BIN_NAME}-#{arch}-#{QEMU_VERSION}")
|
|
||||||
|
|
||||||
exports.installQemu = (arch) ->
|
|
||||||
request = require('request')
|
|
||||||
fs = require('fs')
|
|
||||||
zlib = require('zlib')
|
|
||||||
tar = require('tar-stream')
|
|
||||||
|
|
||||||
getQemuPath(arch)
|
|
||||||
.then (qemuPath) ->
|
|
||||||
new Promise (resolve, reject) ->
|
|
||||||
installStream = fs.createWriteStream(qemuPath)
|
|
||||||
|
|
||||||
qemuArch = balenaArchToQemuArch(arch)
|
|
||||||
downloadArchiveName = "qemu-#{QEMU_VERSION.replace(/^v/, '')}-#{qemuArch}.tar.gz"
|
|
||||||
qemuUrl = "https://github.com/balena-io/qemu/releases/download/#{QEMU_VERSION}/#{downloadArchiveName}"
|
|
||||||
|
|
||||||
extract = tar.extract()
|
|
||||||
extract.on 'entry', (header, stream, next) ->
|
|
||||||
stream.on('end', next)
|
|
||||||
if header.name.includes("qemu-#{qemuArch}-static")
|
|
||||||
stream.pipe(installStream)
|
|
||||||
else
|
|
||||||
stream.resume()
|
|
||||||
|
|
||||||
request(qemuUrl)
|
|
||||||
.on('error', reject)
|
|
||||||
.pipe(zlib.createGunzip())
|
|
||||||
.on('error', reject)
|
|
||||||
.pipe(extract)
|
|
||||||
.on('error', reject)
|
|
||||||
.on 'finish', ->
|
|
||||||
fs.chmodSync(qemuPath, '755')
|
|
||||||
resolve()
|
|
||||||
|
|
||||||
balenaArchToQemuArch = (arch) ->
|
|
||||||
switch arch
|
|
||||||
when 'armv7hf', 'rpi', 'armhf' then 'arm'
|
|
||||||
when 'aarch64' then 'aarch64'
|
|
||||||
else throw new Error("Cannot install emulator for architecture #{arch}")
|
|
22
lib/utils/qemu.d.ts
vendored
22
lib/utils/qemu.d.ts
vendored
@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2019 Balena Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const QEMU_VERSION: string;
|
|
||||||
export const QEMU_BIN_NAME: string;
|
|
||||||
|
|
||||||
export async function getQemuPath(arch: string): Promise<string>;
|
|
||||||
export async function installQemu(arch: string): Promise<void>;
|
|
128
lib/utils/qemu.js
Normal file
128
lib/utils/qemu.js
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017-2020 Balena Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as Promise from 'bluebird';
|
||||||
|
import { getBalenaSdk } from './lazy';
|
||||||
|
export const QEMU_VERSION = 'v4.0.0-balena';
|
||||||
|
export const QEMU_BIN_NAME = 'qemu-execve';
|
||||||
|
|
||||||
|
export function qemuPathInContext(context) {
|
||||||
|
const path = require('path');
|
||||||
|
const binDir = path.join(context, '.balena');
|
||||||
|
const binPath = path.join(binDir, QEMU_BIN_NAME);
|
||||||
|
return path.relative(context, binPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function copyQemu(context, arch) {
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('mz/fs');
|
||||||
|
// Create a hidden directory in the build context, containing qemu
|
||||||
|
const binDir = path.join(context, '.balena');
|
||||||
|
const binPath = path.join(binDir, QEMU_BIN_NAME);
|
||||||
|
|
||||||
|
return Promise.resolve(fs.mkdir(binDir))
|
||||||
|
.catch({ code: 'EEXIST' }, function() {
|
||||||
|
// noop
|
||||||
|
})
|
||||||
|
.then(() => getQemuPath(arch))
|
||||||
|
.then(
|
||||||
|
qemu =>
|
||||||
|
new Promise(function(resolve, reject) {
|
||||||
|
const read = fs.createReadStream(qemu);
|
||||||
|
const write = fs.createWriteStream(binPath);
|
||||||
|
|
||||||
|
read
|
||||||
|
.on('error', reject)
|
||||||
|
.pipe(write)
|
||||||
|
.on('error', reject)
|
||||||
|
.on('finish', resolve);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then(() => fs.chmod(binPath, '755'))
|
||||||
|
.then(() => path.relative(context, binPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getQemuPath = function(arch) {
|
||||||
|
const balena = getBalenaSdk();
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('mz/fs');
|
||||||
|
|
||||||
|
return balena.settings.get('binDirectory').then(binDir =>
|
||||||
|
Promise.resolve(fs.mkdir(binDir))
|
||||||
|
.catch({ code: 'EEXIST' }, function() {
|
||||||
|
// noop
|
||||||
|
})
|
||||||
|
.then(() =>
|
||||||
|
path.join(binDir, `${QEMU_BIN_NAME}-${arch}-${QEMU_VERSION}`),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function installQemu(arch) {
|
||||||
|
const request = require('request');
|
||||||
|
const fs = require('fs');
|
||||||
|
const zlib = require('zlib');
|
||||||
|
const tar = require('tar-stream');
|
||||||
|
|
||||||
|
return getQemuPath(arch).then(
|
||||||
|
qemuPath =>
|
||||||
|
new Promise(function(resolve, reject) {
|
||||||
|
const installStream = fs.createWriteStream(qemuPath);
|
||||||
|
|
||||||
|
const qemuArch = balenaArchToQemuArch(arch);
|
||||||
|
const downloadArchiveName = `qemu-${QEMU_VERSION.replace(
|
||||||
|
/^v/,
|
||||||
|
'',
|
||||||
|
)}-${qemuArch}.tar.gz`;
|
||||||
|
const qemuUrl = `https://github.com/balena-io/qemu/releases/download/${QEMU_VERSION}/${downloadArchiveName}`;
|
||||||
|
|
||||||
|
const extract = tar.extract();
|
||||||
|
extract.on('entry', function(header, stream, next) {
|
||||||
|
stream.on('end', next);
|
||||||
|
if (header.name.includes(`qemu-${qemuArch}-static`)) {
|
||||||
|
stream.pipe(installStream);
|
||||||
|
} else {
|
||||||
|
stream.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return request(qemuUrl)
|
||||||
|
.on('error', reject)
|
||||||
|
.pipe(zlib.createGunzip())
|
||||||
|
.on('error', reject)
|
||||||
|
.pipe(extract)
|
||||||
|
.on('error', reject)
|
||||||
|
.on('finish', function() {
|
||||||
|
fs.chmodSync(qemuPath, '755');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var balenaArchToQemuArch = function(arch) {
|
||||||
|
switch (arch) {
|
||||||
|
case 'armv7hf':
|
||||||
|
case 'rpi':
|
||||||
|
case 'armhf':
|
||||||
|
return 'arm';
|
||||||
|
case 'aarch64':
|
||||||
|
return 'aarch64';
|
||||||
|
default:
|
||||||
|
throw new Error(`Cannot install emulator for architecture ${arch}`);
|
||||||
|
}
|
||||||
|
};
|
9
npm-shrinkwrap.json
generated
9
npm-shrinkwrap.json
generated
@ -1135,6 +1135,15 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/moment-duration-format": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/moment-duration-format/-/moment-duration-format-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-CuYswsMI3y5uR5sD9i/VUqIbZrsYN2eaCs7nH3qpDl2CZlNI48mjMf4ve2RpQ/65irprtnQVetfnea9my+jqcg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"moment": ">=2.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/mz": {
|
"@types/mz": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mz/-/mz-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mz/-/mz-2.7.0.tgz",
|
||||||
|
@ -119,6 +119,7 @@
|
|||||||
"@types/mkdirp": "^0.5.2",
|
"@types/mkdirp": "^0.5.2",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/mock-require": "^2.0.0",
|
"@types/mock-require": "^2.0.0",
|
||||||
|
"@types/moment-duration-format": "^2.2.2",
|
||||||
"@types/mz": "^2.7.0",
|
"@types/mz": "^2.7.0",
|
||||||
"@types/net-keepalive": "^0.4.0",
|
"@types/net-keepalive": "^0.4.0",
|
||||||
"@types/nock": "^11.0.7",
|
"@types/nock": "^11.0.7",
|
||||||
|
Loading…
Reference in New Issue
Block a user