TRITON-124 add node-triton support for bhyve
Reviewed by: Trent Mick <trentm@gmail.com> Approved by: Trent Mick <trentm@gmail.com>
This commit is contained in:
parent
3f243f8c8f
commit
26b97b5bed
@ -6,6 +6,13 @@ Known issues:
|
|||||||
|
|
||||||
## not yet released
|
## not yet released
|
||||||
|
|
||||||
|
## 5.8.0
|
||||||
|
|
||||||
|
- [TRITON-124] add node-triton support for bhyve. This adds a `triton instance
|
||||||
|
create --brand=bhyve ...` option that can be used for zvol images that support
|
||||||
|
it. Note that bhyve support is alpha in TritonDC -- most datacenters won't yet
|
||||||
|
support this option.
|
||||||
|
|
||||||
## 5.7.0
|
## 5.7.0
|
||||||
|
|
||||||
- [TRITON-116] node-triton image sharing. Adds `triton image share` and
|
- [TRITON-116] node-triton image sharing. Adds `triton image share` and
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Joyent, Inc.
|
* Copyright 2018 Joyent, Inc.
|
||||||
*
|
*
|
||||||
* `triton fwrule instances ...`
|
* `triton fwrule instances ...`
|
||||||
*/
|
*/
|
||||||
@ -111,6 +111,7 @@ function do_instances(subcmd, opts, args, cb) {
|
|||||||
common.uuidToShortId(inst.image);
|
common.uuidToShortId(inst.image);
|
||||||
inst.shortid = inst.id.split('-', 1)[0];
|
inst.shortid = inst.id.split('-', 1)[0];
|
||||||
var flags = [];
|
var flags = [];
|
||||||
|
if (inst.brand === 'bhyve') flags.push('B');
|
||||||
if (inst.docker) flags.push('D');
|
if (inst.docker) flags.push('D');
|
||||||
if (inst.firewall_enabled) flags.push('F');
|
if (inst.firewall_enabled) flags.push('F');
|
||||||
if (inst.brand === 'kvm') flags.push('K');
|
if (inst.brand === 'kvm') flags.push('K');
|
||||||
@ -159,6 +160,7 @@ do_instances.help = [
|
|||||||
'for convenience):',
|
'for convenience):',
|
||||||
' shortid* A short ID prefix.',
|
' shortid* A short ID prefix.',
|
||||||
' flags* Single letter flags summarizing some fields:',
|
' flags* Single letter flags summarizing some fields:',
|
||||||
|
' "B" the brand is "bhyve"',
|
||||||
' "D" docker instance',
|
' "D" docker instance',
|
||||||
' "F" firewall is enabled',
|
' "F" firewall is enabled',
|
||||||
' "K" the brand is "kvm"',
|
' "K" the brand is "kvm"',
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Joyent, Inc.
|
* Copyright 2018 Joyent, Inc.
|
||||||
*
|
*
|
||||||
* `triton instance create ...`
|
* `triton instance create ...`
|
||||||
*/
|
*/
|
||||||
@ -376,6 +376,9 @@ function do_create(subcmd, opts, args, cb) {
|
|||||||
function (net) { return net.id; })
|
function (net) { return net.id; })
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (opts.brand) {
|
||||||
|
createOpts.brand = opts.brand;
|
||||||
|
}
|
||||||
if (ctx.volMounts) {
|
if (ctx.volMounts) {
|
||||||
createOpts.volumes = ctx.volMounts;
|
createOpts.volumes = ctx.volMounts;
|
||||||
}
|
}
|
||||||
@ -492,6 +495,13 @@ do_create.options = [
|
|||||||
{
|
{
|
||||||
group: 'Create options'
|
group: 'Create options'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
names: ['brand'],
|
||||||
|
helpArg: 'BRAND',
|
||||||
|
type: 'string',
|
||||||
|
help: 'Override the default brand for this instance. Most users will ' +
|
||||||
|
'not need this option.'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
names: ['name', 'n'],
|
names: ['name', 'n'],
|
||||||
helpArg: 'NAME',
|
helpArg: 'NAME',
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Joyent, Inc.
|
* Copyright (c) 2018, Joyent, Inc.
|
||||||
*
|
*
|
||||||
* `triton instance list ...`
|
* `triton instance list ...`
|
||||||
*/
|
*/
|
||||||
@ -150,6 +150,7 @@ function do_list(subcmd, opts, args, callback) {
|
|||||||
common.uuidToShortId(inst.image);
|
common.uuidToShortId(inst.image);
|
||||||
inst.shortid = inst.id.split('-', 1)[0];
|
inst.shortid = inst.id.split('-', 1)[0];
|
||||||
var flags = [];
|
var flags = [];
|
||||||
|
if (inst.brand === 'bhyve') flags.push('B');
|
||||||
if (inst.docker) flags.push('D');
|
if (inst.docker) flags.push('D');
|
||||||
if (inst.firewall_enabled) flags.push('F');
|
if (inst.firewall_enabled) flags.push('F');
|
||||||
if (inst.brand === 'kvm') flags.push('K');
|
if (inst.brand === 'kvm') flags.push('K');
|
||||||
@ -208,6 +209,7 @@ do_list.help = [
|
|||||||
'for convenience):',
|
'for convenience):',
|
||||||
' shortid* A short ID prefix.',
|
' shortid* A short ID prefix.',
|
||||||
' flags* Single letter flags summarizing some fields:',
|
' flags* Single letter flags summarizing some fields:',
|
||||||
|
' "B" the brand is "bhyve"',
|
||||||
' "D" docker instance',
|
' "D" docker instance',
|
||||||
' "F" firewall is enabled',
|
' "F" firewall is enabled',
|
||||||
' "K" the brand is "kvm"',
|
' "K" the brand is "kvm"',
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Joyent, Inc.
|
* Copyright 2018 Joyent, Inc.
|
||||||
*
|
*
|
||||||
* `triton snapshot create ...`
|
* `triton snapshot create ...`
|
||||||
*/
|
*/
|
||||||
@ -133,7 +133,7 @@ do_create.help = [
|
|||||||
'{{usage}}',
|
'{{usage}}',
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Snapshot do not work for instances of type "kvm".'
|
'Snapshots do not work for instances of type "bhyve" or "kvm".'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_create.completionArgtypes = ['tritoninstance', 'none'];
|
do_create.completionArgtypes = ['tritoninstance', 'none'];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "triton",
|
"name": "triton",
|
||||||
"description": "Joyent Triton CLI and client (https://www.joyent.com/triton)",
|
"description": "Joyent Triton CLI and client (https://www.joyent.com/triton)",
|
||||||
"version": "5.7.0",
|
"version": "5.8.0",
|
||||||
"author": "Joyent (joyent.com)",
|
"author": "Joyent (joyent.com)",
|
||||||
"homepage": "https://github.com/joyent/node-triton",
|
"homepage": "https://github.com/joyent/node-triton",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -26,6 +26,11 @@
|
|||||||
// to true.
|
// to true.
|
||||||
"skipAffinityTests": false,
|
"skipAffinityTests": false,
|
||||||
|
|
||||||
|
// Optional. Set to 'true' to skip testing of bhyve things. Some DCs might
|
||||||
|
// not support bhyve (no packages or images available, and/or no CNs with
|
||||||
|
// bhyve compatible hardware).
|
||||||
|
"skipBhyveTests": false,
|
||||||
|
|
||||||
// Optional. Set to 'true' to skip testing of KVM things. Some DCs might
|
// Optional. Set to 'true' to skip testing of KVM things. Some DCs might
|
||||||
// not support KVM (no KVM packages or images available).
|
// not support KVM (no KVM packages or images available).
|
||||||
"skipKvmTests": false,
|
"skipKvmTests": false,
|
||||||
@ -36,6 +41,12 @@
|
|||||||
"resizePackage": "<package name>",
|
"resizePackage": "<package name>",
|
||||||
"image": "<image uuid, name or name@version>"
|
"image": "<image uuid, name or name@version>"
|
||||||
|
|
||||||
|
// The params used for test *bhyve* provisions. By default the tests use:
|
||||||
|
// the smallest RAM package with "kvm" in the name, the latest
|
||||||
|
// ubuntu-certified image.
|
||||||
|
"bhyvePackage": "<package name or uuid>",
|
||||||
|
"bhyveImage": "<image uuid, name or name@version>",
|
||||||
|
|
||||||
// The params used for test *KVM* provisions. By default the tests use:
|
// The params used for test *KVM* provisions. By default the tests use:
|
||||||
// the smallest RAM package with "kvm" in the name, the latest
|
// the smallest RAM package with "kvm" in the name, the latest
|
||||||
// ubuntu-certified image.
|
// ubuntu-certified image.
|
||||||
|
92
test/integration/cli-instance-create-bhyve.test.js
Normal file
92
test/integration/cli-instance-create-bhyve.test.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2018, Joyent, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test creating a bhyve VM.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var os = require('os');
|
||||||
|
|
||||||
|
var format = require('util').format;
|
||||||
|
var test = require('tape');
|
||||||
|
|
||||||
|
var h = require('./helpers');
|
||||||
|
|
||||||
|
|
||||||
|
// --- globals
|
||||||
|
|
||||||
|
var INST_ALIAS = 'nodetritontest-instance-create-bhyve-' +
|
||||||
|
os.hostname();
|
||||||
|
|
||||||
|
var testOpts = {
|
||||||
|
skip: !h.CONFIG.allowWriteActions || h.CONFIG.skipBhyveTests
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// --- Tests
|
||||||
|
|
||||||
|
test('triton image ...', testOpts, function (tt) {
|
||||||
|
var imgId;
|
||||||
|
var inst;
|
||||||
|
var pkgId;
|
||||||
|
|
||||||
|
tt.comment('Test config:');
|
||||||
|
Object.keys(h.CONFIG).forEach(function (key) {
|
||||||
|
var value = h.CONFIG[key];
|
||||||
|
tt.comment(format('- %s: %j', key, value));
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: `triton rm -f` would be helpful for this
|
||||||
|
tt.test(' setup: rm existing inst ' + INST_ALIAS, function (t) {
|
||||||
|
h.deleteTestInst(t, INST_ALIAS, function onDel() {
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tt.test(' setup: find image', function (t) {
|
||||||
|
h.getTestBhyveImg(t, function (err, _imgId) {
|
||||||
|
t.ifError(err, 'getTestImg' + (err ? ': ' + err : ''));
|
||||||
|
imgId = _imgId;
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tt.test(' setup: find test package', function (t) {
|
||||||
|
h.getTestBhyvePkg(t, function (err, _pkgId) {
|
||||||
|
t.ifError(err, 'getTestPkg' + (err ? ': ' + err : ''));
|
||||||
|
pkgId = _pkgId;
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tt.test(' setup: triton create ... -n ' + INST_ALIAS, function (t) {
|
||||||
|
var argv = ['create', '-wj', '--brand=bhyve', '-n', INST_ALIAS,
|
||||||
|
imgId, pkgId];
|
||||||
|
h.safeTriton(t, argv, function (err, stdout) {
|
||||||
|
var lines = h.jsonStreamParse(stdout);
|
||||||
|
inst = lines[1];
|
||||||
|
t.ok(inst.id, 'inst.id: ' + inst.id);
|
||||||
|
t.equal(lines[1].state, 'running', 'inst is running');
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: Once have `triton ssh ...` working in test suite without hangs,
|
||||||
|
// then want to check that the created VM works.
|
||||||
|
|
||||||
|
// Remove instance. Add a test timeout, because '-w' on delete doesn't
|
||||||
|
// have a way to know if the attempt failed or if it is just taking a
|
||||||
|
// really long time.
|
||||||
|
tt.test(' cleanup: triton rm', {timeout: 10 * 60 * 1000}, function (t) {
|
||||||
|
h.safeTriton(t, ['rm', '-w', inst.id], function () {
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Joyent, Inc.
|
* Copyright 2018 Joyent, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -211,6 +211,46 @@ function getTestImg(t, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and return an image that can be used for test *bhyve* provisions.
|
||||||
|
*
|
||||||
|
* @param {Tape} t - tape test object
|
||||||
|
* @param {Function} cb - `function (err, imgId)`
|
||||||
|
* where `imgId` is an image identifier (an image name, shortid, or id).
|
||||||
|
*/
|
||||||
|
function getTestBhyveImg(t, cb) {
|
||||||
|
if (CONFIG.bhyveImage) {
|
||||||
|
assert.string(CONFIG.bhyvePackage, 'CONFIG.bhyvePackage');
|
||||||
|
t.ok(CONFIG.bhyveImage, 'bhyveImage from config: ' + CONFIG.bhyveImage);
|
||||||
|
cb(null, CONFIG.bhyveImage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidateImageNames = {
|
||||||
|
'ubuntu-certified-16.04': true
|
||||||
|
};
|
||||||
|
safeTriton(t, ['img', 'ls', '-j'], function (err, stdout) {
|
||||||
|
var imgId;
|
||||||
|
var imgs = jsonStreamParse(stdout);
|
||||||
|
// Newest images first.
|
||||||
|
tabula.sortArrayOfObjects(imgs, ['-published_at']);
|
||||||
|
var imgRepr;
|
||||||
|
for (var i = 0; i < imgs.length; i++) {
|
||||||
|
var img = imgs[i];
|
||||||
|
if (candidateImageNames[img.name]) {
|
||||||
|
imgId = img.id;
|
||||||
|
imgRepr = f('%s@%s', img.name, img.version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.ok(imgId,
|
||||||
|
f('latest bhyve image (using subset of supported names): %s (%s)',
|
||||||
|
imgId, imgRepr));
|
||||||
|
cb(err, imgId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find and return an image that can be used for test *KVM* provisions.
|
* Find and return an image that can be used for test *KVM* provisions.
|
||||||
*
|
*
|
||||||
@ -281,6 +321,38 @@ function getTestPkg(t, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find and return an package that can be used for *bhyve* test provisions.
|
||||||
|
*
|
||||||
|
* @param {Tape} t - tape test object
|
||||||
|
* @param {Function} cb - `function (err, pkgId)`
|
||||||
|
* where `pkgId` is an package identifier (a name, shortid, or id).
|
||||||
|
*/
|
||||||
|
function getTestBhyvePkg(t, cb) {
|
||||||
|
if (CONFIG.bhyvePackage) {
|
||||||
|
assert.string(CONFIG.bhyvePackage, 'CONFIG.bhyvePackage');
|
||||||
|
t.ok(CONFIG.bhyvePackage, 'bhyvePackage from config: ' +
|
||||||
|
CONFIG.bhyvePackage);
|
||||||
|
cb(null, CONFIG.bhyvePackage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bhyve uses the same packages as kvm
|
||||||
|
safeTriton(t, ['pkg', 'ls', '-j'], function (err, stdout) {
|
||||||
|
var pkgs = jsonStreamParse(stdout);
|
||||||
|
// Filter on those with 'kvm' in the name.
|
||||||
|
pkgs = pkgs.filter(function (pkg) {
|
||||||
|
return pkg.name.indexOf('kvm') !== -1;
|
||||||
|
});
|
||||||
|
// Smallest RAM first.
|
||||||
|
tabula.sortArrayOfObjects(pkgs, ['memory']);
|
||||||
|
var pkgId = pkgs[0].id;
|
||||||
|
t.ok(pkgId, f('smallest (RAM) available kvm package: %s (%s)',
|
||||||
|
pkgId, pkgs[0].name));
|
||||||
|
cb(null, pkgId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find and return an package that can be used for *KVM* test provisions.
|
* Find and return an package that can be used for *KVM* test provisions.
|
||||||
*
|
*
|
||||||
@ -511,8 +583,10 @@ module.exports = {
|
|||||||
deleteTestImg: deleteTestImg,
|
deleteTestImg: deleteTestImg,
|
||||||
|
|
||||||
getTestImg: getTestImg,
|
getTestImg: getTestImg,
|
||||||
|
getTestBhyveImg: getTestBhyveImg,
|
||||||
getTestKvmImg: getTestKvmImg,
|
getTestKvmImg: getTestKvmImg,
|
||||||
getTestPkg: getTestPkg,
|
getTestPkg: getTestPkg,
|
||||||
|
getTestBhyvePkg: getTestBhyvePkg,
|
||||||
getTestKvmPkg: getTestKvmPkg,
|
getTestKvmPkg: getTestKvmPkg,
|
||||||
getResizeTestPkg: getResizeTestPkg,
|
getResizeTestPkg: getResizeTestPkg,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user