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:
Josh Wilsdon 2018-02-19 17:28:42 -08:00
parent 3f243f8c8f
commit 26b97b5bed
9 changed files with 205 additions and 7 deletions

View File

@ -6,6 +6,13 @@ Known issues:
## 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
- [TRITON-116] node-triton image sharing. Adds `triton image share` and

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright 2016 Joyent, Inc.
* Copyright 2018 Joyent, Inc.
*
* `triton fwrule instances ...`
*/
@ -111,6 +111,7 @@ function do_instances(subcmd, opts, args, cb) {
common.uuidToShortId(inst.image);
inst.shortid = inst.id.split('-', 1)[0];
var flags = [];
if (inst.brand === 'bhyve') flags.push('B');
if (inst.docker) flags.push('D');
if (inst.firewall_enabled) flags.push('F');
if (inst.brand === 'kvm') flags.push('K');
@ -159,6 +160,7 @@ do_instances.help = [
'for convenience):',
' shortid* A short ID prefix.',
' flags* Single letter flags summarizing some fields:',
' "B" the brand is "bhyve"',
' "D" docker instance',
' "F" firewall is enabled',
' "K" the brand is "kvm"',

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright 2017 Joyent, Inc.
* Copyright 2018 Joyent, Inc.
*
* `triton instance create ...`
*/
@ -376,6 +376,9 @@ function do_create(subcmd, opts, args, cb) {
function (net) { return net.id; })
};
if (opts.brand) {
createOpts.brand = opts.brand;
}
if (ctx.volMounts) {
createOpts.volumes = ctx.volMounts;
}
@ -492,6 +495,13 @@ do_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'],
helpArg: 'NAME',

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2017, Joyent, Inc.
* Copyright (c) 2018, Joyent, Inc.
*
* `triton instance list ...`
*/
@ -150,6 +150,7 @@ function do_list(subcmd, opts, args, callback) {
common.uuidToShortId(inst.image);
inst.shortid = inst.id.split('-', 1)[0];
var flags = [];
if (inst.brand === 'bhyve') flags.push('B');
if (inst.docker) flags.push('D');
if (inst.firewall_enabled) flags.push('F');
if (inst.brand === 'kvm') flags.push('K');
@ -208,6 +209,7 @@ do_list.help = [
'for convenience):',
' shortid* A short ID prefix.',
' flags* Single letter flags summarizing some fields:',
' "B" the brand is "bhyve"',
' "D" docker instance',
' "F" firewall is enabled',
' "K" the brand is "kvm"',

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright 2016 Joyent, Inc.
* Copyright 2018 Joyent, Inc.
*
* `triton snapshot create ...`
*/
@ -133,7 +133,7 @@ do_create.help = [
'{{usage}}',
'',
'{{options}}',
'Snapshot do not work for instances of type "kvm".'
'Snapshots do not work for instances of type "bhyve" or "kvm".'
].join('\n');
do_create.completionArgtypes = ['tritoninstance', 'none'];

View File

@ -1,7 +1,7 @@
{
"name": "triton",
"description": "Joyent Triton CLI and client (https://www.joyent.com/triton)",
"version": "5.7.0",
"version": "5.8.0",
"author": "Joyent (joyent.com)",
"homepage": "https://github.com/joyent/node-triton",
"dependencies": {

View File

@ -26,6 +26,11 @@
// to true.
"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
// not support KVM (no KVM packages or images available).
"skipKvmTests": false,
@ -36,6 +41,12 @@
"resizePackage": "<package name>",
"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 smallest RAM package with "kvm" in the name, the latest
// ubuntu-certified image.

View 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();
});
});
});

View File

@ -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.
*
@ -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.
*
@ -511,8 +583,10 @@ module.exports = {
deleteTestImg: deleteTestImg,
getTestImg: getTestImg,
getTestBhyveImg: getTestBhyveImg,
getTestKvmImg: getTestKvmImg,
getTestPkg: getTestPkg,
getTestBhyvePkg: getTestBhyvePkg,
getTestKvmPkg: getTestKvmPkg,
getResizeTestPkg: getResizeTestPkg,