From 9562ddad5c62d1ea333cfaccb05ef350b40eb586 Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Fri, 29 Jul 2022 17:33:14 -0400 Subject: [PATCH 1/7] weak-ass start --- src/dockerinit/mdata-client/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/dockerinit/mdata-client/README.md b/src/dockerinit/mdata-client/README.md index f0bc1e206..cfeb95d7a 100644 --- a/src/dockerinit/mdata-client/README.md +++ b/src/dockerinit/mdata-client/README.md @@ -1,12 +1,13 @@ # mdata-client This repository contains metadata retrieval and manipulation tools for use -within guests of the SmartOS (and SDC) hypervisor. These guests may be either -SmartOS Zones or KVM virtual machines. +within guests of the SmartOS (and Triton) hypervisor. These guests may be +either SmartOS Zones or KVM virtual machines. -This repository is part of the Joyent SmartDataCenter project (SDC). For -contribution guidelines, issues, and general documentation, visit the main -[SDC](http://github.com/joyent/sdc) project page. +This repository is part of the Triton Data Center project (formerly known as +SmartDataCenter, hence SDC). For contribution guidelines, issues, and +general documentation, visit the main +[Triton](http://github.com/TritonDataCenter/triton) project page. # Commands From 72f499e4c0aec698628c89727979906539747146 Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Thu, 20 Oct 2022 13:44:18 -0400 Subject: [PATCH 2/7] Fix up tools (hopefully correctly) --- tools/jr-manifest.json | 2 +- tools/smartos-release | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/jr-manifest.json b/tools/jr-manifest.json index fd67e0695..660efd26d 100644 --- a/tools/jr-manifest.json +++ b/tools/jr-manifest.json @@ -2,7 +2,7 @@ "jrVersion": 1, "description": "SmartOS platform public repositories", "repoCandidateSearch": { - "description": "public github.com/joyent repos directly relevant to development of SmartOS", + "description": "public github.com/TritonDataCenter repos directly relevant to development of SmartOS", "type": "public", "includeArchived": false }, diff --git a/tools/smartos-release b/tools/smartos-release index a2f3a2a99..af67274bd 100755 --- a/tools/smartos-release +++ b/tools/smartos-release @@ -14,9 +14,9 @@ # This script is run as part of the biweekly SmartOS release process. It # uploads the release artifacts from the platform build bits directory to # ~~/public/SmartOS// , for processing -# by the https://github.com/joyent/smartos-changelog generator, and uploads -# the 'latest' release artifacts to ~~/public/SmartOS/*-latest.* to preserve -# compatibility with scripts that expect to find them there. +# by the https://github.com/TritonDataCenter/smartos-changelog generator, +# and uploads the 'latest' release artifacts to ~~/public/SmartOS/*-latest.* +# to preserve compatibility with scripts that expect to find them there. # # Update the SmartOS release directory From 197bd1745630ee48d9b925eca3f09ef7a4499b1e Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Tue, 1 Nov 2022 10:48:51 -0400 Subject: [PATCH 3/7] More low-hanging fruit --- src/dockerinit/mdata-client/README.md | 6 +++--- src/dockerinit/mdata-client/debian/control | 4 ++-- src/fw/package.json | 2 +- src/piadm.sh | 1 + 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dockerinit/mdata-client/README.md b/src/dockerinit/mdata-client/README.md index cfeb95d7a..8df352823 100644 --- a/src/dockerinit/mdata-client/README.md +++ b/src/dockerinit/mdata-client/README.md @@ -46,9 +46,9 @@ is absolutely welcome. MIT (See _LICENSE_.) -[mdata_docs]: http://eng.joyent.com/mdata/ -[protocol]: http://eng.joyent.com/mdata/protocol.html -[datadict]: http://eng.joyent.com/mdata/datadict.html +[mdata_docs]: http://eng.tritondatacenter.com/mdata/ +[protocol]: http://eng.tritondatacenter.com/mdata/protocol.html +[datadict]: http://eng.tritondatacenter.com/mdata/datadict.html [mdata_get]: http://smartos.org/man/8/mdata-get [mdata_delete]: http://smartos.org/man/8/mdata-delete [mdata_put]: http://smartos.org/man/8/mdata-put diff --git a/src/dockerinit/mdata-client/debian/control b/src/dockerinit/mdata-client/debian/control index 0aaafcfe6..de6967e92 100644 --- a/src/dockerinit/mdata-client/debian/control +++ b/src/dockerinit/mdata-client/debian/control @@ -1,5 +1,5 @@ Source: joyent-mdata-client -Maintainer: Joshua M. Clulow +Maintainer: SmartOS Community Section: misc Priority: optional Standards-Version: 3.9.4 @@ -8,6 +8,6 @@ Build-Depends: debhelper (>= 8) Package: joyent-mdata-client Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Homepage: https://github.com/joyent/mdata-client +Homepage: https://github.com/TritonDataCenter/mdata-client Description: Metadata client tools for use in guest virtual machines hosted on a SmartOS hypervisor. diff --git a/src/fw/package.json b/src/fw/package.json index 12d0b195d..e3db1ad16 100644 --- a/src/fw/package.json +++ b/src/fw/package.json @@ -2,7 +2,7 @@ "name": "fw", "description": "Administrative tool for managing SmartOS VM firewalls", "version": "1.2.2", - "author": "Joyent (joyent.com)", + "author": "SmartOS (smartos.org)", "private": true, "main": "./lib/fw.js", "devDependencies": { diff --git a/src/piadm.sh b/src/piadm.sh index e96b41ddd..581df55c8 100755 --- a/src/piadm.sh +++ b/src/piadm.sh @@ -109,6 +109,7 @@ getbootable() { numbootfs=${#allbootfs[@]} } +# NOTE: If/when we change the uname information, we'll need to change the sed. declare activestamp activestamp=$(uname -v | sed 's/joyent_//g') declare installstamp From c819e9a47cf32e6805b1ea72a306c26422f20ac5 Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Wed, 2 Nov 2022 09:37:59 -0400 Subject: [PATCH 4/7] Last back skipping package.json. May need to alter src/vm/runtest... --- src/img/CHANGES.md | 8 ++++---- src/img/node_modules/imgmanifest/lib/imgmanifest.js | 4 ++-- src/vm/lib/metadata/agent.js | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/img/CHANGES.md b/src/img/CHANGES.md index 431270444..d1c1d682c 100644 --- a/src/img/CHANGES.md +++ b/src/img/CHANGES.md @@ -21,7 +21,7 @@ Known issues: ## 3.9.3 -- joyent/smartos-live#771 imgadm vacuum will try to reap images used by bhyve vms +- TritonDataCenter/smartos-live#771 imgadm vacuum will try to reap images used by bhyve vms ## 3.9.2 @@ -39,7 +39,7 @@ Known issues: ## 3.8.0 -- joyent/imgadm#644 Update imgadm to use newer docker-registry-client so it can +- TritonDataCenter/imgadm#644 Update imgadm to use newer docker-registry-client so it can pull from v2 registries. Docker v1 registry pulls are no longer supported. ## 3.7.4 @@ -175,7 +175,7 @@ Known issues: ## 3.0.0 -- [joyent/smartos-live#120] Support using a HTTP(S) proxy via +- [TritonDataCenter/smartos-live#120] Support using a HTTP(S) proxy via the `https_proxy` or `http_proxy` environment variable. - Docker image import: both in importing images of `type=docker` from an @@ -245,7 +245,7 @@ Known issues: ## 2.6.12 -- [OS-2981, joyent/smartos-live#322] Fix 'imgadm avail' crash with a DSAPI +- [OS-2981, TritonDataCenter/smartos-live#322] Fix 'imgadm avail' crash with a DSAPI image source. diff --git a/src/img/node_modules/imgmanifest/lib/imgmanifest.js b/src/img/node_modules/imgmanifest/lib/imgmanifest.js index 44baa61cc..e4e32cb2b 100644 --- a/src/img/node_modules/imgmanifest/lib/imgmanifest.js +++ b/src/img/node_modules/imgmanifest/lib/imgmanifest.js @@ -6,7 +6,7 @@ /* * Copyright (c) 2018, Joyent, Inc. - * Copyright 2018 MNX Cloud, Inc. + * Copyright 2022 MNX Cloud, Inc. */ /* @@ -183,7 +183,7 @@ function upgradeTo2(oldManifest) { delete manifest.creator_name; delete manifest.cloud_name; - // Bogus field in some datasets.joyent.com/datasets (DATASET-629). + // Bogus field in some datasets.tritondatacenter.com/datasets (DATASET-629). delete manifest.creator_admin; if (manifest.restricted_to_uuid) { diff --git a/src/vm/lib/metadata/agent.js b/src/vm/lib/metadata/agent.js index 4938efec6..ed62ed0cd 100644 --- a/src/vm/lib/metadata/agent.js +++ b/src/vm/lib/metadata/agent.js @@ -21,6 +21,7 @@ * CDDL HEADER END * * Copyright 2019 Joyent, Inc. + * Copyright 2022 MNX Cloud, Inc. * * * # OVERVIEW @@ -66,7 +67,7 @@ * With a socket created and the server listening, the client in the zone can * make queries using the metadata protocol described at: * - * https://eng.joyent.com/mdata/protocol.html + * https://eng.tritondatacenter.com/mdata/protocol.html * * * # CLEANUP AND ERRORS From 77c47156536c17d5895c31d8c6ecdf307be7f58a Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Thu, 17 Nov 2022 16:06:01 -0500 Subject: [PATCH 5/7] A bit more --- configure | 2 +- src/fw/README.md | 8 ++++---- src/fw/test/node_modules/nodeunit/bin/nodeunit | 2 +- src/img/node_modules/imgmanifest/package.json | 4 ++-- src/img/node_modules/sdc-clients/package.json | 4 ++-- src/vm/node_modules/macaddr/package.json | 4 ++-- .../triton-netconfig/node_modules/ip6addr/package.json | 4 ++-- src/vm/node_modules/triton-netconfig/package.json | 10 +++++----- src/vm/node_modules/vasync/package.json | 8 ++++---- src/vm/package.json | 2 +- src/vm/tests/test-validate-payload.js | 3 ++- 11 files changed, 26 insertions(+), 25 deletions(-) diff --git a/configure b/configure index cbb0b8c2c..485189e18 100755 --- a/configure +++ b/configure @@ -40,7 +40,7 @@ fi # We configure the projects framework using a 'configure-projects' file. This # is a plain text file which contains the project name, the branch we wish to # build it at, and either a URL to a git repository or 'origin' to denote the -# github.com/joyent/ location. See create_projects. +# github.com/TritonDataCenter/ location. See create_projects. # read -r -d '' configure_projects < default.configure-projects diff --git a/src/fw/README.md b/src/fw/README.md index c5f2a07f6..dc77014e3 100644 --- a/src/fw/README.md +++ b/src/fw/README.md @@ -1,10 +1,10 @@ # fwadm -Repository: -Browsing: +Repository: +Browsing: Who: SmartOS mailing list -Docs: -Tickets/bugs: +Docs: +Tickets/bugs: # Overview diff --git a/src/fw/test/node_modules/nodeunit/bin/nodeunit b/src/fw/test/node_modules/nodeunit/bin/nodeunit index e3e15b57c..91ba5adff 100755 --- a/src/fw/test/node_modules/nodeunit/bin/nodeunit +++ b/src/fw/test/node_modules/nodeunit/bin/nodeunit @@ -4,7 +4,7 @@ var fs = require('fs'), path = require('path'); -// TODO: remove this when https://github.com/joyent/node/pull/1312 +// TODO: remove this when https://github.com/TritonDataCenter/node/pull/1312 // lands in core. // // Until then, use console.log from npm (https://gist.github.com/1077544) diff --git a/src/img/node_modules/imgmanifest/package.json b/src/img/node_modules/imgmanifest/package.json index c0e2384cb..5b4a9e810 100644 --- a/src/img/node_modules/imgmanifest/package.json +++ b/src/img/node_modules/imgmanifest/package.json @@ -3,8 +3,8 @@ "description": "Library for working with Triton/SDC/SmartOS image manifests", "version": "3.1.0", "author": { - "name": "Joyent", - "url": "joyent.com" + "name": "Triton Data Center", + "url": "tritondatacenter.com" }, "main": "./lib/imgmanifest.js", "dependencies": { diff --git a/src/img/node_modules/sdc-clients/package.json b/src/img/node_modules/sdc-clients/package.json index ff7b6456e..8a467ce9d 100644 --- a/src/img/node_modules/sdc-clients/package.json +++ b/src/img/node_modules/sdc-clients/package.json @@ -2,11 +2,11 @@ "name": "sdc-clients", "description": "Contains node.js client libraries for SDC REST APIs.", "version": "8.2.0", - "homepage": "http://www.joyent.com", + "homepage": "http://www.tritondatacenter.com", "private": true, "repository": { "type": "git", - "url": "https://github.com/joyent/node-sdc-clients.git" + "url": "https://github.com/TritonDataCenter/node-sdc-clients.git" }, "main": "./lib/index.js", "dependencies": { diff --git a/src/vm/node_modules/macaddr/package.json b/src/vm/node_modules/macaddr/package.json index 487977aec..01490f859 100644 --- a/src/vm/node_modules/macaddr/package.json +++ b/src/vm/node_modules/macaddr/package.json @@ -26,8 +26,8 @@ "test": "istanbul cover --print none test/runall.js" }, "author": { - "name": "Joyent", - "url": "joyent.com" + "name": "Triton Data Center", + "url": "tritondatacenter.com" }, "license": "MPL-2.0", "gitHead": "aa5d43b69451aedb4412b860e113c8091d0ed854", diff --git a/src/vm/node_modules/triton-netconfig/node_modules/ip6addr/package.json b/src/vm/node_modules/triton-netconfig/node_modules/ip6addr/package.json index 99cf57d43..600279062 100644 --- a/src/vm/node_modules/triton-netconfig/node_modules/ip6addr/package.json +++ b/src/vm/node_modules/triton-netconfig/node_modules/ip6addr/package.json @@ -19,8 +19,8 @@ "test": "istanbul cover --print none test/runall.js" }, "author": { - "name": "Joyent", - "url": "joyent.com" + "name": "Triton Data Center", + "url": "tritondatacenter.com" }, "license": "MPL-2", "bugs": { diff --git a/src/vm/node_modules/triton-netconfig/package.json b/src/vm/node_modules/triton-netconfig/package.json index b11756371..b6c2443a8 100644 --- a/src/vm/node_modules/triton-netconfig/package.json +++ b/src/vm/node_modules/triton-netconfig/package.json @@ -4,21 +4,21 @@ "description": "Common methods for managing Triton network configuration", "repository": { "type": "git", - "url": "git+https://github.com/joyent/node-triton-netconfig.git" + "url": "git+https://github.com/TritonDataCenter/node-triton-netconfig.git" }, "keywords": [ "joyent", "triton" ], "author": { - "name": "Joyent", - "url": "joyent.com" + "name": "Triton Data Center", + "url": "tritondatacenter.com" }, "license": "MPL-2.0", "engines": [ "node >=4.0.0" ], - "homepage": "https://github.com/joyent/node-triton-netconfig", + "homepage": "https://github.com/TritonDataCenter/node-triton-netconfig", "main": "./lib", "dependencies": { "ip6addr": "0.2.0" @@ -34,7 +34,7 @@ }, "gitHead": "879f7d54dd042a8af8ca950a3c907caf1a3c8361", "bugs": { - "url": "https://github.com/joyent/node-triton-netconfig/issues" + "url": "https://github.com/TritonDataCenter/node-triton-netconfig/issues" }, "_id": "triton-netconfig@1.2.0", "_npmVersion": "6.4.1", diff --git a/src/vm/node_modules/vasync/package.json b/src/vm/node_modules/vasync/package.json index 73f2f41f1..80d0a2b06 100644 --- a/src/vm/node_modules/vasync/package.json +++ b/src/vm/node_modules/vasync/package.json @@ -5,7 +5,7 @@ "main": "./lib/vasync.js", "repository": { "type": "git", - "url": "https://github.com/davepacheco/node-vasync.git" + "url": "https://github.com/TritonDataCenter/node-vasync.git" }, "scripts": { "test": "tap --stdout tests/ && ./node_modules/.bin/nodeunit tests/compat.js && ./node_modules/.bin/nodeunit tests/compat_tryEach.js" @@ -22,7 +22,7 @@ ], "license": "MIT", "gitHead": "b267712029d0b7e3e5fe30a8426400027076dfe0", - "readme": "# vasync: observable asynchronous control flow\n\nThis module provides several functions for asynchronous control flow. There are\nmany modules that do this already (notably async.js). This one's claim to fame\nis improved debuggability.\n\n\n## Observability is important\n\nWorking with Node's asynchronous, callback-based model is much easier with a\nhandful of simple control-flow abstractions, like:\n\n* waterfalls and pipelines (which invoke a list of asynchronous callbacks\n sequentially)\n* parallel pipelines (which invoke a list of asynchronous callbacks in parallel\n and invoke a top-level callback when the last one completes).\n* queues\n* barriers\n\nBut these structures also introduce new types of programming errors: failing to\ninvoke the callback can cause the program to hang, and inadvertently invoking it\ntwice can cause all kinds of mayhem that's very difficult to debug.\n\nThe functions in this module keep track of what's going on so that you can\nfigure out what happened when your program goes wrong. They generally return an\nobject describing details of the current state. If your program goes wrong, you\nhave several ways of getting at this state:\n\n* On illumos-based systems, use MDB to [find the status object](http://dtrace.org/blogs/bmc/2012/05/05/debugging-node-js-memory-leaks/)\n and then [print it out](http://dtrace.org/blogs/dap/2012/01/13/playing-with-nodev8-postmortem-debugging/).\n* Provide an HTTP API (or AMQP, or whatever) that returns these pending status\n objects as JSON (see [kang](https://github.com/davepacheco/kang)).\n* Incorporate a REPL into your program and print out the status object.\n* Use the Node debugger to print out the status object.\n\n## Functions\n\n* [parallel](#parallel-invoke-n-functions-in-parallel): invoke N functions in\n parallel (and merge the results)\n* [forEachParallel](#foreachparallel-invoke-the-same-function-on-n-inputs-in-parallel):\n invoke the same function on N inputs in parallel\n* [pipeline](#pipeline-invoke-n-functions-in-series-and-stop-on-failure): invoke\n N functions in series (and stop on failure)\n* [tryEach](#tryeach-invoke-n-functions-in-series-and-stop-on-success): invoke\n N functions in series (and stop on success)\n* [forEachPipeline](#foreachpipeline-invoke-the-same-function-on-n-inputs-in-series-and-stop-on-failure):\n invoke the same function on N inputs in series (and stop on failure)\n* [filter/filterSeries/filterLimit](#filterfilterlimitfilterseries-filter-n-inputs-serially-or-concurrently):\n filter N inputs serially or concurrently\n* [whilst](#whilst-invoke-a-function-repeatedly-until-a-stopping-condition-is-met):\n invoke a function repeatedly until a stopping condition is met\n* [waterfall](#waterfall-invoke-n-functions-in-series-stop-on-failure-and-propagate-results):\n like pipeline, but propagating results between stages\n* [barrier](#barrier-coordinate-multiple-concurrent-operations): coordinate\n multiple concurrent operations\n* [queue/queuev](#queuequeuev-fixed-size-worker-queue): fixed-size worker queue\n\n### parallel: invoke N functions in parallel\n\nSynopsis: `parallel(args, callback)`\n\nThis function takes a list of input functions (specified by the \"funcs\" property\nof \"args\") and runs them all. These input functions are expected to be\nasynchronous: they get a \"callback\" argument and should invoke it as\n`callback(err, result)`. The error and result will be saved and made available\nto the original caller when all of these functions complete.\n\nThis function returns the same \"result\" object it passes to the callback, and\nyou can use the fields in this object to debug or observe progress:\n\n* `operations`: array corresponding to the input functions, with\n * `func`: input function,\n * `status`: \"pending\", \"ok\", or \"fail\",\n * `err`: returned \"err\" value, if any, and\n * `result`: returned \"result\" value, if any\n* `successes`: \"result\" field for each of \"operations\" where\n \"status\" == \"ok\" (in no particular order)\n* `ndone`: number of input operations that have completed\n* `nerrors`: number of input operations that have failed\n\nThis status object lets you see in a debugger exactly which functions have\ncompleted, what they returned, and which ones are outstanding.\n\nAll errors are combined into a single \"err\" parameter to the final callback (see\nbelow).\n\nExample usage:\n\n```js\nconsole.log(mod_vasync.parallel({\n 'funcs': [\n function f1 (callback) { mod_dns.resolve('joyent.com', callback); },\n function f2 (callback) { mod_dns.resolve('github.com', callback); },\n function f3 (callback) { mod_dns.resolve('asdfaqsdfj.com', callback); }\n ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\nIn the first tick, this outputs:\n\n```js\nstatus: { operations:\n [ { func: [Function: f1], status: 'pending' },\n { func: [Function: f2], status: 'pending' },\n { func: [Function: f3], status: 'pending' } ],\n successes: [],\n ndone: 0,\n nerrors: 0 }\n```\n\nshowing that there are three operations pending and none has yet been started.\nWhen the program finishes, it outputs this error:\n\n error: first of 1 error: queryA ENOTFOUND\n\nwhich encapsulates all of the intermediate failures. This model allows you to\nwrite the final callback like you normally would:\n\n```js\nif (err)\n return (callback(err));\n```\n\nand still propagate useful information to callers that don't deal with multiple\nerrors (i.e. most callers).\n\nThe example also prints out the detailed final status, including all of the\nerrors and return values:\n\n```js\nresults: { operations:\n [ { func: [Function: f1],\n funcname: 'f1',\n status: 'ok',\n err: null,\n result: [ '165.225.132.33' ] },\n { func: [Function: f2],\n funcname: 'f2',\n status: 'ok',\n err: null,\n result: [ '207.97.227.239' ] },\n { func: [Function: f3],\n funcname: 'f3',\n status: 'fail',\n err: { [Error: queryA ENOTFOUND] code: 'ENOTFOUND',\n errno: 'ENOTFOUND', syscall: 'queryA' },\n result: undefined } ],\n successes: [ [ '165.225.132.33' ], [ '207.97.227.239' ] ],\n ndone: 3,\n nerrors: 1 }\n```\n\nYou can use this if you want to handle all of the errors individually or to get\nat all of the individual return values.\n\nNote that \"successes\" is provided as a convenience and the order of items in\nthat array may not correspond to the order of the inputs. To consume output in\nan ordered manner, you should iterate over \"operations\" and pick out the result\nfrom each item.\n\n\n### forEachParallel: invoke the same function on N inputs in parallel\n\nSynopsis: `forEachParallel(args, callback)`\n\nThis function is exactly like `parallel`, except that the input is specified as\na *single* function (\"func\") and a list of inputs (\"inputs\"). The function is\ninvoked on each input in parallel.\n\nThis example is exactly equivalent to the one above:\n\n```js\nconsole.log(mod_vasync.forEachParallel({\n 'func': mod_dns.resolve,\n 'inputs': [ 'joyent.com', 'github.com', 'asdfaqsdfj.com' ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\n### pipeline: invoke N functions in series (and stop on failure)\n\nSynopsis: `pipeline(args, callback)`\n\nThe named arguments (that go inside `args`) are:\n\n* `funcs`: input functions, to be invoked in series\n* `arg`: arbitrary argument that will be passed to each function\n\nThe functions are invoked in order as `func(arg, callback)`, where \"arg\" is the\nuser-supplied argument from \"args\" and \"callback\" should be invoked in the usual\nway. If any function emits an error, the whole pipeline stops.\n\nThe return value and the arguments to the final callback are exactly the same as\nfor `parallel`. The error object for the final callback is just the error\nreturned by whatever pipeline function failed (if any).\n\nThis example is similar to the one above, except that it runs the steps in\nsequence and stops early because `pipeline` stops on the first error:\n\n```js\nconsole.log(mod_vasync.pipeline({\n 'funcs': [\n function f1 (_, callback) { mod_fs.stat('/tmp', callback); },\n function f2 (_, callback) { mod_fs.stat('/noexist', callback); },\n function f3 (_, callback) { mod_fs.stat('/var', callback); }\n ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\nAs a result, the status after the first tick looks like this:\n\n```js\n{ operations:\n [ { func: [Function: f1], status: 'pending' },\n { func: [Function: f2], status: 'waiting' },\n { func: [Function: f3], status: 'waiting' } ],\n successes: [],\n ndone: 0,\n nerrors: 0 }\n```\n\nNote that the second and third stages are now \"waiting\", rather than \"pending\"\nin the `parallel` case. The error and complete result look just like the\nparallel case.\n\n### tryEach: invoke N functions in series (and stop on success)\n\nSynopsis: `tryEach(funcs, callback)`\n\nThe `tryEach` function invokes each of the asynchronous functions in `funcs`\nserially. Each function takes a single argument: an interstitial-callback.\n`tryEach` will keep calling the functions until one of them succeeds (or they\nall fail). At the end, the terminating-callback is invoked with the error\nand/or results provided by the last function that was called (either the last\none that failed or the first one that succeeded).\n\nThis example is similar to the one above, except that it runs the steps in\nsequence and stops early because `tryEach` stops on the first success:\n\n```js\nconsole.log(mod_vasync.tryEach([\n function f1 (callback) { mod_fs.stat('/notreal', callback); },\n function f2 (callback) { mod_fs.stat('/noexist', callback); },\n function f3 (callback) { mod_fs.stat('/var', callback); },\n function f4 (callback) { mod_fs.stat('/noexist', callback); }\n ],\n function (err, results) {\n console.log('error: %s', err);\n console.log('results: %s', mod_util.inspect(results));\n}));\n\n```\n\nThe above code will stop when it finishes f3, and we will only print a single\nresult and no errors:\n\n```js\nerror: null\nresults: { dev: 65760,\n mode: 16877,\n nlink: 41,\n uid: 0,\n gid: 3,\n rdev: -1,\n blksize: 2560,\n ino: 11,\n size: 41,\n blocks: 7,\n atime: Thu May 28 2015 16:21:25 GMT+0000 (UTC),\n mtime: Thu Jan 21 2016 22:08:50 GMT+0000 (UTC),\n ctime: Thu Jan 21 2016 22:08:50 GMT+0000 (UTC) }\n```\n\nIf we comment out `f3`, we get the following output:\n\n```js\nerror: Error: ENOENT, stat '/noexist'\nresults: undefined\n```\n\nNote that: there is a mismatch (inherited from `async`) between the semantics\nof the interstitial callback and the sematics of the terminating callback. See\nthe following example:\n\n```js\nconsole.log(mod_vasync.tryEach([\n function f1 (callback) { callback(new Error()); },\n function f2 (callback) { callback(new Error()); },\n function f3 (callback) { callback(null, 1, 2, 3); },\n function f4 (callback) { callback(null, 1); }\n ],\n function (err, results) {\n console.log('error: %s', err);\n console.log('results: %s', mod_util.inspect(results));\n}));\n\n```\n\nWe pass one or more results to the terminating-callback via the\ninterstitial-callback's arglist -- `(err, res1, res2, ...)`. From the\ncallback-implementor's perspective, the results get wrapped up in an array\n`(err, [res1, res2, ...])` -- unless there is only one result, which simply\ngets passed through as the terminating callback's second argument. This means\nthat when we call the callback in `f3` above, the terminating callback receives\nthe list `[1, 2, 3]` as its second argument. If, we comment out `f3`, we will\nend up calling the callback in `f4` which will end up invoking the terminating\ncallback with a single result: `1`, instead of `[1]`.\n\n\nIn short, be mindful that there is not always a 1:1 correspondence between the\nterminating callback that you define, and the interstitial callback that gets\ncalled from the function.\n\n\n\n### forEachPipeline: invoke the same function on N inputs in series (and stop on failure)\n\nSynopsis: `forEachPipeline(args, callback)`\n\nThis function is exactly like `pipeline`, except that the input is specified as\na *single* function (\"func\") and a list of inputs (\"inputs\"). The function is\ninvoked on each input in series.\n\nThis example is exactly equivalent to the one above:\n\n```js\nconsole.log(mod_vasync.forEachPipeline({\n 'func': mod_dns.resolve,\n 'inputs': [ 'joyent.com', 'github.com', 'asdfaqsdfj.com' ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\n### waterfall: invoke N functions in series, stop on failure, and propagate results\n\nSynopsis: `waterfall(funcs, callback)`\n\nThis function works like `pipeline` except for argument passing.\n\nEach function is passed any values emitted by the previous function (none for\nthe first function), followed by the callback to invoke upon completion. This\ncallback must be invoked exactly once, regardless of success or failure. As\nconventional in Node, the first argument to the callback indicates an error (if\nnon-null). Subsequent arguments are passed to the next function in the \"funcs\"\nchain.\n\nIf any function fails (i.e., calls its callback with an Error), then the\nremaining functions are not invoked and \"callback\" is invoked with the error.\n\nThe only difference between waterfall() and pipeline() are the arguments passed\nto each function in the chain. pipeline() always passes the same argument\nfollowed by the callback, while waterfall() passes whatever values were emitted\nby the previous function followed by the callback.\n\nHere's an example:\n\n```js\nmod_vasync.waterfall([\n function func1(callback) {\n \tsetImmediate(function () {\n\t\tcallback(null, 37);\n\t});\n },\n function func2(extra, callback) {\n\tconsole.log('func2 got \"%s\" from func1', extra);\n\tcallback();\n }\n], function () {\n\tconsole.log('done');\n});\n```\n\nThis prints:\n\n```\nfunc2 got \"37\" from func1\nbetter stop early\n```\n\n### filter/filterLimit/filterSeries: filter N inputs serially or concurrently\n\nSynopsis: `filter(inputs, filterFunc, callback)`\n\nSynopsis: `filterSeries(inputs, filterFunc, callback)`\n\nSynopsis: `filterLimit(inputs, limit, filterFunc, callback)`\n\nThese functions take an array (of anything) and a function to call on each\nelement of the array. The function must callback with a true or false value as\nthe second argument or an error object as the first argument. False values\nwill result in the element being filtered out of the results array. An error\nobject passed as the first argument will cause the filter function to stop\nprocessing new elements and callback to the caller with the error immediately.\nOriginal input array order is maintained.\n\n`filter` and `filterSeries` are analogous to calling `filterLimit` with\na limit of `Infinity` and `1` respectively.\n\n\n```js\nvar inputs = [\n 'joyent.com',\n 'github.com',\n 'asdfaqsdfj.com'\n];\nfunction filterFunc(input, cb) {\n mod_dns.resolve(input, function (err, results) {\n if (err) {\n cb(null, false);\n } else {\n cb(null, true);\n }\n }\n}\nmod_vasync.filter(inputs, filterFunc, function (err, results) {\n // err => undefined\n // results => ['joyent.com', 'github.com']\n});\n```\n\n### whilst: invoke a function repeatedly until a stopping condition is met\n\nSynopsis: `whilst(testFunc, iterateFunc, callback)`\n\nRepeatedly invoke `iterateFunc` while `testFunc` returns a true value.\n`iterateFunc` is an asychronous function that must call its callback (the first\nand only argument given to it) when it is finished with an optional error\nobject as the first argument, and any other arbitrary arguments. If an error\nobject is given as the first argument, `whilst` will finish and call `callback`\nwith the error object. `testFunc` is a synchronous function that must return\na value - if the value resolves to true `whilst` will invoke `iterateFunc`, if\nit resolves to false `whilst` will finish and invoke `callback` with the last\nset of arguments `iterateFunc` called back with.\n\n`whilst` also returns an object suitable for introspecting the current state of\nthe specific `whilst` invocation which contains the following properties:\n\n* `finished`: boolean if this invocation has finished or is in progress\n* `iterations`: number of iterations performed (calls to `iterateFunc`)\n\nCompatible with `async.whilst`\n\n```js\nvar n = 0;\n\nvar w = mod_vasync.whilst(\n function testFunc() {\n return (n < 5);\n },\n function iterateFunc(cb) {\n n++;\n cb(null, {n: n});\n },\n function whilstDone(err, arg) {\n // err => undefined\n // arg => {n: 5}\n // w => {finished: true, iterations: 5}\n }\n);\n\n// w => {finished: false, iterations: 0}\n```\n\n### barrier: coordinate multiple concurrent operations\n\nSynopsis: `barrier([args])`\n\nReturns a new barrier object. Like `parallel`, barriers are useful for\ncoordinating several concurrent operations, but instead of specifying a list of\nfunctions to invoke, you just say how many (and optionally which ones) are\noutstanding, and this object emits `'drain'` when they've all completed. This\nis syntactically lighter-weight, and more flexible.\n\n* Methods:\n\n * start(name): Indicates that the named operation began. The name must not\n match an operation which is already ongoing.\n * done(name): Indicates that the named operation ended.\n\n\n* Read-only public properties (for debugging):\n\n * pending: Set of pending operations. Keys are names passed to \"start\", and\n values are timestamps when the operation began.\n * recent: Array of recent completed operations. Each element is an object\n with a \"name\", \"start\", and \"done\" field. By default, 10 operations are\n remembered.\n\n\n* Options:\n\n * nrecent: number of recent operations to remember (for debugging)\n\nExample: printing sizes of files in a directory\n\n```js\nvar mod_fs = require('fs');\nvar mod_path = require('path');\nvar mod_vasync = require('../lib/vasync');\n\nvar barrier = mod_vasync.barrier();\n\nbarrier.on('drain', function () {\n console.log('all files checked');\n});\n\nbarrier.start('readdir');\n\nmod_fs.readdir(__dirname, function (err, files) {\n barrier.done('readdir');\n\n if (err)\n throw (err);\n\n files.forEach(function (file) {\n barrier.start('stat ' + file);\n\n var path = mod_path.join(__dirname, file);\n\n mod_fs.stat(path, function (err2, stat) {\n barrier.done('stat ' + file);\n console.log('%s: %d bytes', file, stat['size']);\n });\n });\n});\n```\n\nThis emits:\n\n barrier-readdir.js: 602 bytes\n foreach-parallel.js: 358 bytes\n barrier-basic.js: 552 bytes\n nofail.js: 384 bytes\n pipeline.js: 490 bytes\n parallel.js: 481 bytes\n queue-serializer.js: 441 bytes\n queue-stat.js: 529 bytes\n all files checked\n\n\n### queue/queuev: fixed-size worker queue\n\nSynopsis: `queue(worker, concurrency)`\n\nSynopsis: `queuev(args)`\n\nThis function returns an object that allows up to a fixed number of tasks to be\ndispatched at any given time. The interface is compatible with that provided\nby the \"async\" Node library, except that the returned object's fields represent\na public interface you can use to introspect what's going on.\n\n* Arguments\n\n * worker: a function invoked as `worker(task, callback)`, where `task` is a\n task dispatched to this queue and `callback` should be invoked when the\n task completes.\n * concurrency: a positive integer indicating the maximum number of tasks\n that may be dispatched at any time. With concurrency = 1, the queue\n serializes all operations.\n\n\n* Methods\n\n * push(task, [callback]): add a task (or array of tasks) to the queue, with\n an optional callback to be invoked when each task completes. If a list of\n tasks are added, the callback is invoked for each one.\n * length(): for compatibility with node-async.\n * close(): signal that no more tasks will be enqueued. Further attempts to\n enqueue tasks to this queue will throw. Once all pending and queued\n tasks are completed the object will emit the \"end\" event. The \"end\"\n event is the last event the queue will emit, and it will be emitted even\n if no tasks were ever enqueued.\n * kill(): clear enqueued tasks and implicitly close the queue. Several\n caveats apply when kill() is called:\n * The completion callback will _not_ be called for items purged from\n the queue.\n * The drain handler is cleared (for node-async compatibility)\n * Subsequent calls to kill() or close() are no-ops.\n * As with close(), it is not legal to call push() after kill().\n\n\n* Read-only public properties (for debugging):\n\n * concurrency: for compatibility with node-async\n * worker: worker function, as passed into \"queue\"/\"queuev\"\n * worker\\_name: worker function's \"name\" field\n * npending: the number of tasks currently being processed\n * pending: an object (*not* an array) describing the tasks currently being\n processed\n * queued: array of tasks currently queued for processing\n * closed: true when close() has been called on the queue\n * ended: true when all tasks have completed processing, and no more\n processing will occur\n * killed: true when kill() has been called on the queue\n\n\n* Hooks (for compatibility with node-async):\n\n * saturated\n * empty\n * drain\n\n* Events\n\n * 'end': see close()\n\nIf the tasks are themselves simple objects, then the entire queue may be\nserialized (as via JSON.stringify) for debugging and monitoring tools. Using\nthe above fields, you can see what this queue is doing (worker\\_name), which\ntasks are queued, which tasks are being processed, and so on.\n\n### Example 1: Stat several files\n\nHere's an example demonstrating the queue:\n\n```js\nvar mod_fs = require('fs');\nvar mod_vasync = require('../lib/vasync');\n\nvar queue;\n\nfunction doneOne()\n{\n console.log('task completed; queue state:\\n%s\\n',\n JSON.stringify(queue, null, 4));\n}\n\nqueue = mod_vasync.queue(mod_fs.stat, 2);\n\nconsole.log('initial queue state:\\n%s\\n', JSON.stringify(queue, null, 4));\n\nqueue.push('/tmp/file1', doneOne);\nqueue.push('/tmp/file2', doneOne);\nqueue.push('/tmp/file3', doneOne);\nqueue.push('/tmp/file4', doneOne);\n\nconsole.log('all tasks dispatched:\\n%s\\n', JSON.stringify(queue, null, 4));\n```\n\nThe initial queue state looks like this:\n\n```js\ninitial queue state:\n{\n \"nextid\": 0,\n \"worker_name\": \"anon\",\n \"npending\": 0,\n \"pending\": {},\n \"queued\": [],\n \"concurrency\": 2\n}\n```\nAfter four tasks have been pushed, we see that two of them have been dispatched\nand the remaining two are queued up:\n\n```js\nall tasks pushed:\n{\n \"nextid\": 4,\n \"worker_name\": \"anon\",\n \"npending\": 2,\n \"pending\": {\n \"1\": {\n \"id\": 1,\n \"task\": \"/tmp/file1\"\n },\n \"2\": {\n \"id\": 2,\n \"task\": \"/tmp/file2\"\n }\n },\n \"queued\": [\n {\n \"id\": 3,\n \"task\": \"/tmp/file3\"\n },\n {\n \"id\": 4,\n \"task\": \"/tmp/file4\"\n }\n ],\n \"concurrency\": 2\n}\n```\n\nAs they complete, we see tasks moving from \"queued\" to \"pending\", and completed\ntasks disappear:\n\n```js\ntask completed; queue state:\n{\n \"nextid\": 4,\n \"worker_name\": \"anon\",\n \"npending\": 1,\n \"pending\": {\n \"3\": {\n \"id\": 3,\n \"task\": \"/tmp/file3\"\n }\n },\n \"queued\": [\n {\n \"id\": 4,\n \"task\": \"/tmp/file4\"\n }\n ],\n \"concurrency\": 2\n}\n```\n\nWhen all tasks have completed, the queue state looks like it started:\n\n```js\ntask completed; queue state:\n{\n \"nextid\": 4,\n \"worker_name\": \"anon\",\n \"npending\": 0,\n \"pending\": {},\n \"queued\": [],\n \"concurrency\": 2\n}\n```\n\n\n### Example 2: A simple serializer\n\nYou can use a queue with concurrency 1 and where the tasks are themselves\nfunctions to ensure that an arbitrary asynchronous function never runs\nconcurrently with another one, no matter what each one does. Since the tasks\nare the actual functions to be invoked, the worker function just invokes each\none:\n\n```js\nvar mod_vasync = require('../lib/vasync');\n\nvar queue = mod_vasync.queue(\n function (task, callback) { task(callback); }, 1);\n\nqueue.push(function (callback) {\n console.log('first task begins');\n setTimeout(function () {\n console.log('first task ends');\n callback();\n }, 500);\n});\n\nqueue.push(function (callback) {\n console.log('second task begins');\n process.nextTick(function () {\n console.log('second task ends');\n callback();\n });\n});\n```\n\nThis example outputs:\n\n $ node examples/queue-serializer.js\n first task begins\n first task ends\n second task begins\n second task ends\n", + "readme": "# vasync: observable asynchronous control flow\n\nThis module provides several functions for asynchronous control flow. There are\nmany modules that do this already (notably async.js). This one's claim to fame\nis improved debuggability.\n\n\n## Observability is important\n\nWorking with Node's asynchronous, callback-based model is much easier with a\nhandful of simple control-flow abstractions, like:\n\n* waterfalls and pipelines (which invoke a list of asynchronous callbacks\n sequentially)\n* parallel pipelines (which invoke a list of asynchronous callbacks in parallel\n and invoke a top-level callback when the last one completes).\n* queues\n* barriers\n\nBut these structures also introduce new types of programming errors: failing to\ninvoke the callback can cause the program to hang, and inadvertently invoking it\ntwice can cause all kinds of mayhem that's very difficult to debug.\n\nThe functions in this module keep track of what's going on so that you can\nfigure out what happened when your program goes wrong. They generally return an\nobject describing details of the current state. If your program goes wrong, you\nhave several ways of getting at this state:\n\n* On illumos-based systems, use MDB to [find the status object](http://dtrace.org/blogs/bmc/2012/05/05/debugging-node-js-memory-leaks/)\n and then [print it out](http://dtrace.org/blogs/dap/2012/01/13/playing-with-nodev8-postmortem-debugging/).\n* Provide an HTTP API (or AMQP, or whatever) that returns these pending status\n objects as JSON (see [kang](https://github.com/davepacheco/kang)).\n* Incorporate a REPL into your program and print out the status object.\n* Use the Node debugger to print out the status object.\n\n## Functions\n\n* [parallel](#parallel-invoke-n-functions-in-parallel): invoke N functions in\n parallel (and merge the results)\n* [forEachParallel](#foreachparallel-invoke-the-same-function-on-n-inputs-in-parallel):\n invoke the same function on N inputs in parallel\n* [pipeline](#pipeline-invoke-n-functions-in-series-and-stop-on-failure): invoke\n N functions in series (and stop on failure)\n* [tryEach](#tryeach-invoke-n-functions-in-series-and-stop-on-success): invoke\n N functions in series (and stop on success)\n* [forEachPipeline](#foreachpipeline-invoke-the-same-function-on-n-inputs-in-series-and-stop-on-failure):\n invoke the same function on N inputs in series (and stop on failure)\n* [filter/filterSeries/filterLimit](#filterfilterlimitfilterseries-filter-n-inputs-serially-or-concurrently):\n filter N inputs serially or concurrently\n* [whilst](#whilst-invoke-a-function-repeatedly-until-a-stopping-condition-is-met):\n invoke a function repeatedly until a stopping condition is met\n* [waterfall](#waterfall-invoke-n-functions-in-series-stop-on-failure-and-propagate-results):\n like pipeline, but propagating results between stages\n* [barrier](#barrier-coordinate-multiple-concurrent-operations): coordinate\n multiple concurrent operations\n* [queue/queuev](#queuequeuev-fixed-size-worker-queue): fixed-size worker queue\n\n### parallel: invoke N functions in parallel\n\nSynopsis: `parallel(args, callback)`\n\nThis function takes a list of input functions (specified by the \"funcs\" property\nof \"args\") and runs them all. These input functions are expected to be\nasynchronous: they get a \"callback\" argument and should invoke it as\n`callback(err, result)`. The error and result will be saved and made available\nto the original caller when all of these functions complete.\n\nThis function returns the same \"result\" object it passes to the callback, and\nyou can use the fields in this object to debug or observe progress:\n\n* `operations`: array corresponding to the input functions, with\n * `func`: input function,\n * `status`: \"pending\", \"ok\", or \"fail\",\n * `err`: returned \"err\" value, if any, and\n * `result`: returned \"result\" value, if any\n* `successes`: \"result\" field for each of \"operations\" where\n \"status\" == \"ok\" (in no particular order)\n* `ndone`: number of input operations that have completed\n* `nerrors`: number of input operations that have failed\n\nThis status object lets you see in a debugger exactly which functions have\ncompleted, what they returned, and which ones are outstanding.\n\nAll errors are combined into a single \"err\" parameter to the final callback (see\nbelow).\n\nExample usage:\n\n```js\nconsole.log(mod_vasync.parallel({\n 'funcs': [\n function f1 (callback) { mod_dns.resolve('tritondatacenter.com', callback); },\n function f2 (callback) { mod_dns.resolve('github.com', callback); },\n function f3 (callback) { mod_dns.resolve('asdfaqsdfj.com', callback); }\n ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\nIn the first tick, this outputs:\n\n```js\nstatus: { operations:\n [ { func: [Function: f1], status: 'pending' },\n { func: [Function: f2], status: 'pending' },\n { func: [Function: f3], status: 'pending' } ],\n successes: [],\n ndone: 0,\n nerrors: 0 }\n```\n\nshowing that there are three operations pending and none has yet been started.\nWhen the program finishes, it outputs this error:\n\n error: first of 1 error: queryA ENOTFOUND\n\nwhich encapsulates all of the intermediate failures. This model allows you to\nwrite the final callback like you normally would:\n\n```js\nif (err)\n return (callback(err));\n```\n\nand still propagate useful information to callers that don't deal with multiple\nerrors (i.e. most callers).\n\nThe example also prints out the detailed final status, including all of the\nerrors and return values:\n\n```js\nresults: { operations:\n [ { func: [Function: f1],\n funcname: 'f1',\n status: 'ok',\n err: null,\n result: [ '165.225.132.33' ] },\n { func: [Function: f2],\n funcname: 'f2',\n status: 'ok',\n err: null,\n result: [ '207.97.227.239' ] },\n { func: [Function: f3],\n funcname: 'f3',\n status: 'fail',\n err: { [Error: queryA ENOTFOUND] code: 'ENOTFOUND',\n errno: 'ENOTFOUND', syscall: 'queryA' },\n result: undefined } ],\n successes: [ [ '165.225.132.33' ], [ '207.97.227.239' ] ],\n ndone: 3,\n nerrors: 1 }\n```\n\nYou can use this if you want to handle all of the errors individually or to get\nat all of the individual return values.\n\nNote that \"successes\" is provided as a convenience and the order of items in\nthat array may not correspond to the order of the inputs. To consume output in\nan ordered manner, you should iterate over \"operations\" and pick out the result\nfrom each item.\n\n\n### forEachParallel: invoke the same function on N inputs in parallel\n\nSynopsis: `forEachParallel(args, callback)`\n\nThis function is exactly like `parallel`, except that the input is specified as\na *single* function (\"func\") and a list of inputs (\"inputs\"). The function is\ninvoked on each input in parallel.\n\nThis example is exactly equivalent to the one above:\n\n```js\nconsole.log(mod_vasync.forEachParallel({\n 'func': mod_dns.resolve,\n 'inputs': [ 'tritondatacenter.com', 'github.com', 'asdfaqsdfj.com' ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\n### pipeline: invoke N functions in series (and stop on failure)\n\nSynopsis: `pipeline(args, callback)`\n\nThe named arguments (that go inside `args`) are:\n\n* `funcs`: input functions, to be invoked in series\n* `arg`: arbitrary argument that will be passed to each function\n\nThe functions are invoked in order as `func(arg, callback)`, where \"arg\" is the\nuser-supplied argument from \"args\" and \"callback\" should be invoked in the usual\nway. If any function emits an error, the whole pipeline stops.\n\nThe return value and the arguments to the final callback are exactly the same as\nfor `parallel`. The error object for the final callback is just the error\nreturned by whatever pipeline function failed (if any).\n\nThis example is similar to the one above, except that it runs the steps in\nsequence and stops early because `pipeline` stops on the first error:\n\n```js\nconsole.log(mod_vasync.pipeline({\n 'funcs': [\n function f1 (_, callback) { mod_fs.stat('/tmp', callback); },\n function f2 (_, callback) { mod_fs.stat('/noexist', callback); },\n function f3 (_, callback) { mod_fs.stat('/var', callback); }\n ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\nAs a result, the status after the first tick looks like this:\n\n```js\n{ operations:\n [ { func: [Function: f1], status: 'pending' },\n { func: [Function: f2], status: 'waiting' },\n { func: [Function: f3], status: 'waiting' } ],\n successes: [],\n ndone: 0,\n nerrors: 0 }\n```\n\nNote that the second and third stages are now \"waiting\", rather than \"pending\"\nin the `parallel` case. The error and complete result look just like the\nparallel case.\n\n### tryEach: invoke N functions in series (and stop on success)\n\nSynopsis: `tryEach(funcs, callback)`\n\nThe `tryEach` function invokes each of the asynchronous functions in `funcs`\nserially. Each function takes a single argument: an interstitial-callback.\n`tryEach` will keep calling the functions until one of them succeeds (or they\nall fail). At the end, the terminating-callback is invoked with the error\nand/or results provided by the last function that was called (either the last\none that failed or the first one that succeeded).\n\nThis example is similar to the one above, except that it runs the steps in\nsequence and stops early because `tryEach` stops on the first success:\n\n```js\nconsole.log(mod_vasync.tryEach([\n function f1 (callback) { mod_fs.stat('/notreal', callback); },\n function f2 (callback) { mod_fs.stat('/noexist', callback); },\n function f3 (callback) { mod_fs.stat('/var', callback); },\n function f4 (callback) { mod_fs.stat('/noexist', callback); }\n ],\n function (err, results) {\n console.log('error: %s', err);\n console.log('results: %s', mod_util.inspect(results));\n}));\n\n```\n\nThe above code will stop when it finishes f3, and we will only print a single\nresult and no errors:\n\n```js\nerror: null\nresults: { dev: 65760,\n mode: 16877,\n nlink: 41,\n uid: 0,\n gid: 3,\n rdev: -1,\n blksize: 2560,\n ino: 11,\n size: 41,\n blocks: 7,\n atime: Thu May 28 2015 16:21:25 GMT+0000 (UTC),\n mtime: Thu Jan 21 2016 22:08:50 GMT+0000 (UTC),\n ctime: Thu Jan 21 2016 22:08:50 GMT+0000 (UTC) }\n```\n\nIf we comment out `f3`, we get the following output:\n\n```js\nerror: Error: ENOENT, stat '/noexist'\nresults: undefined\n```\n\nNote that: there is a mismatch (inherited from `async`) between the semantics\nof the interstitial callback and the sematics of the terminating callback. See\nthe following example:\n\n```js\nconsole.log(mod_vasync.tryEach([\n function f1 (callback) { callback(new Error()); },\n function f2 (callback) { callback(new Error()); },\n function f3 (callback) { callback(null, 1, 2, 3); },\n function f4 (callback) { callback(null, 1); }\n ],\n function (err, results) {\n console.log('error: %s', err);\n console.log('results: %s', mod_util.inspect(results));\n}));\n\n```\n\nWe pass one or more results to the terminating-callback via the\ninterstitial-callback's arglist -- `(err, res1, res2, ...)`. From the\ncallback-implementor's perspective, the results get wrapped up in an array\n`(err, [res1, res2, ...])` -- unless there is only one result, which simply\ngets passed through as the terminating callback's second argument. This means\nthat when we call the callback in `f3` above, the terminating callback receives\nthe list `[1, 2, 3]` as its second argument. If, we comment out `f3`, we will\nend up calling the callback in `f4` which will end up invoking the terminating\ncallback with a single result: `1`, instead of `[1]`.\n\n\nIn short, be mindful that there is not always a 1:1 correspondence between the\nterminating callback that you define, and the interstitial callback that gets\ncalled from the function.\n\n\n\n### forEachPipeline: invoke the same function on N inputs in series (and stop on failure)\n\nSynopsis: `forEachPipeline(args, callback)`\n\nThis function is exactly like `pipeline`, except that the input is specified as\na *single* function (\"func\") and a list of inputs (\"inputs\"). The function is\ninvoked on each input in series.\n\nThis example is exactly equivalent to the one above:\n\n```js\nconsole.log(mod_vasync.forEachPipeline({\n 'func': mod_dns.resolve,\n 'inputs': [ 'tritondatacenter.com', 'github.com', 'asdfaqsdfj.com' ]\n}, function (err, results) {\n console.log('error: %s', err.message);\n console.log('results: %s', mod_util.inspect(results, null, 3));\n}));\n```\n\n### waterfall: invoke N functions in series, stop on failure, and propagate results\n\nSynopsis: `waterfall(funcs, callback)`\n\nThis function works like `pipeline` except for argument passing.\n\nEach function is passed any values emitted by the previous function (none for\nthe first function), followed by the callback to invoke upon completion. This\ncallback must be invoked exactly once, regardless of success or failure. As\nconventional in Node, the first argument to the callback indicates an error (if\nnon-null). Subsequent arguments are passed to the next function in the \"funcs\"\nchain.\n\nIf any function fails (i.e., calls its callback with an Error), then the\nremaining functions are not invoked and \"callback\" is invoked with the error.\n\nThe only difference between waterfall() and pipeline() are the arguments passed\nto each function in the chain. pipeline() always passes the same argument\nfollowed by the callback, while waterfall() passes whatever values were emitted\nby the previous function followed by the callback.\n\nHere's an example:\n\n```js\nmod_vasync.waterfall([\n function func1(callback) {\n \tsetImmediate(function () {\n\t\tcallback(null, 37);\n\t});\n },\n function func2(extra, callback) {\n\tconsole.log('func2 got \"%s\" from func1', extra);\n\tcallback();\n }\n], function () {\n\tconsole.log('done');\n});\n```\n\nThis prints:\n\n```\nfunc2 got \"37\" from func1\nbetter stop early\n```\n\n### filter/filterLimit/filterSeries: filter N inputs serially or concurrently\n\nSynopsis: `filter(inputs, filterFunc, callback)`\n\nSynopsis: `filterSeries(inputs, filterFunc, callback)`\n\nSynopsis: `filterLimit(inputs, limit, filterFunc, callback)`\n\nThese functions take an array (of anything) and a function to call on each\nelement of the array. The function must callback with a true or false value as\nthe second argument or an error object as the first argument. False values\nwill result in the element being filtered out of the results array. An error\nobject passed as the first argument will cause the filter function to stop\nprocessing new elements and callback to the caller with the error immediately.\nOriginal input array order is maintained.\n\n`filter` and `filterSeries` are analogous to calling `filterLimit` with\na limit of `Infinity` and `1` respectively.\n\n\n```js\nvar inputs = [\n 'tritondatacenter.com',\n 'github.com',\n 'asdfaqsdfj.com'\n];\nfunction filterFunc(input, cb) {\n mod_dns.resolve(input, function (err, results) {\n if (err) {\n cb(null, false);\n } else {\n cb(null, true);\n }\n }\n}\nmod_vasync.filter(inputs, filterFunc, function (err, results) {\n // err => undefined\n // results => ['tritondatacenter.com', 'github.com']\n});\n```\n\n### whilst: invoke a function repeatedly until a stopping condition is met\n\nSynopsis: `whilst(testFunc, iterateFunc, callback)`\n\nRepeatedly invoke `iterateFunc` while `testFunc` returns a true value.\n`iterateFunc` is an asychronous function that must call its callback (the first\nand only argument given to it) when it is finished with an optional error\nobject as the first argument, and any other arbitrary arguments. If an error\nobject is given as the first argument, `whilst` will finish and call `callback`\nwith the error object. `testFunc` is a synchronous function that must return\na value - if the value resolves to true `whilst` will invoke `iterateFunc`, if\nit resolves to false `whilst` will finish and invoke `callback` with the last\nset of arguments `iterateFunc` called back with.\n\n`whilst` also returns an object suitable for introspecting the current state of\nthe specific `whilst` invocation which contains the following properties:\n\n* `finished`: boolean if this invocation has finished or is in progress\n* `iterations`: number of iterations performed (calls to `iterateFunc`)\n\nCompatible with `async.whilst`\n\n```js\nvar n = 0;\n\nvar w = mod_vasync.whilst(\n function testFunc() {\n return (n < 5);\n },\n function iterateFunc(cb) {\n n++;\n cb(null, {n: n});\n },\n function whilstDone(err, arg) {\n // err => undefined\n // arg => {n: 5}\n // w => {finished: true, iterations: 5}\n }\n);\n\n// w => {finished: false, iterations: 0}\n```\n\n### barrier: coordinate multiple concurrent operations\n\nSynopsis: `barrier([args])`\n\nReturns a new barrier object. Like `parallel`, barriers are useful for\ncoordinating several concurrent operations, but instead of specifying a list of\nfunctions to invoke, you just say how many (and optionally which ones) are\noutstanding, and this object emits `'drain'` when they've all completed. This\nis syntactically lighter-weight, and more flexible.\n\n* Methods:\n\n * start(name): Indicates that the named operation began. The name must not\n match an operation which is already ongoing.\n * done(name): Indicates that the named operation ended.\n\n\n* Read-only public properties (for debugging):\n\n * pending: Set of pending operations. Keys are names passed to \"start\", and\n values are timestamps when the operation began.\n * recent: Array of recent completed operations. Each element is an object\n with a \"name\", \"start\", and \"done\" field. By default, 10 operations are\n remembered.\n\n\n* Options:\n\n * nrecent: number of recent operations to remember (for debugging)\n\nExample: printing sizes of files in a directory\n\n```js\nvar mod_fs = require('fs');\nvar mod_path = require('path');\nvar mod_vasync = require('../lib/vasync');\n\nvar barrier = mod_vasync.barrier();\n\nbarrier.on('drain', function () {\n console.log('all files checked');\n});\n\nbarrier.start('readdir');\n\nmod_fs.readdir(__dirname, function (err, files) {\n barrier.done('readdir');\n\n if (err)\n throw (err);\n\n files.forEach(function (file) {\n barrier.start('stat ' + file);\n\n var path = mod_path.join(__dirname, file);\n\n mod_fs.stat(path, function (err2, stat) {\n barrier.done('stat ' + file);\n console.log('%s: %d bytes', file, stat['size']);\n });\n });\n});\n```\n\nThis emits:\n\n barrier-readdir.js: 602 bytes\n foreach-parallel.js: 358 bytes\n barrier-basic.js: 552 bytes\n nofail.js: 384 bytes\n pipeline.js: 490 bytes\n parallel.js: 481 bytes\n queue-serializer.js: 441 bytes\n queue-stat.js: 529 bytes\n all files checked\n\n\n### queue/queuev: fixed-size worker queue\n\nSynopsis: `queue(worker, concurrency)`\n\nSynopsis: `queuev(args)`\n\nThis function returns an object that allows up to a fixed number of tasks to be\ndispatched at any given time. The interface is compatible with that provided\nby the \"async\" Node library, except that the returned object's fields represent\na public interface you can use to introspect what's going on.\n\n* Arguments\n\n * worker: a function invoked as `worker(task, callback)`, where `task` is a\n task dispatched to this queue and `callback` should be invoked when the\n task completes.\n * concurrency: a positive integer indicating the maximum number of tasks\n that may be dispatched at any time. With concurrency = 1, the queue\n serializes all operations.\n\n\n* Methods\n\n * push(task, [callback]): add a task (or array of tasks) to the queue, with\n an optional callback to be invoked when each task completes. If a list of\n tasks are added, the callback is invoked for each one.\n * length(): for compatibility with node-async.\n * close(): signal that no more tasks will be enqueued. Further attempts to\n enqueue tasks to this queue will throw. Once all pending and queued\n tasks are completed the object will emit the \"end\" event. The \"end\"\n event is the last event the queue will emit, and it will be emitted even\n if no tasks were ever enqueued.\n * kill(): clear enqueued tasks and implicitly close the queue. Several\n caveats apply when kill() is called:\n * The completion callback will _not_ be called for items purged from\n the queue.\n * The drain handler is cleared (for node-async compatibility)\n * Subsequent calls to kill() or close() are no-ops.\n * As with close(), it is not legal to call push() after kill().\n\n\n* Read-only public properties (for debugging):\n\n * concurrency: for compatibility with node-async\n * worker: worker function, as passed into \"queue\"/\"queuev\"\n * worker\\_name: worker function's \"name\" field\n * npending: the number of tasks currently being processed\n * pending: an object (*not* an array) describing the tasks currently being\n processed\n * queued: array of tasks currently queued for processing\n * closed: true when close() has been called on the queue\n * ended: true when all tasks have completed processing, and no more\n processing will occur\n * killed: true when kill() has been called on the queue\n\n\n* Hooks (for compatibility with node-async):\n\n * saturated\n * empty\n * drain\n\n* Events\n\n * 'end': see close()\n\nIf the tasks are themselves simple objects, then the entire queue may be\nserialized (as via JSON.stringify) for debugging and monitoring tools. Using\nthe above fields, you can see what this queue is doing (worker\\_name), which\ntasks are queued, which tasks are being processed, and so on.\n\n### Example 1: Stat several files\n\nHere's an example demonstrating the queue:\n\n```js\nvar mod_fs = require('fs');\nvar mod_vasync = require('../lib/vasync');\n\nvar queue;\n\nfunction doneOne()\n{\n console.log('task completed; queue state:\\n%s\\n',\n JSON.stringify(queue, null, 4));\n}\n\nqueue = mod_vasync.queue(mod_fs.stat, 2);\n\nconsole.log('initial queue state:\\n%s\\n', JSON.stringify(queue, null, 4));\n\nqueue.push('/tmp/file1', doneOne);\nqueue.push('/tmp/file2', doneOne);\nqueue.push('/tmp/file3', doneOne);\nqueue.push('/tmp/file4', doneOne);\n\nconsole.log('all tasks dispatched:\\n%s\\n', JSON.stringify(queue, null, 4));\n```\n\nThe initial queue state looks like this:\n\n```js\ninitial queue state:\n{\n \"nextid\": 0,\n \"worker_name\": \"anon\",\n \"npending\": 0,\n \"pending\": {},\n \"queued\": [],\n \"concurrency\": 2\n}\n```\nAfter four tasks have been pushed, we see that two of them have been dispatched\nand the remaining two are queued up:\n\n```js\nall tasks pushed:\n{\n \"nextid\": 4,\n \"worker_name\": \"anon\",\n \"npending\": 2,\n \"pending\": {\n \"1\": {\n \"id\": 1,\n \"task\": \"/tmp/file1\"\n },\n \"2\": {\n \"id\": 2,\n \"task\": \"/tmp/file2\"\n }\n },\n \"queued\": [\n {\n \"id\": 3,\n \"task\": \"/tmp/file3\"\n },\n {\n \"id\": 4,\n \"task\": \"/tmp/file4\"\n }\n ],\n \"concurrency\": 2\n}\n```\n\nAs they complete, we see tasks moving from \"queued\" to \"pending\", and completed\ntasks disappear:\n\n```js\ntask completed; queue state:\n{\n \"nextid\": 4,\n \"worker_name\": \"anon\",\n \"npending\": 1,\n \"pending\": {\n \"3\": {\n \"id\": 3,\n \"task\": \"/tmp/file3\"\n }\n },\n \"queued\": [\n {\n \"id\": 4,\n \"task\": \"/tmp/file4\"\n }\n ],\n \"concurrency\": 2\n}\n```\n\nWhen all tasks have completed, the queue state looks like it started:\n\n```js\ntask completed; queue state:\n{\n \"nextid\": 4,\n \"worker_name\": \"anon\",\n \"npending\": 0,\n \"pending\": {},\n \"queued\": [],\n \"concurrency\": 2\n}\n```\n\n\n### Example 2: A simple serializer\n\nYou can use a queue with concurrency 1 and where the tasks are themselves\nfunctions to ensure that an arbitrary asynchronous function never runs\nconcurrently with another one, no matter what each one does. Since the tasks\nare the actual functions to be invoked, the worker function just invokes each\none:\n\n```js\nvar mod_vasync = require('../lib/vasync');\n\nvar queue = mod_vasync.queue(\n function (task, callback) { task(callback); }, 1);\n\nqueue.push(function (callback) {\n console.log('first task begins');\n setTimeout(function () {\n console.log('first task ends');\n callback();\n }, 500);\n});\n\nqueue.push(function (callback) {\n console.log('second task begins');\n process.nextTick(function () {\n console.log('second task ends');\n callback();\n });\n});\n```\n\nThis example outputs:\n\n $ node examples/queue-serializer.js\n first task begins\n first task ends\n second task begins\n second task ends\n", "readmeFilename": "README.md", "gitHead": "c99965d04df49ddec0d613d740f3ad6e7065727c", "bugs": { @@ -31,6 +31,6 @@ "homepage": "https://github.com/davepacheco/node-vasync", "_id": "vasync@2.2.0", "_shasum": "e954b29f3da731929b43e5de172345b747ab8ef9", - "_from": "https://github.com/joyent/node-vasync.git", - "_resolved": "https://github.com/joyent/node-vasync.git#b267712029d0b7e3e5fe30a8426400027076dfe0" + "_from": "https://github.com/TritonDataCenter/node-vasync.git", + "_resolved": "https://github.com/TritonDataCenter/node-vasync.git#b267712029d0b7e3e5fe30a8426400027076dfe0" } diff --git a/src/vm/package.json b/src/vm/package.json index 1fffa9a15..68808149f 100644 --- a/src/vm/package.json +++ b/src/vm/package.json @@ -2,7 +2,7 @@ "name": "vmadm", "description": "administrative tool(s) for managing VMs", "version": "1.0.5", - "author": "Joyent (joyent.com)", + "author": "Triton Data Center (tritondatacenter.com)", "private": true, "devDependencies": { }, diff --git a/src/vm/tests/test-validate-payload.js b/src/vm/tests/test-validate-payload.js index c4c7e2cc0..4114ab148 100644 --- a/src/vm/tests/test-validate-payload.js +++ b/src/vm/tests/test-validate-payload.js @@ -1,4 +1,5 @@ // Copyright 2015 Joyent, Inc. All rights reserved. +// Copyright 2022 MNX Cloud, Inc. var brand; var os_brands = ['joyent', 'joyent-minimal']; @@ -534,7 +535,7 @@ for (brand in os_brands) { image_uuid: '01b2c898-945f-11e1-a523-af1afbe22822', delegate_dataset: 'true', do_not_inventory: 'true', - dns_domain: 'joyent.com', + dns_domain: 'tritondatacenter.com', filesystems: [{type: 'lofs', source: '/var/tmp', target: '/gztmp', options: ['ro', 'nodevices']}], fs_allowed: ['ufs', 'tmpfs', 'pcfs'], hostname: 'maximumpower', From bce3ff08c407e291224c72f15d93a04809d93179 Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Thu, 17 Nov 2022 16:11:18 -0500 Subject: [PATCH 6/7] oops --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 485189e18..f15bd75fd 100755 --- a/configure +++ b/configure @@ -154,7 +154,7 @@ function checkout_project function create_projects { local dir="projects/local" - local git_stem="https://github.com/joyent" + local git_stem="https://github.com/TritonDataCenter" [[ -d "$dir" ]] || mkdir -p "$dir" || fatal "failed to create $dir" From de221ce6866e10507bb3b66765e5fee14b42a2e9 Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Thu, 11 Apr 2024 08:50:11 -0400 Subject: [PATCH 7/7] Update readme --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 64c54832a..618cf04e5 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ QEMU ## Setting up a Build Environment The first step when building is to set up a build environment. The SmartOS -build requires building on SmartOS. As of the `base-64-lts 21.4.0` build +build requires building on SmartOS. As of the `base-64-lts 21.4.1` build image, the SmartOS Platform Image must be 20211007 or newer. This can be done in VMware, on an existing SmartOS machine, or other virtualization. You must build inside of a non-global zone. @@ -179,19 +179,19 @@ As of [OS-8412](https://smartos.org/bugview/OS-8412), OpenSSH requires OpenSSL ### Importing the Zone Image -The SmartOS build currently uses the `base-64-lts 21.4.0` image -which has a UUID of `c8715b60-7e98-11ec-82d1-03d16599f529 `. To import +The SmartOS build currently uses the `base-64-lts 21.4.1` image +which has a UUID of `85d0f826-0131-11ed-973d-2bfeef68011c `. To import the image, you should run the imgadm command from the global zone: ``` -# imgadm import c8715b60-7e98-11ec-82d1-03d16599f529 -Importing c8715b60-7e98-11ec-82d1-03d16599f529 (base-64-lts@21.4.0) from "https://images.smartos.org" -Gather image c8715b60-7e98-11ec-82d1-03d16599f529 ancestry +# imgadm import 85d0f826-0131-11ed-973d-2bfeef68011c +Importing 85d0f826-0131-11ed-973d-2bfeef68011c (base-64-lts@21.4.1) from "https://images.smartos.org" +Gather image 85d0f826-0131-11ed-973d-2bfeef68011c ancestry Must download and install 1 image (148.6 MiB) Download 1 image [=======================>] 100% 148.62MB 497.77KB/s 5m 5s -Downloaded image c8715b60-7e98-11ec-82d1-03d16599f529 (148.6 MiB) +Downloaded image 85d0f826-0131-11ed-973d-2bfeef68011c (148.6 MiB) ...82d1-03d16599f529 [=======================>] 100% 148.62MB 5.12MB/s 29s -Imported image c8715b60-7e98-11ec-82d1-03d16599f529 (base-64-lts@21.4.0) +Imported image 85d0f826-0131-11ed-973d-2bfeef68011c (base-64-lts@21.4.1) # ``` @@ -201,7 +201,7 @@ To create a zone, you need to create a `joyent` branded zone with `vmadm`. We recommend that the zone have the following attributes: * The brand set to `"joyent"` -* The `image_uuid` set to `"c8715b60-7e98-11ec-82d1-03d16599f529"` +* The `image_uuid` set to `"85d0f826-0131-11ed-973d-2bfeef68011c"` * At least 25 GiB of disk space specified in the `quota` property * At least 2-4 GiB of DRAM specified in the `max-physical-memory` property