[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Report a bug you found\ntitle: \"[BUG]\"\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Create the `pot` with this command: '...'\n2. Run this command: '...'\n3. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**System configuration - if possible**\n - `/usr/local/etc/pot/pot.conf`\n\n** If network related **\n - `cat /etc/pf.conf`\n - `potnet show -v`\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: A nice to have\ntitle: ''\nlabels: feature\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the feature you'd like to have**\nA clear and concise description of what you want to happen.\n\n**Describe potential alternatives or workaround you've considered (if any)**\nA clear and concise description of any alternative solutions or workaround you've considered.\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Run CI\non:\n  workflow_dispatch:\n  push:\n    branches: [ github-ci-action ]\n#  pull_request:\n#    branches: [ master ]\n\njobs:\n  ci_test_suite:\n    name: CI test suite\n    runs-on: ${{ matrix.job.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        job:\n          - { os: macos-12 }\n        release: [ \"13.1\" ]\n    steps:\n    - uses: actions/checkout@v3\n    - name: Run tests/CI/run.sh\n      uses: vmactions/freebsd-vm@v0\n      with:\n        mem: 8192\n        usesh: true\n        copyback: false\n        prepare: pkg install -y curl gmake potnet freebsd-release-manifests nmap\n        run: |\n          #####################################################################################\n          ###  Prepare, build, and test\n          #####################################################################################\n          ###  based on ref: <https://github.com/rust-lang/rustup/pull/2783>\n          ###  and on ref: <https://github.com/uutils/coreutils/commit/86c610a84b8b6c>\n          ###  * NOTE: All steps need to be run in this block, otherwise, we are operating back\n          ###    on the mac host\n          set -exo pipefail\n          #\n          ### Basic user setup ################################################################\n          TEST_USER=tester\n          TEST_USER_HOME=\"/opt/$TEST_USER\"\n          REPO_NAME=${GITHUB_WORKSPACE##*/}\n          WORKSPACE_PARENT=\"/Users/runner/work/${REPO_NAME}\"\n          WORKSPACE=\"${WORKSPACE_PARENT}/${REPO_NAME}\"\n          OS_VERSION=\"$(freebsd-version | awk -F- '{print $1}')\"\n          PUB_INTF=\"$(netstat -4rn | grep default | awk '{ print $4}')\"\n          ifconfig\n          #\n          mkdir -p \"$TEST_USER_HOME\"\n          pw adduser -n \"$TEST_USER\" -d \"$TEST_USER_HOME\" -c \"Tester\" -h -\n          chown -R \"$TEST_USER\":\"$TEST_USER\" \"$TEST_USER_HOME\"\n          chown -R \"$TEST_USER\":\"$TEST_USER\" \"/$WORKSPACE_PARENT\"/\n          whoami\n          #\n          ### Output some information about the environment  ##################################\n          # environment\n          echo \"## environment\"\n          env | sort\n          # tooling info\n          echo \"## installed packages\"\n          pkg info\n          #\n          ### Create zpool ####################################################################\n          dd if=/dev/zero of=/zfs1 bs=1 count=1 seek=2G\n          zdev=$(mdconfig -a -t vnode -S 4096 -f /zfs1)\n          zpool create -f zroot \"$zdev\"\n          #\n          ### Configure pf and pot ############################################################\n          echo \"set skip on lo0\" >/etc/pf.conf\n          echo pass >>/etc/pf.conf\n          service pf enable\n          service pf start\n          pw groupadd pot\n          bin/pot init\n          #\n          ### Run CI tests ################################################\n          cd \"$WORKSPACE\"\n          cp -f etc/pot/pot.default.conf etc/pot/pot.conf\n          cd tests/CI\n          set +e\n          FAULT=0\n          ./run.sh || FAULT=1\n          echo \"Log output:\"\n          cat pot-ci-*\n          if [ $FAULT -ne 0 ]; then exit 1; fi\n          #\n          ### Finished ########################################################################\n          echo \"Done\"\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "# This is a basic workflow to help you get started with Actions\n\nname: unit-test\n\n# Controls when the action will run. Triggers the workflow on push or pull request\n# events but only for the master branch\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\n# A workflow run is made up of one or more jobs that can run sequentially or in parallel\njobs:\n  # This workflow contains a single job called \"build\"\n  build:\n    # The type of runner that the job will run on\n    runs-on: ubuntu-latest\n\n    # Steps represent a sequence of tasks that will be executed as part of the job\n    steps:\n    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it\n    - uses: actions/checkout@v2\n\n    # Runs a single command using the runners shell\n    - name: Run a one-line script\n      run: cd tests && ./test-suite.sh\n"
  },
  {
    "path": ".github/workflows/shellcheck.yml",
    "content": "name: Shellcheck\n\non: [ pull_request ]\n\njobs:\n  shellcheck:\n    name: Shellcheck\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - name: Run ShellCheck\n      uses: ludeeus/action-shellcheck@master\n      with:\n        scandir: share/pot\n        additional_files: bin/pot\n"
  },
  {
    "path": ".gitignore",
    "content": "/doc\n*.swp\n*~\n/etc/pot/pot.conf\n/etc/pot/flavours/*\n!/etc/pot/flavours/dns.sh\n!/etc/pot/flavours/dns\n!/etc/pot/flavours/slim.sh\n!/etc/pot/flavours/fbsd-update.sh\ndevenv.sh\n/tests/CI/pot-ci*\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: bash\nscript: cd tests && ./test-suite.sh\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)\nand this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).\n\n## Unreleased\n### Added\n- import/prepare: Support setting a default signature public key to verify pot signature (#296)\n\n### Fixed\n- prune: Only attempt to stop pot if it is running (#295)\n\n## [0.16.0] 2023-12-30\n### Added\n- tinirc: Write tinirc's pid to /tmp/tinirc.pid (#277)\n- set-attr/stop: Add attributes exec_stop and stop_timeout (#275)\n- init/de-init: Add flag \"-m\" to be minimally intrusive, add flag -p to specify pf file (#284)\n- init: Add flag -s to not alter syslogd settings, deprecate flag -f pf_file, as it is replaced by -p (#284)\n- vnet: Add global configuration POT_ISOLATE_VNET_POTS to prevent direct traffic between VNET pots (#283)\n\n### Fixed\n- tinirc: Overwrite tinirc on start instead of appending to an existing file (#277)\n- start: Fix setting of nullfs attribute\n- set-status: Ignore status files that predate system boot (#278)\n- set-status: Forward verbosity flags (#279)\n- network: Find bridge interfaces by interface group, this allows custom bridge names (#282)\n\n## [0.15.6] 2023-09-29\n### Added\n- start: Add custom pf rule configuration hook, POT_EXPORT_PORTS_PF_RULES_HOOK (#273)\n- Remove basepath from mountpoint, make mount-in/out errors more visible (#259)\n\n## [0.15.5] 2023-06-29\n### Added\n- set-attr: Add support for setting devfs_ruleset (#270)\n- set-attr: Add support for setting mlock, sysvshm, sysvsem, sysvmsg, retire sysvipc attribute, which was always a noop (#263)\n\n### Fixed\n- pot-cmd: Output problems with pot root to stderr (#254)\n- version: Don't require pot root to exist to run version command (#253)\n- mount-in: Skip empty lines in fscomp.conf during mount process (#258)\n\n## [0.15.4] 2022-12-15\n### Added\n- set-attr: add jail attributes \"raw_sockets\", \"sysvipc\" (#247, #248)\n- import/export/prepare: support signing pots (#221)\n\n### Changed\n- flavours: scripts are made executable when loading\n- destroy: remove status file when destroying\n- vnet: use unique epaira interface names (#232)\n- Add pot group to protect pot root (#240)\n\n### Fixed\n- Reverted the change of permissions of pot root mountpoint to fix a regression (#233)\n- set-attr: fix no-etc-hosts attribute handling\n- Remove leftover mount points on destroy (#236)\n- set-attr/get-attr: fix help output (#245)\n- Fix running flavour script on non-persistent pot (#238)\n\n## [0.15.3] 2022-09-17\n### Fixed\n- stop: Destroy epair interface if stop is not called from start (#229)\n\n## [0.15.2] 2022-09-17\n### Fixed\n- start: fix pot getting stuck in state \"starting\" on pot start failure (#227)\n\n## [0.15.1] 2022-09-16\n### Fixed\n- set-status: fix a bug that deletes the status (#224)\n\n## [0.15.0] 2022-09-11\n### Added\n- mount-out: new command to remove or unmount a previously mount-in folder or fs\n- attribute no-tmpfs: an attribute, for single dataset only, to not use tmpfs for /tmp\n- create/import: inherit ZFS encryption property from parent filesystem (#196)\n- attribute no-etchosts: an attribute, to not inject additional /etc/hosts entries from `potnet`\n- last-run-stats: new command to get statistics on the last run of a pot, currently contains \"ExitCode\", which is the exit code of pot.cmd (#200)\n- start: return with code 125 in case pot.cmd of a non-persistent pot failed (#200)\n- tinirc: wait for epair interface, exit early if it doesn't become available (#204)\n- ifconfig: label and group interfaces created by pot (#206)\n- clone: add dns option, to customize DNS configuration while cloning (#199)\n- prepare: add -d option to change dns configuration during clone (#192)\n- signal: send signals to processes running inside a pot (#216)\n- exec: command to execute programs inside a running pot (#217)\n\n### Changed\n- Stop logging trivial commands like get-rss to syslog by default (#190)\n- get-rss: test if the pot is running, instead of it only exists during input validation\n- mount-in: mountpoint cannot contain spaces anymore (#187)\n- start: allow pots to run for less than 5 seconds (#200)\n- start: always stop and cleanup non-persistent pots once pot.cmd finished, prevents stray background tasks from keeping them alive (#200)\n- prune: add flag \"-g\" to delay pruning of pots that just stopped, so users have a chance to inspect last-run-stats (#200)\n- help: rework usage screens (#209)\n- prepare: enable attribute no-tmpfs and no-etc-hosts (#192)\n- tests: improved monitoring of tests, requires sysutils/flock on FreeBSD (#220)\n- Change permissions of pot root mount point to be only accessible by root user (#218)\n\n### Fixed\n- start: correct invocation of prestart and poststart hooks (#200)\n- tinirc: configure address selection policy (#205)\n- fdescfs/procfs: fixed the correcte behavior of those attribute, such as mount them at start\n- mount-out: fix it\n- clone: fix cleanup after failed clone (#214)\n- start/stop: heavy rework to fix concurrency (#202)\n\n## [0.14.0] 2021-10-31\n### Added\n- copy-in: -c option to create missing dirs on copy-in (#172)\n- create: New command copy-in-flv, which is the same as copy-in, but always relative to flavourdir (#173)\n- init: -f option to specify pf file to patch on init (#181)\n\n### Changed\n- start: do not write jid files to POT_TMP (#178)\n- start/stop: remove pot_stopped files from TMP_DIR after stopping non-persistent jails (#179)\n\n### Fixed\n- prepare: fix -N option to allow network-type \"host\" as used by nomad-pot-driver (#177)\n- copy-in: fix tmp source directory creation\n\n## [0.13.0] 2021-09-21\n### Added\n- import-export: add support for layered images (#151)\n- POT_TMP: add a parameter to select the folder used to create temporary files\n- flavour: -f option support a full pathname (#161)\n- copy-out: new command to copy file or folder out from a pot (#162)\n\n### Changed\n- start: simplify startup, use jexec to run pot.cmd (#150)\n- flavour: the current directory is added to the flavour search path (#161)\n\n### Fixed\n- start/stop: prevent stopping non-persistent jails twice (#152)\n- stop: garbage collect POSIX shared memory (#150)\n- start: fix ncat failing to start due to argv handling (#167)\n\n## [0.12.0] 2021-05-22\n### Added\n- pot.conf: add parameter to control max hostname length inside the pot (#118)\n- CI: add shellcheck as hard requirements in the PR flow\n- export-ports: add UDP support, as -e udp:53:53 (#115)\n- create: dns custom allows to statically provide a resolv.conf\n- POT_EXTIF_ADDR: new parameter to force which IP of EXTIF should be used for NAT and RDR\n- clone: add support for applying flavors to cloned pots\n- clone: add -k flag to keep the cloned pot for debug when the process failed\n- info: -s to list available snapshots of a pot\n- clone: -s flag to explicitly choose the snapshot to clone\n- architecture: remove limitation of amd64 as the only architecture supported (#143 by jmg@)\n- start/stop/term/run: add support to -p potname on those commands, the only one not supporting it\n\n### Changed\n- hostname: max default length for hostname set to 64 (#118)\n- create: adopt the new hostname length parameter (#118)\n- clone: adopt the new hostname length parameter (#118)\n- ext-if: do not include interface aliases in the bridges network if EXTIF has them (#120)\n- start: add support for custom dns resolver\n- init: create backup of rc.conf and pf.conf before to apply pot related changes\n- info: -B instead of -b for private bridge information\n- copy-in: copy is executed in the jail environment, to avoid soft-link related issues in the destination path\n- copy-in: with running pots, a -F flag is needed to force the copy, an operation that is discouraged for security reasons\n- fetch base.txz: the base FreeBSD tarball used to be temporarily stored in /tmp. While a POT_CACHE folder is available, use that instead.\n\n### Removed\n- create-dns: remove this already deprecated command, leaving the user to create a dns for the public bridge\n\n### Fixed\n- zsh: fix autocompletion for set-hook (#139 by urosgruber)\n\n## [0.11.6] 2020-12-14\n### Fixed\n- stop: remove resolv.conf only if dns is not off (#117)\n\n## [0.11.5] 2020-11-21\n### Added\n- create: dns off allows to skip the resolv.conf configuration\n\n### Fixed\n- start: (FreeBSD 12.2) pf fails to load rdr rule in some cases\n\n## [0.11.4] 2020-09-12\n### Added\n- set-attr: add many jails attributes: enforce_stats mount fdescfs libprocfs nullfs procfs tmpfs zfs children\n\n### Fixed\n- localhost-tunnel: fix multiple port support (#108)\n\n## [0.11.3] 2020-08-03\n### Changed\n- start: remove temporary files (#91 #92)\n\n### Fixes\n- clone: fix a typo refactoring the grep that remove network parameters (#90)\n- mount-in: fix mountpoint validation when pot is stopped and -v is passed (#93)\n- clone: hooks have been ignored by clone (#94)\n- info: fix withespace quoting with -E flag (#95)\n- prepare: fix -i command to allow multiple IP addresses (#97)\n- ifconfig: force IFCONFIG_FORMAT to avoid conflicting user setting (#99)\n\n## [0.11.2] 2020-05-01\n### Added\n- prepare: the -S option is now used to specify the network stack\n\n### Changed\n- prepare: the -S flag to start the imported pot changed in -s\n\n### Fixed\n- fbsd-update: don't assume there is a tty (#86)\n- clone: duplicate the entry pot.stack (#88)\n\n## [0.11.1] 2020-04-19\n### Fixed\n- set-attr: attribute early-start-at-boot is now correctly recognized\n\n## [0.11.0] 2020-04-19\n### Added\n- create-base: automatically call freebsd-update when a base is created (#83)\n- attribute early-start-at-boot: for pot needed to start early at boot (REQUIRE: NETWORKING syslogd pf)\n- create: add a -k flag to keep the pot, even if it's creation process failed\n- network stack: add network stack as framework concept (ipv4, ipv6 or dual)\n- CI: import the run.sh script, with regression system tests\n- alias: the new notation -i can be repeated to assign multiple IPs to different NICs\n- hooks: added variables to provide the full new alias network configuration\n\n### Changed\n- osrelease: detect it from freebsd-version, deprecating the osrelease field in pot.conf (#83)\n- start-at-boot: the pot rc.d service will be executed late, with jail\n- create: if create fails, the partially created pot is automatically destroyed\n- create: -P will use send/receive from a snapshot, to cut the dependency with the snapshot\n- create-multi: usr.local and custom dataset are send/received instead of cloned\n- inherit: it inherits the stack configured in pot.conf\n- alias: extend -i option to accept netif|ipaddr\n- alias: -i option can be repeated more than once to add more ip addresses to the same instance\n- syslogd: initial removal of syslogd forwarding\n\n### Removed\n- alias: remove option -I, in favour of a more flexible and powerful -i\n- export: remove option -s, to select a specific snapshot (already deprecated)\n- snapshot: remove option -n, to specify a snapshot name (already deprecated)\n- snapshot: remove flag -a, to snapshot external ZFS datasets (already deprecated)\n- revert: remove flag -a, to restore external ZFS datasets (already deprecated)\n\n### Fixed\n- mount-in: compute the realpath of the mount-point\n- create: use pipefail only where implemented\n- ipv6: rtsold doesn't start in a jail on 11.3\n\n## [0.10.4] 2020-02-23\n### Added\n- alias: add ability to use a different network interface for alias network type (#80)\n- env: add pot info -E output to environment or tinirc\n- log: add the ability to log activites in syslog\n\n### Fixed\n- prepare: fix multiple export port support\n- rc script: extend PATH to make potnet accessible\n- etc/hosts: add full hostname to localhost\n\n## [0.10.3] 2020-01-07\n### Changed\n- export-ports: relax the check bout the pot's network type\n- list: print a message, if there are no pot yet\n\n## [0.10.2] 2019-12-17\n### Added\n- fbsd-update flavour: add a flavour to run freebsd update\n\n### Changed\n- slim flavour: remove a bounch of other directories\n\n### Fixed\n- flavor: set-cmd can cause issue if it has quotes or double quotes in the command string\n- tinirc: lo1 initialization needed only for public or private bridge\n- start: background tasks now check if the pot is running\n- init: fix bridge folder creation\n- prepare: fix prepare when no command is provided (-c is optional)\n\n## [0.10.1] 2019-12-04\n### Added\n- set-hooks: add support for pre/post start/stop hooks. Script are executed in the host environment (#61)\n\n### Changed\n- home-usr/home: those link are not always available. Change create and crate-base to have them always (reported by Philip Jocks)\n\n### Fixed\n- create: permission of /tmp in single type are wrong (#72)\n- create: if FreeBSD base fetch is interrupted, a broken file is left and the checksum will always fail (#73)\n- import: if the image fetch is interrupted, a broken file is left and the checksum will always fail\n- import: fix hostname rename\n- localhost-tunnel: fix kill of ncat tunnel, when the pot has a long name\n\n## [0.10.0] 2019-11-01\n### Added\n- info: support for bridge\n- set-hosts: new command to add custom etc/hosts entries to a pot\n- set-env: new command to add environment variable to a pot\n- network-type private-bridge: add a new network layout, to provide private bridges for a group of pots\n- create-private-bridge: new subcommand to define and create a private-bridge\n- create: add option -B, to provide the bridge name if network-type is private-bridge\n- clone: add option -B, to provide the bridge name if network-type is private-bridge\n- prepare: add option -B, to provide the bridge name if network-type is private-bridge\n- destroy: add option -B, to provide a way to destroy a bridge\n- Image Guide: added a guide about how to create an Image of a pot\n- POT_EXTRA_EXTIF: add addition network interfaces support\n\n### Changed\n- start: overwrite /etc/hosts of a pot, adding all pots on the same bridge and custom entries added via set-hosts\n- flavorable commands: extend support to set-cmd and set-env\n- pot-rdr anchor: the name of the anchor is now a truncated pot name (the last 54 characters)\n- export: it's executed only if one snapshot is available. -F force execution, -A fix the number of snapshots, via purge-snapshots or taking a shapshot automagically\n- start: using exec.start instead of command (it seems more predictable)\n\n### Deprecated\n- snapshot: -n option to provide custom name to snapshots\n- support to full pot snapshot (external zfs dataset) in snapshot and start, as well as the _pot_zfs_snap_full function\n- support to full pot revert (external zfs dataset) in revert/rollback (option -a)\n- create-dns: undocumented and too hard to maintain\n- export: -s option, to specify a snapshot. It's misleading, because zfs send -R will send all the previous snapshots anyway\n\n### Fixed\n- flavorable commands: they cannot exit, but return. create can stop flavour execution otherwise\n- show: fix single type support and directory in fscomp.conf\n- start: if the command has arguments with equals, it would have been truncated\n\n## [0.9.2] 2019-08-25\n### Added\n- prune: invoke a stop, before the destroy, even if the pot is not runing\n- lockf: introducing lockf to run create, import or clone one at a time\n\n### Fixed\n- stop: make the pkill on ncat more robust\n- stop: add a workaround for a race condition in the epair driver\n\n## [0.9.1] 2019-08-20\n### Added\n- localhost-tunnel attribute: new attribute to create a tunnet to redirect traffic from localhost (consul feature)\n\n### Changed\n- prepare: allow network type \"host\" as alias for \"inherit\" (nomad-friendly feature)\n- prepare: set localhost-tunnel automatically (consul-friendly feature)\n\n### Fixed\n- get-rss: fix return code when the pot is not valid\n- set-cmd: fix potential double quotes surrouding the command\n- get-rss: TotalTicks is now expressed in Mhz (pcpu * max cpu Frequency)\n- get-rss: add swap usage statistic\n- start: fix tinirc permission if no-rc-script is used with network type different than public-bridge\n- destroy: use -f to remove the 'Device busy' issue\n\n## [0.9.0] 2019-08-13\n### Added\n- Installation Guide: a more detailed guide, that better explains the installation of pot\n- fdescfs attribute: new attribute to mount fdescfs inside the pot\n- init: add a network configuration validation step\n\n### Changed\n- POT_CACHE: the cache used by import is now a dataset, child of POT_ZFS_ROOT\n- set-rss: CPU limits is set as maximum amount of CPU. At start, pot decide where to allocate using potcpu\n- prunable: if a pot is prunable, it has to be started at least once to be pruned (flavour counts)\n\n## [0.8.0] 2019-07-30\n### Added\n- update-config: implemented -a flag to update all pot configurations in one run\n- get-rss: show the current resources usage (output available in json)\n- procfs attribute: new attribute to mount a procfs inside the pot\n- prunable attribute: new attribute prunable, to automatically delete not running pots (prune)\n- prune: new command to automatically destro yinactive prunable pots\n\n### Changed\n- create: rework how to configure the network type of a pot\n- Quickstart Guide: rework the guide using mount-in and copy-in, listing all possibilities\n- README: remove the introduction and pointing to the Quickstart guide instead\n- import: removed -a option, not really needed during import\n- prepare: optimized, importing once and using clone instead of import+rename every time\n- clone: add -N option, to change network type while cloning\n- prepare: add -N option, to change network type while preparing\n\n### Removed\n- promote: after a long deprecation time, promote has been deleted\n- add-fscomp: removed, mount-in is its more generic replacement\n- add-file: removed, copy-in is its more generic replacement\n- execute: remove this alias of prepare\n\n### Fixed\n- start: if the start command doesn't go in background, rss and persist weren't managed\n\n## [0.7.0] 2019-07-04\n### Added\n- update-config: new command that will update a pot configuration\n- execute: an orchestration oriented command that imports and automatically set several settings on a pot\n- prepare: new command, taking the place of execute\n- copy-in: new command, to copy files or directory inside a pot (generalized replacement of add-file)\n- mount-in: new command, to mount a directory, a zfs dataset or a fscomp inside a pot (replacement for add-fscomp)\n\n### Changed\n- export-ports: removed -S for static port export\n- export-ports: add the ability to associate any host port to a pot port to be exported using pot_port:host_port format\n- execute: an alias for prepare\n\n### Deprecated\n- add-file: deprecated, replaced by the more general new copy-in command\n- add-fscomp: deprecated, replaces by the more general new mount-in command\n\n## [0.6.1] 2019-06-25\n### Fixed\n- init: make pf.conf more robust\n- vnet-start: make pf start more robust, in case pf as service is not up\n\n## [0.6.0] 2019-06-23\n### Added\n- add-fscomp: add option -d, to allow to mount generic directories into a pot (-d and -f are mutual)\n- show: add -q flag, to only show pot names\n- set-attribute: to set pot attributes (options/flags/configurations)\n- get-attribute: to get pot attributes (options/flags/configurations)\n- FreeBSD version usable to create a pot are all the ones listed in the FreeBSD MANIFEST\n- attributes: add persistent attribute to jail\n- attributes: add no-rc-script attribute to start a pot without a rc script\n- add-file: new command to copy a single file inside a pot\n\n### Changed\n- inherit network: added ipv6 support (automatic)\n- static IP network: added ipv6 support\n- pf: adopt anchor with relevant changes in nat rules management\n\n### Deprecated\n- pot_list: in rc.conf pot_list is not supported anymore. Please use the start-at-boot attribute\n\n### Fixed\n- syntax error in zsh autocompletion\n- ls fscomp: using zfs instead of ls (if a fscomp is re-mounted, the mountpoint is not in /opt/pot/fscomp anymore)\n- static-ip: Fix invocation to potnet to validate ip addresses\n\n## [0.5.11] 2019-03-04\n### Added\n- export: new command. export generates a compressed file with the entire pot in it. It works only for single type pot\n- export: -D option to change export directory and -l option to change compression level\n- POT_CACHE: a place to cache pot images. It's a variable of pot.conf\n- import: new command. import create a new pot based on an image generated via export\n- import-export: add skein has verification support\n\n### Changed\n- rc.d: changed order, to start pot before ntpdate\n- destroy: extend the usage of -F to be able to destroy corrupted pots\n\n### Fixed\n- destroy: fix return code\n- rename: fix single pot support\n- get_conf_var: using a better RE to avoid to detect variables value in pot names (Thanks to Johan Hendriks to report)\n\n## [0.5.10] 2019-01-15\n### Added\n- destroy: option -f can be used to delete/destroy a fscomp (no recursive support yet)\n- vnet-start: add support to VPN and custom pf configuration\n\n### Changed\n- destroy: option -f (force) is now -F\n\n### Fixed\n- is_pot: improve support to single pots, that don't have fscomp.conf file\n- create-base: fix regression introduced on 0.5.9 (RC support and create -F removal)\n\n## [0.5.9] 2018-12-16\n### Added\n- Add support to RC FreeBSD version\n- config: add pot_prefix and fscomp_prefix as possible values\n- snapshot: add option -n to give a name to the snapshot; valid for fscomp only\n- Add support to FreeBSD 12.0\n\n### Changed\n- create: removed -F option and silent default flavor invocation. Default flavor has to be explicitely selected via -f\n- create-base: removed support for undocumented default-base flavor\n\n## [0.5.8] 2018-11-29\n### Added\n- QuickStart.md : a markdown quick guide, for new users\n- create : -i auto (based on potnet) to get automatically a valid IP address\n- clone : -i auto (based on potnet) to get automatically a valid IP address\n- clone : add support to single type pot\n- export-port : new command that allow pot ports to be exposed outside (vnet case)\n- slim flavor, designed to be used with single dataset pot types\n- purge-snapshot : new command that will remove all snapshots, except the last one\n- export-port : static option, to add statically exported ports\n\n### Changed\n- init : it takes care of syslogd configuration in the host system\n- create : type=single will install plain FreeBSD and run the default flavour\n- create : multiple flavour support, executed in sequentially; option -f can be repeated\n- add-fscomp : exploit the new internal refactorized mount and umount function to avoid to start the pot\n- add-fscomp : if the pot is running, mount the new fscomp right away\n\n### Fixed\n- clone : fix a misleading/false positive error message\n- clone : fix syslogd configuration in the cloned pot\n- destroy : fix if pot is a single dataset one\n- start : fix hostname warning\n- start (#046) : run the jail in a clean enviroment\n- term (#046) : spawn the shell in a jail using the jailed user environment\n- add-fscomp (#045) : check the mount point and create it, if missing\n- list (#052) : fixing xargs invocation\n\n### Deprecated\n- promote : mark promot as deprecated, so we can remove it in the next major release\n\n## [0.5.7] 2018-06-28\n### Added\n- create-base : add support to FreeBSD 11.2\n\n### Fixed\n- version (#038) : fix the version number showed\n\n## [0.5.6] 2018-05-18\n### Added\n- create-base : add option -b, to provide a specific name to a base and support multiple bases with the same FreeBSD version\n- create: add support to single dataset pots.\n- set-cmd: add the command to manage the command line that starts the container\n- top: add a new command, to spawn a top only on a pot\n\n## [0.5.5] 2018-04-18\n### Added\n- ps : add ps subcommand, to show information about which pot is running\n- config : add config subcommand, to easily access configuration values\n- zsh autocompletion (#013): pot autocompletion support for zsh\n- syslogd log unification (#032): when possible, syslogd autoconfigured to log in the host instead of in the pot\n\n### Changed\n- list : keep it more simple, leaving more information under -v\n- show : add -r (all running pots) option and made it the new default\n- show : -a greatly improved show all relevant information per pot\n\n### Removed\n- fs.conf is not supported anymore\n\n## [0.5.0] 2018-03-16\n### Added\n- add-fscomp : add the ability to remount a fscomp (-w), instead of mount it via nullfs\n- add-fscomp : add the ability to mount a fscomp in read-only (-r)\n- info : new command, to get information about a specific pot\n- rc.d script (#022)\n- create (#020) : add option -s, to configure static ip address (alias to external network interface)\n- create-base (#030) : add sha verification using freebsd-release-manifests\n- version : add a subcommand the print the current version of the utility\n- fscomp.conf : new fs component description file\n- clone : -f option to automatically get a snapshot of a dataset, if needed\n- promote (#008) : add promote command\n\n### Changed\n- create: the new wiki page shows the slightly different behavior of all use cases\n- create: fscomp.conf is generated instead of fs.conf, using dataset instead of mountpoint as first column\n- private datasets are now mounted changing the mountpoint of the dataset, instead of relying on nullfs\n  For that reasons, an option called \"zfs-remount\" is added to the fs.conf file\n\n### Deprecated\n- fs.conf: fs.conf is deprecated. Support will be removed in the next release.\n\n### Removed\n- create: -S option, not needed anymore\n\n## [0.4.0] 2018-02-13\n### Added\n- rollback : added rollback as alias of revert\n- help : add support for aliases\n- add-fscomp (#027): add support for external ZFS dataset via the option -e\n- de-init (0#23): new command to completely remove (de-install) pot from your system\n\n### Fixed\n- stop (#024): check the pot existance\n- stop : fixed error messages referring to \"jail\"\n- list : fix help, option -s never implemented\n- destroy (0#25): fix pot name validation and add dependency detection\n\n## [0.3.1] 2018-01-26\n### Added\n- pot.conf.sample : a documentated pot.conf example\n\n## [0.3.0] 2018-01-26\n### Added\n- Every command that need root privileges perform a check of the user id\n- create (#010): add a validation of command types executable in a pot flavour\n- Checks about VIMAGE and rctl usability (#018)\n\n### Changed\n- set-rss : rename command (it was add-rss)\n- vnet-start (#019): automatic activation of ip forwarding\n\n### Fixed\n- create-base (#016): do not re-create the base pot\n- rename (#017): apply the rename also in dependents pots (level 2 or runtime dependency)\n- create (#021): -b argument validation\n\n## [0.2.0] 2018-01-23\n### Added\n- create-dns : new command, to create the dns pot\n- create : add the option -d to choose the type of dns (inherit or pot)\n- start : add the support to dns types\n\n### Fixed\n- rename : remove a misleading error message\n- start : proper stop, if one mount fails\n- vnet-start (#009): pf module loaded and firewall enabled\n\n## [0.1.0] 2017-12-14\n### Added\n- Add resource constraints, via add-rss command\n- Add clone-fscomp command, to clone a fscomp\n- Add clone command, to clone a pot\n- Add rename command, to completely rename a pot\n- Add dependency support, and related command add-dep\n- Add support to destroy bases and their related level 0 pot\n- Add support to recursive destroy\n- Add support to default flavour with create-base\n- Add -F option to create, to disable the default flavour\n- More tests\n\n### Changed\n- Move packages db to the usr.local dataset - it's a breaking change\n\n## [0.0.2] 2017-12-03\n### Fixed\n- Fixed start, a typo prevents the correct behavior\n\n## [0.0.1] 2017-12-03\n### Added\n- Add a revert command, to rollback a pot snapshot\n- Add snaposhot information in list command\n- Add a test framework\n- Add travis-ci support\n\n### Changed\n- snapshot options has changed to be more consistent and to support fscomp\n- revert options has changed to be more consistent and to support fscomp\n\n### Fixed\n- If a start fails, it tries to clean up (umount)\n\n## [0.0.1-rc.1] 2017-11-28\n### Added\n- Add a vnet-start command, to properly init the vnet network configuration (bridge+pf)\n- Add an option to show, to show all pot resource usage\n- Add some command alias: ls is an alias of list\n- Auto-start of vnet, when needed\n- Add level 2 pot support, adding special option -P and -S in create command\n- Add a run command, to start and enter in a pot\n- Add a -f option to destroy and term, to fix/force the operation\n- Add -F for flavor and -a for all in list command\n\n### Changed\n- Changed pot configuration. No jail.conf anymore, but pot.conf\n- Pots with an ip are now based on epair/vnet/VIMAGE technology\n- Command show now shows resource usage of all pots by default\n- Add more information in show and list command\n\n### Deprecated\n- jail.conf files are currently ignored, please destroy and recreate pots\n\n### Removed\n- scripts directory and j\\* commands in bin. None of them could really works\n## [0.0.1-beta] 2017-11-07\n### Added\n- Add option -b to list, to list available bases\n- Add option -f to list, to list available fs components\n- Add a destroy command, to destroy a pot\n- Add a term command, to start a pot\n- First implementation of show, that shows memory used by running pots\n- Add support to flavour- pot subcommand and shell script\n\n### Changed\n- Remove jail references and use pot instead (not in zfs)\n- jstart command is now start\n- jstop command is now stop\n- create-jail command is not create\n- create-base creates the related level 0 pot automatically\n- start doesn't invoke exit if succeeds\n\n### Fixed\n- Fix add-fscomp that can introduce valid, but imprecise mount-point\n- Fix create-base that created a wrong usr.local.etc link\n\n## [0.0.1-alpha] 2017-10-20\n### Added\n- Add the central utility called 'pot'\n- Add a central configuration file\n- Add a init command, to initialize the zfs layout\n- Add a create-base command, to create a new base\n- Add a create-fscomp command, to create a new base\n- Add a create-jail command, to create a new base\n- Add a jstart command, to start a pot\n- Add a jstop command, to stop a pot\n- Add an option to jstart, to take a snapshot of the pot before the start\n- Add a help command, to show subcommand helps\n- Add a list command, to list of pots\n- Add a add-fscomp command, to add fscomponents to pots\n- Add a snapshot command, to take a snapshot of a pot\n\n### Changed\n- After long time spent on thinking, the project has a new nice name, pot.\n"
  },
  {
    "path": "Jenkinsfile",
    "content": "pipeline {\n\tagent any\n\n\tenvironment {\n\t\tTERM = 'rxvt'\n\t}\n\n\tstages {\n\t\tstage('Test') {\n\t\t\tsteps {\n\t\t\t\tsh 'echo \"Hello World\"'\n\t\t\t\tsh '''\n\t\t\t\t\tcd tests\n\t\t\t\t\t./test-suite.sh\n\t\t\t\t'''\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2017, Luca Pizzamiglio\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "# THIS REPOSITORY IS NO LONGER ACTIVELY MAINTAINED, IT HAS MOVED TO https://codeberg.org/bsdpot/pot\n# pot\n\n[![build-badge](https://github.com/pizzamig/pot/workflows/unit-test/badge.svg)](https://github.com/pizzamig/pot/actions) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n\nAnother container framework based on jails, to run FreeBSD containers on FreeBSD.\nEvery running instance is called `pot`, like the one that I use to cook all the different type of pasta.\nIt's heavily based on FreeBSD, in particular on jails, ZFS, pf and rctl.\n\nThe project's initial goal was to prove that FreeBSD has all the technologies to have a container-alike environment.\nThe project then evolved into something more robust and feature-rich.\n\nThe project was presented for the first time at FOSDEM 2018: ([talk page](https://archive.fosdem.org/2018/schedule/event/pot_container_framework/))\n\nIf you are more interested in jail orchestration, a nomad driver is provided to interact with `pot` and this work has been presented at FOSDEM 2020 ([talk page](https://archive.fosdem.org/2020/schedule/event/orchestrating_jails/))\n\n### Documentation\nThe project's documentation is available at [https://pot.pizzamig.dev](https://pot.pizzamig.dev)\n\nMore in details:\n* A Getting started guide is available [here](https://pot.pizzamig.dev/Getting)\n* An installation guide, with detailed description is available [here](https://pot.pizzamig.dev/Installation)\n\n### Nomad pot driver integration\nA driver to allow [nomad](https://www.nomadproject.io) to interact with `pot` has been developed and available [here](https://github.com/trivago/nomad-pot-driver)\n\n### Ansible Collection\n\nThere is pot collection for Ansible provided by github user @zilti available at https://galaxy.ansible.com/zilti/pot.\n\n### Online help\n`pot` provide an online help:\n```\n# pot help\nUsage: pot command [options]\n\nCommands:\n\thelp\t-- Show help\n\tversion -- Show the pot version\n\tconfig  -- Show pot framework configuration\n\tls/list\t-- List of the installed pots\n\tshow\t-- Show pot information\n\tinfo    -- Print minimal information on a pot\n\ttop     -- Run the unix top in the pot\n\tps      -- Show running pots\n\tinit\t-- Initialize the ZFS layout\n\tde-init\t-- Deinstall pot from your system\n\tvnet-start -- Start the vnet configuration\n\tcreate-base\t-- Create a new base image\n\tcreate-fscomp -- Create a new fs component\n\tcreate-private-bridge -- Create a new private bridge\n\tcreate -- Create a new pot (jail)\n\tclone -- Clone a pot creating a new one\n\tclone-fscomp - Clone a fscomp\n\trename -- Rename a pot\n\tdestroy -- Destroy a pot\n\tprune   -- Destroy not running prunable pots\n\tcopy-in -- Copy a file or a directory into a pot\n\tmount-in -- Mount a directory, a zfs dataset or a fscomp into a pot\n\tadd-dep -- Add a dependency\n\tset-rss -- Set a resource constraint\n\tget-rss -- Get the current resource usage\n\tset-cmd -- Set the command to start the pot\n\tset-env -- Set environment variabls inside a pot\n\tset-hosts -- Set etc/hosts entries inside a pot\n\tset-hook -- Set hook scripts for a pot\n\tset-attr -- Set a pot's attribute\n\tget-attr -- Get a pot's attribute\n\texport-ports -- Let export tcp ports\n\tstart -- Start a jail (pot)\n\tstop -- Stop a jail (pot)\n\tterm -- Start a terminal in a pot\n\trun -- Start and open a terminal in a pot\n\tsnap/snapshot -- Take a snapshot of a pot\n\trollback/revert -- Restore the last snapshot\n\tpurge-snapshots -- Remove old/all snapshots\n\texport -- Export a pot to a file\n\timport -- Import a pot from a file or a URL\n\tprepare -- Import and prepare a pot - designed for jail orchestrator\n\tupdate-config -- Update the configuration of a pot\n```\n\nEvery command has its own online help as well. For instance:\n```\npot create [-hv] -p potname [-N network-type] [-i ipaddr] [-l lvl] [-f flavour]\n  [-b base | -P basepot ] [-d dns] [-t type]\n  -h print this help\n  -v verbose\n  -k keep the pot, if create fails\n  -p potname : the pot name (mandatory)\n  -l lvl : pot level (only for type multi)\n  -b base : the base pot\n  -P pot : the pot to be used as reference\n  -d dns : one between inherit(default), pot, off or custom:filename\n  -f flavour : flavour to be used\n  -t type: single or multi (default multi)\n         single: the pot is based on a unique ZFS dataset\n         multi: the pot is composed by a classical collection of 3 ZFS dataset\n  -N network-type: one of those\n         inherit: inherit the host network stack (default)\n         alias: use a static ip as alias configured directly to the host NIC\n         public-bridge: use the internal commonly public bridge\n         private-bridge: use an internal private bridge (with option -B)\n  -i ipaddr : an ip address or the keyword auto (if compatible with the network-type)\n         auto: usable with public-bridge and private-bridge (default)\n         ipaddr: mandatory with alias, usable with public-bridge and private-bridge\n  -B bridge-name : the name of the bridge to be used (private-bridge only)\n  -S network-stack : the network stack (ipv4, ipv6 or dual)\n```\n"
  },
  {
    "path": "bin/pot",
    "content": "#!/bin/sh\n\n# Copyright (c) 2017, Luca Pizzamiglio <pizzamig@FreeBSD.org>\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n#\n# * Redistributions of source code must retain the above copyright notice, this\n#   list of conditions and the following disclaimer.\n#\n# * Redistributions in binary form must reproduce the above copyright notice,\n#   this list of conditions and the following disclaimer in the documentation\n#   and/or other materials provided with the distribution.\n#\n# * Neither the name of the copyright holder nor the names of its\n#   contributors may be used to endorse or promote products derived from\n#   this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# Force ifconfig into expected format\nexport IFCONFIG_FORMAT=addr:default\n\n# Environment initialization and initial checks\n\n# shellcheck disable=SC2034\n_POT_VERSION=0.16.0\n_POT_PATHNAME=\"$(realpath \"$0\")\"\n_POT_PREFIX=\"$(dirname \"${_POT_PATHNAME}\")\"\n_POT_INCLUDE=\"$( realpath \"${_POT_PREFIX}/../share/pot\")\"\n_POT_ETC=\"$( realpath \"${_POT_PREFIX}/../etc/pot\")\"\nif [ -d \"${_POT_ETC}/flavours\" ]; then\n\t_POT_FLAVOUR_DIR=\"$( realpath \"${_POT_ETC}/flavours\")\"\nelse\n\t# shellcheck disable=SC2034\n\t_POT_FLAVOUR_DIR=\nfi\n\nif [ ! -d \"${_POT_INCLUDE}\" ]; then\n\techo \"Fatal error! Not able to find the subroutines directory as ${_POT_INCLUDE}!\"\n\texit 1\nfi\n\n# loading subroutines\n\nif [ ! -r \"${_POT_INCLUDE}/common.sh\" ]; then\n\techo \"Fatal error! Not able to find common subroutines in ${_POT_INCLUDE}!\"\n\texit 1\nfi\n# shellcheck disable=SC1090\n. \"${_POT_INCLUDE}/common.sh\"\n\nif [ ! -r \"${_POT_INCLUDE}/common-flv.sh\" ]; then\n\techo \"Fatal error! Not able to find flavor subroutines in ${_POT_INCLUDE}!\"\n\texit 1\nfi\n# shellcheck disable=SC1090\n. \"${_POT_INCLUDE}/common-flv.sh\"\n\nif [ ! -r \"${_POT_INCLUDE}/network.sh\" ]; then\n\techo \"Fatal error! Not able to find network subroutines in ${_POT_INCLUDE}!\"\n\texit 1\nfi\n# shellcheck disable=SC1090\n. \"${_POT_INCLUDE}/network.sh\"\n\n# loading configuration\nif [ -r \"$_POT_ETC/pot.default.conf\" ]; then\n\t# shellcheck disable=SC1090\n\t. \"$_POT_ETC/pot.default.conf\"\nelse\n\t_error \"Fatal error! Not able to find default configuration file on $_POT_ETC\"\n\texit 1\nfi\n\nif [ -r \"$_POT_ETC/pot.conf\" ]; then\n\t# shellcheck disable=SC1090\n\t. \"$_POT_ETC/pot.conf\"\nfi\n\nusage() {\n\tcat <<-\"EOF\"\n\tUsage: pot command [options]\n\n\tCommands:\n\t    help    -- Show help\n\t    version -- Show version of the pot command\n\t    config  -- Show pot framework configuration\n\t    ls/list -- List of the installed pots\n\t    show    -- Show information on pots\n\t    info    -- Print minimal information on a pot\n\t    top     -- Run top(1) inside the pot\n\t    ps      -- Show running pots\n\t    init    -- Initialize the ZFS layout\n\t    de-init -- Remove pot from your system\n\t    vnet-start -- Start vnet configuration\n\t    create-base -- Create a new base image\n\t    create-fscomp -- Create a new fs component\n\t    create-private-bridge -- Create a new private bridge\n\t    create -- Create a new pot (jail)\n\t    clone -- Clone a pot, creating a new one\n\t    clone-fscomp -- Clone an fscomp\n\t    rename -- Rename a pot\n\t    destroy -- Destroy a pot\n\t    prune   -- Destroy non-running, prunable pots\n\t    copy-in -- Copy a file or a directory into a pot\n\t    copy-out -- Copy a file or a directory out of a pot\n\t    mount-in -- Mount directory, ZFS dataset, or fscomp into a pot\n\t    mount-out -- Unmount directory, ZFS dataset, or fscomp from a pot\n\t    add-dep -- Add a dependency\n\t    set-rss -- Set a resource constraint\n\t    get-rss -- Get the current resource usage\n\t    set-cmd -- Set the command to start the pot\n\t    set-env -- Set environment variables inside a pot\n\t    set-hosts -- Set /etc/hosts entries inside a pot\n\t    set-hook -- Set hook scripts for a pot\n\t    set-attribute/set-attr -- Set an attribute on a pot\n\t    get-attribute/set-attr -- Get an attribute from a pot\n\t    export-ports -- Allows exposing tcp and udp ports\n\t    start -- Start a pot (jail)\n\t    stop -- Stop a pot (jail)\n\t    term -- Open terminal inside of a pot\n\t    run -- Same as term, but start pot if it is not running\n\t    snap/snapshot -- Take a snapshot of a pot\n\t    rollback/revert -- Restore the latest snapshot\n\t    purge-snapshots -- Remove old/all snapshots\n\t    export -- Export a pot to a file\n\t    import -- Import a pot from a file or a URL\n\t    prepare -- Import and prepare a pot, used by orchestrators\n\t    update-config -- Update the configuration of a pot\n\t    last-run-stats -- Get statistics about a pot's last run\n\t    signal -- Send signal to pot\n\t    exec -- Execute a progam inside of a pot\n\tEOF\n}\n\n# shellcheck disable=SC2034\n# variable initialization\n_POT_VERBOSITY=1\n\n# parsing command line subcommand\nif [ $# -lt 1 ]; then\n\tusage\n\texit 1\nfi\nCMD=\"$1\"\nshift\n\ncase \"${CMD}\" in\n\tls)\n\t\tCMD=list\n\t\t;;\n\trollback)\n\t\tCMD=revert\n\t\t;;\n\tsnap)\n\t\tCMD=snapshot\n\t\t;;\n\tset-attr)\n\t\tCMD=set-attribute\n\t\t;;\n\tget-attr)\n\t\tCMD=get-attribute\n\t\t;;\nesac\n\ncase \"${CMD}\" in\n\thelp)\n\t\tif [ -n \"$1\" ]; then\n\t\t\tpot-cmd \"${CMD}\" \"$1\"\n\t\t\texit 0\n\t\telse\n\t\t\tusage\n\t\t\texit 0\n\t\tfi\n\t\t;;\n\tshow|version|config|\\\n\tlist|info|ps|top|\\\n\tinit|de-init|vnet-start|\\\n\tcreate-base|create-fscomp|create|\\\n\tcreate-private-bridge|\\\n\tcopy-in|copy-out|mount-in|mount-out|prune|set-hook|\\\n\tdestroy|add-dep|set-rss|get-rss|set-cmd|set-env|set-hosts|\\\n\texport|import|prepare|\\\n\texport-ports|set-attribute|get-attribute|\\\n\tstart|stop|term|\\\n\trename|clone|clone-fscomp|promote|\\\n\tsnapshot|revert|purge-snapshots|update-config|\\\n\tlast-run-stats|signal|exec|set-status)\n\t\tpot-cmd \"${CMD}\" \"$@\"\n\t\texit $?\n\t\t;;\n\trun)\n\t\tpot-cmd term -f \"$@\"\n\t\texit $?\n\t\t;;\n\t*)\n\t\tusage\n\t\texit 1\n\t\t;;\nesac\n"
  },
  {
    "path": "etc/pot/flavours/dns",
    "content": "set-attribute -A start-at-boot -V YES\n"
  },
  {
    "path": "etc/pot/flavours/dns.sh",
    "content": "#!/bin/sh\n\npkg install -y dnsmasq\npkg install -y consul\npkg clean -ayq\n\nif [ ! -d /usr/local/etc/consul.d ]; then\n\tmkdir -p /usr/local/etc/consul.d\nfi\n\n_epair=\"$(ifconfig | egrep 'epair.*b' | cut -f 1 -d':')\"\n_ip=\"$( ifconfig $_epair inet | awk '/inet/ { print $2; }' )\"\n_ip1=\"$( echo $_ip | cut -f 1 -d'.' )\"\n_ip2=\"$( echo $_ip | cut -f 2 -d'.' )\"\n_domain=\"$( hostname | cut -f 2 -d'.' )\"\necho \"server=/${_domain}/127.0.0.1#8600\" >> /usr/local/etc/dnsmasq.conf\necho \"server=/0.${_ip2}.${_ip1}.in-addr.arpa/127.0.0.1#8600\" >> /usr/local/etc/dnsmasq.conf\necho \"listen-address=${_ip}\" >> /usr/local/etc/dnsmasq.conf\n\nsysrc dnsmasq_enable=\"YES\"\nsysrc consul_enable=\"YES\"\nsysrc consul_args=\"-server -dev -domain=${_domain} -bind=${_ip}\"\n"
  },
  {
    "path": "etc/pot/flavours/fbsd-update.sh",
    "content": "#!/bin/sh\n\nexport PAGER=/bin/cat\nfreebsd-update --not-running-from-cron fetch install\n"
  },
  {
    "path": "etc/pot/flavours/slim.sh",
    "content": "#!/bin/sh\n\ndirs=\"/usr/share/bsdconfig /usr/share/doc /usr/share/dtrace /usr/share/examples /usr/share/man /usr/share/openssl /usr/share/sendmail /usr/share/pc-sysinstall /usr/libexec/bsdinstall /usr/libexec/bsdconfig /rescue /usr/tests /usr/lib32 /usr/lib/clang /usr/include /var/db/freebsd-update /var/db/etcupdate /boot\"\nusr_bin=\"c++ c++filt c89 c99 cc CC cpp clang clang-cpp clang-tblgen clang++ gdb gdbtui gdbserver ld ld.bfd ld.lld lldb llvm-objdump llvm-tblgen nm objcopy objdump strings strip\"\nusr_bin_glob=\"svnlite yp\"\n\nusr_sbin=\"dtrace\"\nusr_sbin_glob=\"bhyve boot yp\"\nrm -f /usr/lib/*.a\n## Remove pkg stuff\nrm -rf /var/db/pkg/*\nrm -rf /usr/sbin/pkg\nrm -rf /usr/local/sbin/pkg\n\nfor d in $dirs ; do\n\trm -rf ${d}\ndone\n(\n\tcd /usr/bin\n\tfor f in $usr_bin ; do\n\t\trm -f $f\n\tdone\n\tfor g in $usr_bin_glob ; do\n\t\trm -rf ${g}*\n\tdone\n)\n(\n\tcd /usr/sbin\n\tfor g in $usr_sbin_glob ; do\n\t\trm -rf ${g}*\n\tdone\n\trm -f $usr_sbin\n)\n"
  },
  {
    "path": "etc/pot/pot.conf.sample",
    "content": "# pot configuration file\n\n# All datasets related to pot use the some zfs dataset as parent\n# With this variable, you can choose which dataset has to be used\n# POT_ZFS_ROOT=zroot/pot\n\n# It is also important to know where the root dataset is mounted\n# POT_FS_ROOT=/opt/pot\n\n# This is the cache used to import/export pots\n# POT_CACHE=/var/cache/pot\n\n# This is where pot is going to store temporary files\n# POT_TMP=/tmp\n\n# This is the group owning POT_FS_ROOT\n# POT_GROUP=pot\n\n# This is the suffix added to temporary files created using mktemp,\n# X is a placeholder for a random character, see mktemp(1)\n# POT_MKTEMP_SUFFIX=.XXXXXXXX\n\n# Define the max length of the hostname inside the pot\n# POT_HOSTNAME_MAX_LENGTH=64\n\n# Internal Virtual Network configuration\n\n# IPv4 Internal Virtual network\n# POT_NETWORK=10.192.0.0/10\n\n# Internal Virtual Network netmask\n# POT_NETMASK=255.192.0.0\n\n# The default gateway of the Internal Virtual Network\n# POT_GATEWAY=10.192.0.1\n\n# The name of the network physical interface, to be used as default gateway\n# POT_EXTIF=em0\n\n# The list of extra network interface, to make other network segments accessible\n# POT_EXTRA_EXTIF=vlan20 vlan50\n# for each extra interface, a variable is used to sepcify its network segment\n# POT_NETWORK_vlan20=192.168.100.0/24\n# POT_NETWORK_vlan50=10.50.50.0/24\n\n# Do not allow bridge-based pots to forward traffic to each other\n# POT_ISOLATE_VNET_POTS=true\n\n# DNS on the Internal Virtual Network\n\n# name of the pot running the DNS\n# POT_DNS_NAME=dns\n\n# IP of the DNS\n# POT_DNS_IP=10.192.0.2\n\n# Path to default public key to verify pot signatures using signify(1)\n# on import/prepare - can be overridden using `-C pubkey`.\n# POT_DEFAULT_SIGNATURE_PUBKEY=/usr/local/etc/pot/sign_key.pub\n\n# VPN support\n\n# name of the tunnel network interface\n# POT_VPN_EXTIF=tun0\n# POT_VPN_NETWORKS=192.168.0.0/24 192.168.10.0/24\n"
  },
  {
    "path": "etc/pot/pot.default.conf",
    "content": "# pot configuration file - default values\n\n# All datasets related to pot use the some zfs dataset as parent\n# With this variable, you can choose which dataset has to be used\nPOT_ZFS_ROOT=zroot/pot\n\n# It is also important to know where the root dataset is mounted\nPOT_FS_ROOT=/opt/pot\n\n# This is the cache used to import/export pots\nPOT_CACHE=/var/cache/pot\n\n# This is where pot is going to store temporary files\nPOT_TMP=/tmp\n\n# This is the group owning POT_FS_ROOT\nPOT_GROUP=pot\n\n# This is the suffix added to temporary files created using mktemp,\n# X is a placeholder for a random character, see mktemp(1)\nPOT_MKTEMP_SUFFIX=.XXXXXXXX\n\n# Define the max length of the hostname inside the pot\nPOT_HOSTNAME_MAX_LENGTH=64\n\n# Internal Virtual Network configuration\n# IPv4 Internal Virtual network\nPOT_NETWORK=10.192.0.0/10\n# Internal Virtual Network netmask\nPOT_NETMASK=255.192.0.0\n# The default gateway of the Internal Virtual Network\nPOT_GATEWAY=10.192.0.1\n# The name of the network physical interface, to be used as default gateway\nPOT_EXTIF=em0\n# Additional network interfaces\nPOT_EXTRA_EXTIF=\n# If not empty, it will use this IPv4 on POT_EXTIF as defualt gateway\nPOT_EXTIF_ADDR=\n\n# Three possible values: ipv4, ipv6, dual\nPOT_NETWORK_STACK=ipv4\n\n# DNS on the Internal Virtual Network\n# name of the pot running the DNS\nPOT_DNS_NAME=dns\n# IP of the DNS\nPOT_DNS_IP=10.192.0.2\n\n# If set to true, isolate pot vnet bridge members\n# (by using `ifconfig <bridgeif> private <memberif>`, see ifconfig(8))\nPOT_ISOLATE_VNET_POTS=false\n\n# If not empty, this script will be called by pot and the pf rules\n# returned on stdout will be loaded into \"pot-rdr/anchor\" instead\n# of those which pot would usually create. This also skips\n# creation of netcat-based localhost-tunnels.\n# Only works with IPv4 at the moment.\n#\n# Parameters sent to the script are:\n# POT_EXTIF BRIDGE POT_NETWORK POT_GATEWAY proto host_port pot_ip pot_port\n# Example:\n# igb0 bridge1 10.192.0.0/10 10.192.0.1 tcp 32732 10.192.0.10 80\nPOT_EXPORT_PORTS_PF_RULES_HOOK=\n# VPN support\n\n# Path to default public key to verify pot signatures using signify(1)\n# on import/prepare - can be overridden using `-C pubkey`.\nPOT_DEFAULT_SIGNATURE_PUBKEY=\n\n# name of the tunnel network interface\nPOT_VPN_EXTIF=\nPOT_VPN_NETWORKS=\n\n# POT log facility\nPOT_LOG_FACILITY=local2\n"
  },
  {
    "path": "etc/rc.d/pot",
    "content": "#!/bin/sh\n\n# PROVIDE: pot\n# REQUIRE: NETWORKING LOGIN FILESYSTEM\n# BEFORE: securelevel\n# KEYWORD: shutdown nojail\n\n. /etc/rc.subr\n\nPATH=$PATH:/usr/local/bin\nname=\"pot\"\ndesc=\"Pot containers\"\nprocname=\"pot\"\nrcvar=pot_enable\nstart_cmd=\"pot_start\"\nstop_cmd=\"pot_stop\"\nrestart_cmd=\"pot_restart\"\nstatus_cmd=\"pot_status\"\nstart_precmd=\"pot_deprecated_start\"\nstop_postcmd=\"pot_deprecated_stop\"\n\nload_rc_config $name\n: ${pot_enable:=NO}\n\npot_start()\n{\n\tlocal _pname _dyn_pot_list _start\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A start-at-boot -q )\" = \"YES\" ]; then\n\t\t\t/usr/local/bin/pot start \"$_pname\"\n\t\tfi\n\tdone\n}\n\npot_stop()\n{\n\tlocal _pname _dyn_pot_list _start\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A start-at-boot -q )\" = \"YES\" ]; then\n\t\t\t/usr/local/bin/pot stop \"$_pname\"\n\t\tfi\n\tdone\n}\n\npot_early_start()\n{\n\tlocal _pname _dyn_pot_list _start\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A early-start-at-boot -q )\" = \"YES\" ]; then\n\t\t\t/usr/local/bin/pot start \"$_pname\"\n\t\tfi\n\tdone\n}\n\npot_early_stop()\n{\n\tlocal _pname _dyn_pot_list _start\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A early-start-at-boot -q )\" = \"YES\" ]; then\n\t\t\t/usr/local/bin/pot stop \"$_pname\"\n\t\tfi\n\tdone\n}\n\npot_restart()\n{\n\tpot_stop\n\tpot_early_stop\n\tsleep 5\n\tpot_early_start\n\tpot_start\n}\n\npot_status()\n{\n\tlocal _pname _dyn_pot_list\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A early-start-at-boot -q )\" = \"YES\" ] ||\n\t\t   [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A start-at-boot -q )\" = \"YES\" ]; then\n\t\t\tif /usr/local/bin/pot info -qrp \"$_pname\" ; then\n\t\t\t\techo \"pot $_pname is up and running\"\n\t\t\telse\n\t\t\t\techo \"pot $_pname is not running\"\n\t\t\tfi\n\t\tfi\n\tdone\n}\n\nrun_rc_command \"$1\"\n"
  },
  {
    "path": "etc/rc.d/pot_early",
    "content": "#!/bin/sh\n\n# PROVIDE: pot_early\n# REQUIRE: NETWORKING syslogd pf\n# BEFORE: ntpdate\n# KEYWORD: shutdown nojail\n\n. /etc/rc.subr\n\nPATH=$PATH:/usr/local/bin\nname=\"pot_early\"\ndesc=\"Pot containers - early start\"\nprocname=\"pot\"\nrcvar=pot_enable\nstart_cmd=\"pot_early_start\"\nstop_cmd=\"pot_early_stop\"\n\nload_rc_config $name\n: ${pot_enable:=NO}\n\npot_early_start()\n{\n\tlocal _pname _dyn_pot_list _start\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A early-start-at-boot -q )\" = \"YES\" ]; then\n\t\t\t/usr/local/bin/pot start \"$_pname\"\n\t\tfi\n\tdone\n}\n\npot_early_stop()\n{\n\tlocal _pname _dyn_pot_list _start\n\t_dyn_pot_list=$(/usr/local/bin/pot ls -q)\n\tfor _pname in $_dyn_pot_list ; do\n\t\tif [ \"$( /usr/local/bin/pot get-attr -p \"$_pname\" -A early-start-at-boot -q )\" = \"YES\" ]; then\n\t\t\t/usr/local/bin/pot stop \"$_pname\"\n\t\tfi\n\tdone\n}\n\nrun_rc_command \"$1\"\n"
  },
  {
    "path": "release.sh",
    "content": "#!/bin/sh\n\nprint_syntax() { echo \"$0\" X.Y.Z ; exit \"${1:-1}\"; }\n\nif [ -z \"$1\" ]; then\n\tprint_syntax\nfi\n\nif [ \"$1\" = \"$(echo \"$1\" | sed -E 's/[0-9]+(\\.[0-9]+)+//')\" ]; then\n\techo invalid verion number $1\n\tprint_syntax\n\texit\nfi\n\nversion=\"$1\"\ntag_date=\"$(date +%Y-%m-%d)\"\necho applying new version \"$version\" with date \"$tag_date\"\n\nsed -i '' \"s/^_POT_VERSION=.*$/_POT_VERSION=$version/\" 'bin/pot'\nsed -i '' 's/^## \\[Unreleased\\]/## \\[Unreleased\\]\\\n\\\n### NEWVERSION/' CHANGELOG.md\n\nsed -i '' \"s/### NEWVERSION/## \\[$version\\] $tag_date/\" CHANGELOG.md\n\nsed -i '' \"s/^version = .*$/version = \\\"$version\\\"/\" 'share/doc/pot/conf.py'\nsed -i '' \"s/^release = .*$/release = \\\"$version\\\"/\" 'share/doc/pot/conf.py'\n\ngit diff -p --stat\n"
  },
  {
    "path": "share/doc/pot/.gitignore",
    "content": "_build\n"
  },
  {
    "path": "share/doc/pot/Description.md",
    "content": "DESCRIPTION\n-----------\nAnother container framework based on jails, to run FreeBSD containers on\nFreeBSD.  Every running instance is called \"pot\", but less flexible than a\nVM.  It's heavily based on FreeBSD, in particular on jails, ZFS, pf and\nrctl.\n"
  },
  {
    "path": "share/doc/pot/Images.md",
    "content": "# Using `pot` images\n\nThis guide has the ambitious goal of explain how to create `pot` images, a feature that allows `pot` to be used with nomad, but it can be useful in other use cases.\nThis guide assumes that you have already installed `pot` and you are already familiar with it (installation and quickstart guide).\n\n## What is a `pot` image?\n\nA `pot` image is a binary blob representing the `pot` configuration file and it's file system.\nIn more detail, it's a compressed archive containing a ZFS snapshot of a file system.\n\n## Create an images `pot`\n\nThe fundamental steps to create an image of a `pot` container are:\n* create a `pot`\n* \"customize\" the `pot` as needed\n* take a snapshot\n* export the image\n\n**NOTE** `export` and `import` support `single` type `pot`s. Multi-dataset `pot` are not supported yet.\n\n#### Create a `pot`\n\nA `pot` named `test` can be created using the command `pot create`:\n```console\n# pot create -p test -b 12.0 -N public-bridge -t single`\n```\n* `-p test` : the `pot` name\n* `-b 12.0` : the FreeBSD release version to be used\n* `-t single` : the `pot` type. Only `single` type are supported at the moment for `import`/`export`\n* `-N public-bridge` : the network type (it can be changed during `import`, but it can be useful to use a network type that is relevant for the use case)\n\nOnce the `pot` named `test` is created, it's possible to :\n* customize its configuration (attributes, starting command, and so on)\n* enter in it and do whatever is needed, for instance install `nginx`\n```console\n# pot run test\n[...]\nroot@test:~ # pkg install nginx\n[...]\nroot@test:~ # exit\nexit\n# pot set-cmd -p test -c \"nginx -g 'daemon off;'\"\n# pot set-attr -p test -A no-rc-script -V ON\n# pot set-attr -p test -A persistent -V NO\n# pot set-rss -p test -C 1\n```\n\nOnce you're satisfied with your `pot`, you can stop it and take a snapshot:\n```console\n# pot stop test\n# pot snapshot -p test\n```\n\nThe snapshot can be now exported as an image, with the command `export`\n```console\n# pot export -p test -t 1.0\n```\n* `-t 1.0`: the same image can have multiple version. The option `-t` allows to provide a tag to the image\n\nThe `export` command can take quite some time, because of the compression step.\nOnce the `export` command ends, it generates 2 files:\n```console\ntest_1.0.xz\ntest_1.0.xz.skein\n```\nThe first file is the image, the second file is a hash file, used by the `import` command to verify the integrity.\n\n#### Snapshots management\n\nThe `export` command will create an image if and only if one snapshot is available.\nThe flag `-A` try to automatically fix the number of available snapshots:\n* if 0 snapshots are available, `-A` will automatically invoke `pot snapshot`\n* if 2+ snapshots are available, `-A` will automatically invoke `pot purge-snapshots`\n\nThe command `pot purge-snapshots` deletes all snapshots, except the last one.\n\n### Images creation automated with flavours\n\nFlavour is the way we currently provide to automate the customization of a `pot`.\nWith flavour, it's possible to automatically:\n* apply configuration parameters to your `pot`\n* execute a bootstrap script\n\njust putting some files in flavour folder (`/usr/local/etc/pot/flavours`).\n\nIn the example above, we customized the `pot` `test` via:\n```console\n# pot run test\n[...]\nroot@test:~ # pkg install nginx\n[...]\nroot@test:~ # exit\nexit\n# pot set-cmd -p test -c \"nginx -g 'daemon off;'\"\n# pot set-attr -p test -A no-rc-script -V ON\n# pot set-attr -p test -A persistent -V NO\n# pot set-rss -p test -C 1\n```\n\nNow we automate those commands in a flavour, called `nginx-test`.\nIn the flavour folder we create one file for the `pot` configuration:\n```console\n# cat /usr/local/etc/pot/flavours/nginx-test\nset-cmd -c \"nginx -g 'daemon off;'\"\nset-attribute -A no-rc-script -V YES\nset-attribute -A persistent -V NO\nset-rss -C 1\n```\n\nThe bootstrap script, that will be executed inside the jail, would look like this:\n```console\n# chmode a+x /usr/local/etc/pot/flavours/nginx-test.sh\n# cat /usr/local/etc/pot/flavours/nginx-test.sh\n#!/bin/sh\n\n[ -w /etc/pkg/FreeBSD.conf ] && sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf\nASSUME_ALWAYS_YES=yes pkg bootstrap\ntouch /etc/rc.conf\nsysrc sendmail_enable=\"NONE\"\npkg install -y nginx\npkg clean -y\n```\n\nThe flavour `nginx-test` can now be used with the `create` command:\n```console\n# pot create -p test-flavour -b 12.0 -N public-bridge -t single -f nginx-test\n```\n\nAn important note: while the bootstrap script is a shell script, where you can do whatever you want, the `pot` command usable in a flavour are a small subset:\n* `add-dep`\n* `export-ports`\n* `copy-in`\n* `mount-in`\n* `set-attribute` (the abbreviated form `set-attr` is not recognized here)\n* `set-cmd`\n* `set-env`\n* `set-rss`\n\n**NOTE** the `mount-in` command has to be used carefully. If the `pot` will be migrated to a different machine, the folders or the ZFS datasets has to be manually migrated as well\n\n### Images registry and import\nOnce an image is created, we've seen it can be exported:\n```console\n# pot export -p test -t 1.0\n# ls\ntest_1.0.xz  \ntest_1.0.xz.skein\n```\nThe image freshly created can now be used to create new `pot` via the command `import`:\n```console\n# pot import -p test -t 1.0 -U file:///path/to/images\n===>  importing test @ 1.0 as test_1_0\n/var/cache/pot/test_1.0.xz                     174 MB  527 MBps    00s\n/var/cache/pot/test_1.0.xz.skein               257  B  598 kBps    00s\n===>  Assigning new IP: 10.192.0.15\n```\n* `-p potname` : the name of the pot to be imported\n* `-t tag`: the version of the image to be imported\n* `-U URL`: the base URL to be used to download the `pot` image\n\nThe command, when executed, will download the image from the URL (caching them to `/var/cache/pot` and create a new `pot` called `test_1_0` using that image as file system:\n```console\n# pot info -vp test_1_0\npot name : test_1_0\n\ttype : single\n\tbase : 12.0\n\tlevel : 0\n\tnetwork_type : public-bridge\n\tip : 10.192.0.15\n\t\tno ports exported\n\tactive : false\n\tdatasets:\n\t\ttest_1_0/m\n\tsnapshots:\n\t\tzroot/pot/jails/test_1_0@1569922467\n\t\tzroot/pot/jails/test_1_0/m@1569922467\n\tattributes:\n\t\tstart-at-boot: NO\n\t\tpersistent: NO\n\t\tno-rc-script: YES\n\t\tprocfs: NO\n\t\tfdescfs: NO\n\t\tprunable: NO\n\t\tlocalhost-tunnel: NO\n\t\tto-be-pruned: NO\n\tresource limits:\n\t\tmax amount cpus: 1\n```\nThe `import` process automatically recognizes that the `pot` uses the `prublic-bridge` and assigns a new available IP to the imported `pot`\n\n\n"
  },
  {
    "path": "share/doc/pot/Installation.md",
    "content": "# `pot` installation guide \n\nThis is a guide to prepare your FreeBSD installation to use the `pot` jail framework.\n\n**NOTE**: 99% of the operations needs `root` privileges. In this guide, we consider to be logged in as `root`\n\n**NOTE2**: ZFS is mandatory, so if you don't know what it is or you don't have a ZFS pool, please consider to read this [quick guide](https://www.freebsd.org/doc/handbook/zfs-quickstart.html).\n\n## FreeBSD version\n`pot` is mainly developed on CURRENT, but it's tested and used on 12.0.\nThose two are the versions suggested.\nIt should work also on 11.3, even if the kernel has to be rebuild, to activate VNET(9), via the VIMAGE option.\nIf you want to use FreeBSD 11.3, please follow the instruction reported [here](https://www.freebsd.org/doc/handbook/kernelconfig.html) to build a custom kernel with the VIMAGE option enabled.\n\n## Install `pot`\n`pot` is available as package or port.\n\nThe suggested way is to install it using the packages:\n```console\n# pkg install -y pot\n```\nAll dependencies will be automatically installed (if not yet present)\n\nIf you want to install it using ports, you can\n```console\n# cd /usr/ports/sysutils/pot\n# make install clean\n```\n**NOTE** A dependency of `pot`, called `potnet` is written in Rust. If you install `potnet` via ports, the build dependencies will be built as well, and it can take really long time (depending on the power of you system, it could be several hours).\n\n## Enable the resource limit database\nOne really useful feature, needed to improve the isolation between jail, is the resource limit database.\nThis feature is normally disabled (it seems it causes a performance penalty), and it can be enabled only at boot.\nTo do so:\n```console\n# echo kern.racct.enable=1 >> /boot/loader.conf\n# reboot\n```\nThis settings will take effect at the next reboot.\n\n#### Known issue\nWe have found a performance issue with the `vtnet` driver.\nIf you are installing `pot` on a VM using `vtnet`, probably you want to add this line to your `/boot/loader.conf`:\n```console\necho hw.vtnet.lro_disable=1 >> /boot/loader.conf\n```\nThis settings will take effect at the next reboot.\n## `pot` framework configuration\n\nUnder the folder `/usr/local/etc/pot` you'll find two files:\n* `pot.default.conf`\n* `pot.conf`\n\nThe `pot.default.conf` contains all the default values and it shouldn't be touched.\n\nAll needed changes can be made in the `pot.conf` file. \nThis configuration file provide already a brief explanation for all paramaters, but here we go deep, explaining them one by one\n\n### File system parameters\n`pot` is based on ZFS. In the configuration file, 2 parameters are used to let `pot` use your ZFS pool correctly.\n#### `POT_ZFS_ROOT` (default `zroot/pot`)\nThis paramater is the ZFS dataset that will be used by `pot` to store whatever will be needed: jails file systems, bases, and so on.\nIf the dataset doesn't exist, it will be created by the initialization command (See the last chapter).\n#### `POT_FS_ROOT` (default `/opt/pot`)\nThis parameter is the mountpoint for the `POT_ZFS_ROOT` dataset. You shouldn't use a mountpoint that exists and contains file, otherwise the content will become unreachable.\n#### `POT_CACHE` (default `/var/cache/pot`)\nThis parameter specifies the mountpoint of the dataset `POT_ZFS_ROOT/cache`. This dataset is used only to store `pot` images for the `import` and the `prepare`command. The default value is the suggested one.\n\n### Network parameters\nIn order to use network types like `alias` or `public-bridge`, some configuration parameters are needed.\n\n#### `POT_EXTIF` (default `em0`)\nCurrently, `pot` assumes that all the network traffic is going through one physical network interface.\nThis parameter configures `pot` to use the specified network interface.\nIt's relevant for `alias`, `public-bridge` and `private-bridge` network type.\n\n#### `POT_NETWORK` (default `10.192.0.0/10`)\nThis parameter specifies the IPv4 address of you internal virtual network and is used by the `public-bridge` network type only.\nIt's wise to choose a private network segment that doesn't conflict with your current network setup.\nThe default address space is huge, however you can choose the network range that match your needs.\n\n#### `POT_NETMASK` (default `255.192.0.0`)\nThis parameter specifies the netmask relative to the `POT_NETWORK`.\nTheoretically, the netmask can be derived by the `POT_NETWORK`. For now, this is not the case, so you have to provide a netmask consistent with the network specified in `POT_NETWORK`\n\n#### `POT_GATEWAY` (default `10.192.0.1`)\nThis parameter specifies the IP address that will be used as default gateway in your internal virtual network. It has to be part of the network specified in `POT_NETWORK` and it will be used as default gateway for all `pot`s attached to the internal virtual network (`public-bridge` network type).\n\n#### `POT_EXTRA_EXTIF` (default empty)\nIn case your host has multiple network interfaces connected to multiple network segments, this option allows your `pot`s to access those network segments.\nFor example, let's say that you have 2 vlan interfaces, called `vlan20` and `vlan30`.\n`vlan20` is configured as 10.0.20.4/24\n`vlan30` is configured as 10.0.30.8/24\nTo make those segments accessible, the configuration file should look like:\n```\nPOT_EXTRA_EXTIF=vlan20 vlan30\nPOT_NETWORK_vlan20=10.0.20.0/24\nPOT_NETWORK_vlan30=10.0.30.0/24\n```\nCurrently there is no way to use additional external interface for the network type `alias`.\nAll other network types are supported\n\n#### Network validation\nIf you want to check that your network configuration is valid, you can use the utility `potnet`:\n\n```console\n# potnet config-check\n```\nThis command will show only the errors.\n\n### Experimental parameters\nThere are other parameters that are used by some experimental features.\n\n#### dns `pot`\nAn experimental feature is to provide an internal dns service running in a `pot` attached to the internal virtual network.\nThe dns is still a work in progress, however two parameters are already present for this feature:\n* `POT_DNS_NAME`: this parameter specifies the name of the `pot` that will run the dns; default => `dns`\n* `POT_DNS_IP`: this parameter specifies the IP (internal to the `POT_NETWORK` that the \"dns `pot`\" will have; default => `10.192.0.2`\n\n#### VPN support\nIf your host system is using a VPN to reach some network segments, you can add some parameters in order to be able to connect your internal virtual network to those networks\n\n* `POT_VPN_EXTIF`: the name of the network interface of the VPN software tunnel; default: `tun0`\n* `POT_VPN_NETWORKS`: a list of all network segments served by the VPN; default: `192.168.0.0/16`\n\nIf you have multiple network segments, you have to list them all. For instance:\n```sh\nPOT_VPN_NETWORKS=\"192.168.0.0/24 192.168.10.0/24 10.10.0.0/16\"\n```\n\n## Initialize the environment\nThe initialization of the environment will:\n* Create the ZFS datasets\n* Validate the network parameters\n* Configure `pf(4)` to be aware of the internal virtual network\n\nIf you are already using `pf`, I suggest to make a backup of you `pf` configuration file.\n\nWhen ready, you can initialize the environment with the command (use the flag `-v` if you want a bit more of verbosity):\n```console\n# pot init\n```\n\n### Initialize and test the internal virtual network\nThe internal virtual network is not always active, but it's automatically activated if a `pot` configured to use it get started.\nHowever, a command is provided to activate the virtual network:\n\n```console\n# pot vnet-start\n```\n\nFrom your host, you can now ping the virtual network default gateway (always reachable from the host):\n```console\n# ping 10.192.0.1\n```\n\n## Remove the `pot` environment\nIn order to remove the `pot` from your system, a command is provided to make it easy:\n```console\n# pot de-init\n```\nThis powerful command will remove everything related to `pot` and it cannot be undone.\n\nEven if not mandatory, it would be nice to know why you removed it.\nPlease, consider to write a feedback email to pizzamig at FreeBSD dot org\n* What's wrong with `pot`?\n* What's the missing feature I really need?\n* How bad is to use it? How can it be more user-friendly?\n"
  },
  {
    "path": "share/doc/pot/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nSPHINXPROJ    = pot\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)"
  },
  {
    "path": "share/doc/pot/QuickStart.md",
    "content": "# QuickStart Guide on `pot`\n\nThis is an introduction at the usage of `pot`, a `jail(8)` wrapper based on ZFS and `pf(4)` that naively tries to emulate containerization on FreeBSD.\n\n`pot` uses FreeBSD specific technologies, so you need a FreeBSD machine to run it.\n\n**NOTE**: 99% of the operations needs `root` privileges. In this guide, we consider to be logged in as `root`\n\n**NOTE2**: ZFS is mandatory, so if you don't know what it is or you don't have a ZFS pool, please consider to read this [quick guide](https://www.freebsd.org/doc/handbook/zfs-quickstart.html).\n\n**NOTE3**: Some features, like memory limits and memory usage, rely on the resources limit framework, normally disabled. Even if it's not mandatory, it's suggested to enable it, with the following steps:\n```console\n# echo kern.racct.enable=1 >> /boot/loader.conf\n```\nThis settings will take effect at the next reboot.\n\n**NOTE4**: One of the 3 network configuration need `VNET(9)`, the network subsystem virtualization infrastructure, enabled in the kernel.\nOn FreeBSD 12 and later, this kernel feature is already enabled and you don't need to do anything.\nOn FreeBSD 11.x, you have to rebuild the kernel, enabling the VIMAGE options, following the instruction reported [here](https://www.freebsd.org/doc/handbook/kernelconfig.html)\n## Install `pot`\nThe installation process is pretty straightforward:\n```console\n# pkg install -y pot\n```\nThat's it, `pot` and its dependencies are installed, but we're not yet ready.\n#### Configuration [Optional]\nUnder the folder `/usr/local/etc/pot` you'll find two files:\n* `pot.default.conf`\n* `pot.conf`\n\nThe `pot.default.conf` contains all the default values and it shouldn't be touched.\n\nAll needed changes have to be stored in the `pot.conf` file. Please take your time to give a look to this file and to change configuration accordingly to your system\n\n### Initialization\nWhen you are happy with your configuration file, especially with the location of `POT_ZFS_ROOT`, you can run:\n```console\n# pot init\n```\nThis command will just create the needed ZFS datasets.\n## Create a simple `pot`\nWe can now create the simplest `pot`\n```console\n# pot create -p mypot -t single -b 11.3\n```\n**NOTE** The FreeBSD machine doesn't have to be the same version of your `pot` (jail). However, the hosting machine's version has to be greater or equal than the `pot`'s one.\nFor instance, you can run a FreeBSD 10.4 `pot` on a FreeBSD 11.3 host. You **cannot** run a FreeBSD 12 `pot` on a FreeBSD 11.3 host.\n\nSo, we created a `pot`, named `mypot`, based on FreeBSD 11.3 consisting of one ZFS dataset.\n\nNow you can start it or stop it, via:\n```console\n# pot start mypot\n# pot stop mypot\n```\nIf you want to have a shell inside your pot:\n```console\n# pot term mypot\n# pot run mypot # an alias for start+term\n```\n## A bit of diagnostic\nVia the command:\n```console\n# pot ls\n# pot ls -v # more information\n```\nYou can see a list of the `pot`s available on you local machine. The verbose output would look like this:\n```console\npot name : mypot\n\tip4 : inherit\n\tactive : true\n\tbase : 11.3\n\tlevel : 0\n\tdatasets:\n\tsnapshot:\n```\nIf you want to get some information on a specific `pot`, this command is more useful:\n```console\n# pot info -v -p mypot\npot name : mypot\n\ttype : single\n\tbase : 11.3\n\tlevel : 0\n\tip4 : inherit\n\tactive : true\n\tdatasets:\n\t\tmypot/m\n\tsnapshot:\n\tattributes:\n\t\tstart-at-boot: NO\n\t\tpersistent: YES\n\t\tno-rc-script: NO\n\t\tprocfs: NO\n\t\tprunable: NO\n```\nSome explanation of this output:\n* `type`: currently two types of `pot` are supported: `single`, based on one ZFS dataset, and `multi`, based on multiple ZFS dataset.\n* `base`: the FreeBSD version used to build this `pot`.\n* `level`: for single type `pot` the level is always `0`. Levels are explained for the multi type `pot`.\n* `ip4`: the IPv4 address of the `pot` or the keyword `inherit`. By default, `inherit` is chosen, that means that this `pot` is sharing the same network stack of the running machine.\n* `active`: it's a boolean value, that tells you if your `pot` is running or not.\n* `datasets`: single type `pot`s have only one dataset.\n* `snapshot`: the list of snapshots of this `pot`; currently empty.\n* `attributes`: attributes/properties of this this `pot`\n\nIf your `pot` is running, runtime information can be obtained via:\n```console\n# pot start mypot\n# pot show -p mypot\npot mypot\n\tdisk usage      : 274M\n\tvirtual memory  : 13M\n\tphysical memory : 4820K\n```\nThis command will show the current amount of resources used by this `pot`\n## Take a snapshot of your `pot`\nThanks to ZFS, taking a snapshot of your stopped `pot` is easy and super fast:\n```console\n# pot stop mypot\n# pot snap mypot\n# pot info -v -p mypot\n[..]\n\tsnapshot:\n\t\tzroot/pot/jails/mypot@1539804703\n\t\tzroot/pot/jails/mypot/m@1539804703\n```\nThe snapshot's name is the Unix epoch and it's used to automatically determine the snapshot's chronological sequence. \n\nNow you can restart it and do some real damage:\n```console\n# pot run mypot\nroot@mypot:~ # rm -rf /*\n[..]\nroot@mypot:~ # exit\n# pot stop mypot\n```\nWe have deleted almost every file in the `pot`, the pot cannot start again (feel free to try!)\nThe snapshot can be used to revert all the modifications occurred between the time that the snapshot was taken and now, using the following command:\n```console\n# pot revert -p mypot\n# pot run mypot\n```\nThe revert command will automatically select the newest snapshot available.\n## Attach a \"volume\" to your pot\nLet's say that you want to attach a pre-existent \"volume\" to your `pot`.\nThere are several way to do that, depending on what your volume is.\n\n### First volume type: fscomp\nTo support users managing ZFS datasets for `pot`, the concept of `fscomp` (AKA file system component) is introduced.\nYou can create a file system component in the `pot` ecosystem, that can be attached to one or more `pot`s.\n\nWhen a `fscomp` is created, the underlaying ZFS dataset is created as well.\n\nTo create a `fscomp`, you can run:\n```console\n# pot create-fscomp -f myfscomp\n```\nWith this command, you have created an empty ZFS dataset, a \"volume\", that can be attached to one or more `pot`s\n\nA list of available `fscomp`s can be obtained with the command:\n```console\n# pot ls -f\n```\nTo mount your new `fscomp` to a `pot`, you can use the command:\n```console\n# pot mount-in -p mypot -f myfscomp -m /mnt\n# pot info -p mypot -v\n```\nThe `-m` mandatory option represents the mountpoint (absolute pathname) inside the `pot`.\n\nThe advantage of this approach, is that `fscomp` are recognized by the `pot` framework, and a set of features is provided, like snapshot, rollback and clone.\n\n### Second volume type: an already existent dataset\nIt could happen that you want to attach to a `pot` a pre-existing ZFS dataset and you don't want to create an emtpy `fscomp` and move all data there.\n\nTo add and external ZFS dataset, the command would be:\n```console\n# pot mount-in -p mypot -m /mnt -z zroot/mydataset\n```\nThe only difference is the different option used (`-z` instead of `-f`)  and the argument of the option is not a `fscomp` name, but a generic valid ZFS dataset.\n\n### Third volume type: a generic directory\nThere two ways to make external directories available in a `pot`: mount them or copy them.\nThe decision to mount or to copy is to the user to take, with obvious pros and cons.\n\nTo mount a directory, the command would be:\n```console\n# pot mount-in -p mypot -m /mnt -d mydir\n```\nThe directory `mydir` will be mounted at `/mnt`\n\nTo copy a directory, the command would be:\n```console\n# pot copy-in -p mypot -s mydir -d /mnt\n```\nThe directory `mydir` (and all its file) will be copied in `/mnt`, creating the directory `/mnt/mydir`\n\n### Forth volume type: a single file\nFor single files, only the copy option is available.\n```console\n# pot copy-in -p mypot -s myfile -d /mnt\n```\nThe file `myfile` will be copied in `/mnt`.\n\n### Common consideration\nThe `mount-in` command will change the configuration of the `pot`; the \"volume\" will be automatically mounted when the `pot` starts and unmounted when the `pot` stops.\nIf you run `mount-in` when the `pot` is already running, the \"volume\" is mounted on the fly.\nA \"volume\" can be used with multiple `pot`s. Potential problems, like concurrent access to the same files, cannot be managed by `pot` and are left to the user.\n\nIn order to mitigate concurrency access to the same `fscomp`, the option `-r` is introduced:\n```console\n# pot mount-in -p mypot-ro -f myfscomp -m /mnt -r\n# pot mount-in -p mypot-rw -f myfscomp -m /mnt\n```\nThis option will inform the framework to mount `myfscomp` in `mypot-ro` in read-only mode, while in `mypot-rw` that same `myfscomp` is mounted in read-write mode.\n\n## Network configuration\nDuring the creation phase, it's possible to specify which type of network our `pot` should use.\n`pot` supports three different type of network configurations:\n* inherit\n* alias (IPv4 or IPv6) n the host network interface\n* IPv4 address on the public internal virtual network\n* IPv4 address on a private internal virtual network\n\nBy default, `inherit` is the chosen one.\n### Network configuration: inherit\nTo use the `inherit` network type, a `pot` can be created with the following command:\n```console\n# pot create -p mypot -t single -b 11.3 -N inherit\n```\nThe option `-N` can be omitted, because `inherit` is the default value.\nThe `inherit` type means that `mypot` will reuse the same network stack of the host machine.\nThis network type works pretty well when your `pot` doesn't provide/export any network services, but it uses the network's host as client, like a `pot` created to build applications.\n\n### Network configuration: IPv4 or IPv6 alias\nIf your host is a network that support static IPs, you can assign one static IP address to your `pot` via this network configuration type.\n**NOTE** Be sure that in the `pot` configuration file (`/usr/local/etc/pot/pot.conf`) you have correctly set the variable `POT_EXTIF`; this network interface is the one used to route the network traffic and to assign the IP address.\nFor example, your system has 192.168.178.20/24 as IP address and your network administrator reserved you the additional IP address 192.168.178.200.\nTo assing the latter IP address to your `pot` you can create it with the following command:\n```console\n# pot create -p mypot -t single -b 11.3 -N alias -i 192.168.178.200\n# pot start mypot\n# pot info -vp mypot\n```\nThe alias 192.168.178.200 will be assigned to the network interface during the start phase.\nNow, your `pot` is bound to the address 192.168.178.200\nWhen the `pot` is stopped, the alias will be automatically removed from the inferface.\nMore information about alias addresses on network interfaces are available in the `man` page of `ifconfig(8)`\n\n### Network configuration: public virtual network bridge\nThanks to `VNET(9)`, `pot` supports an IPv4 virtual network. This network is configured in configuration file (`/usr/local/etc/pot/pot.conf`), so be sure you have it properly configured.\nThis network type refers to a shared bridge where the public virtual network lives. All `pot`s with this network type will share it. The virtual internal network is connected with the ouside via NAT.\n\nTo help the `pot` framework and all users to manage the public virtual network, an additional package is required, normally automatically installed as dependency of the package `pot`. It's also manually installable via:\n```console\n# pkg install potnet\n```\nTo verify you virtual network configuration, this command can be used:\n```console\n# potnet show\nNetwork topology:\n\tnetwork : 10.192.0.0\n\tmin addr: 10.192.0.0\n\tmax addr: 10.255.255.255\n\nAddresses already taken:\n\t10.192.0.0\t\n\t10.192.0.1\tdefault gateway\n\t10.192.0.2\tdns\n```\nThe output is from my configuration (and also the default one), however your address' range can differ, depending on the configuration values you have adopted.\n\nOptionally, you can start the virtual network via the command:\n```console\n# pot vnet-start\n```\nThis command will create and configure the network interfaces properly and will activate `pf` to perform NAT on the virtual network.\n\n**NOTE** This command is automatically executed when a `pot` is configured to use the public virtual network. There is no need to run it manually.\n\nThe following command will create a `pot` running on the internal network:\n```console\n# pot create -p mypot -t single -b 11.3 -N public-bridge -i auto\n# pot run mypot\nroot@mypot:~ # ping 1.1.1.1\n[..]\nroot@mypot:~ # exit\n# pot stop mypot\n```\nThe `auto` keyword will automatically select an available address in the internal virtual network and it's the default value, hence the `-i` option can be omitted.\nCommands like `pot info -p mypot` and `potnet show` will show you exactly which address has been assigned to your `pot`\n\nIf you prefer to assign a specific IP address of your virtual network to your `pot`, you can just do:\n```console\n# pot create -p mypot2 -t single -b 11.3 -N public-bridge -i 10.192.0.10\n```\n`pot` will verify if the IP address is available and free to be used.\n\n### Network configuration: private virtual network bridge\nThe public virtual network has the downside that all `pot`s share the same bridge, affecting isolation.\nTo mitigate this issue, private virtual network has been introduced.\nA private virtual network is just a different bridge, that can be used to connect multiple `pot`s, but it's not automatically shared with all `pot`s.\n\nFirst of all, to use a private virtual network a private bridge has to be created:\n```console\n# pot create-private-bridge -B mybridge -S 4\n```\nThis command will create a new private bridge, called `mybridge`, with a network segment big enough to connect 4 `pot`s.\nUsing `potnet` it's possible to check the details of the private bridge via the command:\n```console\n# potnet show -b mybridge\n\t10.192.0.16\tmybridge bridge - network\n\t10.192.0.17\tmybridge bridge - gateway\n\t10.192.0.23\tmybridge bridge - broadcast\n```\nThe output is from my configuration, however your address' range can differ, depending on the configuration values you have adopted and the network segment available when the bridge is created.\n\nTo activate a specific bridge, you can use the command:\n```console\n# pot vnet-start -B mybridge\n```\nThis command will create and configure the network interfaces properly and will activate `pf` to perform NAT on the virtual network.\n\n**NOTE** This command is automatically executed when a `pot` is configured to use the public virtual network. There is no need to run it manually.\n\nThe following command will create a `pot` running on the private internal network:\n```console\n# pot create -p mypot -t single -b 11.3 -N private-bridge -B mybridge -i auto\n# pot run mypot\nroot@mypot:~ # ping 1.1.1.1\n[..]\nroot@mypot:~ # exit\n# pot stop mypot\n```\nThe `auto` keyword will automatically select an available address in the internal virtual network and it's the default value, hence the `-i` option can be omitted.\nCommands like `pot info -p mypot` and `potnet show -b mybridge` will show you exactly which address has been assigned to your `pot`\n\nIf you prefer to assign a specific IP address of your virtual network to your `pot`, you can just do:\n```console\n# pot create -p mypot2 -t single -b 11.3 -N private-bridge -B mybridge -i 10.192.0.19\n```\n`pot` will verify if the IP address is available and free to be used.\n### Export network services with the internal network\nThe virtual network is not visible outside the host machine, becuase it's based on NAT of the pf's NAT.\nTo make your network services running in your `pot` visible outside the TCP/UDP, desired ports have to be exported/redirected.\n`pot` provides a command to tell which port has to be exported.\n```console\n# pot export-ports -p mypot -e 80 -e 443\n```\nThe `export-ports` command will make available the port 80 and 443 outside the virtual network. At start, `pot` look for an available host port that can be used to redirect the traffic from the host to the virtual network.\n\nTo know which port is used, you can use the `show` command:\n```console\n# pot start mypot\n# pot show -p mypot\npot mypot\n\tdisk usage      : 274M\n\tvirtual memory  : 13M\n\tphysical memory : 4824K\n\n\tNetwork port redirection\n\t\t192.168.178.20 port 1024 -> 10.192.0.3 port 80\n\t\t192.168.178.20 port 1025 -> 10.192.0.3 port 443\n```\n\nTo map the network services to a specific port, instead of leaving the decision to `pot`, the following syntax can be used:\n```console\n# pot export-ports -p mypot -e 80:30080 -e 443:30443\n# pot start mypot\n# pot show -p mypot\npot mypot\n\tdisk usage      : 266M\n\tvirtual memory  : 33M\n\tphysical memory : 17M\n\n\tNetwork port redirection\n\t\t192.168.178.20 port 30080 -> 10.192.0.11 port 80\n\t\t192.168.178.20 port 30443 -> 10.192.0.11 port 443\n\n```\nHowever, there is no guarantee that the choosen ports are available.\n"
  },
  {
    "path": "share/doc/pot/Synopsis.md",
    "content": "SYNOPSIS\n--------\n\n`pot` SUBCOMMAND\n"
  },
  {
    "path": "share/doc/pot/conf.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# pot documentation build configuration file, created by\n# sphinx-quickstart on Thu Nov 28 15:41:27 2019.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\n# import os\n# import sys\n# sys.path.insert(0, os.path.abspath('.'))\n\nfrom recommonmark.transform import AutoStructify\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#\n# needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = ['sphinx.ext.githubpages', 'recommonmark']\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.md'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'pot'\ncopyright = '2019, Luca Pizzamiglio'\nauthor = 'Luca Pizzamiglio'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = \"0.16.0\"\n# The full version, including alpha/beta/rc tags.\nrelease = \"0.16.0\"\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = 'alabaster'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#\n# html_theme_options = {}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Custom sidebar templates, must be a dictionary that maps document names\n# to template names.\n#\n# This is required for the alabaster theme\n# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars\nhtml_sidebars = {\n    '**': [\n        'relations.html',  # needs 'show_related': True theme option to display\n        'searchbox.html',\n    ]\n}\n\n\n# -- Options for HTMLHelp output ------------------------------------------\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'potdoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n    # The paper size ('letterpaper' or 'a4paper').\n    #\n    # 'papersize': 'letterpaper',\n\n    # The font size ('10pt', '11pt' or '12pt').\n    #\n    # 'pointsize': '10pt',\n\n    # Additional stuff for the LaTeX preamble.\n    #\n    # 'preamble': '',\n\n    # Latex figure (float) alignment\n    #\n    # 'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, 'pot.tex', 'pot Documentation',\n     'Luca Pizzamiglio', 'manual'),\n]\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'pot', 'Another container framework based on jails',\n     [author], 8)\n]\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (master_doc, 'pot', 'pot Documentation',\n     author, 'pot', 'One line description of project.',\n     'Miscellaneous'),\n]\n\n# app setup hook\ndef setup(app):\n    app.add_config_value('recommonmark_config', {\n        'auto_toc_tree_section': 'Contents',\n        'enable_math': False,\n        'enable_inline_math': False,\n        'enable_eval_rst': True,\n    }, True)\n    app.add_transform(AutoStructify)\n"
  },
  {
    "path": "share/doc/pot/index.md",
    "content": "Contents\n--------\n\n* [Synopsis](Synopsis.md)\n* [Description](Description.md)\n* [QuickStart](QuickStart.md)\n* [Installation](Installation.md)\n* [migration](migration.md)\n* [Images](Images.md)\n"
  },
  {
    "path": "share/doc/pot/migration.md",
    "content": "## Manual migration handbook\n\n### Prerequisite\n\n* testing with single type pot\n* a snapshot is already present\n\n### A xz archive of the datasets\n\n* `zfs send -R zroot/pot/jails/mypot@1539804703 | xz > mypot.1539804703.xz`\n\nSome statistics on FreeBSD 12.0\nThe file systems are accounted for 801MB, lz4 providing 2.23 as compression ration, leaving 383MB on the disk.\nxz -9 is extremely slow, using +800MB of RAM and producing an output of 132MB\nxz -6 (default) is quite slow, producing an output of 148MB\nxz -3 is decently fast, producing an output of 164MB\nxz -0 is quite fast, producing an output of 182MB\n\n# Speculation\n\n### A migration process\n\nsend the first xz file and combine with the receive\n* `xzcat mypot.1539804703.xz | zfs receive ${POT_ZFS_ROOT}/jails/mypot@1539804703\n\ndepending on the content of pot.conf and fscomp.conf, get and extract the other datasets propery\nIn this case:\n* xzcat mypot_m.1539804703.xz | zfs receive ${POT_ZFS_ROOT}/jails/mypot/m@1539804703\n"
  },
  {
    "path": "share/pot/add-dep.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nadd-dep-help()\n{\n\tcat <<-\"EOH\"\n\tpot add-dep [-hv] -p potname -P depPot\n\t  -h print this help\n\t  -v verbose\n\t  -p potname : the working pot\n\t  -P depPot : the pot to depend on. Will be started automatically\n\t              before starting the working pot \"potname\".\n\tEOH\n}\n\n# $1 pot\n# $2 depPot\n_add_dependency()\n{\n\tlocal _depPot _pname _cdir\n\t_pname=\"$1\"\n\t_depPot=\"$2\"\n\t_cdir=$POT_FS_ROOT/jails/$_pname/conf\n\techo \"pot.depend=$_depPot\" >> \"$_cdir\"/pot.conf\n}\n\npot-add-dep()\n{\n\tlocal _pname _depPot\n\t_depPot=\n\t_pname=\n\tOPTIND=1\n\twhile getopts \"hvp:P:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tadd-dep-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tP)\n\t\t\t_depPot=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tadd-dep-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tadd-dep-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_depPot\" ]; then\n\t\t_error \"A dependency pot is mandatory\"\n\t\tadd-dep-help\n\t\treturn 1\n\tfi\n\tif [ \"$_pname\" = \"$_depPot\" ]; then\n\t\t_error \"a pot cannot be run time dependecy of itself\"\n\t\tadd-dep-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tadd-dep-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_depPot\" ; then\n\t\t_error \"dependency pot $_depPot is not valid\"\n\t\tadd-dep-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\t_add_dependency \"$_pname\" \"$_depPot\"\n}\n"
  },
  {
    "path": "share/pot/clone-fscomp.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nclone-fscomp-help()\n{\n\tcat <<-\"EOH\"\n\tpot clone-fscomp [-hv] -f fscomp -F fscomp\n\t  -h print this help\n\t  -v verbose\n\t  -F fscomp : the fscomp to be cloned (mandatory)\n\t  -f fscomp : the fscomp name (mandatory)\n\tEOH\n}\n\n# $1 new fscomp name\n# $2 old fscomp name\n_cf_zfs()\n{\n\tlocal _fscomp _cfscomp _fsdset _fsdir _snap\n\t_fscomp=$1\n\t_cfscomp=$2\n\t_fsdset=${POT_ZFS_ROOT}/fscomp\n\t_fsdir=${POT_FS_ROOT}/fscomp\n\t_snap=$( _zfs_last_snap \"$_fsdset/$_cfscomp\" )\n\tif [ -z \"$_snap\" ]; then\n\t\t_error \"$_fsdset/$_cfscomp has no snapshots - please take one\"\n\t\treturn 1\n\telse\n\t\t_debug \"Cloning $_cfscomp@$_snap into $_fsdset/$_fscomp\"\n\t\tzfs clone -o mountpoint=\"$_fsdir/$_fscomp\" \"$_fsdset/$_cfscomp@$_snap\" \"$_fsdset/$_fscomp\"\n\tfi\n\treturn 0 # true\n}\n\npot-clone-fscomp()\n{\n\tlocal _fscomp _cfscomp\n\t_fscomp=\n\t_cfscomp=\n\tOPTIND=1\n\twhile getopts \"hvf:F:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tclone-fscomp-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tf)\n\t\t\t_fscomp=$OPTARG\n\t\t\t;;\n\t\tF)\n\t\t\t_cfscomp=$OPTARG\n\t\t\t;;\n\t\t*)\n\t\t\tclone-fscomp-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\t# parameter validation\n\tif [ -z \"$_fscomp\" ]; then\n\t\t_error \"fscomp name is missing (option -f)\"\n\t\tclone-fscomp-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_cfscomp\" ]; then\n\t\t_error \"clonable fscomp name is missing (option -F)\"\n\t\tclone-fscomp-help\n\t\t${EXIT} 1\n\tfi\n\tif _zfs_dataset_valid \"${POT_ZFS_ROOT}/fscomp/$_fscomp\" ; then\n\t\t_error \"fscomp $_fscomp already exists\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/fscomp/$_cfscomp\" ; then\n\t\t_error \"fscomp $_cfscomp doesn't exist\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _cf_zfs \"$_fscomp\" \"$_cfscomp\" ; then\n\t\t${EXIT} 1\n\tfi\n}\n"
  },
  {
    "path": "share/pot/clone.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ntrap _cj_undo_clone TERM INT\n_set_pipefail\n\nclone-help()\n{\n\tcat <<-\"EOH\"\n\tpot clone [-hvF] -p potname -P basepot [-i ipaddr]\n\t  -h print this help\n\t  -v verbose\n\t  -k keep the pot, if clone fails\n\t  -P potname : the pot to be cloned (template)\n\t  -s snapshot : the snapshot to be used to clone\n\t  -p potname : the name of the pot that is created\n\t  -f flavour : flavour to be used\n\t  -N network-type : new network type of the cloned pot\n\t  -i ipaddr : an ip address or the keyword auto (if applicable)\n\t  -B bridge-name : the name of the private bridge to be used\n\t  -S network-stack : the network stack (ipv4, ipv6 or dual)\n\t  -d dns : change pot dns resolver configuration, one of\n\t           inherit       - inherit from jailhost\n\t           pot           - the pot configured in POT_DNS_NAME\n\t           custom:<file> - copy <file> into pot configuration\n\t           off           - leave resolver config unaltered\n\t  -F : automatically take snapshots of dataset that has none\n\tEOH\n}\n\n# $1 pot name\n_cj_undo_clone()\n{\n\t_POT_VERBOSITY=0\n\tif [ -z \"$_cleanup_pname\" ]; then\n\t\t${EXIT} 1\n\tfi\n\t# stop in subshell, so it won't end script execution\n\t(\n\t\tpot-cmd stop \"$_cleanup_pname\" >/dev/null 2>&1\n\t)\n\tif [ \"$_cleanup_keep\" != \"YES\" ]; then\n\t\tpot-cmd destroy -Fp \"$_cleanup_pname\" -q\n\tfi\n\tunset _cleanup_pname\n\tunset _cleanup_keep\n\t${EXIT} 1\n}\n\n# $1 pot name\n# $2 pot-base name\n# $3 auto-snapshot\n# $4 custom snapshot tag\n_cj_zfs()\n{\n\tlocal _pname _potbase _jdset _pdir _pbdir _pbdset _mnt_p _opt _autosnap _snaptag _pb_type _snap __last_snap\n\t_pname=$1\n\t_potbase=$2\n\t_autosnap=\"$3\"\n\t_snap=\"$4\"\n\t__last_snap=\n\t_jdset=${POT_ZFS_ROOT}/jails/$_pname\n\t_pbdset=${POT_ZFS_ROOT}/jails/$_potbase\n\t_pdir=${POT_FS_ROOT}/jails/$_pname\n\t_pbdir=${POT_FS_ROOT}/jails/$_potbase\n\t_pb_type=\"$( _get_conf_var \"$_potbase\" pot.type )\"\n\t# Create the main jail zfs dataset\n\tif ! _zfs_dataset_valid \"$_jdset\" ; then\n\t\tzfs create \"$_jdset\"\n\telse\n\t\t_info \"$_jdset exists already\"\n\tfi\n\t# Create the conf directory\n\tif [ ! -d \"$_pdir/conf\" ]; then\n\t\t_debug \"Create conf dir ($_pdir/conf)\"\n\t\tmkdir -p \"$_pdir/conf\"\n\tfi\n\tif [ -e \"$_pdir/conf/fscomp.conf\" ]; then\n\t\trm -f \"$_pdir/conf/fscomp.conf\"\n\tfi\n\t_debug \"Cloning $_potbase with snap $_snap\"\n\t_update_fscomp \"$_potbase\"\n\tif [ \"$_pb_type\" = \"single\" ]; then\n\t\t_dset=\"${_pbdset}/m\"\n\t\tif [ -z \"$_snap\" ]; then\n\t\t\t_snap=$( _zfs_last_snap \"$_dset\" )\n\t\tfi\n\t\tif [ -z \"$_snap\" ]; then\n\t\t\tif [ \"$_autosnap\" = \"YES\" ]; then\n\t\t\t\t_snaptag=\"$(date +%s)\"\n\t\t\t\t_info \"$_dset has no snap - taking a snapshot on the fly with tag $_snaptag\"\n\t\t\t\tzfs snapshot \"${_dset}@${_snaptag}\"\n\t\t\t\t_snap=$_snaptag\n\t\t\telse\n\t\t\t\t_error \"$_dset has no snap - please take a snapshot of $_potbase\"\n\t\t\t\t_cj_undo_clone\n\t\t\t\treturn 1 # error\n\t\t\tfi\n\t\tfi\n\t\t_debug \"clone $_dset@$_snap into $_jdset/m\"\n\t\tzfs clone -o mountpoint=\"$_pdir/m\" \"$_dset@$_snap\" \"$_jdset/m\"\n\t\tcp \"${_pbdir}/conf/fscomp.conf\" \"$_pdir/conf/fscomp.conf\"\n\telif [ \"$_pb_type\" = \"multi\" ]; then\n\t\t# Create the root mountpoint\n\t\t_create_pot_mountpoint \"$_pdir/m\"\n\t\tif [ -z \"$_snap\" ]; then\n\t\t\t__last_snap=\"YES\"\n\t\tfi\n\t\twhile read -r line ; do\n\t\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t\t_mnt_p=$( echo \"$line\" | awk '{print $2}' )\n\t\t\t_opt=$( echo \"$line\" | awk '{print $3}' )\n\t\t\t# ro components are replicated \"as is\"\n\t\t\tif [ \"$_opt\" = ro ] ; then\n\t\t\t\t_debug \"$_dset ${_mnt_p} $_opt\"\n\t\t\t\techo \"$_dset ${_mnt_p} $_opt\" >> \"$_pdir/conf/fscomp.conf\"\n\t\t\telse\n\t\t\t\t# managing potbase datasets\n\t\t\t\tif [ \"$_dset\" != \"${_dset##\"${_pbdset}\"}\" ]; then\n\t\t\t\t\t_dname=\"${_dset##\"${_pbdset}\"/}\"\n\t\t\t\t\tif [ \"$__last_snap\" = \"YES\" ]; then\n\t\t\t\t\t\t_snap=$( _zfs_last_snap \"$_dset\" )\n\t\t\t\t\tfi\n\t\t\t\t\tif [ -z \"$_snap\" ]; then\n\t\t\t\t\t\tif [ \"$_autosnap\" = \"YES\" ]; then\n\t\t\t\t\t\t\t_snaptag=\"$(date +%s)\"\n\t\t\t\t\t\t\t_info \"$_dset has no snap - taking a snapshot on the fly with tag $_snaptag\"\n\t\t\t\t\t\t\tzfs snapshot \"${_dset}@${_snaptag}\"\n\t\t\t\t\t\t\t_snap=$_snaptag\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t_error \"$_dset has no snap - please take a snapshot of $_potbase\"\n\t\t\t\t\t\t\t_cj_undo_clone \"$_pname\"\n\t\t\t\t\t\t\treturn 1\n\t\t\t\t\t\tfi\n\t\t\t\t\tfi\n\t\t\t\t\tif _zfs_exist \"$_jdset/$_dname\" \"$_pdir/$_dname\" ; then\n\t\t\t\t\t\t_debug \"$_dname dataset already cloned\"\n\t\t\t\t\telse\n\t\t\t\t\t\t_debug \"clone $_dset@$_snap into $_jdset/$_dname\"\n\t\t\t\t\t\tzfs clone -o mountpoint=\"$_pdir/$_dname\" \"$_dset@$_snap\" \"$_jdset/$_dname\"\n\t\t\t\t\t\tif [ -z \"$_opt\" ]; then\n\t\t\t\t\t\t\t_debug \"$_jdset/$_dname ${_mnt_p}\"\n\t\t\t\t\t\t\techo \"$_jdset/$_dname ${_mnt_p}\" >> \"$_pdir/conf/fscomp.conf\"\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t_debug \"$_jdset/$_dname ${_mnt_p} $_opt\"\n\t\t\t\t\t\t\techo \"$_jdset/$_dname ${_mnt_p} $_opt\" >> \"$_pdir/conf/fscomp.conf\"\n\t\t\t\t\t\tfi\n\t\t\t\t\tfi\n\t\t\t\t# managing fscomp datasets - the simple way - no clone support for fscomp\n\t\t\t\telif [ \"$_dset\" != \"${_dset##\"${POT_ZFS_ROOT}\"/fscomp}\" ]; then\n\t\t\t\t\t_debug \"$_dset ${_mnt_p}\"\n\t\t\t\t\techo \"$_dset ${_mnt_p}\" >> \"$_pdir/conf/fscomp.conf\"\n\t\t\t\telse\n\t\t\t\t\t_error \"not able to manage $_dset\"\n\t\t\t\tfi\n\t\t\tfi\n\t\tdone < \"${POT_FS_ROOT}/jails/$_potbase/conf/fscomp.conf\"\n\tfi\n\treturn 0 # true\n}\n\n# $1 pot name\n# $2 pot-base name\n# $3 network type\n# $4 ip\n# $5 bridge name\n# $6 network stack\n# $7 dns\n_cj_conf()\n{\n\tlocal _pname _potbase _ip _network_type _bridge_name _stack _dns _potdns\n\t_pname=$1\n\t_potbase=$2\n\t_network_type=$3\n\t_ip=$4\n\t_bridge_name=$5\n\t_stack=$6\n\t_dns=$7\n\t_pdir=${POT_FS_ROOT}/jails/$_pname\n\t_pbdir=${POT_FS_ROOT}/jails/$_potbase\n\tif [ ! -d \"$_pdir/conf\" ]; then\n\t\tmkdir -p \"$_pdir/conf\"\n\tfi\n\tif [ \"$_dns\" != \"${_dns##custom:}\" ]; then # if dns is custom:filename\n\t\tcp \"${_dns##custom:}\" \"$_pdir/conf/resolv.conf\" # copy custom dns config to pot config\n\t\t_potdns=custom\n\telse\n\t\t_potdns=\"$_dns\"\n\tfi\n\tgrep -vE '^(host.hostname|bridge|ip|vnet|network_type|pot.stack|pot.dns)' \"$_pbdir/conf/pot.conf\" > \"$_pdir/conf/pot.conf\"\n\t{\n\t\techo \"host.hostname=\\\"$( _get_usable_hostname \"${_pname}\" )\\\"\"\n\t\techo \"pot.stack=$_stack\"\n\t\techo \"network_type=$_network_type\"\n\t\tcase \"$_network_type\" in\n\t\t\"inherit\")\n\t\t\techo \"vnet=false\"\n\t\t\t;;\n\t\t\"alias\")\n\t\t\techo \"vnet=false\"\n\t\t\techo \"ip=$_ip\"\n\t\t\t;;\n\t\t\"public-bridge\")\n\t\t\techo \"vnet=true\"\n\t\t\techo \"ip=$_ip\"\n\t\t\t;;\n\t\t\"private-bridge\")\n\t\t\techo \"vnet=true\"\n\t\t\techo \"ip=$_ip\"\n\t\t\techo \"bridge=$_bridge_name\"\n\t\t\t;;\n\t\tesac\n\t\techo \"pot.dns=$_potdns\"\n\t} >> \"$_pdir/conf/pot.conf\"\n\tif [ -e \"$_pbdir/conf/prestart.sh\" ]; then\n\t\tcp \"$_pbdir/conf/prestart.sh\" \"$_pdir/conf/prestart.sh\"\n\tfi\n\tif [ -e \"$_pbdir/conf/prestop.sh\" ]; then\n\t\tcp \"$_pbdir/conf/prestop.sh\" \"$_pdir/conf/prestop.sh\"\n\tfi\n\tif [ -e \"$_pbdir/conf/poststart.sh\" ]; then\n\t\tcp \"$_pbdir/conf/poststart.sh\" \"$_pdir/conf/poststart.sh\"\n\tfi\n\tif [ -e \"$_pbdir/conf/poststop.sh\" ]; then\n\t\tcp \"$_pbdir/conf/poststop.sh\" \"$_pdir/conf/poststop.sh\"\n\tfi\n\tif [ -e \"$_pbdir/conf/resolv.conf\" ]; then\n\t\tcp \"$_pbdir/conf/resolv.conf\" \"$_pdir/conf/resolv.conf\"\n\tfi\n}\n\npot-clone()\n{\n\tlocal _pname _ipaddr _potbase _pblvl _autosnap _pb_type _pb_network_type _network_type _bridge_name _network_stack _snap _flv _dns\n\t_pname=\n\t_ipaddr=\n\t_potbase=\n\t_pblvl=0\n\t_autosnap=\"NO\"\n\t_bridge_name=\n\t_network_stack=\n\t_cleanup_keep=\"NO\"\n\t_snap=\n\t_flv=\n\t_dns=\n\tOPTIND=1\n\twhile getopts \"hvp:i:P:FN:B:S:f:ks:d:\" _o ; do\n\t\tcase \"$_o\" in\n\t\t\th)\n\t\t\t\tclone-help\n\t\t\t\t${EXIT} 0\n\t\t\t\t;;\n\t\t\tv)\n\t\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t\t;;\n\t\t\tk)\n\t\t\t\t_cleanup_keep=\"YES\"\n\t\t\t\t;;\n\t\t\tp)\n\t\t\t\tif ! _is_valid_potname \"$OPTARG\" ; then\n\t\t\t\t\t_error \"$OPTARG is not a valid name for a pot ('.' is the only character not allowed)\"\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\t_pname=$OPTARG\n\t\t\t\t;;\n\t\t\tN)\n\t\t\t\t# shellcheck disable=SC2086\n\t\t\t\tif ! _is_in_list \"$OPTARG\" $_POT_NETWORK_TYPES ; then\n\t\t\t\t\t_error \"Network type $OPTARG not recognized\"\n\t\t\t\t\tclone-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\t_network_type=\"$OPTARG\"\n\t\t\t\t;;\n\t\t\ti)\n\t\t\t\tif [ -z \"$_ipaddr\" ]; then\n\t\t\t\t\t_ipaddr=\"$OPTARG\"\n\t\t\t\telse\n\t\t\t\t\t_ipaddr=\"$_ipaddr $OPTARG\"\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\tP)\n\t\t\t\t_potbase=$OPTARG\n\t\t\t\t;;\n\t\t\ts)\n\t\t\t\t_snap=$OPTARG\n\t\t\t\t;;\n\t\t\tB)\n\t\t\t\t_bridge_name=$OPTARG\n\t\t\t\t;;\n\t\t\tS)\n\t\t\t\tif ! _is_in_list \"$OPTARG\" \"ipv4\" \"ipv6\" \"dual\" ; then\n\t\t\t\t\t_error \"Network stack $OPTARG not valid\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\t_network_stack=\"$OPTARG\"\n\t\t\t\t;;\n\t\t\tF)\n\t\t\t\t_autosnap=\"YES\"\n\t\t\t\t;;\n\t\t\tf)\n\t\t\t\tif _is_flavour \"$OPTARG\" ; then\n\t\t\t\t\tif [ -z \"$_flv\" ]; then\n\t\t\t\t\t\t_flv=\"$OPTARG\"\n\t\t\t\t\telse\n\t\t\t\t\t\t_flv=\"$_flv $OPTARG\"\n\t\t\t\t\tfi\n\t\t\t\telse\n\t\t\t\t\t_error \"Flavour $OPTARG not found\"\n\t\t\t\t\t_debug \"Looking in the flavour dir ${_POT_FLAVOUR_DIR}\"\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\td)\n\t\t\t\tcase $OPTARG in\n\t\t\t\t\tinherit|pot|off)\n\t\t\t\t\t\t_dns=$OPTARG\n\t\t\t\t\t\t;;\n\t\t\t\t\tcustom:*)\n\t\t\t\t\t\tif [ -r \"${OPTARG##custom:}\" ]; then\n\t\t\t\t\t\t\t_dns=$OPTARG\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t_error \"The file ${OPTARG##custom:} is not valid or readable\"\n\t\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\t\tfi\n\t\t\t\t\t\t;;\n\t\t\t\t\t*)\n\t\t\t\t\t\t\t_error \"'${OPTARG}' is not a valid dns option\"\n\t\t\t\t\t\t\tclone-help\n\t\t\t\t\t\t\t${EXIT} 1\n\t\t\t\tesac\n\t\t\t\t;;\n\n\t\t\t*)\n\t\t\t\tclone-help\n\t\t\t\t${EXIT} 1\n\t\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"pot name is missing (option -p)\"\n\t\tclone-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_potbase\" ]; then\n\t\t_error \"reference pot name is missing (option -P)\"\n\t\tclone-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_potbase\" quiet ; then\n\t\t_error \"reference pot $_potbase not found\"\n\t\tclone-help\n\t\t${EXIT} 1\n\tfi\n\tif _is_pot \"$_pname\" quiet ; then\n\t\t_error \"pot $_pname already exists\"\n\t\tclone-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_snap\" ]; then\n\t\tif [ \"$_autosnap\" = \"YES\" ]; then\n\t\t\t_error \"-s and -F are incompatible - which snapshot should I use\"\n\t\t\tclone-help\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t# shellcheck disable=SC2046\n\t\tif ! _is_in_list \"$_snap\" $(_get_pot_snaps \"$_potbase\" | tr '\\n' ' ') ; then\n\t\t\t_error \"snapshot $_snap not found\"\n\t\t\t_debug \"snapshots available $(_get_pot_snaps \"$_potbase\" | tr '\\n' ' ')\"\n\t\t\tclone-help\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif [ -z \"$_network_type\" ]; then\n\t\t_pb_network_type=\"$( _get_pot_network_type \"$_potbase\" )\"\n\t\tif [ -z \"$_pb_network_type\" ] ; then\n\t\t\t_error \"Configuration file for $_potbase contains obsolete elements\"\n\t\t\t_error \"Please run pot update-config -p $_potbase to fix\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_network_type=\"$_pb_network_type\"\n\tfi\n\tif [ -z \"$_network_stack\" ]; then\n\t\t_network_stack=\"$( _get_pot_network_stack \"$_potbase\" )\"\n\tfi\n\tif ! _ipaddr=\"$( _validate_network_param \"$_network_type\" \"$_ipaddr\" \"$_bridge_name\" \"$_network_stack\" )\" ; then\n\t\techo \"$_ipaddr\"\n\t\tclone-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_dns\" ]; then\n\t\t_dns=\"$(_get_conf_var \"$_potbase\" pot.dns)\"\n\tfi\n\t_pblvl=\"$( _get_conf_var \"$_potbase\" pot.level )\"\n\t_pb_type=\"$( _get_conf_var \"$_potbase\" pot.type )\"\n\tif [ \"$_pblvl\" = \"0\" ] && [ \"$_pb_type\" != \"single\" ]; then\n\t\t_error \"Level 0 pots cannot be cloned\"\n\t\tclone-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\texport _cleanup_pname=\"$_pname\"\n\texport _cleanup_keep\n\tif ! _cj_zfs \"$_pname\" \"$_potbase\" \"$_autosnap\" \"$_snap\" ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _cj_conf \"$_pname\" \"$_potbase\" \"$_network_type\" \"$_ipaddr\" \"$_bridge_name\" \"$_network_stack\" \"$_dns\"; then\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_flv\" ]; then\n\t\tfor _f in $_flv ; do\n\t\t\tif ! _exec_flv \"$_pname\" \"$_f\" ; then\n\t\t\t\t_cj_undo_clone\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tdone\n\tfi\n\tunset _cleanup_pname\n\tunset _cleanup_keep\n}\n"
  },
  {
    "path": "share/pot/common-flv.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n\n# $1 flavour name\n_is_flavour()\n{\n\tlocal _flv_name\n\t_flv_name=\"$1\"\n\tif [ -n \"$( _get_flavour_script \"$_flv_name\" )\" ] ||\n\t\t[ -n \"$( _get_flavour_cmd_file \"$_flv_name\" )\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_get_flavour_script()\n{\n\tlocal _flv_name\n\t_flv_name=\"$1\"\n\tif [ -f \"$_flv_name\" ] && [ \"$_flv_name\" != \"${_flv_name%%.sh}\" ]; then ## it's a script path name\n\t\techo \"$_flv_name\"\n\telif [ -f \"$_flv_name.sh\" ];  then ## it's a path name\n\t\techo \"$_flv_name.sh\"\n\telif [ -f \"./$_flv_name.sh\" ]; then\n\t\techo \"./$_flv_name.sh\"\n\telif [ -f \"${_POT_FLAVOUR_DIR}/$_flv_name.sh\" ]; then\n\t\techo \"${_POT_FLAVOUR_DIR}/$_flv_name.sh\"\n\tfi\n}\n\n_get_flavour_cmd_file()\n{\n\tlocal _flv_name\n\t_flv_name=\"$1\"\n\t# if the flavor name ends with .sh return immediately\n\tif [ \"$_flv_name\" != \"${_flv_name%%.sh}\" ]; then\n\t\treturn\n\tfi\n\tif [ -f \"$_flv_name\" ] && [ -r \"$_flv_name\" ]; then ## it's a cmd file path name\n\t\techo \"$_flv_name\"\n\telif [ -f \"./$_flv_name\" ] && [ -r \"./$_flv_name\" ]; then\n\t\techo \"./$_flv_name\"\n\telif [ -f \"${_POT_FLAVOUR_DIR}/$_flv_name\" ] || [ -r \"${_POT_FLAVOUR_DIR}/$_flv_name\" ]; then\n\t\techo \"${_POT_FLAVOUR_DIR}/$_flv_name\"\n\tfi\n}\n\n# $1 the cmd\n# all other parameter will be ignored\n# tested\n_is_cmd_flavorable()\n{\n\tlocal _cmd\n\t_cmd=$1\n\tcase $_cmd in\n\t\tadd-dep|set-attribute|\\\n\t\tcopy-in|copy-in-flv|mount-in|\\\n\t\tset-rss|export-ports|\\\n\t\tset-cmd|set-env)\n\t\treturn 0\n\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n# Special version of set-cmd usable only for flavours\n# $1 : pot name\n# $2 : the set-cmd line in the file\n_flv_set_cmd()\n{\n\tlocal _pname _line _cmd\n\t_pname=\"$1\"\n\t_line=\"$2\"\n\t_cmd=\"${_line#set-cmd -c }\"\n\tif [ \"$_line\" = \"$_cmd\" ]; then\n\t\t_error \"In flavour only 'set-cmd -c ' is supported\"\n\t\treturn 1\n\tfi\n\t_set_command \"$_pname\" \"$_cmd\"\n}\n\n_exec_flv()\n{\n\tlocal _pname _flv _pdir _flv_cmd_file _flv_script _flv_dir _previous_pwd _persist\n\t_pname=$1\n\t_flv=$2\n\t_pdir=${POT_FS_ROOT}/jails/$_pname\n\t_debug \"Flavour: $_flv\"\n\t_flv_cmd_file=\"$( _get_flavour_cmd_file \"$_flv\" )\"\n\t_flv_dir=$(dirname \"${_flv_cmd_file}\")\n\tif [ -n \"${_flv_cmd_file}\" ]; then\n\t\t_debug \"Executing $_flv pot commands on $_pname\"\n\t\twhile read -r line ; do\n\t\t\t# shellcheck disable=SC2086\n\t\t\tif _is_cmd_flavorable $line ; then\n\t\t\t\tif [ \"$line\" != \"${line#set-cmd}\" ]; then\n\t\t\t\t\t# workaround for set-cmd / damn quoting and shell scripts\n\t\t\t\t\tif ! _flv_set_cmd \"$_pname\" \"$line\" ; then\n\t\t\t\t\t\treturn 1\n\t\t\t\t\tfi\n\t\t\t\telif [ \"$line\" != \"${line#copy-in-flv}\" ]; then\n\t\t\t\t\t# copy-in relative to flavour dir\n\t\t\t\t\t_previous_pwd=$PWD\n\t\t\t\t\tif ! cd \"$_flv_dir\"; then\n\t\t\t\t\t\t_error \"Can't chdir to flavour dir $_flv_dir\"\n\t\t\t\t\t\treturn 1\n\t\t\t\t\tfi\n\t\t\t\t\tline=$(echo \"$line\" | sed \"s/^copy-in-flv/copy-in/\")\n\t\t\t\t\tif ! pot-cmd $line -p \"$_pname\" ; then\n\t\t\t\t\t\treturn 1\n\t\t\t\t\tfi\n\t\t\t\t\tif ! cd \"$_previous_pwd\"; then\n\t\t\t\t\t\t_error \"Can't chdir to previous pwd $_previous_pwd\"\n\t\t\t\t\t\treturn 1\n\t\t\t\t\tfi\n\t\t\t\telse\n\t\t\t\t\t# shellcheck disable=SC2086\n\t\t\t\t\tif ! pot-cmd $line -p \"$_pname\" ; then\n\t\t\t\t\t\treturn 1\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t_error \"Flavor $_flv: line $line not valid - ignoring\"\n\t\t\tfi\n\t\tdone < \"${_flv_cmd_file}\"\n\tfi\n\t_flv_script=\"$( _get_flavour_script \"$_flv\" )\"\n\tif [ -n \"${_flv_script}\" ]; then\n\t\t_debug \"Starting $_pname pot for the initial bootstrap\"\n\n\t\t_persist=\"$(_get_conf_var \"$_pname\" \"pot.attr.persistent\")\"\n\t\tif [ \"$_persist\" = \"NO\" ]; then\n\t\t\t_debug \"Setting pot $_pname temporarily to persistent\"\n\t\t\tif ! pot-cmd set-attribute -A persistent -V YES -p \"$_pname\" ; then\n\t\t\t\treturn 1\n\t\t\tfi\n\t\tfi\n\n\t\tpot-cmd start \"$_pname\"\n\t\tcp -v \"${_flv_script}\" \"$_pdir/m/tmp\"\n\t\tchmod a+x \"$_pdir/m/tmp/$(basename \"${_flv_script}\" )\"\n\t\t_debug \"Executing $_flv script on $_pname\"\n\t\tif ! jexec \"$_pname\" \"/tmp/$(basename \"${_flv_script}\")\" \"$_pname\" ; then\n\t\t\t_error \"create: flavour $_flv failed (script)\"\n\t\t\treturn 1\n\t\tfi\n\t\tpot-cmd stop \"$_pname\"\n\t\tif [ \"$_persist\" = \"NO\" ]; then\n\t\t\t_debug \"Reverting pot $_pname to non-persistent\"\n\t\t\tif ! pot-cmd set-attribute -A persistent -V NO -p \"$_pname\" ; then\n\t\t\t\treturn 1\n\t\t\tfi\n\t\tfi\n\telse\n\t\t_debug \"No shell script available for the flavour $_flv\"\n\tfi\n\n}\n"
  },
  {
    "path": "share/pot/common.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC2034,SC3033,SC3040,SC3043\n\n: \"${EXIT:=exit}\"\n: \"${ECHO:=echo}\"\n: \"${SED:=sed}\"\n\n_POT_RW_ATTRIBUTES=\"start-at-boot early-start-at-boot persistent no-rc-script prunable localhost-tunnel no-tmpfs no-etc-hosts\"\n_POT_RO_ATTRIBUTES=\"to-be-pruned\"\n_POT_NETWORK_TYPES=\"inherit alias public-bridge private-bridge\"\n\n# not devfs handles separately\n_POT_JAIL_RW_ATTRIBUTES='enforce_statfs mount fdescfs linprocfs nullfs procfs tmpfs zfs raw_sockets sysvshm sysvsem sysvmsg children mlock devfs_ruleset exec_stop stop_timeout'\n\n# N: arg name jail command, T: type of data, D: deafult value\n# devfs is always mounted\n_POT_DEFAULT_mount_N='allow.mount'\n_POT_DEFAULT_mount_T='bool'\n_POT_DEFAULT_mount_D='NO'\n_POT_DEFAULT_fdescfs_N='mount.fdescfs'\n_POT_DEFAULT_fdescfs_T='bool'\n_POT_DEFAULT_fdescfs_D='NO'\n_POT_DEFAULT_linprocfs_N='allow.mount.linprocfs'\n_POT_DEFAULT_linprocfs_T='bool'\n_POT_DEFAULT_linprocfs_D='NO'\n_POT_DEFAULT_nullfs_N='allow.mount.nullfs'\n_POT_DEFAULT_nullfs_T='bool'\n_POT_DEFAULT_nullfs_D='NO'\n_POT_DEFAULT_procfs_N='mount.procfs'\n_POT_DEFAULT_procfs_T='bool'\n_POT_DEFAULT_procfs_D='NO'\n_POT_DEFAULT_tmpfs_N='allow.mount.tmpfs'\n_POT_DEFAULT_tmpfs_T='bool'\n_POT_DEFAULT_tmpfs_D='NO'\n_POT_DEFAULT_zfs_N='allow.mount.zfs'\n_POT_DEFAULT_zfs_T='bool'\n_POT_DEFAULT_zfs_D='NO'\n_POT_DEFAULT_raw_sockets_N='allow.raw_sockets'\n_POT_DEFAULT_raw_sockets_T='bool'\n_POT_DEFAULT_raw_sockets_D='NO'\n_POT_DEFAULT_sysvshm_N='sysvshm'\n_POT_DEFAULT_sysvshm_T='sysvopt'\n_POT_DEFAULT_sysvshm_D='new'\n_POT_DEFAULT_sysvsem_N='sysvsem'\n_POT_DEFAULT_sysvsem_T='sysvopt'\n_POT_DEFAULT_sysvsem_D='new'\n_POT_DEFAULT_sysvmsg_N='sysvmsg'\n_POT_DEFAULT_sysvmsg_T='sysvopt'\n_POT_DEFAULT_sysvmsg_D='new'\n_POT_DEFAULT_children_N='children.max'\n_POT_DEFAULT_children_T='uint'\n_POT_DEFAULT_children_D='0'\n_POT_DEFAULT_devfs_ruleset_N='devfs_ruleset'\n_POT_DEFAULT_devfs_ruleset_T='uint'\n_POT_DEFAULT_devfs_ruleset_D='4'\n_POT_DEFAULT_mlock_N='allow.mlock'\n_POT_DEFAULT_mlock_T='bool'\n_POT_DEFAULT_mlock_D='NO'\n_POT_DEFAULT_exec_stop_N='exec.stop'\n_POT_DEFAULT_exec_stop_T='string'\n_POT_DEFAULT_exec_stop_D=''\n_POT_DEFAULT_stop_timeout_N='stop.timeout'\n_POT_DEFAULT_stop_timeout_T='uint'\n_POT_DEFAULT_stop_timeout_D='10'\n# 0:everything, 1:chroot+below(poudriere), 2:just chroot(normal jail)\n_POT_DEFAULT_enforce_statfs_N='enforce_statfs'\n_POT_DEFAULT_enforce_statfs_T='uint'\n_POT_DEFAULT_enforce_statfs_D='2'\n\n\n__POT_MSG_ERR=0\n__POT_MSG_INFO=1\n__POT_MSG_DBG=2\n# $1 severity\n_msg()\n{\n\tlocal _sev\n\t_sev=$1\n\tshift\n\tif [ \"$_sev\" -gt \"${_POT_VERBOSITY:-0}\" ]; then\n\t\treturn\n\tfi\n\tcase $_sev in\n\t\t\"$__POT_MSG_ERR\")\n\t\t\techo \"###> \" \"$@\"\n\t\t\t;;\n\t\t\"$__POT_MSG_INFO\")\n\t\t\techo \"===> \" \"$@\"\n\t\t\t;;\n\t\t\"$__POT_MSG_DBG\")\n\t\t\techo \"=====> \" \"$@\"\n\t\t\t;;\n\t\t*)\n\t\t\t;;\n\tesac\n}\n\n_error()\n{\n\t_msg $__POT_MSG_ERR \"$@\"\n}\n\n_info()\n{\n\t_msg $__POT_MSG_INFO \"$@\"\n}\n\n_debug()\n{\n\t_msg $__POT_MSG_DBG \"$@\"\n}\n\n# $1 quiet / no _error message is emitted\n_qerror()\n{\n\tif [ \"$1\" != \"quiet\" ]; then\n\t\t_error \"$@\"\n\tfi\n}\n\n_set_pipefail()\n{\n\tlocal _major _version\n\t_major=\"$(sysctl -n kern.osrelease | cut -f 1 -d '.')\"\n\tif [ \"$_major\" -ge \"13\" ]; then\n\t\t# shellcheck disable=SC3040\n\t\tset -o pipefail\n\t\treturn\n\tfi\n\t_version=\"$(sysctl -n kern.osrelease | cut -f 1 -d '-')\"\n\tcase \"$_version\" in\n\t\t\"12.1\"|\"12.2\")\n\t\t\t# shellcheck disable=SC3040\n\t\t\tset -o pipefail\n\t\t\t;;\n\tesac\n}\n\n# tested\n_is_verbose()\n{\n\tif [ \"$_POT_VERBOSITY\" -gt $__POT_MSG_INFO ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# $1 quiet / no _error messages are emitted (sometimes useful)\n_is_uid0()\n{\n\tif [ \"$(id -u)\" = \"0\" ]; then\n\t\treturn 0 # true\n\telse\n\t\t_qerror \"$1\" \"This operation needs 'root' privilegies\"\n\t\treturn 1 # false\n\tfi\n}\n\n# tested\n# check if the argument is an absolute pathname\n_is_absolute_path()\n{\n\tif [ \"$1\" = \"${1#/}\" ]; then\n\t\treturn 1 # false\n\telse\n\t\treturn 0 # true\n\tfi\n}\n\n# save encoded parameters suitable for use in `set --`\n_save_params () {\n\tfor i; do\n\t\tprintf %s\\\\n \"$i\" |\\\n\t\tsed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\"\n\tdone\n\techo \" \"\n}\n\n# get system boot time in seconds since the epoch\n_get_system_uptime() {\n\tsysctl -n kern.boottime | sed -e 's/.*[^u]sec = \\([0-9]*\\).*$/\\1/'\n}\n\n# check if the argument is a valid boolean value\n# if valid, it returns true and it echo a normalized version of the boolean value (YES/NO)\n# if not valid, it return false\n_normalize_true_false() {\n\tcase $1 in\n\t\t[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn])\n\t\t\techo YES\n\t\t\treturn 0 # true\n\t\t\t;;\n\t\t[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff])\n\t\t\techo NO\n\t\t\treturn 0 # true\n\t\t\t;;\n\t\t*)\n\t\t\treturn 1 # false\n\tesac\n}\n\n# validate some values of the configuration files\n# $1 quiet / no _error messages are emitted\n_conf_check()\n{\n\tif [ -z \"${POT_ZFS_ROOT}\" ]; then\n\t\t_qerror \"$1\" \"POT_ZFS_ROOT is mandatory\"\n\t\treturn 1 # false\n\tfi\n\tif [ -z \"${POT_FS_ROOT}\" ]; then\n\t\t_qerror \"$1\" \"POT_FS_ROOT is mandatory\"\n\t\treturn 1 # false\n\tfi\n\tif ! getent group \"${POT_GROUP:-pot}\" >/dev/null 2>&1; then\n\t\t_qerror \"$1\" \"Group '${POT_GROUP:-pot}' is missing, create it or change POT_GROUP\"\n\t\treturn 1 # false\n\tfi\n\treturn 0 # true\n}\n\n# it checkes that the pot environment is initialized\n# $1 quiet / no _error messages are emitted\n_is_init()\n{\n\tif ! _conf_check \"$1\" ; then\n\t\t_qerror \"$1\" \"Configuration not valid, please verify it\"\n\t\treturn 1 # false\n\tfi\n\tif ! _zfs_exist \"${POT_ZFS_ROOT}\" \"${POT_FS_ROOT}\" ; then\n\t\t_qerror \"$1\" \"Your system is not initialized, please run pot init\"\n\t\treturn 1 # false\n\tfi\n\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/bases\" || \\\n\t   ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/jails\" || \\\n\t   ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/fscomp\" ; then\n\t\t_qerror \"$1\" \"Your system is not propery initialized, please run pot init to fix it\"\n\tfi\n}\n\n# check the POT_TMP directory\n# if missing, it will initialize it\n_is_pot_tmp_dir()\n{\n\tlocal _pot_tmp\n\t_pot_tmp=\"${POT_TMP:-/tmp}\"\n\tif [ ! -d \"$_pot_tmp\" ]; then\n\t\tmkdir -p \"$_pot_tmp\"\n\tfi\n\tif [ ! -d \"$_pot_tmp\" ]; then\n\t\treturn 1 # false\n\tfi\n}\n\n# set status of pot, locks properly\n# $1 pot name\n# $2 status to set\n# $3 interfaces for pot (epaira)\n_set_pot_status()\n{\n\tlocal _pname _status _interfaces _verbose _param\n\t_pname=$1\n\t_status=$2\n\t_interfaces=$3\n\t_param=$(_save_params \"-p\" \"$_pname\" \"-s\" \"$_status\")\n\tif [ -n \"$_interfaces\" ]; then\n\t\t_param=\"$_param\"$(_save_params \"-i\" \"$_interfaces\")\n\tfi\n\tif [ \"$_POT_VERBOSITY\" -gt 1 ]; then\n\t\t_verbose=$(printf -- \"-%$(( _POT_VERBOSITY - 1 ))s\" |\\\n\t\t  tr \" \" \"v\")\n\t\t_param=\"$_param\"$(_save_params \"$_verbose\")\n\tfi\n\teval \"set -- $_param\"\n\tlockf \"${POT_TMP:-/tmp}/pot-lock-$_pname\" \"${_POT_PATHNAME}\"\\\n\t  set-status \"$@\"\n}\n\n# check if the dataset is a dataset name\n# $1 the dataset NAME\n# tested\n_zfs_dataset_valid()\n{\n\t[ -z \"$1\" ] && return 1 # return false\n\tif [ \"$1\" = \"$( zfs list -o name -H \"$1\" 2> /dev/null)\" ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# check if the dataset $1 with the mountpoint $2 exists\n# $1 the dataset NAME\n# $2 the mountpoint\n# tested\n_zfs_exist()\n{\n\tlocal _mnt_\n\t[ -z \"$2\" ] && return 1 # false\n\tif ! _zfs_dataset_valid \"$1\" ; then\n\t\treturn 1 # false\n\tfi\n\t_mnt_=\"$(zfs list -H -o mountpoint \"$1\" 2> /dev/null )\"\n\tif [ \"$_mnt_\" != \"$2\" ]; then\n\t\treturn 1 # false\n\tfi\n\treturn 0 # true\n}\n\n# check if the dataset $1 is mounted\n# $1 the dataset NAME\n_zfs_mounted()\n{\n\tif [ \"$(zfs get -Ho value mounted \"$1\")\" != \"yes\" ]; then\n\t\treturn 1; # false\n\tfi\n\treturn 0 # true\n}\n\n# given a dataset, look for the corresponding mountpoint\n# $1 the dataset\n_get_zfs_mountpoint()\n{\n\tlocal _mnt_p _dset\n\t_dset=$1\n\t_mnt_p=\"$( zfs list -o mountpoint -H \"$_dset\" 2> /dev/null )\"\n\techo \"$_mnt_p\"\n}\n\n# given a mountpoint, look for the corresponding dataset\n# $1 the mountpoint\n_get_zfs_dataset()\n{\n\tlocal _mnt_p _dset\n\t_mnt_p=$1\n\t_dset=$(zfs list -o name,mountpoint -H 2>/dev/null | awk -v \"mntp=${_mnt_p}\" '{ if ($2 == mntp) print $1 }')\n\techo \"$_dset\"\n}\n\n# check if POT_ZFS_ROOT supports given property\n# $1 the property to check\n_is_zfs_property_supported()\n{\n\tlocal _properties _ret\n\n\t_properties=$(zfs get -o property all \"${POT_ZFS_ROOT}\")\n\t_ret=$?\n\tif [ $_ret -ne 0 ]; then\n\t\t_error \"Could not determine if $POT_ZFS_ROOT supports encryption\"\n\t\treturn 2 # error\n\tfi\n\tif echo \"$_properties\" | grep -xq \"$1\" ; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# get extra arguments to be added to the zfs receive command.\n# Output can be used without addional escaping.\n# In case of errors, the returned string will make sure\n# the zfs receive command fails in case the called\n# didn't check the return value.\n#\n# Usage:\n#     zfs receive $(_get_zfs_receive_extra_args) pool/fs\n_get_zfs_receive_extra_args()\n{\n\tlocal _ret\n\n\t_is_zfs_property_supported \"encryption\"\n\t_ret=$?\n\tcase $_ret in\n\t\t0)\t# encryption supported\n\t\t\techo \"-x encryption\"\n\t\t\treturn 0\n\t\t\t;;\n\t\t1)\t# encryption not supported\n\t\t\techo \"\"\n\t\t\treturn 0\n\t\t\t;;\n\t\t*)\t# communicate error\n\t\t\techo \"-x therewasanerror\"\n\t\t\treturn 1\n\t\t\t;;\n\tesac\n}\n\n# take a zfs recursive snapshot of a pot\n# $1 pot name\n_pot_zfs_snap()\n{\n\tlocal _pname _snaptag _dset\n\t_pname=$1\n\t_snaptag=\"$(date +%s)\"\n\t_debug \"Take snapshot of $_pname\"\n\tzfs snapshot -r \"${POT_ZFS_ROOT}/jails/${_pname}@${_snaptag}\"\n}\n\n# recursively remove the oldest snapshot of a pot\n# $1 pot name\n_remove_oldest_pot_snap()\n{\n\tlocal _pname _snap _pdset\n\t_pname=$1\n\t_pdset=\"${POT_ZFS_ROOT}/jails/${_pname}\"\n\t_snap=\"$( _zfs_oldest_snap \"$_pdset\" )\"\n\tif [ -n \"$_snap\" ]; then\n\t\tzfs destroy -r \"$_pdset@${_snap}\"\n\tfi\n}\n\n# take a zfs snapshot of all rw dataset found in the fscomp.conf of a pot\n# $1 pot name\n# DEPRECATED - but still used by create-base\n_pot_zfs_snap_full()\n{\n\tlocal _pname _node _opt _snaptag _dset\n\t_pname=$1\n\t_snaptag=\"$(date +%s)\"\n\t_debug \"Take snapshot of the full $_pname\"\n\twhile read -r line ; do\n\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t_opt=$( echo \"$line\" | awk '{print $3}' )\n\t\tif [ \"$_opt\" = \"ro\" ]; then\n\t\t\tcontinue\n\t\tfi\n\t\tif _is_absolute_path \"$_dset\" ; then\n\t\t\t_debug \"Skip $_dset, it's not a dataset\"\n\t\telse\n\t\t\t_debug \"snapshot of $_dset\"\n\t\t\tzfs snapshot \"${_dset}@${_snaptag}\"\n\t\tfi\n\tdone < \"${POT_FS_ROOT}/jails/$_pname/conf/fscomp.conf\"\n}\n\n# recursively remove the oldest snapshot of a pot\n# $1 pot name\n_remove_oldest_fscomp_snap()\n{\n\tlocal _fscomp _snap _fdset\n\t_fscomp=$1\n\t_fdset=\"${POT_ZFS_ROOT}/fscomp/${_fscomp}\"\n\t_snap=\"$( _zfs_oldest_snap \"$_fdset\" )\"\n\tif [ -n \"$_snap\" ]; then\n\t\tzfs destroy -r \"$_fdset@${_snap}\"\n\tfi\n}\n# take a zfs snapshot of a fscomp\n# $1 fscomp name\n_fscomp_zfs_snap()\n{\n\tlocal _fscomp _snaptag _dset\n\t_fscomp=$1\n\t_snaptag=\"$(date +%s)\"\n\t_debug \"Take snapshot of $_fscomp\"\n\tzfs snapshot \"${POT_ZFS_ROOT}/fscomp/${_fscomp}@${_snaptag}\"\n}\n\n# get the last available snapshot of a given dataset\n# $1 the dataset name\n_zfs_last_snap()\n{\n\tlocal _dset _output\n\t_dset=\"$1\"\n\tif [ -z \"$_dset\" ]; then\n\t\treturn 1 # false\n\tfi\n\t_output=\"$(zfs list -d 1 -H -t snapshot \"$_dset\" | sort -r | cut -d'@' -f2 | cut -f1 | head -n1)\"\n\tif [ -z \"$_output\" ]; then\n\t\treturn 1 # false\n\tfi\n\techo \"${_output}\"\n\treturn 0 # true\n}\n\n# get the oldest available snapshot of a given dataset\n# $1 the dataset name\n_zfs_oldest_snap()\n{\n\tlocal _dset _output\n\t_dset=\"$1\"\n\tif [ -z \"$_dset\" ]; then\n\t\treturn 1 # false\n\tfi\n\t_output=\"$(zfs list -d 1 -H -t snapshot \"$_dset\" | sort -r | cut -d'@' -f2 | cut -f1 | tail -n1)\"\n\tif [ -z \"$_output\" ]; then\n\t\treturn 1 # false\n\tfi\n\techo \"${_output}\"\n\treturn 0 # true\n}\n\n# get the amount of available snapshots of a given dataset\n# $1 the dataset name\n_zfs_count_snap()\n{\n\tlocal _dset _output\n\t_dset=\"$1\"\n\tif [ -z \"$_dset\" ]; then\n\t\treturn 1 # false\n\tfi\n\t_output=\"$(zfs list -d 1 -H -t snapshot \"$_dset\" | grep -c . )\"\n\tif [ -z \"$_output\" ]; then\n\t\t echo 0\n\tfi\n\techo \"${_output}\"\n}\n\n# check if the snapshot of the pot does exist\n# $1 pot name\n# $2 snapshot name\n_is_zfs_pot_snap()\n{\n\tlocal _pname _snap _dset\n\t_pname=$1\n\t_snap=$2\n\tif zfs list -t snap \"${POT_ZFS_ROOT}/jails/${_pname}@${_snap}\" 2>/dev/null ; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# $1 pot name\n# tested (common.sh 7)\n_get_usable_hostname() {\n\tlocal _pname _hname _phname\n\t_pname=\"$1\"\n\t_hname=\"$(hostname)\"\n\tif [ ${#_pname} -gt \"${POT_HOSTNAME_MAX_LENGTH:-64}\" ]; then\n\t\techo \"$_pname\" | awk -v len=\"${POT_HOSTNAME_MAX_LENGTH:-64}\" '{ truncated = substr($1, 1, len); printf(\"%s\", truncated); }'\n\telse\n\t\t_phname=\"${_pname}.$_hname\"\n\t\tif [ ${#_phname} -gt \"${POT_HOSTNAME_MAX_LENGTH:-64}\" ]; then\n\t\t\techo \"$_pname\"\n\t\telse\n\t\t\techo \"$_phname\"\n\t\tfi\n\tfi\n}\n\n# $1 bridge name\n# $2 var name\n_get_bridge_var()\n{\n\tlocal _Bname _cfile _var _value\n\t_Bname=\"$1\"\n\t_cfile=\"${POT_FS_ROOT}/bridges/$_Bname\"\n\t_var=\"$2\"\n\t_value=\"$( grep \"^$_var=\" \"$_cfile\" | tr -d ' \\t\"' | cut -f2 -d'=' )\"\n\techo \"$_value\"\n}\n\n# $1 pot name\n# $2 var name\n_get_conf_var()\n{\n\tlocal _pname _cdir _var _value\n\t_pname=\"$1\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_var=\"$2\"\n\t_value=\"$( grep \"^$_var=\" \"$_cdir/pot.conf\" | tr -d ' \\t\"' | cut -f2 -d'=' )\"\n\techo \"$_value\"\n}\n\n# $1 pot name\n# $2 var name\n_get_conf_var_string()\n{\n\tlocal _pname _cdir _var _value\n\t_pname=\"$1\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_var=\"$2\"\n\t_value=\"$( grep \"^$_var=\" \"$_cdir/pot.conf\" | cut -f2 -d'=' )\"\n\techo \"$_value\"\n}\n\n# $1 pot name\n# $2 var name\n_get_ip_var()\n{\n\tlocal _pname _cdir _var _value\n\t_pname=\"$1\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_value=\"$( grep \"^ip=\" \"$_cdir/pot.conf\" | sed 's/^ip=//' )\"\n\techo \"$_value\"\n}\n\n_get_pot_export_ports()\n{\n\tlocal _pname _cdir _var _value\n\t_pname=\"$1\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_value=\"$(awk '/pot.export.ports/ { n=split($0,array,\"=\"); if (n==2) { print array[2]; } }' \"$_cdir/pot.conf\" )\"\n\techo \"$_value\"\n}\n\n# $1 pot name\n_get_pot_base()\n{\n\t_get_conf_var \"$1\" pot.base\n}\n\n# $1 pot name\n_get_pot_lvl()\n{\n\t_get_conf_var \"$1\" pot.level\n}\n\n# $1 pot name\n_get_pot_type()\n{\n\tlocal _type\n\t_type=\"$( _get_conf_var \"$1\" pot.type )\"\n\tif [ -z \"$_type\" ]; then\n\t\t_type=\"multi\"\n\tfi\n\techo \"$_type\"\n}\n\n# $1 pot name\n_get_pot_network_type()\n{\n\t_get_conf_var \"$1\" network_type\n}\n\n# $1 pot name\n_is_ip_inherit()\n{\n\tlocal _pname _val\n\t_pname=\"$1\"\n\tif [ \"$(_get_pot_network_type \"$_pname\" )\" = \"inherit\" ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# $1 pot name\n_is_pot_vnet()\n{\n\tlocal _pname _val\n\t_pname=\"$1\"\n\t_val=\"$( _get_conf_var \"$_pname\" vnet )\"\n\tif [ \"$_val\" = \"true\" ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# $1 pot name\n_is_pot_prunable()\n{\n\tlocal _pname\n\t_pname=\"$1\"\n\tif [ \"$( _get_conf_var \"$_pname\" \"pot.attr.prunable\" )\" = \"YES\" ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1\n\tfi\n}\n\n# $1 bridge name\n# $2 quiet / no _error messages are emitted (sometimes useful)\n_is_bridge()\n{\n\tlocal _bname _bconf\n\t_bname=\"$1\"\n\t_bconf=\"${POT_FS_ROOT}/bridges/$_bname\"\n\tif [ ! -e \"$_bconf\" ]; then\n\t\t_qerror \"$2\" \"bridge $_bname not found\"\n\t\treturn 1 # false\n\tfi\n\treturn 0 # true\n}\n\n# $1 fscomp name\n# $2 quiet / no _error messages are emitted (sometimes useful)\n# tested\n_is_fscomp()\n{\n\tlocal _fscomp _fdir _fdset\n\t_fscomp=\"$1\"\n\t_fdir=\"${POT_FS_ROOT}/fscomp/$_fscomp\"\n\t_fdset=\"${POT_ZFS_ROOT}/fscomp/$_fscomp\"\n\tif [ ! -d \"$_fdir\" ]; then\n\t\t_qerror \"$2\" \"fscomp $_fscomp not found\"\n\t\treturn 1\n\tfi\n\tif ! _zfs_dataset_valid \"$_fdset\" ; then\n\t\t_qerror \"$2\" \"dataset $_fdset for fscomp $_fscomp not found\"\n\t\treturn 2\n\tfi\n\treturn 0\n}\n\n# $1 base name\n# $2 quiet / no _error messages are emitted (sometimes useful)\n# tested\n_is_base()\n{\n\tlocal _base _bdir _bdset\n\t_base=\"$1\"\n\t_bdir=\"${POT_FS_ROOT}/bases/$_base\"\n\t_bdset=\"${POT_ZFS_ROOT}/bases/$_base\"\n\tif [ ! -d \"$_bdir\" ]; then\n\t\tif [ \"$2\" != \"quiet\" ]; then\n\t\t\t_error \"Base $_base not found\"\n\t\tfi\n\t\treturn 1 # false\n\tfi\n\tif ! _zfs_dataset_valid \"$_bdset\" ; then\n\t\tif [ \"$2\" != \"quiet\" ]; then\n\t\t\t_error \"zfs dataset $_bdset not found\"\n\t\tfi\n\t\treturn 2 #false\n\tfi\n\treturn 0 # true\n}\n\n# $1 pot name\n# $2 quiet / no _error messages are emitted (sometimes useful)\n# tested\n_is_pot()\n{\n\tlocal _pname _pdir\n\t_pname=\"$1\"\n\t_pdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\tif [ ! -d \"$_pdir\" ]; then\n\t\t_qerror \"$2\" \"Pot $_pname not found\"\n\t\treturn 1 # false\n\tfi\n\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/jails/$_pname\" ; then\n\t\t_qerror \"$2\" \"zfs dataset $_pname not found\"\n\t\treturn 2 # false\n\tfi\n\n\tif [ ! -d \"$_pdir/m\" ] || [ ! -r \"$_pdir/conf/pot.conf\" ] ; then\n\t\t_qerror \"$2\" \"Some component of the pot $_pname is missing\"\n\t\treturn 3 # false\n\tfi\n\tif [ \"$( _get_pot_type \"$_pname\" )\" = \"multi\" ] && [ ! -r \"$_pdir/conf/fscomp.conf\" ]; then\n\t\t_qerror \"$2\" \"Some component of the pot $_pname is missing\"\n\t\treturn 4 # false\n\tfi\n\treturn 0 # true\n}\n\n# $1 pot name\n# tested\n_is_pot_running()\n{\n\tif [ -z \"$1\" ]; then\n\t\treturn 1 ## false\n\tfi\n\tjls -j \"$1\" >/dev/null 2>/dev/null\n\treturn $?\n}\n\n# $1 pot name\n# tested (common1)\n_is_valid_potname()\n{\n\tif echo \"$1\" | grep -Fq '.' ; then\n\t\treturn 1 # false\n\telse\n\t\treturn 0 # true\n\tfi\n}\n\n# $1 the element to search\n# $2.. the list\n# tested\n_is_in_list()\n{\n\tlocal _e\n\tif [ $# -lt 2 ]; then\n\t\treturn 1 # false\n\tfi\n\t_e=\"$1\"\n\tshift\n\t# shellcheck disable=SC2068\n\tfor e in $@ ; do\n\t\tif [ \"$_e\" = \"$e\" ]; then\n\t\t\treturn 0 # true\n\t\tfi\n\tdone\n\treturn 1 # false\n}\n\n# $1 the number to test\n# tested ( common8 )\n_is_natural_number()\n{\n\tcase \"$1\" in\n\t\t''|*[!0-9]*)\n\t\t\treturn 1 # false\n\t\t\t;;\n\t\t*)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n}\n\n# $1 a string\n# tested ( common8 )\n_contains_spaces()\n{\n\techo \"$1\" | grep -q \"[[:space:]]\"\n}\n\n# $1 mountpoint\n# tested\n_is_mounted()\n{\n\tlocal _mnt_p _mounted\n\t_mnt_p=$1\n\tif [ -z \"$_mnt_p\" ]; then\n\t\treturn 1 # false\n\tfi\n\t_mounted=$( mount | grep -F \"$_mnt_p\" | awk '{print $3}')\n\tfor m in $_mounted ; do\n\t\tif [ \"$m\" = \"$_mnt_p\" ]; then\n\t\t\treturn 0 # true\n\t\tfi\n\tdone\n\treturn 1 # false\n}\n\n# $1 mountpoint\n# tested\n_umount()\n{\n\tlocal _mnt_p\n\t_mnt_p=$1\n\tif _is_mounted \"$_mnt_p\" ; then\n\t\t_debug \"unmount $_mnt_p\"\n\t\tumount -f \"$_mnt_p\"\n\telse\n\t\t_debug \"$_mnt_p is already unmounted\"\n\tfi\n}\n\n# $1 pot\n# $2 cmd\n_set_command()\n{\n\tlocal _pname _cmd _cdir _cmd1 _cmd2\n\t_pname=\"$1\"\n\t_cmd=\"$2\"\n\t_cdir=$POT_FS_ROOT/jails/$_pname/conf\n\tsed -i '' -e \"/^pot.cmd=.*/d\" \"$_cdir/pot.conf\"\n\t_cmd1=\"$( echo \"$_cmd\" | sed 's/^\"//' )\"\n\tif [ \"$_cmd\" = \"$_cmd1\" ]; then\n\t\techo \"pot.cmd=$_cmd\" >> \"$_cdir\"/pot.conf\n\telse\n\t\t_cmd2=\"$( echo \"$_cmd1\" | sed 's/\"$//' )\"\n\t\techo \"pot.cmd=$_cmd2\" >> \"$_cdir/pot.conf\"\n\tfi\n}\n\n# tested\n_is_rctl_available()\n{\n\tlocal _racct\n\t_racct=\"$(sysctl -qn kern.racct.enable)\"\n\tif [ \"$_racct\" = \"1\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_is_vnet_available()\n{\n\tif [ \"$(sysctl -n kern.features.vimage 2>/dev/null)\" = \"1\" ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n_is_potnet_available()\n{\n\tif which potnet 2> /dev/null > /dev/null ; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# tested (common7)\n_get_arch()\n{\n\n\techo \"$(sysctl -n hw.machine)-$(sysctl -n hw.machine_arch)\"\n}\n\n# tested (common7)\n_get_valid_releases()\n{\n\tlocal _arch _file_prefix\n\t_file_prefix=\"$(_get_arch)\"\n\tif [ -z \"$_file_prefix\" ]; then\n\t\techo\n\tfi\n\treleases=\"$( find /usr/local/share/freebsd/MANIFESTS -type f -name \"${_file_prefix}-*\" | sed s%/usr/local/share/freebsd/MANIFESTS/\"${_file_prefix}\"-%% | sort -V | sed 's/-RELEASE//' | tr '\\n' ' ' )\"\n\techo \"$releases\"\n}\n\n# tested (common7)\n_is_valid_release()\n{\n\tlocal _rel _releases\n\tif [ -z \"$1\" ]; then\n\t\treturn 1 # false\n\tfi\n\t_rel=\"$1\"\n\t_releases=\"$( _get_valid_releases )\"\n\t# shellcheck disable=SC2086\n\tif _is_in_list \"$_rel\" $_releases ; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# $1 potname\n# it's required to have all the file-system mounted to access /bin/freebsd-version\n_get_os_release()\n{\n\tlocal _pname\n\t_pname=\"$1\"\n\tif [ -r \"${POT_FS_ROOT}/jails/$_pname/m/bin/freebsd-version\" ]; then\n\t\tgrep ^USERLAND \"${POT_FS_ROOT}/jails/$_pname/m/bin/freebsd-version\" | cut -f 2 -d\"=\" | tr -d \\\"\n\telse\n\t\t_get_conf_var \"$_pname\" osrelease\n\tfi\n}\n\n# $1 FreeBSD release.\n# for instance 12.0 or 13.0-RC1\n_get_freebsd_release_name()\n{\n\tif echo \"$1\" | grep -q \"RC\" ; then\n\t\techo \"$1\"\n\telse\n\t\techo \"$1-RELEASE\"\n\tfi\n}\n\n_fetch_freebsd()\n{\n\tlocal _archpath _rel\n\t_archpath=\"$(_get_arch)\"\n\n\tif ! _fetch_freebsd_internal \"$1\" \"$_archpath\"; then\n\t\t# remove artifact and retry only once\n\t\t_rel=\"$( _get_freebsd_release_name \"$1\" )\"\n\t\trm -f \"${POT_CACHE}/${_rel}\"_base.txz\n\t\tif ! _fetch_freebsd_internal \"$1\" \"$_archpath\"; then\n\t\t\treturn 1 # false\n\t\tfi\n\t\treturn 0 # true\n\tfi\n\treturn 0 # true\n}\n\n# $1 release, in short format, major.minor or major.minor-RC#\n_fetch_freebsd_internal()\n{\n\tlocal _rel _sha _sha_m _archpath\n\t_rel=\"$( _get_freebsd_release_name \"$1\" )\"\n\t_archpath=\"$( echo \"$2\" | sed -e 's:-:/:' )\"\n\n\tif [ ! -r \"${POT_CACHE}/${_rel}\"_base.txz ]; then\n\t\tfetch -m https://ftp.freebsd.org/pub/FreeBSD/releases/\"$_archpath\"/\"${_rel}\"/base.txz -o \"${POT_CACHE}/${_rel}\"_base.txz\n\tfi\n\n\tif [ ! -r \"${POT_CACHE}/${_rel}\"_base.txz ]; then\n\t\treturn 1 # false\n\tfi\n\tif [ -r /usr/local/share/freebsd/MANIFESTS/\"$2\"-\"${_rel}\" ]; then\n\t\t_sha=$( sha256 -q \"${POT_CACHE}/${_rel}\"_base.txz )\n\t\t# shellcheck disable=SC2002\n\t\t_sha_m=$( cat /usr/local/share/freebsd/MANIFESTS/\"$2\"-\"${_rel}\" | awk '/^base.txz/ { print $2 }' )\n\t\t# This version would remove the useless cat, but the testability of this function is compromised\n\t\t#_sha_m=$( awk '/^base.txz/ { print $2 }' < /usr/local/share/freebsd/MANIFESTS/\"$2\"-\"${_rel}\")\n\t\tif [ \"$_sha\" != \"$_sha_m\" ]; then\n\t\t\t_error \"sha256 doesn't match! Aborting\"\n\t\t\treturn 1 # false\n\t\tfi\n\telse\n\t\t_error \"No manifests found - please install the package freebsd-release-manifests\"\n\t\treturn 1 # false\n\tfi\n\treturn 0 # true\n}\n\n# $1 fscomp.conf absolute pathname\n_print_pot_fscomp()\n{\n\tlocal _dset _mnt_p\n\twhile read -r line ; do\n\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t_mnt_p=$( echo \"$line\" | awk '{print $2}' )\n\t\tprintf \"\\\\t\\\\t%s => %s\\\\n\" \"${_mnt_p##\"${POT_FS_ROOT}\"/jails/}\" \"${_dset##\"${POT_ZFS_ROOT}\"/}\"\n\tdone < \"$1\"\n}\n\n# $1 pot name\n_print_pot_snaps()\n{\n\tif [ -z \"$( zfs list -t snapshot -o name -Hr \"${POT_ZFS_ROOT}/jails/$1\")\" ]; then\n\t\tprintf \"\\t\\tno snapshots\\n\"\n\telse\n\t\tfor _s in $( zfs list -t snapshot -o name -Hr \"${POT_ZFS_ROOT}/jails/$1\" | tr '\\n' ' ' ) ; do\n\t\t\tprintf \"\\\\t\\\\t%s\\\\n\" \"$_s\"\n\t\tdone\n\tfi\n}\n\n#1 pot name\n_get_pot_snaps()\n{\n\tfor _s in $( zfs list -t snapshot -o name -H \"${POT_ZFS_ROOT}/jails/$1\" | tr '\\n' ' ' ) ; do\n\t\techo \"${_s##*@}\"\n\tdone\n}\n\n# $1 mountpoint to create (proper permissions are applied)\n_create_pot_mountpoint()\n{\n\tlocal _mp\n\t_mp=\"$1\"\n\n\tif [ ! -d \"$_mp\" ]; then\n\t\t_debug \"Creating mountpoint $_mp\"\n\t\tmkdir -p \"$_mp\" || exit 1\n\tfi\n}\n\n# $1 pot name\n_is_fscomp_old()\n{\n\tlocal _pname _fsconf _mnt_p _stripped_mnt_p\n\t_pname=\"$1\"\n\t_fsconf=\"${POT_FS_ROOT}/jails/$_pname/conf/fscomp.conf\"\n\twhile read -r line; do\n\t\t_mnt_p=$( echo \"$line\" | awk '{print $2}' )\n\t\t_stripped_mnt_p=\"${_mnt_p##\"${POT_FS_ROOT}/jails/$_pname/m\"}\"\n\t\tif [ \"$_stripped_mnt_p\" != \"$_mnt_p\" ]; then\n\t\t\treturn 0 # true\n\t\tfi\n\tdone < \"$_fsconf\"\n\treturn 1 # false\n}\n\n# $1 pot name\n_update_fscomp()\n{\n\tlocal _pname _fsconf _mnt_p _stripped_mnt_p _dset _opt _tmpfile\n\t_pname=\"$1\"\n\tif _is_fscomp_old \"$_pname\" ; then\n\t\t_fsconf=\"${POT_FS_ROOT}/jails/$_pname/conf/fscomp.conf\"\n\t\t_tmpfile=$(mktemp \"${POT_TMP:-/tmp}/fscomp.conf.${_pname}${POT_MKTEMP_SUFFIX}\")\n\t\twhile read -r line; do\n\t\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t\t_mnt_p=$( echo \"$line\" | awk '{print $2}' )\n\t\t\t_opt=$( echo \"$line\" | awk '{print $3}' )\n\t\t\t_stripped_mnt_p=\"${_mnt_p##\"${POT_FS_ROOT}/jails/$_pname/m\"}\"\n\t\t\tif [ -z \"$_stripped_mnt_p\" ]; then\n\t\t\t\t_stripped_mnt_p=\"/\"\n\t\t\tfi\n\t\t\t${ECHO} \"$_dset $_stripped_mnt_p $_opt\" >> \"$_tmpfile\"\n\t\tdone < \"$_fsconf\"\n\t\tmv \"$_tmpfile\" \"$_fsconf\"\n\tfi\n}\n\n# $1 pot name\n_pot_mount()\n{\n\tlocal _pname _dset _mnt_p _opt _node\n\t_pname=\"$1\"\n\tif ! _is_pot \"$_pname\" ; then\n\t\treturn 1 # false\n\tfi\n\t_update_fscomp \"$_pname\"\n\twhile read -r line ; do\n\t\tif [ -z \"$line\" ]; then\n\t\t\t_debug \"Empty line found. Skipping.\"\n\t\t\tcontinue\n\t\tfi\n\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t_mnt_p=$( echo \"$line\" | awk '{print $2}' )\n\t\t_mnt_p=\"${POT_FS_ROOT}/jails/$_pname/m$_mnt_p\"\n\t\t_mnt_p=\"${_mnt_p%/}\"\n\t\t_opt=$( echo \"$line\" | awk '{print $3}' )\n\t\tif [ \"$_opt\" = \"zfs-remount\" ]; then\n\t\t\t# if the mountpoint doesn't exist, zfs will create it\n\t\t\tzfs set mountpoint=\"$_mnt_p\" \"$_dset\"\n\t\t\t_node=$( _get_zfs_mountpoint \"$_dset\" )\n\t\t\tif _zfs_exist \"$_dset\" \"$_node\" ; then\n\t\t\t\t# the information are correct - move the mountpoint\n\t\t\t\t_debug \"_pot_mount: the dataset $_dset is mounted at $_node\"\n\t\t\telse\n\t\t\t\t# mountpoint already moved ?\n\t\t\t\t_error \"_pot_mount: Dataset $_dset not mounted at $_mnt_p! Aborting\"\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\telse\n\t\t\tif _is_absolute_path \"$_dset\" ; then\n\t\t\t\tif ! mount_nullfs -o \"${_opt:-rw}\" \"$_dset\" \"$_mnt_p\" ; then\n\t\t\t\t\t_error \"Error mounting $_dset on $_mnt_p\"\n\t\t\t\t\treturn 1 # false\n\t\t\t\telse\n\t\t\t\t\t_debug \"mount $_mnt_p\"\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t_node=$( _get_zfs_mountpoint \"$_dset\" )\n\t\t\t\tif [ ! -d \"$_mnt_p\" ]; then\n\t\t\t\t\t_debug \"start: creating the missing mountpoint $_mnt_p\"\n\t\t\t\t\tif ! mkdir \"$_mnt_p\" ; then\n\t\t\t\t\t\t_error \"Error creating the missing mountpoint $_mnt_p\"\n\t\t\t\t\t\treturn 1\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\tif ! mount_nullfs -o \"${_opt:-rw}\" \"$_node\" \"$_mnt_p\" ; then\n\t\t\t\t\t_error \"Error mounting $_node\"\n\t\t\t\t\treturn 1 # false\n\t\t\t\telse\n\t\t\t\t\t_debug \"mount $_mnt_p\"\n\t\t\t\tfi\n\t\t\tfi\n\t\tfi\n\tdone < \"${POT_FS_ROOT}/jails/$_pname/conf/fscomp.conf\"\n\tif [ \"$(_get_conf_var \"$_pname\" pot.attr.no-tmpfs)\" = \"YES\" ]; then\n\t\t_debug \"Not mounting tmpfs because of no-tmppfs attribure\"\n\telse\n\t\tif ! mount -t tmpfs tmpfs \"${POT_FS_ROOT}/jails/$_pname/m/tmp\" ; then\n\t\t\t_error \"Error mounting tmpfs\"\n\t\t\treturn 1\n\t\telse\n\t\t\t_debug \"mount ${POT_FS_ROOT}/jails/$_pname/m/tmp\"\n\t\tfi\n\tfi\n\treturn 0 # true\n}\n\n# $1 pot name\n_pot_umount()\n{\n\tlocal _pname _tmpfile _jdir _node _mnt_p _opt _dset\n\t_pname=\"$1\"\n\tif ! _tmpfile=$(mktemp -t \"${_pname}.XXXXXX\") ; then\n\t\t_error \"not able to create temporary file - umount failed\"\n\t\treturn 1 # false\n\tfi\n\t_jdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\n\tif [ \"$(_get_conf_var \"$_pname\" pot.attr.no-tmpfs)\" = \"YES\" ]; then\n\t\t_debug \"Not umounting tmpfs because of no-tmppfs attribure\"\n\telse\n\t\t_umount \"$_jdir/m/tmp\"\n\tfi\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.fdescfs\")\" = \"YES\" ]; then\n\t\t_umount \"$_jdir/m/dev/fs\"\n\tfi\n\t_umount \"$_jdir/m/dev\"\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.procfs\")\" = \"YES\" ]; then\n\t\t_umount \"$_jdir/m/proc\"\n\tfi\n\tif [ -e \"$_jdir/conf/fscomp.conf\" ]; then\n\t\t_update_fscomp \"$_pname\"\n\t\ttail -r \"$_jdir/conf/fscomp.conf\" > \"$_tmpfile\"\n\t\twhile read -r line ; do\n\t\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t\t_mnt_p=$( echo \"$line\" | awk '{print $2}' )\n\t\t\t_mnt_p=\"${POT_FS_ROOT}/jails/$_pname/m$_mnt_p\"\n\t\t\t_mnt_p=${_mnt_p%/}\n\t\t\t_opt=$( echo \"$line\" | awk '{print $3}' )\n\t\t\tif [ \"$_opt\" = \"zfs-remount\" ]; then\n\t\t\t\t_node=${POT_FS_ROOT}/jails/$_pname/$(basename \"$_dset\")\n\t\t\t\tzfs set mountpoint=\"$_node\" \"$_dset\"\n\t\t\t\tif _zfs_exist \"$_dset\" \"$_node\" ; then\n\t\t\t\t\t# the information are correct - move the mountpoint\n\t\t\t\t\t_debug \"stop: the dataset $_dset is mounted at $_node\"\n\t\t\t\telse\n\t\t\t\t\t# mountpoint not moved\n\t\t\t\t\t_error \"Dataset $_dset moved to $_node (Fix it manually)\"\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t_umount \"$_mnt_p\"\n\t\t\tfi\n\t\tdone < \"$_tmpfile\"\n\t\trm \"$_tmpfile\"\n\tfi\n}\n\n_get_pot_list()\n{\n\t# shellcheck disable=SC2011\n\tls -d \"${POT_FS_ROOT}/jails/\"*/ 2>/dev/null | xargs -I {} basename {} | tr '\\n' ' '\n}\n\n_get_bridge_list()\n{\n\t# shellcheck disable=SC2038\n\tfind \"${POT_FS_ROOT}/bridges\" -type f 2>/dev/null | xargs -I {} basename {} | tr '\\n' ' '\n}\n\npot-cmd()\n{\n\tlocal _cmd _func\n\t_cmd=$1\n\tshift\n\tif [ ! -r \"${_POT_INCLUDE}/${_cmd}.sh\" ]; then\n\t\t_error \"Fatal error! $_cmd implementation not found!\"\n\t\t${EXIT} 1\n\tfi\n\n\tif [ \"$_cmd\" != \"init\" ] && [ \"$_cmd\" != \"de-init\" ] && [ \"$_cmd\" != \"version\" ] ; then\n\t\tif [ ! -d \"$POT_FS_ROOT\" ]; then\n\t\t\t>&2 _error \"$POT_FS_ROOT does not exist, please run 'pot init'\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif [ ! -r \"$POT_FS_ROOT\" ]; then\n\t\t\t>&2 _error \"Current user has no read access to $POT_FS_ROOT\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\n\t# shellcheck disable=SC1090\n\t. \"${_POT_INCLUDE}/${_cmd}.sh\"\n\t_func=pot-${_cmd}\n\tcase \"$_cmd\" in\n\t\tcreate|import|clone|create-private-bridge|prepare|copy-in)\n\t\t\tif [ \"$_POT_RECURSIVE\" = \"1\" ]; then\n\t\t\t\tlogger -p \"${POT_LOG_FACILITY}\".info -t pot \"$_func $*\"\n\t\t\t\t$_func \"$@\"\n\t\t\telse\n\t\t\t\texport _POT_RECURSIVE=1\n\t\t\t\tlockf -k /tmp/pot-lock-file \"$_POT_PATHNAME\" \"$_cmd\" \"$@\"\n\t\t\tfi\n\t\t\t;;\n\t\tconfig|get-attr|get-rss|info|last-run-stats|list|ps|show|top)\n\t\t\tif _is_verbose ; then\n\t\t\t\tlogger -p \"${POT_LOG_FACILITY}\".debug -t pot \"$_func $*\"\n\t\t\tfi\n\t\t\t$_func \"$@\"\n\t\t\t;;\n\t\t*)\n\t\t\tlogger -p \"${POT_LOG_FACILITY}\".info -t pot \"$_func $*\"\n\t\t\t$_func \"$@\"\n\t\t\t;;\n\tesac\n}\n"
  },
  {
    "path": "share/pot/config.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n\n: \"${_config_names:=\"fs_root zfs_root gateway syslogd pot_prefix fscomp_prefix network_stack\"}\"\n\nconfig-help()\n{\n\tcat <<-EOH\n\tpot config [-hvq] [-g name]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\t  -g name : get value of config item \"name\", one of:\n\t$(echo \"$_config_names\" | xargs -n1 echo \"     +\" | sort)\n\tEOH\n}\n\n# $1 quiet\n# $2 name\n# $3 value\n_config_echo()\n{\n\tif [ \"$1\" = \"quiet\" ]; then\n\t\techo \"$3\"\n\telse\n\t\techo \"$2 = $3\"\n\tfi\n}\n\npot-config()\n{\n\tlocal _quiet\n\t_quiet=\"NO\"\n\t_get=\n\tOPTIND=1\n\n\twhile getopts \"hvqg:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tconfig-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"quiet\"\n\t\t\t;;\n\t\tg)\n\t\t\tif _is_in_list \"$OPTARG\" \"$_config_names\" ; then\n\t\t\t\t_get=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_qerror $_quiet \"$OPTARG is not a valid name\"\n\t\t\t\t[ \"quiet\" != \"$_quiet\" ] && config-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\t?)\n\t\t\tconfig-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_get\" ]; then\n\t\t_qerror $_quiet \"option -g is mandatory\"\n\t\t[ \"quiet\" != \"$_quiet\" ] && config-help\n\t\t${EXIT} 1\n\tfi\n\tcase $_get in\n\t\tfs_root)\n\t\t\t_config_echo $_quiet \"fs_root\" \"$POT_FS_ROOT\"\n\t\t\t;;\n\t\tzfs_root)\n\t\t\t_config_echo $_quiet \"zfs_root\" \"$POT_ZFS_ROOT\"\n\t\t\t;;\n\t\tgateway)\n\t\t\t_config_echo $_quiet \"gateway\" \"$POT_GATEWAY\"\n\t\t\t;;\n\t\tsyslogd)\n\t\t\t_config_echo $_quiet \"syslogd flags\" \"-b 127.0.0.1 -b $POT_GATEWAY -a $POT_NETWORK\"\n\t\t\t;;\n\t\tpot_prefix)\n\t\t\t_config_echo $_quiet \"pot prefix\" \"$POT_FS_ROOT/jails\"\n\t\t\t;;\n\t\tfscomp_prefix)\n\t\t\t_config_echo $_quiet \"fscomp prefix\" \"$POT_FS_ROOT/fscomp\"\n\t\t\t;;\n\t\tnetwork_stack)\n\t\t\t_config_echo $_quiet \"network stack\" \"$( _get_network_stack )\"\n\t\t\t;;\n\tesac\n}\n"
  },
  {
    "path": "share/pot/copy-in.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ncopy-in-help()\n{\n\tcat <<-\"EOH\"\n\tpot copy-in [-hv] -p pot -s source -d dest\n\t  -h print this help\n\t  -v verbose\n\t  -F force copy operation for running jails\n\t     (WARNING: can expose parts of the host file system)\n\t  -p pot : the working pot\n\t  -s source : the file or directory to be copied in\n\t  -d dest : the final location inside the pot\n\t  -c create any missing path components to `dirname destination`\n\t     inside the pot\n\tEOH\n}\n\n# $1 source\n_source_validation()\n{\n\tlocal _source\n\t_source=\"$1\"\n\tif [ -f \"$_source\" ] || [ -d \"$_source\" ]; then\n\t\tif [ -r \"$_source\" ]; then\n\t\t\treturn 0 # true\n\t\telse\n\t\t\t_error \"$_source not readable\"\n\t\tfi\n\telse\n\t\t_error \"$_source not valid\"\n\t\treturn 1 # false\n\tfi\n}\n\n_make_temp_source()\n{\n\tlocal _proot\n\t_proot=\"$1\"\n\tmktemp -d \"$_proot/tmp/copy-in${POT_MKTEMP_SUFFIX}\"\n}\n\n_mount_source_into_potroot()\n{\n\tlocal _source _mountpoint _source_mnt\n\t_source=\"$1\"\n\t_mountpoint=\"$2\"\n\tif [ -f \"$_source\" ]; then\n\t\t_source_mnt=\"$( dirname \"$_source\" )\"\n\telse\n\t\t_source_mnt=\"$_source\"\n\tfi\n\tif ! mount_nullfs -o ro \"$_source_mnt\" \"$_mountpoint\" ; then\n\t\t_error \"Failed to mount source inside the pot\"\n\t\treturn 1\n\tfi\n}\n\npot-copy-in()\n{\n\tlocal _pname _source _destination _to_be_umount _rc _force _proot _cp_opt _create_dirs\n\tOPTIND=1\n\t_pname=\n\t_destination=\n\t_force=\n\t_cp_opt=\"-a\"\n\t_create_dirs=\n\twhile getopts \"hvs:d:p:Fc\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tcopy-in-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tF)\n\t\t\t_force=\"YES\"\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t_cp_opt=\"-va\"\n\t\t\t;;\n\t\ts)\n\t\t\t_source=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\td)\n\t\t\t_destination=\"$OPTARG\"\n\t\t\t;;\n\t\tc)\n\t\t\t_create_dirs=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tcopy-in-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tcopy-in-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_source\" ]; then\n\t\t_error \"A source is mandatory\"\n\t\tcopy-in-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_destination\" ]; then\n\t\t_error \"A destination is mandatory\"\n\t\tcopy-in-help\n\t\treturn 1\n\tfi\n\tif ! _is_absolute_path \"$_destination\" ; then\n\t\t_error \"The destination has to be an absolute pathname\"\n\t\treturn 1\n\tfi\n\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tcopy-in-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif ! _source_validation \"$_source\" ; then\n\t\tcopy-in-help\n\t\treturn 1\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif [ \"$_force\" != \"YES\" ]; then\n\t\t\t_error \"Copying files on a running pot is discouraged, it can partially expose the host file system to the jail\"\n\t\t\t_info \"Using the -F flag, the operation can be executed anyway, but we disagree\"\n\t\t\treturn 1\n\t\telse\n\t\t\t_debug \"Copying files on a running pot allowed, because of the -F flag\"\n\t\tfi\n\telse\n\t\t_pot_mount \"$_pname\"\n\t\t_to_be_umount=1\n\tfi\n\t_proot=${POT_FS_ROOT}/jails/$_pname/m\n\tif [ \"$_create_dirs\" = \"YES\" ]; then\n\t\tif _is_pot_running \"$_pname\" ; then\n\t\t\tif jexec \"$_pname\" /bin/mkdir -p \"$(dirname \"$_destination\")\" ; then\n\t\t\t\t_debug \"Destination path $_destination created in the pot $_pname\"\n\t\t\telse\n\t\t\t\t_error \"Destination path $_destination NOT created because of an error\"\n\t\t\t\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t\t\t\t_pot_umount \"$_pname\"\n\t\t\t\tfi\n\t\t\t\treturn 1\n\t\t\tfi\n\t\telse\n\t\t\tif jail -c path=\"$_proot\" command=/bin/mkdir -p \"$(dirname \"$_destination\")\" ; then\n\t\t\t\t_debug \"Destination path $_destination created in the pot $_pname\"\n\t\t\telse\n\t\t\t\t_error \"Destination path $_destination NOT created because of an error\"\n\t\t\t\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t\t\t\t_pot_umount \"$_pname\"\n\t\t\t\tfi\n\t\t\t\treturn 1\n\t\t\tfi\n\t\tfi\n\tfi\n\tif ! _source_mountpoint=\"$( _make_temp_source \"$_proot\" )\" ; then\n\t\t_error \"Failed to build a temporary folder in the pot /tmp\"\n\t\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t\t_pot_umount \"$_pname\"\n\t\tfi\n\t\treturn 1\n\tfi\n\tif ! _mount_source_into_potroot \"$_source\" \"$_source_mountpoint\" ; then\n\t\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t\t_pot_umount \"$_pname\"\n\t\tfi\n\t\treturn 1\n\tfi\n\tif [ -f \"$_source\" ]; then\n\t\t_cp_source=\"/tmp/$( basename \"$_source_mountpoint\" )/$( basename \"$_source\" )\"\n\telse\n\t\t_cp_source=\"/tmp/$( basename \"$_source_mountpoint\" )\"\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif jexec \"$_pname\" /bin/cp \"$_cp_opt\" \"$_cp_source\" \"$_destination\" ; then\n\t\t\t_debug \"Source $_source copied in the pot $_pname\"\n\t\t\t_rc=0\n\t\telse\n\t\t\t_error \"Source $_source NOT copied because of an error\"\n\t\t\t_rc=1\n\t\tfi\n\telse\n\t\tif jail -c path=\"$_proot\" command=/bin/cp \"$_cp_opt\" \"$_cp_source\" \"$_destination\" ; then\n\t\t\t_debug \"Source $_source copied in the pot $_pname\"\n\t\t\t_rc=0\n\t\telse\n\t\t\t_error \"Source $_source NOT copied because of an error\"\n\t\t\t_rc=1\n\t\tfi\n\tfi\n\n\tif ! umount -f \"$_source_mountpoint\" ; then\n\t\t_error \"Failed to unmount the source tmp folder from the pot\"\n\t\t_rc=1\n\tfi\n\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t_pot_umount \"$_pname\"\n\telse\n\t\trmdir \"$_source_mountpoint\"\n\tfi\n\treturn $_rc\n}\n"
  },
  {
    "path": "share/pot/copy-out.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ncopy-out-help()\n{\n\tcat <<-\"EOH\"\n\tpot copy-out [-hv] -p pot -s source -d dest\n\t  -h print this help\n\t  -v verbose\n\t  -F force copy operation for running jails\n\t     (warning: can expose parts of the host file system)\n\t  -p pot : the working pot\n\t  -s source : the file or directory inside the pot\n\t  -d dest : the location (directory) on the host to copy-out to\n\tEOH\n}\n\n# $1 source\n_destination_validation()\n{\n\tlocal _destination\n\t_destination=\"$1\"\n\tif [ -r \"$_destination\" ] && [ -d \"$_destination\" ] && [ -x \"$_destination\" ]; then\n\t\treturn 0 # true\n\telse\n\t\t_error \"$_destination not valid\"\n\tfi\n}\n\n_make_temp_destination()\n{\n\tlocal _proot\n\t_proot=\"$1\"\n\tmktemp -d \"$_proot/tmp/copy-out${POT_MKTEMP_SUFFIX}\"\n}\n\n_mount_destination_into_potroot()\n{\n\tlocal _destination _mountpoint\n\t_destination=\"$1\"\n\t_mountpoint=\"$2\"\n\tif ! mount_nullfs \"$_destination\" \"$_mountpoint\" ; then\n\t\t_error \"Failed to mount destination inside the pot\"\n\t\treturn 1\n\tfi\n}\n\npot-copy-out()\n{\n\tlocal _pname _source _destination _to_be_umount _rc _force _proot _cp_opt _destination_mountpoint\n\tOPTIND=1\n\t_pname=\n\t_destination=\n\t_force=\n\t_cp_opt=\"-a\"\n\twhile getopts \"hvs:d:p:F\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tcopy-out-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tF)\n\t\t\t_force=\"YES\"\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t_cp_opt=\"-va\"\n\t\t\t;;\n\t\ts)\n\t\t\t_source=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\td)\n\t\t\t_destination=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tcopy-out-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tcopy-out-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_source\" ]; then\n\t\t_error \"A source is mandatory\"\n\t\tcopy-out-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_destination\" ]; then\n\t\t_error \"A destination is mandatory\"\n\t\tcopy-out-help\n\t\treturn 1\n\tfi\n\tif ! _is_absolute_path \"$_source\" ; then\n\t\t_error \"The source has to be an absolute pathname\"\n\t\treturn 1\n\tfi\n\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tcopy-out-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif ! _destination_validation \"$_destination\" ; then\n\t\tcopy-out-help\n\t\treturn 1\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif [ \"$_force\" != \"YES\" ]; then\n\t\t\t_error \"Copying files from a running pot is discouraged, it can partially expose the host file system to the jail\"\n\t\t\t_info \"Using the -F flag, the operation can be executed anyway, but we disagree\"\n\t\t\treturn 1\n\t\telse\n\t\t\t_debug \"Copying files from a running pot allowed, because of the -F flag\"\n\t\tfi\n\telse\n\t\t_pot_mount \"$_pname\"\n\t\t_to_be_umount=1\n\tfi\n\t_proot=${POT_FS_ROOT}/jails/$_pname/m\n\tif ! _destination_mountpoint=\"$( _make_temp_destination \"$_proot\" )\" ; then\n\t\t_error \"Failed to build a temporary folder in the pot /tmp\"\n\t\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t\t_pot_umount \"$_pname\"\n\t\tfi\n\t\treturn 1\n\tfi\n\tif ! _mount_destination_into_potroot \"$_destination\" \"$_destination_mountpoint\" ; then\n\t\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t\t_pot_umount \"$_pname\"\n\t\tfi\n\t\treturn 1\n\tfi\n\t_cp_destination=\"/tmp/$( basename \"$_destination_mountpoint\" )\"\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif jexec \"$_pname\" /bin/cp \"$_cp_opt\" \"$_source\" \"$_cp_destination\" ; then\n\t\t\t_debug \"Source $_source copied from the pot $_pname\"\n\t\t\t_rc=0\n\t\telse\n\t\t\t_error \"Source $_source NOT copied because of an error\"\n\t\t\t_rc=1\n\t\tfi\n\telse\n\t\tif jail -c path=\"$_proot\" command=/bin/cp \"$_cp_opt\" \"$_source\" \"$_cp_destination\" ; then\n\t\t\t_debug \"Source $_source copied from the pot $_pname\"\n\t\t\t_rc=0\n\t\telse\n\t\t\t_error \"Source $_source NOT copied because of an error\"\n\t\t\t_rc=1\n\t\tfi\n\tfi\n\n\tif ! umount -f \"$_destination_mountpoint\" ; then\n\t\t_error \"Failed to unmount the source tmp folder from the pot\"\n\t\t_rc=1\n\tfi\n\tif [ \"$_to_be_umount\" = \"1\" ]; then\n\t\t_pot_umount \"$_pname\"\n\telse\n\t\trmdir \"$_destination_mountpoint\"\n\tfi\n\treturn $_rc\n}\n"
  },
  {
    "path": "share/pot/create-base.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\n# supported releases are defined in common.sh\n\ncreate-base-help()\n{\n\tcat <<-EOH\n\tpot create-base [-h] [-r RELEASE] [-b basename]\n\t  -h print this help\n\t  -v verbose\n\t  -r RELEASE : supported release are: $( _get_valid_releases )\n\t$( _get_valid_releases | xargs -n1 echo \"     +\" | sort)\n\t  -b basename : optional, (default: the release)\n\tEOH\n}\n\n# $1 base name\n_cb_zfs()\n{\n\tlocal _bname _dset _mnt\n\t_bname=$1\n\t_dset=\"${POT_ZFS_ROOT}/bases/${_bname}\"\n\t_mnt=\"${POT_FS_ROOT}/bases/${_bname}\"\n\t_info \"Create the zfs datasets for base release $_dset\"\n\tif ! _zfs_exist \"${_dset}\" \"${_mnt}\" ; then\n\t\tif ! zfs create \"$_dset\" ; then\n\t\t\treturn 1\n\t\tfi\n\tfi\n\n\tif ! _zfs_exist \"${_dset}/usr.local\" \"${_mnt}/usr/local\" ; then\n\t\tif ! zfs create -o mountpoint=\"${_mnt}/usr/local\" \"$_dset/usr.local\" ; then\n\t\t\treturn 1\n\t\tfi\n\tfi\n\n\tif ! _zfs_exist \"${_dset}/custom\" \"${_mnt}/opt/custom\" ; then\n\t\tif ! zfs create -o mountpoint=\"${_mnt}/opt/custom\" \"$_dset/custom\" ; then\n\t\t\treturn 1\n\t\tfi\n\tfi\n\treturn 0\n}\n\n# $1 release\n# $2 base name\n_cb_tar_dir()\n{\n\tlocal _rel _bname _mnt\n\tif echo \"$1\" | grep -q \"RC\" ; then\n\t\t_rel=\"$1\"\n\telse\n\t\t_rel=\"$1\"-RELEASE\n\tfi\n\t_bname=$2\n\t_mnt=\"${POT_FS_ROOT}/bases/${_bname}\"\n\t(\n\t\tset -e\n\t\tcd \"$_mnt\"\n\t\ttar xkf \"${POT_CACHE}/${_rel}\"_base.txz\n\t\t# add release information\n\t\techo \"$_rel\" > .osrelease\n\t\tcp -a root opt/custom/\n\t\tcp -a etc opt/custom/\n\t\tcp -a var opt/custom/\n\t\tmkdir -p opt/custom/usr.local.etc\n\t\tmkdir -p opt/custom/usr.home\n\t\t# they could be part of flavor\n\t\tmkdir -p usr/ports\n\n\t\t# remove duplicated dirs\n\t\tchflags -R noschg var/empty\n\t\trm -rf etc/ root/ var/\n\n\t\t# create links\n\t\tln -s opt/custom/etc etc\n\t\tln -s opt/custom/root root\n\t\tln -s opt/custom/var var\n\t\tif [ ! -e home ]; then\n\t\t\tln -s opt/custom/usr.home home\n\t\tfi\n\t\tcd usr\n\t\tln -s ../opt/custom/usr.home home\n\t\tcd local\n\t\tln -s ../../opt/custom/usr.local.etc etc\n\t\tmkdir -p var.db.pkg\n\t\tcd ../../opt/custom/var/db\n\t\trm -rf pkg\n\t\tln -s ../../../../usr/local/var.db.pkg pkg\n\t)\n}\n\n# $1 base name\n_cb_base_pot()\n{\n\tlocal _bname _pname _tmp\n\t_bname=$1\n\t_tmp=$(echo \"$_bname\" | sed 's/\\./_/')\n\t_pname=\"base-$_tmp\"\n\t_info \"Create the related pot [$_pname]\"\n\tif ! _is_pot \"$_pname\" quiet ; then\n\t\tpot-cmd create -l 0 -b \"$_bname\" -p \"$_pname\" -f fbsd-update\n\tfi\n\t_debug \"Taking a snapshot fo $_pname\"\n\t_pot_zfs_snap_full \"$_pname\"\n}\n\npot-create-base()\n{\n\tlocal _rel _bname\n\tOPTIND=1\n\twhile getopts \"hr:b:v\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tcreate-base-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tr)\n\t\t\tif ! _is_valid_release \"$OPTARG\" ; then\n\t\t\t\t_error \"$OPTARG is not a supported release\"\n\t\t\t\tcreate-base-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_rel=$OPTARG\n\t\t\t;;\n\t\tb)\n\t\t\tif _is_base \"$OPTARG\" quiet ; then\n\t\t\t\t_error \"$OPTARG is already a base\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_bname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tcreate-base-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\n\tdone\n\n\tif [ -z \"$_rel\" ]; then\n\t\t_error \"option -r is mandatory\"\n\t\tcreate-base-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_bname\" ]; then\n\t\t_bname=$_rel\n\t\t_info \"Automatically use $_rel as base name\"\n\tfi\n\tif [ \"$_bname\" != \"$_rel\" ] && _is_valid_release \"$_bname\" ; then\n\t\t_error \"$_bname has the name of another valid release and that's forbidden\"\n\t\tcreate-base-help\n\t\t${EXIT} 1\n\tfi\n\tif _is_base \"$_bname\" quiet ; then\n\t\t_error \"$_bname already exist\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_init ; then\n\t\t${EXIT} 1\n\tfi\n\t_info \"Create a base with release $_rel\"\n\t# fetch binaries\n\tif ! _fetch_freebsd \"${_rel}\" ; then\n\t\t_error \"fetch of ${_rel} RELEASE failed\"\n\t\t${EXIT} 1\n\tfi\n\t# create zfs dataset\n\tif ! _cb_zfs \"${_bname}\" ; then\n\t\t_error \"zfs dataset of ${_bname} failed\"\n\t\t${EXIT} 1\n\tfi\n\t# move binaries to the dataset and create linkx\n\t_cb_tar_dir \"${_rel}\" \"${_bname}\"\n\t# create jail level 0\n\t_cb_base_pot \"${_bname}\"\n}\n"
  },
  {
    "path": "share/pot/create-fscomp.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ncreate-fscomp-help()\n{\n\tcat <<-\"EOH\"\n\tpot create-fscomp [-hv] -f name\n\t  -h print this help\n\t  -v verbose\n\t  -f name : the fs component name (mandatory)\n\tEOH\n}\n\npot-create-fscomp()\n{\n\tlocal _dset\n\t_dset=\n\tOPTIND=1\n\twhile getopts \"hvf:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tcreate-fscomp-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tf)\n\t\t\t_dset=\"${POT_ZFS_ROOT}/fscomp/$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tcreate-fscomp-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_dset\" ]; then\n\t\t_error \"fs component name is missing\"\n\t\tcreate-fscomp-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_init ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _zfs_dataset_valid \"$_dset\" ; then\n\t\tif ! _is_uid0 ; then\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! zfs create \"$_dset\" ; then\n\t\t\t_error \"fs component $_dset creation failed\"\n\t\t\t${EXIT} 1\n\t\tfi\n\telse\n\t\t_info \"fs component $_dset already exists\"\n\tfi\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/create-private-bridge.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ncreate-private-bridge-help()\n{\n\tcat <<-\"EOH\"\n\tpot create-private-bridge [-hv] [-B name] [-S size]\n\t  -h print this help\n\t  -v verbose\n\t  -B bridge name\n\t  -S bridge size (number of host expected)\n\tEOH\n}\n\n# $1 bridge-name\n# $2 bridge-size\ncreate-bridge()\n{\n\tlocal _bconf _bname _bsize\n\t_bname=$1\n\t_bsize=$2\n\t_bconf=\"${POT_FS_ROOT}/bridges/$_bname\"\n\tif potnet new-net -s \"$_bsize\" > \"$_bconf\" ; then\n\t\techo \"name=$_bname\" >> \"$_bconf\"\n\telse\n\t\trm -f \"$_bconf\"\n\t\t_error \"Not able to get a valid network with size $_bsize\"\n\t\t${EXIT} 1\n\tfi\n}\n\npot-create-private-bridge()\n{\n\tlocal _bname _host_amount\n\tOPTIND=1\n\twhile getopts \"hvB:S:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tcreate-private-bridge-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tB)\n\t\t\t_bname=\"$OPTARG\"\n\t\t\t;;\n\t\tS)\n\t\t\t_host_amount=\"$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tcreate-private-bridge-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_bname\" ]; then\n\t\t_error \"A bridge name is mandatory (-B option)\"\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_host_amount\" ]; then\n\t\t_error \"The amount of host is mandatory (-S option)\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_potnet_available ; then\n\t   _error \"potnet is not available! It's needed - cannot proceed\"\n\t\t${EXIT} 1\n\tfi\n\tif _is_bridge \"$_bname\" quiet ; then\n\t\t_error \"A bridge with name $_bname already exists\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tmkdir -p \"${POT_FS_ROOT}/bridges\"\n\tcreate-bridge \"$_bname\" \"$_host_amount\"\n}\n"
  },
  {
    "path": "share/pot/create.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ntrap _cj_undo_create TERM INT\n_set_pipefail\n\ncreate-help()\n{\n\tcat <<-\"EOH\"\n\tpot create [-hv] -p potname [-N network-type] [-i ipaddr]\n\t           [-l lvl] [-f flavour] [-b base|-P basepot]\n\t           [-d dns] [-t type]\n\t  -h print this help\n\t  -v verbose\n\t  -k keep the pot, if create fails\n\t  -p potname : the pot name (mandatory)\n\t  -l lvl : pot level (only for type multi)\n\t  -b base : the base pot\n\t  -P pot : the pot to be used as reference\n\t  -d dns : pot dns resolver configuration, one of\n\t           inherit*       - inherit from jailhost (*default)\n\t           pot            - the pot configured in POT_DNS_NAME\n\t           custom:<file>  - copy <file> into pot configuration\n\t           off            - leave resolver config unaltered\n\t  -f flavour : flavour to be used\n\t  -t type: pot file system layout, one of\n\t           single         - the pot is based on a unique ZFS dataset\n\t           multi*         - the pot is composed by a classical\n\t                            collection of 3 ZFS datasets (*default)\n\t  -N network-type: pot network layout, one of\n\t           inherit*       - inherit the host network stack (*default)\n\t           alias          - configure a static ip alias directly on\n\t                            the host's NIC\n\t           public-bridge  - use the common internal public bridge\n\t           private-bridge - use an internal private bridge (with -B)\n\t  -i ipaddr : IP address selection, one of\n\t           auto*          - automatically assign address (*default),\n\t                            only works with (public|private)-bridge\n\t           ipaddr         - mandatory with alias,\n\t                            also works with (public|private)-bridge\n\t  -B bridge-name : the name of the private bridge to be used\n\t  -S network-stack : the network stack (ipv4, ipv6 or dual)\n\tEOH\n}\n\n_cj_undo_create()\n{\n\t_POT_VERBOSITY=0\n\tif [ -z \"$_cleanup_pname\" ]; then\n\t\t${EXIT} 1\n\tfi\n\tpot-cmd stop \"$_cleanup_pname\"\n\tif [ \"$_cleanup_keep\" != \"YES\" ]; then\n\t\tpot-cmd destroy -Fp \"$_cleanup_pname\" -q\n\tfi\n\tunset _cleanup_pname\n\tunset _cleanup_keep\n\t${EXIT} 1\n}\n\n# $1 pot name\n# $2 pot-base name\n_c_zfs_single()\n{\n\tlocal _pname _base _potbase _jdset _snap _dset\n\t_pname=$1\n\t_potbase=$2\n\t_pdset=${POT_ZFS_ROOT}/jails/$_pname\n\t_pdir=${POT_FS_ROOT}/jails/$_pname\n\t# Create the main jail zfs dataset\n\tif ! _zfs_dataset_valid \"$_pdset\" ; then\n\t\tif ! zfs create \"$_pdset\" ; then\n\t\t\t_error \"create: failed to create $_pdset dataset\"\n\t\t\t_cj_undo_create\n\t\t\treturn 1\n\t\tfi\n\telse\n\t\t_info \"$_pdset exists already\"\n\tfi\n\n\tif [ -z \"$_potbase\" ]; then\n\t\t# create an empty dataset\n\t\tif ! zfs create \"$_pdset/m\" ; then\n\t\t\t_error \"create: failed to create $_pdset/m dataset\"\n\t\t\t_cj_undo_create\n\t\t\treturn 1\n\t\tfi\n\t\t# create the minimum needed tree\n\t\tmkdir -p \"$_pdir/m/tmp\"\n\t\tchmod 1777 \"$_pdir/m/tmp\"\n\t\tmkdir -p \"$_pdir/m/dev\"\n\telse\n\t\t# send/receive the last snapshot of _potbase\n\t\t_dset=${POT_ZFS_ROOT}/jails/$_potbase/m\n\t\t_snap=$(_zfs_last_snap \"$_dset\")\n\t\tif [ -n \"$_snap\" ]; then\n\t\t\t_debug \"Clone zfs snapshot $_dset@$_snap\"\n\t\t\t# shellcheck disable=SC2046\n\t\t\tif ! zfs send \"$_dset@$_snap\" | zfs receive \\\n\t\t\t    $(_get_zfs_receive_extra_args) \"$_pdset/m\" ; then\n\t\t\t\t_error \"create: zfs send/receive failed\"\n\t\t\t\t_cj_undo_create\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\telse\n\t\t\t# TODO - autofix\n\t\t\t_error \"no snapshot found for $_dset/m\"\n\t\t\t_cj_undo_create\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\treturn 0\n}\n\n# $1 pot name\n# $2 level\n# $3 base name\n# $4 pot-base name\n_c_zfs_multi()\n{\n\tlocal _pname _base _potbase _jdset _snap _dset\n\t_pname=$1\n\t_lvl=$2\n\t_base=$3\n\t_potbase=$4\n\t_pdset=\"${POT_ZFS_ROOT}/jails/$_pname\"\n\t_pdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\n\t# Create the main jail zfs dataset\n\tif ! _zfs_dataset_valid \"$_pdset\" ; then\n\t\tif ! zfs create \"$_pdset\" ; then\n\t\t\t_error \"create: failed to create $_pdset dataset\"\n\t\t\t_cj_undo_create\n\t\t\treturn 1\n\t\tfi\n\telse\n\t\t_info \"$_pdset exists already\"\n\tfi\n\t# Create the root mountpoint\n\t_create_pot_mountpoint \"$_pdir/m\"\n\t# lvl 0 images mount directly usr.local and custom\n\tif [ \"$_lvl\" = \"0\" ]; then\n\t\treturn 0\n\tfi\n\t# usr.local\n\tif [ \"$_lvl\" -eq 1 ]; then\n\t\t# lvl 1 images send/receive the usr.local dataset\n\t\tif ! _zfs_dataset_valid \"$_pdset/usr.local\" ; then\n\t\t\tif [ -n \"$_potbase\" ]; then\n\t\t\t\t_dset=${POT_ZFS_ROOT}/jails/$_potbase\n\t\t\telse\n\t\t\t\t_dset=${POT_ZFS_ROOT}/bases/$_base\n\t\t\tfi\n\t\t\t_snap=$(_zfs_last_snap \"$_dset/usr.local\")\n\t\t\tif [ -n \"$_snap\" ]; then\n\t\t\t\t_debug \"Import zfs snapshot $_dset/usr.local@$_snap\"\n\t\t\t\t# shellcheck disable=SC2046\n\t\t\t\tif ! zfs send \"$_dset/usr.local@$_snap\" | zfs receive \\\n\t\t\t\t    $(_get_zfs_receive_extra_args) \"$_pdset/usr.local\" ; then\n\t\t\t\t\t_error \"create: zfs send/receive failed\"\n\t\t\t\t\t_cj_undo_create\n\t\t\t\t\treturn 1 # false\n\t\t\t\tfi\n\t\t\t\tif ! zfs destroy \"$_pdset/usr.local@$_snap\" ; then\n\t\t\t\t\t_info \"create: not able to destroy the snapshot of usr.local - please, do it manually\"\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t# TODO - autofix\n\t\t\t\t_error \"no snapshot found for $_dset/usr.local\"\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\telse\n\t\t\t_info \"$_pdset/usr.local exists already\"\n\t\tfi\n\tfi\n\n\t# custom dataset\n\tif ! _zfs_dataset_valid \"$_pdset/custom\" ; then\n\t\tif [ -n \"$_potbase\" ]; then\n\t\t\t_dset=${POT_ZFS_ROOT}/jails/$_potbase/custom\n\t\telse\n\t\t\t_dset=${POT_ZFS_ROOT}/bases/$_base/custom\n\t\tfi\n\t\t_snap=$(_zfs_last_snap \"$_dset\")\n\t\tif [ -n \"$_snap\" ]; then\n\t\t\t_debug \"Clone zfs snapshot $_dset@$_snap\"\n\t\t\t# shellcheck disable=SC2046\n\t\t\tif ! zfs send \"$_dset@$_snap\" | zfs receive \\\n\t\t\t    $(_get_zfs_receive_extra_args) \"$_pdset/custom\" ; then\n\t\t\t\t_error \"create: zfs send/receive failed\"\n\t\t\t\t_cj_undo_create\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\t\tif ! zfs destroy \"$_pdset/custom@$_snap\" ; then\n\t\t\t\t_info \"create: not able to destroy the snapshot of custom - please, do it manually\"\n\t\t\tfi\n\t\telse\n\t\t\t# TODO - autofix\n\t\t\t_error \"no snapshot found for $_dset\"\n\t\t\treturn 1 # false\n\t\tfi\n\telse\n\t\t_info \"$_pdset/custom exists already\"\n\tfi\n\treturn 0 # true\n}\n# $1 pot name\n# $2 type\n# $3 level\n# $4 base name\n# $5 pot-base name\n_cj_zfs()\n{\n\tlocal _pname _base _type _potbase _jdset _snap _dset\n\t_pname=$1\n\t_type=$2\n\t_lvl=$3\n\t_base=$4\n\t_potbase=$5\n\tcase \"$_type\" in\n\t\t\"multi\")\n\t\t\t_c_zfs_multi \"$_pname\" \"$_lvl\" \"$_base\" \"$_potbase\"\n\t\t\t;;\n\t\t\"single\")\n\t\t\t_c_zfs_single \"$_pname\" \"$_potbase\"\n\t\t\t;;\n\tesac\n}\n\n# $1 pot name\n# $2 base name\n# $3 network type\n# $4 ip\n# $5 level\n# $6 dns\n# $7 type\n# $8 private bridge (if network type is private_bridge)\n# $9 pot-base name\n# $10 network-stack\n_cj_conf()\n{\n\tlocal _pname _base _ip _network_type _lvl _jdir _bdir _potbase _dns _type _pblvl _pbpb\n\tlocal _jdset _bdset _pbdset _baseos _bridge_name _stack\n\t_pname=$1\n\t_base=$2\n\t_network_type=$3\n\t_ip=$4\n\t_lvl=$5\n\t_dns=$6\n\t_type=$7\n\t_bridge_name=$8\n\t_potbase=$9\n\t_stack=${10}\n\n\t_jdir=${POT_FS_ROOT}/jails/$_pname\n\t_bdir=${POT_FS_ROOT}/bases/$_base\n\n\t_jdset=${POT_ZFS_ROOT}/jails/$_pname\n\t_bdset=${POT_ZFS_ROOT}/bases/$_base\n\tif [ -n \"$_potbase\" ]; then\n\t\t_pblvl=$( _get_conf_var \"$_potbase\" pot.level )\n\t\t_pbdset=${POT_ZFS_ROOT}/jails/$_potbase\n\telse\n\t\t_pblvl=\n\tfi\n\tif [ ! -d \"$_jdir/conf\" ]; then\n\t\tmkdir -p \"$_jdir/conf\"\n\tfi\n\t(\n\tif [ \"$_type\" = \"multi\" ]; then\n\t\tcase $_lvl in\n\t\t0)\n\t\t\techo \"$_bdset /\"\n\t\t\techo \"$_bdset/usr.local /usr/local\"\n\t\t\techo \"$_bdset/custom /opt/custom\"\n\t\t\t;;\n\t\t1)\n\t\t\techo \"$_bdset / ro\"\n\t\t\techo \"$_jdset/usr.local /usr/local zfs-remount\"\n\t\t\techo \"$_jdset/custom /opt/custom zfs-remount\"\n\t\t\t;;\n\t\t2)\n\t\t\techo \"$_bdset / ro\"\n\t\t\tif [ \"$_pblvl\" -eq 1 ]; then\n\t\t\t\techo \"$_pbdset/usr.local /usr/local ro\"\n\t\t\telse\n\t\t\t\t_pbpb=\"$( _get_conf_var \"$_potbase\" pot.potbase )\"\n\t\t\t\techo \"${POT_ZFS_ROOT}/jails/$_pbpb/usr.local /usr/local ro\"\n\t\t\tfi\n\t\t\techo \"$_jdset/custom /opt/custom zfs-remount\"\n\t\t\t;;\n\t\tesac\n\tfi\n\t) > \"$_jdir/conf/fscomp.conf\"\n\t(\n\t\tif [ \"$_type\" = \"multi\" ]; then\n\t\t\t_baseos=\"$( cat \"$_bdir/.osrelease\" )\"\n\t\telse\n\t\t\t_baseos=\"${_base}\"\n\t\tfi\n\t\techo \"pot.level=${_lvl}\"\n\t\techo \"pot.type=${_type}\"\n\t\techo \"pot.base=${_base}\"\n\t\techo \"pot.potbase=${_potbase}\"\n\t\tif [ \"$_dns\" = \"${_dns##custom:}\" ]; then\n\t\t\techo \"pot.dns=${_dns}\"\n\t\telse\n\t\t\techo \"pot.dns=custom\"\n\t\tfi\n\t\techo \"pot.cmd=sh /etc/rc\"\n\t\techo \"host.hostname=\\\"$( _get_usable_hostname \"${_pname}\" )\\\"\"\n\t\tif echo \"$_baseos\" | grep -q \"RC\" ; then\n\t\t\techo \"osrelease=\\\"${_baseos}\\\"\"\n\t\telif echo \"$_baseos\" | grep -q \"RELEASE\" ; then\n\t\t\techo \"osrelease=\\\"${_baseos}\\\"\"\n\t\telse\n\t\t\techo \"osrelease=\\\"${_baseos}-RELEASE\\\"\"\n\t\tfi\n\t\t# pot attributes\n\t\techo \"pot.attr.no-rc-script=NO\"\n\t\techo \"pot.attr.persistent=YES\"\n\t\techo \"pot.attr.start-at-boot=NO\"\n\t\techo \"pot.attr.prunable=NO\"\n\t\techo \"pot.attr.no-tmpfs=NO\"\n\t\t# jail attributes\n\t\tfor _attr in ${_POT_JAIL_RW_ATTRIBUTES} ; do\n\t\t\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.${_attr}\")\" ]; then\n\t\t\t\t# shellcheck disable=SC1083,SC2086\n\t\t\t\teval _value=\\\"\\${_POT_DEFAULT_${_attr}_D}\\\"\n\t\t\t\t# shellcheck disable=SC2154\n\t\t\t\techo \"pot.attr.${_attr}=${_value}\"\n\t\t\tfi\n\t\tdone\n\n\t\techo \"pot.stack=$_stack\"\n\t\techo \"network_type=$_network_type\"\n\t\tcase $_network_type in\n\t\t\"inherit\")\n\t\t\techo \"vnet=false\"\n\t\t\t;;\n\t\t\"alias\")\n\t\t\techo \"vnet=false\"\n\t\t\techo \"ip=${_ip}\"\n\t\t\t;;\n\t\t\"public-bridge\")\n\t\t\techo \"vnet=true\"\n\t\t\techo \"ip=${_ip}\"\n\t\t\t;;\n\t\t\"private-bridge\")\n\t\t\techo \"vnet=true\"\n\t\t\techo \"ip=${_ip}\"\n\t\t\techo \"bridge=${_bridge_name}\"\n\t\t\t;;\n\t\tesac\n\t\tif [ \"${_dns}\" = \"pot\" ]; then\n\t\t\techo \"pot.depend=${POT_DNS_NAME}\"\n\t\tfi\n\t) > \"$_jdir/conf/pot.conf\"\n\tif [ \"$_dns\" != \"${_dns##custom:}\" ]; then\n\t\tcp \"${_dns##custom:}\" \"$_jdir/conf/resolv.conf\"\n\tfi\n\tif [ \"$_lvl\" -eq 2 ]; then\n\t\tif [ \"$_pblvl\" -eq 1 ]; then\n\t\t\t# CHANGE the potbase usr.local to be not zfs-remount\n\t\t\t# Add an info here would be nice\n\t\t\tif [ -w \"${POT_FS_ROOT}/jails/$_potbase/conf/fscomp.conf\" ]; then\n\t\t\t\t_info \"${POT_FS_ROOT}/jails/$_potbase/conf/fscomp.conf fix (${POT_FS_ROOT}/jails/$_potbase/m/usr/local zfs-remount)\"\n\t\t\t\t# shellcheck disable=SC2086\n\t\t\t\t${SED} -i '' s%${POT_FS_ROOT}/jails/$_potbase/m/usr/local\\ zfs-remount%${POT_FS_ROOT}/jails/$_potbase/m/usr/local% ${POT_FS_ROOT}/jails/$_potbase/conf/fscomp.conf\n\t\t\telse\n\t\t\t\t_info \"$_potbase fscomp.conf has not fscomp.conf\"\n\t\t\tfi\n\t\tfi\n\tfi\n\tif [ \"$_type\" = \"multi\" ]; then\n\t\t_cj_internal_conf \"$_pname\" \"$_type\" \"$_lvl\" \"$_ip\"\n\tfi\n}\n\n# $1 pot name\n# $2 type\n# $3 level\n# $4 ip\n_cj_internal_conf()\n{\n\tlocal _pname _type _lvl _ip _jdir\n\t_pname=$1\n\t_type=$2\n\t_lvl=$3\n\t_ip=$4\n\t_jdir=${POT_FS_ROOT}/jails/$_pname\n\tif [ \"$_type\" = \"multi\" ]; then\n\t\t_etcdir=\"${POT_FS_ROOT}/jails/$_pname/custom/etc\"\n\telse\n\t\t_etcdir=\"${POT_FS_ROOT}/jails/$_pname/m/etc\"\n\tfi\n\n\t# disable some cron jobs, not relevant in a jail\n\tif [ \"$_type\" = \"single\" ] || [ \"$_lvl\" -ne 0 ]; then\n\t\t${SED} -i '' 's/^.*save-entropy$/# &/g' \"${_etcdir}/crontab\"\n\t\t${SED} -i '' 's/^.*adjkerntz.*$/# &/g' \"${_etcdir}/crontab\"\n\tfi\n\n\t# TODO: to be verified\n\t# add remote syslogd capability, if not inherit\n#\tif [ -n \"$_ip\" ]; then\n#\t\t# configure syslog in the pot\n#\t\t${SED} -i '' 's%^[^#].*/var/log.*$%# &%g' \"${_etcdir}/syslog.conf\"\n#\t\techo \"*.*  @${POT_GATEWAY}:514\" > \"${_etcdir}/syslog.d/pot.conf\"\n#\t\tif [ ! -r \"${_etcdir}/rc.conf\" ]; then\n#\t\t\ttouch \"${_etcdir}/rc.conf\"\n#\t\tfi\n#\t\tsysrc -f \"${_etcdir}/rc.conf\" \"syslogd_flags=-vv -s -b $_ip\" > /dev/null\n#\t\t# configure syslogd in the host\n#\t\t(\n#\t\t\techo +\"$_ip\"\n#\t\t\techo '*.*\t\t'\"/var/log/pot/${_pname}.log\"\n#\t\t) > /usr/local/etc/syslog.d/\"${_pname}\".conf\n#\t\ttouch /var/log/pot/\"${_pname}\".log\n#\t\t(\n#\t\t\techo \"# log rotation for pot ${_pname}\"\n#\t\t\techo \"/var/log/pot/${_pname}.log 644 7 * @T00 CX\"\n#\t\t) > /usr/local/etc/newsyslog.conf.d/\"${_pname}\".conf\n#\t\tservice syslogd reload\n#\tfi\n}\n\n# $1 pot name\n# $2 freebsd version\n_cj_single_install()\n{\n\tlocal _pname _base _proot _rel\n\t_pname=$1\n\t_base=$2\n\t_proot=${POT_FS_ROOT}/jails/$_pname/m\n\t_info \"Fetching FreeBSD $_base\"\n\tif ! _fetch_freebsd \"$_base\" ; then\n\t\t_error \"FreeBSD $_base fetch failed - try to continue\"\n\t\t_cj_undo_create\n\t\treturn 1 # false\n\tfi\n\tif echo \"$_base\" | grep -q \"RC\" ; then\n\t\t_rel=\"$_base\"\n\telse\n\t\t_rel=\"$_base\"-RELEASE\n\tfi\n\tif [ ! -r \"${POT_CACHE}/${_rel}_base.txz\" ]; then\n\t\t_error \"FreeBSD base tarball ${POT_CACHE}/${_rel}_base.txz is missing\"\n\t\t_cj_undo_create\n\t\treturn 1 # falase\n\tfi\n\t(\n\t  set -e\n\t  cd \"$_proot\"\n\t  _info \"Extract the tarball\"\n\t  tar xkf \"${POT_CACHE}/${_rel}_base.txz\"\n\t  if [ ! -d usr/home ]; then\n\t\t  mkdir -p usr/home\n\t  fi\n\t  if [ ! -e home ]; then\n\t\t  ln -s usr/home home\n\t  fi\n\t)\n\treturn 0\n}\n\npot-create()\n{\n\tlocal _pname _ipaddr _lvl _base _flv _potbase _dns _type _new_lvl _network_type _private_bridge _network_stack\n\tOPTIND=1\n\t_type=\"multi\"\n\t_network_type=\"inherit\"\n\t_pname=\n\t_base=\n\t_ipaddr=\n\t_lvl=1\n\t_new_lvl=\n\t_flv=\n\t_potbase=\n\t_dns=inherit\n\t_private_bridge=\n\t_network_stack=\"$( _get_network_stack )\"\n\t_cleanup_keep=\"NO\"\n\twhile getopts \"hvp:t:N:i:l:b:f:P:d:B:S:k\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tcreate-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tk)\n\t\t\t_cleanup_keep=\"YES\"\n\t\t\t;;\n\t\tp)\n\t\t\tif ! _is_valid_potname \"$OPTARG\" ; then\n\t\t\t\t_error \"$OPTARG is not a valid name for a pot ('.' is the only character not allowed)\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tt)\n\t\t\tif [ \"$OPTARG\" = \"multi\" ] || [ \"$OPTARG\" = \"single\" ]; then\n\t\t\t\t_type=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"Type $OPTARG not supported\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\tN)\n\t\t\t# shellcheck disable=SC2086\n\t\t\tif ! _is_in_list \"$OPTARG\" $_POT_NETWORK_TYPES ; then\n\t\t\t\t_error \"Network type $OPTARG not recognized\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_network_type=\"$OPTARG\"\n\t\t\t;;\n\t\tB)\n\t\t\t_private_bridge=\"$OPTARG\"\n\t\t\t;;\n\t\tS)\n\t\t\tif ! _is_in_list \"$OPTARG\" \"ipv4\" \"ipv6\" \"dual\" ; then\n\t\t\t\t_error \"Network stack $OPTARG not valid\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_network_stack=\"$OPTARG\"\n\t\t\t;;\n\t\ti)\n\t\t\tif [ -z \"$_ipaddr\" ]; then\n\t\t\t\t_ipaddr=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_ipaddr=\"$_ipaddr $OPTARG\"\n\t\t\tfi\n\t\t\t;;\n\t\tl)\n\t\t\t_lvl=\"$OPTARG\"\n\t\t\t_new_lvl=\"$OPTARG\"\n\t\t\t;;\n\t\tb)\n\t\t\t_base=$OPTARG\n\t\t\t;;\n\t\tP)\n\t\t\t_potbase=$OPTARG\n\t\t\t;;\n\t\td)\n\t\t\tcase $OPTARG in\n\t\t\t\t\"inherit\"|\"pot\"|\"off\")\n\t\t\t\t\t_dns=$OPTARG\n\t\t\t\t\t;;\n\t\t\t\tcustom:*)\n\t\t\t\t\tif [ -r \"${OPTARG##custom:}\" ]; then\n\t\t\t\t\t\t_dns=$OPTARG\n\t\t\t\t\telse\n\t\t\t\t\t\t_error \"The file ${OPTARG##custom:} is not valid or readable\"\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\t;;\n\t\t\t\t*)\n\t\t\t\t\t_error \"'${OPTARG}' is not a valid dns option\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\tesac\n\t\t\t;;\n\t\tf)\n\t\t\tif _is_flavour \"$OPTARG\" ; then\n\t\t\t\tif [ -z \"$_flv\" ]; then\n\t\t\t\t\t_flv=$OPTARG\n\t\t\t\telse\n\t\t\t\t\t_flv=\"$_flv $OPTARG\"\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t_error \"Flavour $OPTARG not found\"\n\t\t\t\t_debug \"Looking in the flavour dir ${_POT_FLAVOUR_DIR}\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\tcreate-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\t# check options consitency\n\tif [ \"$_type\" = \"single\" ]; then\n\t\tif [ -n \"$_new_lvl\" ] && [ \"$_new_lvl\" != \"0\" ]; then\n\t\t\t_error \"single pot level can only be zero (omit -l option)\"\n\t\t\tcreate-help\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_lvl=0\n\t\tif [ -n \"$_potbase\" ]; then\n\t\t\tif ! _is_pot \"$_potbase\" quiet ; then\n\t\t\t\t_error \"pot $_potbase not found\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\tif [ \"$( _get_pot_type \"$_potbase\" )\" != \"single\" ]; then\n\t\t\t\t_error \"pot $_potbase has the wrong type, it has to be of type single\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\tif [ -z \"$_base\" ]; then\n\t\t\t\t_base=\"$( _get_pot_base \"$_potbase\" )\"\n\t\t\telif [ \"$( _get_pot_base \"$_potbase\" )\" != \"$_base\" ]; then\n\t\t\t\t_error \"-b $_base and -P $_potbase are not compatible\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\telse\n\t\t   \tif [ -z \"$_base\" ]; then\n\t\t\t\t_error \"at least one of -b and -P has to be used\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\tif ! _is_valid_release \"$_base\" ; then\n\t\t\t\t_error \"$_base is not a valid release\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tfi\n\telse\n\t\tcase $_lvl in\n\t\t\t\t0)\n\t\t\t\tif [ -z \"$_base\" ]; then\n\t\t\t\t\t_error \"level $_lvl needs option -b\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\tif [ -n \"$_potbase\" ]; then\n\t\t\t\t\t_error \"-P option is not allowed with level $_lvl\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\tif ! _is_base \"$_base\" quiet ; then\n\t\t\t\t\t_error \"$_base is not a valid base\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t1)\n\t\t\t\tif [ -z \"$_base\" ] && [ -z \"$_potbase\" ]; then\n\t\t\t\t\t_error \"at least one of -b and -P has to be used\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\tif [ -n \"$_base\" ] && [ -n \"$_potbase\" ]; then\n\t\t\t\t\tif [ \"$( _get_pot_base \"$_potbase\" )\" != \"$_base\" ]; then\n\t\t\t\t\t\t_error \"-b $_base and -P $_potbase are not compatible\"\n\t\t\t\t\t\tcreate-help\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\t# TODO: an info or debug message che be showned\n\t\t\t\tfi\n\t\t\t\tif [ -n \"$_potbase\" ]; then\n\t\t\t\t\tif ! _is_pot \"$_potbase\" ; then\n\t\t\t\t\t\t_error \"-P $_potbase : is not a pot\"\n\t\t\t\t\t\tcreate-help\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\tif [ \"$( _get_conf_var \"$_potbase\" pot.level )\" != \"1\" ]; then\n\t\t\t\t\t\t_error \"-P $_potbase : it has to be of level 1\"\n\t\t\t\t\t\tcreate-help\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\tif [ -z \"$_base\" ]; then\n\t\t\t\t\t_base=$( _get_pot_base \"$_potbase\" )\n\t\t\t\t\tif [ -z \"$_base\" ]; then\n\t\t\t\t\t\t_error \"-P $_potbase has no base??\"\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\t_debug \"-P $_potbase induced -b $_base\"\n\t\t\t\tfi\n\t\t\t\tif ! _is_base \"$_base\" quiet ; then\n\t\t\t\t\t_error \"$_base is not a valid base\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t2)\n\t\t\t\tif [ -z \"$_potbase\" ]; then\n\t\t\t\t\t_error \"level $_lvl pots need another pot as reference\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\tif [ \"$( _get_conf_var \"$_potbase\" pot.level )\" -lt 1 ]; then\n\t\t\t\t\t_error \"-P $_potbase : it has to be at least of level 1\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\tif ! _is_pot \"$_potbase\" ; then\n\t\t\t\t\t_error \"-P $_potbase : is not a pot\"\n\t\t\t\t\tcreate-help\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\t\tif [ -n \"$_base\" ]; then\n\t\t\t\t\tif ! _is_base \"$_base\" quiet ; then\n\t\t\t\t\t\t_error \"$_base is not a valid base\"\n\t\t\t\t\t\tcreate-help\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\tif [ \"$( _get_pot_base \"$_potbase\" )\" != \"$_base\" ]; then\n\t\t\t\t\t\t_error \"-b $_base and -P $_potbase are not compatible\"\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\telse\n\t\t\t\t\t_base=$( _get_pot_base \"$_potbase\" )\n\t\t\t\t\tif [ -z \"$_base\" ]; then\n\t\t\t\t\t\t_error \"-P $_potbase has no base??\"\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\tif ! _is_base \"$_base\" quiet ; then\n\t\t\t\t\t\t_error \"$_base (induced by the pot $_potbase) is not a valid base\"\n\t\t\t\t\t\tcreate-help\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\t_error \"level $_lvl is not supported\"\n\t\t\t\t${EXIT} 1\n\t\t\t\t;;\n\t\tesac\n\tfi\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"pot name is missing\"\n\t\tcreate-help\n\t\t${EXIT} 1\n\tfi\n\tif _is_pot \"$_pname\" quiet ; then\n\t\t_error \"pot $_pname already exists\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _ipaddr=\"$( _validate_network_param \"$_network_type\" \"$_ipaddr\" \"$_private_bridge\" \"$_network_stack\" )\" ; then\n\t\techo \"$_ipaddr\"\n\t\t${EXIT} 1\n\tfi\n\tif [ \"$_dns\" = \"pot\" ]; then\n\t\tif ! _is_vnet_available ; then\n\t\t\t_error \"This kernel doesn't support VIMAGE! No vnet possible (needed by the dns)\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! _is_pot \"${POT_DNS_NAME}\" quiet ; then\n\t\t\t_error \"dns pot not found ($POT_DNS_NAME) - please fix it\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\t_info \"Creating a new pot\"\n\t_info \"pot name     : $_pname\"\n\t_info \"type         : $_type\"\n\t_info \"base         : $_base\"\n\t_info \"pot_base     : $_potbase\"\n\t_info \"level        : $_lvl\"\n\t_info \"network-type : $_network_type\"\n\t_info \"network-stack: $_network_stack\"\n\t_info \"ip           : $_ipaddr\"\n\t_info \"bridge       : $_private_bridge\"\n\t_info \"dns          : $_dns\"\n\t_info \"flavours     : $_flv\"\n\texport _cleanup_pname=\"$_pname\" # for the cleanup function\n\texport _cleanup_keep\n\tif ! _cj_zfs \"$_pname\" \"$_type\" \"$_lvl\" \"$_base\" \"$_potbase\" ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _cj_conf \"$_pname\" \"$_base\" \"$_network_type\" \"$_ipaddr\" \"$_lvl\" \"$_dns\" \"$_type\" \"$_private_bridge\" \"$_potbase\" \"$_network_stack\" ; then\n\t\t${EXIT} 1\n\tfi\n\tif [ \"$_type\" = \"single\" ]; then\n\t\tif [ -z \"$_potbase\" ]; then\n\t\t\t_cj_single_install \"$_pname\" \"$_base\"\n\t\tfi\n\t\t_cj_internal_conf \"$_pname\" \"$_type\" \"0\" \"$_ipaddr\"\n\tfi\n\tif [ -n \"$_flv\" ]; then\n\t\tfor _f in $_flv ; do\n\t\t\tif ! _exec_flv \"$_pname\" \"$_f\" ; then\n\t\t\t\t_cj_undo_create\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tdone\n\tfi\n\tunset _cleanup_pname\n\tunset _cleanup_keep\n}\n"
  },
  {
    "path": "share/pot/de-init.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nde-init-help()\n{\n\tcat <<-\"EOH\"\n\tpot de-init [-hmvf] [-p pf_file]\n\t  -f force : stop all running pots\n\t  -p pf_file : remove anchors to this file (empty to skip),\n\t               defaults to result of `sysrc -n pf_rules`\n\t  -h print this help\n\t  -m minimal modifications (alias for `-p ''`)\n\t     WARNING: Still destroys POT_ZFS_ROOT\n\t  -v verbose\n\tEOH\n}\n\npot-de-init()\n{\n\tlocal _pots _p _force _zopt _pf_file\n\t_force=\n\t_zopt=\n\t_pf_file=\"$(sysrc -n pf_rules)\"\n\tOPTIND=1\n\twhile getopts \"fhmvp:\" _o ; do\n\t\tcase \"$_o\" in\n\t\tf)\n\t\t\t_force=\"force\"\n\t\t\t;;\n\t\th)\n\t\t\tde-init-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tm)\n\t\t\t_pf_file=\"\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pf_file=\"$OPTARG\"\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t_zopt=\"-v\"\n\t\t\t;;\n\t\t?)\n\t\t\tde-init-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\t_pots=_get_pot_list\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tfor _p in $_pots ; do\n\t\tif _is_pot_running \"$_p\" ; then\n\t\t\tif [ -n \"$_force\" ]; then\n\t\t\t\t_debug \"Stop the pot $_p\"\n\t\t\t\tpot-cmd stop \"$_p\"\n\t\t\telse\n\t\t\t\t_error \"At least on pot is still running. Use -f to force the stop of all pots\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tfi\n\tdone\n\t# Remove pot dataset\n\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}\" ; then\n\t\t_info \"no root dataset found ($POT_ZFS_ROOT)\"\n\telse\n\t\t_info \"Deinstall pot ($POT_ZFS_ROOT)\"\n\t\tzfs destroy -r $_zopt \"${POT_ZFS_ROOT}\"\n\tfi\n\techo \"zfs datasets have been removed\"\n\t# Remove pf entries if needed\n\tif [ -n \"$_pf_file\" ]; then\n\t\tsed -i '' '/^nat-anchor pot-nat$/d' \"$_pf_file\"\n\t\tsed -i '' '/^rdr-anchor \"pot-rdr\\/\\*\"$/d' \"$_pf_file\"\n\t\techo \"pf configuration file should be clean\"\n\t\techo \"  - please check $_pf_file and reload it\"\n\tfi\n\t# Final message\n\techo \"check your rc.conf for potential leftovers variable like:\"\n\techo '  syslogd_flags'\n\techo '  pot_enable'\n\techo \"Please, consider to write a feedback email to pizzamig at FreeBSD dot org\"\n\techo \"It gives us the opportunity to learn and improve\"\n}\n"
  },
  {
    "path": "share/pot/destroy.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ndestroy-help()\n{\n\tcat <<-\"EOH\"\n\tpot destroy [-hvFr] [-p potname|-b basename|-f fscomp|-B bridge]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\t  -F force the stop and destroy\n\t  -p potname : the pot name (mandatory)\n\t  -b basename : the base name (mandatory)\n\t  -f fscomp : the fscomp name (mandatory)\n\t  -B bridge-name : the name of the bridge to be deleted (mandatory)\n\t  -r : destroy recursively all pots based on this base/pot\n\tEOH\n}\n\n# $1 zfs dataset\n_zfs_dataset_destroy()\n{\n\tlocal _dset _zopt\n\t_dset=$1\n\t_zopt=\n\tif _is_verbose ; then\n\t\t_zopt=\"-v\"\n\tfi\n\tzfs destroy -f -r $_zopt \"$_dset\"\n\treturn $?\n}\n\n# $1 pot name\n# $2 force parameter\n_pot_zfs_destroy()\n{\n\tlocal _pname _zopt _jdset _force\n\t_pname=$1\n\t_force=$2\n\t_jdset=${POT_ZFS_ROOT}/jails/$_pname\n\tif ! _zfs_dataset_valid \"$_jdset\" ; then\n\t\t## if a directory is found, just remove if\n\t\tif [ -d \"${POT_FS_ROOT}/jails/$_pname\" ]; then\n\t\t\t_debug \"Dataset of $_pname not found, but removing the directory anyway\"\n\t\t\trm -rf \"${POT_FS_ROOT}/jails/$_pname\"\n\t\t\treturn 0 # true\n\t\tfi\n\t\t_error \"$_pname not found\"\n\t\treturn 1 # false\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif [ \"$_force\" = \"YES\" ]; then\n\t\t\tpot-cmd stop \"$_pname\"\n\t\telse\n\t\t\t_error \"pot $_pname is running\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif ! _zfs_dataset_destroy \"$_jdset\" ; then\n\t\t_error \"zfs failed to destroy the dataset $_jdset\"\n\t\treturn 1 # false\n\tfi\n\tif [ -d \"${POT_FS_ROOT}/jails/$_pname\" ]; then\n\t\t_debug \"Removing leftover mountpoint ${POT_FS_ROOT}/jails/$_pname\"\n\t\trm -rf \"${POT_FS_ROOT}/jails/$_pname\"\n\tfi\n\trm -f \"/usr/local/etc/syslog.d/${_pname}.conf\" \"/usr/local/etc/newsyslog.conf.d/${_pname}.conf\" \"/var/log/pot/${_pname}.log\"\n\treturn $?\n}\n\n# $1 base name\n_base_zfs_destroy()\n{\n\tlocal _bname _bdset\n\t_bname=$1\n\t_bdset=${POT_ZFS_ROOT}/bases/$_bname\n\tif ! _zfs_dataset_destroy \"$_bdset\" ; then\n\t\t_error \"zfs failed to destroy the dataset $_bdset\"\n\t\treturn 1 # false\n\tfi\n\tif [ -d \"${POT_FS_ROOT}/bases/$_bname\" ]; then\n\t\t_debug \"Removing leftover mountpoint ${POT_FS_ROOT}/bases/$_bname\"\n\t\trm -rf \"${POT_FS_ROOT}/bases/$_bname\"\n\tfi\n\treturn 0\n}\n\n# $1 base name\n_fscomp_zfs_destroy()\n{\n\tlocal _fname _fdset\n\t_fname=$1\n\t_fdset=${POT_ZFS_ROOT}/fscomp/$_fname\n\tif ! _zfs_dataset_destroy \"$_fdset\" ; then\n\t\t_error \"zfs failed to destroy the dataset $_fdset\"\n\t\treturn 1 # false\n\tfi\n\tif [ -d \"${POT_FS_ROOT}/fscomp/$_fname\" ]; then\n\t\t_debug \"Removing leftover mountpoint ${POT_FS_ROOT}/fscomp/$_fname\"\n\t\trm -rf \"${POT_FS_ROOT}/fscomp/$_fname\"\n\tfi\n\treturn 0\n}\n\npot-destroy()\n{\n\tlocal _pname _bname _fname _force _recursive _pots _depPot _bridge_name\n\t_pname=\n\t_bname=\n\t_fname=\n\t_bridge_name=\n\t_force=\n\t_recursive=\"NO\"\n\tOPTIND=1\n\twhile getopts \"hvrf:p:b:FB:q\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tdestroy-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_POT_VERBOSITY=0\n\t\t\t;;\n\t\tF)\n\t\t\t_force=\"YES\"\n\t\t\t;;\n\t\tr)\n\t\t\t_recursive=\"YES\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=$OPTARG\n\t\t\t;;\n\t\tb)\n\t\t\t_bname=$OPTARG\n\t\t\t;;\n\t\tf)\n\t\t\t_fname=$OPTARG\n\t\t\t;;\n\t\tB)\n\t\t\t_bridge_name=$OPTARG\n\t\t\t;;\n\t\t*)\n\t\t\tdestroy-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ] && [ -z \"$_bname\" ] && [ -z \"$_fname\" ] && [ -z \"$_bridge_name\" ]; then\n\t\t_error \"-b or -p or -f or -B are missing\"\n\t\tdestroy-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_pname\" ]; then\n\t\tif [ -n \"$_bname\" ] || [ -n \"$_fname\" ] || [ -n \"$_bridge_name\" ] ; then\n\t\t\t_error \"-b, -p, -f and -B cannot be used at the same time\"\n\t\t\tdestroy-help\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif [ -n \"$_bname\" ]; then\n\t\tif [ -n \"$_fname\" ] || [ -n \"$_bridge_name\" ] ; then\n\t\t\t_error \"-b, -p, -f and -B cannot be used at the same time\"\n\t\t\tdestroy-help\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif [ -n \"$_fname\" ] && [ -n \"$_bridge_name\" ] ; then\n\t\t_error \"-b, -p, -f and -B cannot be used at the same time\"\n\t\tdestroy-help\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_bridge_name\" ]; then\n\t\tif [ \"$_force\" = \"YES\" ] || [ \"$_recursive\" = \"YES\" ] ; then\n\t\t\t_info \"Destroy bridge will ignore force and recursive\"\n\t\tfi\n\t\tif ! _is_bridge \"$_bridge_name\" ; then\n\t\t\t_error \"$_bridge_name is not a valid bridge name\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_pots=$( _get_pot_list )\n\t\tfor _p in $_pots ; do\n\t\t\t_bridge=\"$( _get_conf_var \"$_p\" bridge)\"\n\t\t\tif [ \"$_bridge\" = \"$_bridge_name\" ]; then\n\t\t\t\t_error \"the bridge $_bridge_name is still used by the pot $_p - unable to delete\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tdone\n\t\t_info \"Destroying bridge $_bridge_name\"\n\t\trm -f \"${POT_FS_ROOT}/bridges/$_bridge_name\"\n\t\t${EXIT} $?\n\tfi\n\n\tif [ -n \"$_fname\" ]; then\n\t\tif [ \"$_force\" = \"YES\" ] || [ \"$_recursive\" = \"YES\" ] ; then\n\t\t\t_info \"Destroy fscomps will ignore force and recursive\"\n\t\tfi\n\t\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/fscomp/$_fname\" ; then\n\t\t\t_error \"$_fname is not a fscomp\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_info \"Destroying fscomp $_fname\"\n\t\t_fscomp_zfs_destroy \"$_fname\"\n\t\t${EXIT} $?\n\tfi\n\n\tif [ -n \"$_bname\" ]; then\n\t\t# check the base\n\t\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/bases/$_bname\" ; then\n\t\t\t_error \"$_bname is not a base\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif [ \"$_recursive\" = \"YES\" ]; then\n\t\t\tfor _lvl in 2 1 0 ; do\n\t\t\t\t_pots=$( _get_pot_list )\n\t\t\t\tfor _p in $_pots ; do\n\t\t\t\t\tif [ \"$( _get_conf_var \"$_p\" pot.level )\" = \"$_lvl\" ]; then\n\t\t\t\t\t\tif [ \"$( _get_conf_var \"$_p\" pot.base )\" = \"$_bname\" ]; then\n\t\t\t\t\t\t\t_info \"Destroying recursively pot $_p based on $_bname\"\n\t\t\t\t\t\t\t_pot_zfs_destroy \"$_p\" $_force\n\t\t\t\t\t\tfi\n\t\t\t\t\tfi\n\t\t\t\tdone\n\t\t\tdone\n\t\telse\n\t\t\t# check if some pot depends on it\n\t\t\t_pots=$( _get_pot_list )\n\t\t\t_pname=\"base-$(echo \"$_bname\" | sed 's/\\./_/')\"\n\t\t\tfor _p in $_pots ; do\n\t\t\t\tif [ \"$_p\" = \"$_pname\" ]; then\n\t\t\t\t\tcontinue\n\t\t\t\tfi\n\t\t\t\tif [ \"$( _get_conf_var \"$_p\" pot.base )\" = \"$_bname\" ]; then\n\t\t\t\t\t_error \"base $_bname is used at least by one pot - use option -r to destroy it recursively\"\n\t\t\t\t\t${EXIT} 1\n\t\t\t\tfi\n\t\t\tdone\n\t\t\t# if present, destroy the lvl 0 pot\n\t\t\t_debug \"Destroying lvl 0 pot $_pname\"\n\t\t\t_pot_zfs_destroy \"$_pname\" \"$_force\"\n\t\tfi\n\t\t_info \"Destroying base $_bname\"\n\t\t_base_zfs_destroy \"$_bname\"\n\t\t${EXIT} $?\n\tfi\n\tif [ -n \"$_pname\" ]; then\n\t\tif ! _is_pot \"$_pname\" quiet ; then\n\t\t\tif _zfs_dataset_valid \"${POT_ZFS_ROOT}/jails/$_pname\" && [ \"$_force\" = \"YES\" ] ; then\n\t\t\t\t# we can destroy forcibly\n\t\t\t\tif ! _pot_zfs_destroy \"$_pname\" \"$_force\" ; then\n\t\t\t\t\t_error \"Failed to destroy pot $_pname\"\n\t\t\t\t\t${EXIT} 1\n\t\t\t\telse\n\t\t\t\t\t_info \"Forcibly destroyed pot $_pname\"\n\t\t\t\t\t${EXIT} 0\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t_is_pot \"$_pname\"\n\t\t\t\t_error \"pot $_pname not found or corrupted. Try to use the -F flag\"\n\t\t\t\t${EXIT} 1 # false\n\t\t\tfi\n\t\tfi\n\t\tif [ \"$( _get_conf_var \"$_pname\" pot.level )\" = \"0\" ]; then\n\t\t\t# if single we can remove a level 0 pot\n\t\t\tif [ \"$( _get_conf_var \"$_pname\" pot.type )\" = \"single\" ]; then\n\t\t\t\t_pots=$( _get_pot_list )\n\t\t\t\tfor _p in $_pots ; do\n\t\t\t\t\tif [ \"$( _get_conf_var \"$_p\" pot.potbase )\" = \"$_pname\" ]; then\n\t\t\t\t\t\tif [ \"$_recursive\" = \"YES\" ]; then\n\t\t\t\t\t\t\t_debug \"Destroying recursively pot $_p based on $_pname\"\n\t\t\t\t\t\t\t_pot_zfs_destroy \"$_p\" $_force\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t_error \"$_pname is used at least by another pot ($_p) - use option -r to destroy it recursively\"\n\t\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\t\tfi\n\t\t\t\t\tfi\n\t\t\t\tdone\n\t\t\telse\n\t\t\t\t_error \"The pot $_pname has level 0. Please destroy the related base insted\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tfi\n\t\tif [ \"$( _get_conf_var \"$_pname\" pot.level )\" = \"1\" ]; then\n\t\t\t_pots=$( _get_pot_list )\n\t\t\tfor _p in $_pots ; do\n\t\t\t\tif [ \"$( _get_conf_var \"$_p\" pot.potbase )\" = \"$_pname\" ]; then\n\t\t\t\t\tif [ \"$_recursive\" = \"YES\" ]; then\n\t\t\t\t\t\t_debug \"Destroying recursively pot $_p based on $_pname\"\n\t\t\t\t\t\t_pot_zfs_destroy \"$_p\" $_force\n\t\t\t\t\telse\n\t\t\t\t\t\t_error \"$_pname is used at least by one level 2 pot - use option -r to destroy it recursively\"\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\tdone\n\t\tfi\n\t\tif [ \"$( _get_conf_var \"$_pname\" pot.level )\" = \"2\" ] && [ \"$_recursive\" = \"YES\" ]; then\n\t\t\t_debug \"$_pname has level 2. No recursive destroy possible (ignored)\"\n\t\tfi\n\n\t\t## dependency detection\n\t\t_pots=$( _get_pot_list )\n\t\tfor _p in $_pots ; do\n\t\t\t_depPot=\"$( _get_conf_var \"$_p\" pot.depend )\"\n\t\t\tif [ -z \"$_depPot\" ]; then\n\t\t\t\tcontinue\n\t\t\tfi\n\t\t\tfor _d in $_depPot ; do\n\t\t\t\tif [ \"$_d\" = \"$_pname\" ]; then\n\t\t\t\t\t_info \"pot $_p is losing his dependency $_pname\"\n\t\t\t\t\tcontinue\n\t\t\t\tfi\n\t\t\tdone\n\t\tdone\n\n\t\t_info \"Destroying pot $_pname\"\n\t\tif ! _pot_zfs_destroy \"$_pname\" $_force ; then\n\t\t\t_error \"$_pname destruction failed\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif [ -f \"${POT_TMP:-/tmp}/pot_status_${_pname}\" ]; then\n\t\trm -f \"${POT_TMP:-/tmp}/pot_status_${_pname}\"\n\tfi\n}\n"
  },
  {
    "path": "share/pot/exec.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nexec-help()\n{\n\tcat <<-\"EOH\"\n\tpot exec [-hvdt] [-e var=value] [-u username] [-U username]\n\t         -p pot COMMAND\n\t  -h print this help\n\t  -v verbose\n\t  -d detach, run in background\n\t  -t allocate pty\n\t  -e var=value : set environment variable, can be repeated\n\t  -u username: The username from the host environment as whom the\n\t               command should run\n\t  -U username: The username from the pot environment as whom the\n\t               command should run\n\t  -p pot : the pot image\n\n\t  COMMAND is the command to execute and will be executed in the\n\t  username's $HOME\n\tEOH\n}\n\n# Actually send signal to process inside pot\n# $1 pot name\n# $2 detach\n# $3 env (encoded with save_params)\n# $4 alloc_pty\n# $5 user_host\n# $6 user_pot\n# $7-$n command/args\n_exec_cmd()\n{\n\tlocal _pname _detach _env _alloc_pty _user_host _user_pot\n\tlocal _cmd\n\n\t_pname=$1\n\t_detach=$2\n\t_env=$3\n\t_alloc_pty=$4\n\t_user_host=$5\n\t_user_pot=$6\n\tshift 6  # $@ contains command/args now\n\n\t_debug \"Exec in $_pname, cmd: $*\"\n\n\t# assemble command\n\t_cmd=\n\tif [ \"$_alloc_pty\" = \"YES\" ]; then\n\t\t_cmd=\"$_cmd\"$(_save_params \"script\" \"-q\" \"/dev/null\")\n\tfi\n\t_cmd=\"$_cmd\"$(_save_params \"jexec\" \"-l\")\n\tif [ -n \"$_user_host\" ]; then\n\t\t_cmd=\"$_cmd\"$(_save_params \"-u\" \"$_user_host\")\n\telif [ -n \"$_user_pot\" ]; then\n\t\t_cmd=\"$_cmd\"$(_save_params \"-U\" \"$_user_pot\")\n\tfi\n\t_cmd=\"$_cmd\"$(_save_params \"$_pname\")\n\t_cmd=\"$_cmd$_env\"$(_save_params \"$@\")\n\n\t# execute command\n\teval \"set -- $_cmd\"\n\tif [ \"$_detach\" = \"YES\" ]; then\n\t\tnohup \"$@\" >/dev/null 2>&1 &\n\telse\n\t\t\"$@\"\n\tfi\n\t_ret=$?\n\n\treturn \"$_ret\"\n}\n\npot-exec()\n{\n\tlocal _pname _detach _env _alloc_pty _user_host _user_pot _ret\n\t_pname=\n\t_detach=\"NO\"\n\t_env=$(_save_params \"env\")\n\t_alloc_pty=\"NO\"\n\t_user_host=\n\t_user_pot=\n\tOPTIND=1\n\twhile getopts \"hvdtp:e:u:U:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\texec-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\n\t\td)\n\t\t\t_detach=\"YES\"\n\t\t\t;;\n\t\tt)\n\t\t\t_alloc_pty=\"YES\"\n\t\t\t;;\n\t\te)\n\t\t\tif [ \"$OPTARG\" = \"${OPTARG#*=}\" ]; then\n\t\t\t\t# the argument doesn't have an equal sign\n\t\t\t\t_error \"$OPTARG not in a valid form\"\n\t\t\t\t_error \"VARIABLE=value is accetped\"\n\t\t\t\texec-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_env=\"$_env\"$(_save_params \"$OPTARG\")\n\t\t\t;;\n\t\tu)\n\t\t\t_user_host=\"$OPTARG\"\n\t\t\t;;\n\t\tU)\n\t\t\t_user_pot=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\texec-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tshift $((OPTIND-1))\n\n\tif [ \"$#\" -eq 0 ]; then\n\t\t_error \"A command is mandatory\"\n\t\t${EXIT} 1\n\tfi\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\texec-help\n\t\t${EXIT} 1\n\tfi\n\n\tif [ -n \"$_user_host\" ] && [ -n \"$_user_pot\" ]; then\n\t\t_error \"Parameters -u and -U are mutually exclusive\"\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\t_error \"The pot is not running\"\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\n\t_exec_cmd \"$_pname\" \"$_detach\" \"$_env\" \\\n\t  \"$_alloc_pty\" \"$_user_host\" \"$_user_pot\" \"$@\"\n}\n"
  },
  {
    "path": "share/pot/export-ports.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nexport-ports-help()\n{\n\tcat <<-\"EOH\"\n\tpot export-ports configure exported ports - public-bridge only\n\tpot export-ports [-hv] -p pot [-S] -e [proto:]port[:pot_port] ...\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -e [proto:]port[:pot_port] : port(s) to export\n\t         proto can be tcp (default) or udp\n\t         port is the port to export\n\t         pot_port : a static port to NAT to inside the pot\n\t                    dynamically allocated by default\n\t         This option can be repeated to export multiple ports.\n\n\t     Examples:\n\t       -e 80            export proto tcp port 80 to a dynamic port\n\t       -e 80:30000      export proto tcp port 80 to pot_port 30000\n\t       -e tcp:80:30000  export proto tcp port 80 to pot_port 30000\n\t       -e udp:53:30053  export proto udp port 53 to pot_port 30053\n\tEOH\n}\n\n# $1 pot\n# $2 port list\n_export_ports()\n{\n\tlocal _pname _ports _cdir\n\t_pname=\"$1\"\n\t_ports=\"$2\"\n\t_cdir=$POT_FS_ROOT/jails/$_pname/conf\n\tsed -i '' -e \"/pot.export.ports=.*/d\" \"$_cdir/pot.conf\"\n\techo \"pot.export.ports=$_ports\" >> \"$_cdir/pot.conf\"\n}\n\npot-export-ports()\n{\n\tlocal _pname _ports\n\t_pname=\n\t_ports=\n\tOPTIND=1\n\n\twhile getopts \"hvp:e:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\texport-ports-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\te)\n\t\t\tif ! _is_export_port_valid \"${OPTARG}\" ; then\n\t\t\t\t_error \"$OPTARG is not a valid port number\"\n\t\t\t\texport-ports-help\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\tif [ -z \"$_ports\" ]; then\n\t\t\t\t_ports=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_ports=\"$_ports $OPTARG\"\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\texport-ports-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\texport-ports-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"$_pname is not a valid pot name\"\n\t\texport-ports-help\n\t\treturn 1\n\tfi\n\tif [ -z \"${_ports}\" ]; then\n\t\t_error \"One port has to be specified\"\n\t\texport-ports-help\n\t\treturn 1\n\tfi\n\tif [ \"$(_get_pot_network_type \"$_pname\")\" != \"public-bridge\" ] &&\n\t\t[ \"$(_get_pot_network_type \"$_pname\")\" != \"private-bridge\" ] ; then\n\t\t_info \"Only public-bridge and private-bridge network type can export ports - this setting will be ignored during start\"\n\tfi\n\tif [ \"$( _get_pot_network_stack \"$_pname\" )\" = \"ipv6\" ]; then\n\t\t_info \"Only ipv4 can export ports, on ipv6 the pot has already a unique address - this setting will be ignored during start\"\n\tfi\n\t_debug \"Exporting the following ports: $_ports\"\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\t_export_ports \"$_pname\" \"$_ports\"\n}\n"
  },
  {
    "path": "share/pot/export.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\n# TODO\n# Add a way to directly upload the compressed file\n# Add a way to change compression utility\n\nexport-help() {\n\tcat <<-\"EOH\"\n\tpot export [-hv] -p pot [-S seckey] [-t tag] [-D dir] [-l level]\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -t tag : the tag to be used as suffix in the filename\n\t           if not specified, the snapshot name will be used as suffix\n\t  -c : treat tags as versions and check if they are decreasing\n\t  -D dir : where to store the compressed file with the pot\n\t  -l level : compression level from 0 (fast) to 9 (best).\n\t             Default level 6. (see `man xz` for more information)\n\t  -F : force export of multiple snapshot\n\t       (by default, only one snapshot is allowed)\n\t  -A : auto-fix number of snapshots (only one snapshot is allowed)\n\t  -S : sign with secure key 'seckey' using signify(1)\n\tEOH\n}\n\n# $1 : pot name\n# $2 : snapshot\n# $3 : tag name\n# $4 : check tag - if 'YES', make sure tags are not decreasing\n# $5 : target directory - where to write the file\n# $6 : compression level\n# $7 : key to sign with signify\n_export_pot()\n{\n\tlocal _pname _dset _snap _tag _check_tag _prev_tag _prev_snap\n\tlocal _dir _file _clvl _sign_seckey _meta _origin _origin_pname_snapshot\n\tlocal _origin_pname _origin_snapshot _origin_tag _highest_version\n\tlocal _noerr\n\t_pname=\"$1\"\n\t_snap=\"$2\"\n\t_tag=\"$3\"\n\t_check_tag=\"$4\"\n\t_dir=\"$5\"\n\t_clvl=\"$6\"\n\t_sign_seckey=\"$7\"\n\t_file=\"${_dir}/${_pname}_${_tag}.xz\"\n\t_dset=\"${POT_ZFS_ROOT}/jails/$_pname\"\n\t_meta=\"-\"\n\n\t_prev_tag=$(zfs get -H -o value :pot.tag \"${_dset}\")\n\t_prev_snap=$(zfs get -H -o value :pot.snap \"${_dset}\")\n\tif [ \"$_check_tag\" = \"YES\" ] && \\\n\t   [ -n \"$_prev_tag\" ] && [ \"$_prev_tag\" != \"-\" ]; then\n\t\tif [ \"$_prev_tag\" = \"$_tag\" ] && [ \"$_prev_snap\" != \"$_snap\" ]; then\n\t\t\t_error \"Already exported a different snapshot tagged as this version\"\n\t\t\treturn 1 # false\n\t\tfi\n\t\t_highest_version=\"$( \\\n\t\t  (echo \"$_tag\"; echo \"$_prev_tag\") | sort -V | tail -n1)\"\n\t\tif [ \"$_tag\" != \"$_highest_version\" ]; then\n\t\t\t_error \"Tag version lower than the previously exported one\"\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\n\t_origin=$(zfs get -H -o value origin \"${_dset}/m\")\n\tif [ -n \"$_origin\" ] && [ \"$_origin\" != \"-\" ]; then\n\t\t_origin=$(echo \"${_origin}\" | sed 's|/m@|@|g')\n\t\t_origin_pname_snapshot=$(basename \"${_origin}\")\n\t\t_origin_pname=$(echo \"${_origin_pname_snapshot}\" | awk -F\\@ '{ print $1 }')\n\t\t_origin_snapshot=$(echo \"${_origin_pname_snapshot}\" | awk -F@ '{ print $2 }')\n\t\t_origin_tag=$(zfs get -H -o value :pot.tag \"${_origin}\")\n\t\tif [ -z \"$_origin_tag\" ] || [ \"$_origin_tag\" = \"-\" ]; then\n\t\t\t_error \"Origin ${_origin_pname} has no :pot.tag, please export first\"\n\t\t\treturn 1 # false\n\t\tfi\n\t\t_meta=\"${_origin_pname}:${_origin_tag}@${_origin_snapshot}\"\n\tfi\n\n\tif ! zfs send -R \"${_dset}\"@\"${_snap}\" | xz -\"${_clvl}\" -T 0 > \"${_file}\" ; then\n\t\trm -f \"${_file}\"\n\t\treturn 1 # false\n\telif [ ! -r \"${_file}\" ]; then\n\t\treturn 1 # false\n\telse\n\t\t_noerr=0\n\t\techo \"$_meta\" > \"${_file}.meta\"\n\t\t# shellcheck disable=SC2320\n\t\t_noerr=$((_noerr+$?))\n\t\t(cat \"${_file}\" \"${_file}.meta\") | skein1024 -q > \"${_file}.skein\"\n\t\t_noerr=$((_noerr+$?))\n\t\tif [ -n \"$_sign_seckey\" ]; then\n\t\t\tsignify -S -s \"$_sign_seckey\" -m \"${_file}.skein\"\n\t\t\t_noerr=$((_noerr+$?))\n\t\tfi\n\t\tif [ \"$_noerr\" != 0 ]; then\n\t\t\t_error \"Export failed\"\n\t\t\trm -f \"${_file}\" \"${_file}.meta\" \"${_file}.skein\" \"${_file}.skein.sig\"\n\t\tfi\n\t\tzfs set :pot.tag=\"${_tag}\" \"${_dset}\"\n\t\tzfs set :pot.snap=\"${_snap}\" \"${_dset}\"\n\t\treturn 0 # true\n\tfi\n}\n\npot-export()\n{\n\tlocal _pname _snap _tag _dir _auto_purge _force _check_tag _sign_seckey\n\t_pname=\n\t_snap=\n\t_tag=\n\t_dir=\".\"\n\t_clvl=6\n\t_auto_purge=\n\t_force=\n\t_check_tag=\n\t_sign_seckey=\n\tOPTIND=1\n\twhile getopts \"hvcp:t:D:l:FAS:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\texport-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tc)\n\t\t\t_check_tag=\"YES\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tt)\n\t\t\t_tag=\"$OPTARG\"\n\t\t\t;;\n\t\tD)\n\t\t\t_dir=\"$OPTARG\"\n\t\t\tif [ ! -d \"$_dir\" ]; then\n\t\t\t\t_error \"$_dir is not a directory\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\tl)\n\t\t\tif echo \"$OPTARG\" | grep -q '^[0-9]$' ; then\n\t\t\t\t_clvl=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"$OPTARG is an invalid compression level\"\n\t\t\t\texport-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\tF)\n\t\t\t_force=\"YES\"\n\t\t\t;;\n\t\tA)\n\t\t\t_auto_purge=\"YES\"\n\t\t\t;;\n\t\tS)\n\t\t\t_sign_seckey=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\texport-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\texport-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\texport-help\n\t\t${EXIT} 1\n\tfi\n\tif  [ \"$(_get_pot_type \"$_pname\")\" != \"single\" ]; then\n\t\t_error \"pot $_pname not supported - only single type pot can be exported\"\n\t\t${EXIT} 1\n\tfi\n\n\tif [ -n \"$_sign_seckey\" ]; then\n\t\tif [ ! -r \"$_sign_seckey\" ]; then\n\t\t\t_error \"Signature key $_sign_seckey not found\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! type \"signify\" >/dev/null 2>&1; then\n\t\t\t_error \"Could not find 'signify',\"\\\n\t\t\t       \"try 'pkg install signify'\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\n\t_snap=\"$(_zfs_last_snap \"${POT_ZFS_ROOT}/jails/$_pname\" )\"\n\tif [ -z \"$_snap\" ]; then\n\t\tif [ \"$_auto_purge\" = \"YES\" ]; then\n\t\t\t_info \"Taking a snapshot of $_pname\"\n\t\t\tif ! pot-cmd snapshot -p \"$_pname\" ; then\n\t\t\t\t_error \"Failed to take a snapshot of pot $_pname\"\n\t\t\t\t${EXIT} 1\n\t\t\telse\n\t\t\t\t_snap=\"$(_zfs_last_snap \"${POT_ZFS_ROOT}/jails/$_pname\" )\"\n\t\t\t\t_debug \"A snapshot of $_pname has been automatically taken (@$_snap)\"\n\t\t\tfi\n\t\telse\n\t\t\t_error \"Pot $_pname has no snapshots - please use pot snapshot for that\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\n\tif [ \"$( _zfs_count_snap \"${POT_ZFS_ROOT}/jails/$_pname\" )\" -gt 1 ]; then\n\t\tif [ \"$_force\" = \"YES\" ]; then\n\t\t\t_info \"Pot $_pname has multiple snapshots and they all will be exported\"\n\t\telif [ \"$_auto_purge\" = \"YES\" ]; then\n\t\t\t_info \"Pot $_pname has more than 1 snapshot - auto-purge will delete older snapshots\"\n\t\t\tif ! pot-cmd purge-snapshots -p \"$_pname\" ; then\n\t\t\t\t_error \"purge-snapshots failed\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\telse\n\t\t\t_error \"Pot $_pname has more than 1 snapshot - use -A to auto-purge old snapshots or -F to force exporting\"\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\tif [ -z \"$_tag\" ]; then\n\t\t_tag=\"$_snap\"\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\t_info \"exporting $_pname @ $_snap to ${_dir}/${_pname}_${_tag}.xz\"\n\t_export_pot \"$_pname\" \"$_snap\" \"$_tag\" \"$_check_tag\" \"${_dir}\" \"${_clvl}\" \"$_sign_seckey\"\n\treturn $?\n}\n"
  },
  {
    "path": "share/pot/get-attribute.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nget-attribute-help()\n{\n\tcat <<-EOH\n\tpot get-attribute [-hvq] -p pot -A attribute\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\t  -p pot : the working pot\n\t  -A attribute : get value of attribute, one of\n\t$(echo \"$_POT_RW_ATTRIBUTES $_POT_RO_ATTRIBUTES \\\n\t  $_POT_JAIL_RW_ATTRIBUTES\" | xargs -n1 echo \"     +\" | sort)\n\tEOH\n}\n\npot-get-attribute()\n{\n\tlocal _pname _attr _value _quiet\n\t_pname=\n\t_attr=\n\t_value=\n\t_quiet=\"no\"\n\tOPTIND=1\n\twhile getopts \"hvqp:A:V:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tget-attribute-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"quiet\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tA)\n\t\t\t_attr=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tget-attribute-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tget-attribute-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_attr\" ]; then\n\t\t_error \"Option -A is mandatory\"\n\t\tget-attribute-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_pname\" \"$_quiet\" ; then\n\t\tif [ \"$_quiet\" != \"quiet\" ]; then\n\t\t\t_error \"$_pname is not a valid pot\"\n\t\t\tget-attribute-help\n\t\tfi\n\t\t${EXIT} 1\n\tfi\n\t# shellcheck disable=SC2086\n\tif ! _is_in_list \"$_attr\" $_POT_RW_ATTRIBUTES $_POT_RO_ATTRIBUTES $_POT_JAIL_RW_ATTRIBUTES ; then\n\t\t_error \"$_attr is not a valid attribute\"\n\t\tget-attribute-help\n\t\t${EXIT} 1\n\tfi\n\t_value=$(_get_conf_var \"$_pname\" \"pot.attr.$_attr\")\n\tif [ \"$_quiet\" = \"quiet\" ]; then\n\t\techo \"$_value\"\n\telse\n\t\tif [ -z \"$_value\" ]; then\n\t\t\t_info \"The attribute $_attr is not set for the pot $_pname\"\n\t\telse\n\t\t\t_info \"$_attr: $_value\"\n\t\tfi\n\tfi\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/get-rss.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nget-rss-help()\n{\n\tcat <<-\"EOH\"\n\tpot get-rss [-h] -p pot\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -J : output in JSON format\n\tEOH\n}\n\n# $1 pot name\n# $2 json format\nprint_rss()\n{\n\tlocal _rss _pname _json _pcpu _mem _cputime _vmem _clockrate _cputimecounter _swap\n\t_pname=$1\n\t_json=$2\n\t_clockrate=\"$( sysctl -n hw.clockrate )\"\n\t_rss=\"$( rctl -u jail:\"$_pname\" )\"\n\t_pcpu=\"$( echo \"$_rss\" | grep ^pcpu | cut -d'=' -f 2 )\"\n\t_cputimecounter=\"$( echo \"$_rss\" | grep ^cputime | cut -d'=' -f 2 )\"\n\t_mem=\"$( echo \"$_rss\" | grep ^memoryuse | cut -d'=' -f 2 )\"\n\t_vmem=\"$( echo \"$_rss\" | grep ^vmemoryuse | cut -d'=' -f 2 )\"\n\t_swap=\"$( echo \"$_rss\" | grep ^swapuse | cut -d'=' -f 2 )\"\n\t_cputime=\"$( printf \"scale=3\\n %s * %s / 100\\n\" \"$_clockrate\" \"$_pcpu\" | bc )\"\n\tif [ \"$_json\" = \"YES\" ]; then\n\t\techo \"{ \\\"ResourceUsage\\\": { \\\"MemoryStats\\\": { \\\"RSS\\\" : $_mem, \\\"Swap\\\" : $_swap }, \\\"CpuStats\\\": { \\\"TotalTicks\\\": $_cputime, \\\"Percent\\\": $_pcpu } } } \"\n\telse\n\t\techo \"Resource usage by the pot $_pname\"\n\t\tprintf \"\\\\tcpu time (ticks spent) : %s\\\\n\" \"$_cputimecounter\"\n\t\tprintf \"\\\\tcpu time (MHz)         : %s\\\\n\" \"$_cputime\"\n\t\tprintf \"\\\\tpcpu (%%)               : %s\\\\n\" \"$_pcpu\"\n\t\tprintf \"\\\\tvirtual memory         : %s\\\\n\" \"$_vmem\"\n\t\tprintf \"\\\\tphysical memory        : %s\\\\n\" \"$_mem\"\n\t\tprintf \"\\\\tswap memory            : %s\\\\n\" \"$_swap\"\n\tfi\n}\n\npot-get-rss()\n{\n\tlocal _pname _o _json\n\t_pname=\n\t_json=\n\tOPTIND=1\n\twhile getopts \"hvp:J\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tget-rss-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tJ)\n\t\t\t_json=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tget-rss-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tget-rss-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\t_error \"The pot $_pname is not running\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_rctl_available ; then\n\t\t_error \"To get resource usage, rctl has to be enabled\"\n\t\t${EXIT} 1\n\tfi\n\tprint_rss \"$_pname\" \"$_json\"\n\t${EXIT} 0\n}\n"
  },
  {
    "path": "share/pot/help.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n\npot-help()\n{\n\tlocal _cmd _func\n\t_cmd=$1\n\tshift\n\tcase \"${_cmd}\" in\n\t\tls)\n\t\t\t_cmd=list\n\t\t\t;;\n\t\trollback)\n\t\t\t_cmd=revert\n\t\t\t;;\n\t\trun)\n\t\t\t_cmd=term\n\t\t\t;;\n\t\tsnap)\n\t\t\t_cmd=snapshot\n\t\t\t;;\n\t\tset-attr)\n\t\t\t_cmd=set-attribute\n\t\t\t;;\n\t\tget-attr)\n\t\t\t_cmd=get-attribute\n\t\t;;\n\tesac\n\tif [ ! -r \"${_POT_INCLUDE}/${_cmd}.sh\" ]; then\n\t\t_error \"Command ${_cmd} unkown\"\n\t\texit 1\n\tfi\n\t# shellcheck disable=SC1090\n\t. \"${_POT_INCLUDE}/${_cmd}.sh\"\n\t_func=${_cmd}-help\n\t$_func \"$@\"\n}\n"
  },
  {
    "path": "share/pot/import.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\n# TODO\n# add sha256 check on fetch pot and option to disable it\n# add fscomp.conf management\n\nimport-help() {\n\tcat <<-\"EOH\"\n\tpot import [-hv] -p pot -t tag -U URL [-C pubkey]\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the remote pot name\n\t  -t tag : the tag of the pot\n\t  -U URL : the base URL where to find the image file\n\t  -C pubkey : verify with public key 'pubkey' using signify(1)\n\tEOH\n}\n\n# $1 : remote pot name\n# $2 : tag\n# $3 : pubkey (if non-empty, signature is fetched)\n# $4 : URL\n_fetch_pot()\n{\n\tlocal _filename\n\t_filename=\"${1}_${2}.xz\"\n\tif ! _fetch_pot_internal \"$1\" \"$2\" \"$3\" \"$4\" ; then\n\t\t# remove the artifacts and retry, but only once\n\t\trm -f \"${POT_CACHE}/${_filename}\" \\\n\t\t\t\"${POT_CACHE}/${_filename}.meta\" \\\n\t\t\t\"${POT_CACHE}/${_filename}.skein\" \\\n\t\t\t\"${POT_CACHE}/${_filename}.skein.sig\"\n\t\tif ! _fetch_pot_internal \"$1\" \"$2\" \"$3\" \"$4\"; then\n\t\t\treturn 1 # false\n\t\tfi\n\t\treturn 0 # true\n\tfi\n\treturn 0 # true\n}\n\n# $1 : remote pot name\n# $2 : tag\n# $3 : pubkey (if non-empty, signature is fetched)\n# $4 : URL\n_fetch_pot_internal()\n{\n\tlocal _rpname _tag _sign_pubkey _URL _filename\n\t_rpname=$1\n\t_tag=$2\n\t_sign_pubkey=$3\n\t_filename=\"${1}_${2}.xz\"\n\tif [ -z \"$4\" ]; then\n\t\t_URL=\"file://\"\n\telse\n\t\t_URL=\"$4\"\n\tfi\n\tif [ ! -r \"${POT_CACHE}/$_filename.skein\" ]; then\n\t\tif ! fetch \"$_URL/$_filename.skein\" --output \"${POT_CACHE}/$_filename.skein\" ; then\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\tif [ -n \"$_sign_pubkey\" ]; then\n\t\tif [ ! -r \"${POT_CACHE}/$_filename.skein.sig\" ]; then\n\t\t\tif ! fetch \"$_URL/$_filename.skein.sig\" \\\n\t\t\t    --output \"${POT_CACHE}/$_filename.skein.sig\" ; then\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\tfi\n\t\tif signify -V -p \"$_sign_pubkey\" -x \"${POT_CACHE}/$_filename.skein.sig\" \\\n\t\t    -m \"${POT_CACHE}/$_filename.skein\"; then\n\t\t\t_debug \"Signature verification succeeded\"\n\t\telse\n\t\t\t_error \"Signature verification failed\"\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\tif [ ! -r \"${POT_CACHE}/$_filename\" ]; then\n\t\tif ! fetch \"$_URL/$_filename\" --output \"${POT_CACHE}/$_filename\" ; then\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\tif [ ! -r \"${POT_CACHE}/$_filename.meta\" ]; then\n\t\tif ! fetch \"$_URL/$_filename.meta\" --output \"${POT_CACHE}/$_filename.meta\" ; then\n\t\t\t# At the moment, ignore this to be backwards compatible\n\t\t\t_info \"No ${POT_CACHE}/$_filename.meta, ignoring\"\n\t\t\ttouch \"${POT_CACHE}/$_filename.meta\"\n\t\tfi\n\tfi\n\tif (cat \"${POT_CACHE}/$_filename\" \"${POT_CACHE}/$_filename.meta\" |\\\n\t\tskein1024 -q) | cmp \"${POT_CACHE}/$_filename.skein\" - ; then\n\t\t_debug \"Hash confirmed\"\n\telse\n\t\t_error \"The image and its hash do not overlap\"\n\t\treturn 1 # false\n\tfi\n\treturn 0 # false\n}\n\n# $1 : remote pot name\n# $2 : tag\n# $3 : local pot name\n_import_pot()\n{\n\tlocal _pname _rpname _tag _filename _network_type _newip _cdir\n\tlocal _sign_pubkey _origin_pname _origin_snap\n\t_rpname=\"$1\"\n\t_tag=\"$2\"\n\t_pname=\"$3\"\n\t_sign_pubkey=\"$4\"\n\t_origin_pname=\"$5\"\n\t_origin_snap=\"$6\"\n\t_filename=\"${_rpname}_${_tag}.xz\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\n\tif [ -n \"$_origin_pname\" ] && [ -n \"$_origin_snap\" ]; then\n\t\t# shellcheck disable=SC2046\n\t\txzcat \"${POT_CACHE}/$_filename\" | zfs receive -uo \\\n\t\t  \"origin=${POT_ZFS_ROOT}/jails/$_origin_pname@$_origin_snap\" \\\n\t\t  $(_get_zfs_receive_extra_args) \\\n\t\t  \"${POT_ZFS_ROOT}/jails/$_pname\"\n\t\tzfs inherit mountpoint \"${POT_ZFS_ROOT}/jails/$_pname/m\"\n\t\tzfs mount \"${POT_ZFS_ROOT}/jails/$_pname\"\n\t\tzfs mount \"${POT_ZFS_ROOT}/jails/$_pname/m\"\n\telse\n\t\t# shellcheck disable=SC2046\n\t\txzcat \"${POT_CACHE}/$_filename\" | zfs receive \\\n\t\t  $(_get_zfs_receive_extra_args) \"${POT_ZFS_ROOT}/jails/$_pname\"\n\tfi\n\n\t# pot.conf modifications\n\t_hostname=\"${_pname}.$( hostname )\"\n\t${SED} -i '' -e \"/^host.hostname=.*/d\" \"$_cdir/pot.conf\"\n\techo \"host.hostname=\\\"${_hostname}.$( hostname )\\\"\" >> \"$_cdir/pot.conf\"\n\n\t# network rework\n\t_network_type=\"$( _get_pot_network_type \"$_pname\" )\"\n\tcase \"$_network_type\" in\n\t\"inherit\")\n\t\t_debug \"network_type set to inherit, nothing to rework\"\n\t\t;;\n\t\"alias\")\n\t\t_error \"Static IP not supported by import. Moving the pot to the internal network\"\n\t\t${SED} -i '' -e \"s%^vnet=.*$%vnet=true%\" \"${POT_FS_ROOT}/jails/$_pname/conf/pot.conf\"\n\t\t_newip=\"$(potnet next)\"\n\t\tsed -i '' -e \"s%^ip=.*$%ip=${_newip}%\" \"${POT_FS_ROOT}/jails/$_pname/conf/pot.conf\"\n\t\t_info \"Assigning new IP: $_newip\"\n\t\t;;\n\t\"public-bridge\")\n\t\t_newip=\"$(potnet next)\"\n\t\tsed -i '' -e \"s%^ip=.*$%ip=${_newip}%\" \"${POT_FS_ROOT}/jails/$_pname/conf/pot.conf\"\n\t\t_info \"Assigning new IP: $_newip\"\n\t\t;;\n\tesac\n}\n\npot-import()\n{\n\tlocal _rpname _tag _URL _pname _sign_pubkey\n\t_rpname=\n\t_tag=\n\t_URL=\n\t_sign_pubkey=\"$POT_DEFAULT_SIGNATURE_PUBKEY\"\n\tlocal _meta _dep_pname_tag _dep_snap _dep_pname _dep_tag _dep_origin\n\tlocal _filename\n\n\tOPTIND=1\n\twhile getopts \"hvp:t:U:C:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\timport-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_rpname=\"$OPTARG\"\n\t\t\t;;\n\t\tt)\n\t\t\t_tag=\"$OPTARG\"\n\t\t\t;;\n\t\tU)\n\t\t\tif [ -z \"$OPTARG\" ]; then\n\t\t\t\t_error \"Argument of -U cannot be empty\"\n\t\t\t\timport-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_URL=\"$OPTARG\"\n\t\t\t;;\n\t\tC)\n\t\t\t_sign_pubkey=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\timport-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_rpname\" ]; then\n\t\t_error \"A remote pot name is mandatory\"\n\t\timport-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_tag\" ]; then\n\t\t_error \"A tag name is mandatory\"\n\t\timport-help\n\t\t${EXIT} 1\n\tfi\n\t_pname=\"${_rpname}_${_tag}\"\n\t_pname=\"$(echo \"$_pname\" | tr '.' '_')\"\n\tif _is_pot \"$_pname\" quiet ; then\n\t\t_error \"pot $_pname is already present\"\n\t\timport-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_sign_pubkey\" ]; then\n\t\tif [ ! -r \"$_sign_pubkey\" ]; then\n\t\t\t_error \"Public key $_sign_pubkey not found\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! type \"signify\" >/dev/null 2>&1; then\n\t\t\t_error \"Could not find 'signify',\"\\\n\t\t\t       \"try 'pkg install signify'\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\t_info \"importing $_rpname @ $_tag as $_pname\"\n\tif ! _fetch_pot \"$_rpname\" \"$_tag\" \"$_sign_pubkey\" \"$_URL\" ; then\n\t\t${EXIT} 1\n\tfi\n\n\t_dep_origin=\"\"\n\t_dep_snap=\"\"\n\t_filename=\"${_rpname}_${_tag}.xz\"\n\t_meta=$(head -n1 \"${POT_CACHE}/$_filename.meta\")\n\tif [ -n \"${_meta}\" ] && [ \"${_meta}\" != \"-\" ]; then\n\t\t_dep_pname_tag=$(echo \"${_meta}\" | awk -F@ '{ print $1 }')\n\t\t_dep_snap=$(echo \"${_meta}\" | awk -F@ '{ print $2 }')\n\t\t_dep_pname=$(echo \"${_dep_pname_tag}\" | awk -F: '{ print $1 }')\n\t\t_dep_tag=$(echo \"${_dep_pname_tag}\" | awk -F: '{ print $2 }')\n\t\t_dep_origin=$(echo \"${_dep_pname}_${_dep_tag}\" | sed \"s/\\./_/g\")\n\t\t_info \"Pot $_pname depends on ${_dep_origin} (@${_dep_snap})\"\n\t\t# XXX: assumes remote name equals local name\n\t\tif ! _is_pot \"${_dep_origin}\" quiet ; then\n\t\t\t_info \"Installing dependency ${_dep_origin}\"\n\t\t\tif ! pot-cmd import -p \"$_dep_pname\" -t \"$_dep_tag\" \\\n\t\t\t    -U \"$_URL\" -C \"$_sign_pubkey\"; then\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\telse\n\t\t\t_info \"${_dep_origin} already installed\"\n\t\tfi\n\t\t#exit 1\n\telse\n\t\t_info \"Pot $_pname has no dependencies\"\n\tfi\n\n\tif ! _import_pot \"$_rpname\" \"$_tag\" \"$_pname\" \"$_sign_pubkey\" \\\n\t    \"$_dep_origin\" \"$_dep_snap\"; then\n\t\t${EXIT} 1\n\tfi\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/info.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ninfo-help()\n{\n\tcat <<-\"EOH\"\n\tpot info [-hvqr] [-p pname|-B bname]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\t  -p pname : pot name\n\t  -B bname : bridge name\n\t  -r check only if the pot is running\n\t  -E output some pot information as environment variables\n\t  -s list the available snapshots for the pot\n\tEOH\n}\n\n# $! pot name\n_info_pot_env()\n{\n\tlocal _pname _ips _idx _all_ips\n\t_pname=$1\n\techo \"export _POT_NAME=$_pname\"\n\tif [ \"$( _get_pot_network_type \"$_pname\" )\" != \"alias\" ]; then\n\t\techo \"export _POT_IP=$( _get_ip_var \"$_pname\" )\"\n\telse\n\t\t_all_ips=\"$( _get_ip_var \"$_pname\" ) \"\n\t\t_ips=\"$( _get_alias_ipv4 \"$_pname\" \"$_all_ips\" ) $( _get_alias_ipv6 \"$_pname\" \"$_all_ips\" )\"\n\t\t_idx=0\n\t\t_ipvar_list=\"\"\n\t\t_nicvar_list=\"\"\n\t\tfor ip in $_ips ; do\n\t\t\tnic=\"${ip%%|*}\"\n\t\t\tip=\"${ip##*|}\"\n\t\t\tif [ \"$_idx\" = \"0\" ]; then\n\t\t\t\techo \"export _POT_IP=$ip\"\n\t\t\t\t_ipvar_list=\"_POT_IP_$_idx\"\n\t\t\t\t_nicvar_list=\"_POT_NIC_$_idx\"\n\t\t\telse\n\t\t\t\t_ipvar_list=\"$_ipvar_list\\\\ _POT_IP_$_idx\"\n\t\t\t\t_nicvar_list=\"$_nicvar_list\\\\ _POT_NIC_$_idx\"\n\t\t\tfi\n\t\t\techo \"export _POT_IP_$_idx=$ip\"\n\t\t\techo \"export _POT_NIC_$_idx=$nic\"\n\t\t\t_idx=$(( _idx + 1 ))\n\t\tdone\n\t\techo \"export _POT_IP_LIST=$_ipvar_list\"\n\t\techo \"export _POT_NIC_LIST=$_nicvar_list\"\n\tfi\n\tif [ \"$( _get_pot_network_type \"$_pname\" )\" = \"private-bridge\" ]; then\n\t\techo \"export _POT_BRIDGE=$( _get_conf_var \"$_pname\" bridge)\"\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\techo \"export _POT_JID=$( jls -j \"$_pname\" jid )\"\n\tfi\n}\n\n# $1 pot name\n_info_pot()\n{\n\tlocal _pname _cdir _lvl _ports _type\n\t_pname=$1\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_lvl=$( _get_conf_var \"$_pname\" pot.level)\n\t_type=$( _get_conf_var \"$_pname\" pot.type)\n\tprintf \"pot name : %s\\n\" \"$_pname\"\n\tprintf \"\\ttype : %s\\n\" \"$_type\"\n\tprintf \"\\tbase : %s\\n\" \"$( _get_conf_var \"$_pname\" pot.base)\"\n\tprintf \"\\tlevel : %s\\n\" \"$_lvl\"\n\tif [ \"$_lvl\" -eq 2 ]; then\n\t\tprintf \"\\tbase pot : %s\\n\" \"$( _get_conf_var \"$_pname\" pot.potbase)\"\n\tfi\n\tprintf \"\\tnetwork_type : %s\\n\" \"$( _get_pot_network_type \"$_pname\" )\"\n\tif [ \"$( _get_pot_network_type \"$_pname\" )\" != \"inherit\" ]; then\n\t\tprintf \"\\tip : %s\\n\" \"$( _get_ip_var \"$_pname\" )\"\n\t\tif [ \"$( _get_pot_network_type \"$_pname\" )\" = \"private-bridge\" ]; then\n\t\t\tprintf \"\\tbridge : %s\\n\" \"$( _get_conf_var \"$_pname\" bridge)\"\n\t\tfi\n\t\tif _is_verbose ; then\n\t\t\t_ports=\"$( _get_pot_export_ports \"$_pname\" )\"\n\t\t\tif [ -z \"$_ports\" ]; then\n\t\t\t\tprintf \"\\t\\tno ports exported\\n\"\n\t\t\telse\n\t\t\t\tprintf \"\\t\\texported ports: %s\\n\" \"$_ports\"\n\t\t\tfi\n\t\tfi\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tprintf \"\\tactive : true\\n\"\n\telse\n\t\tprintf \"\\tactive : false\\n\"\n\tfi\n\tif _is_verbose ; then\n\t\tprintf \"\\tdatasets:\\n\"\n\t\tif [ \"$_type\" = \"single\" ]; then\n\t\t\tprintf \"\\\\t\\\\t%s\\\\n\" \"$_pname/m\"\n\t\tfi\n\t\t_print_pot_fscomp \"$_cdir/fscomp.conf\"\n\t\tprintf \"\\tsnapshots:\\n\"\n\t\t_print_pot_snaps \"$_pname\"\n\tfi\n\tprintf \"\\tattributes:\\n\"\n\tfor _a in $_POT_RW_ATTRIBUTES $_POT_RO_ATTRIBUTES ; do\n\t\t_value=$( _get_conf_var \"$_pname\" \"pot.attr.$_a\")\n\t\tprintf \"\\t\\t%s: %s\\n\" \"$_a\" \"${_value:-\"NO\"}\"\n\tdone\n\tprintf \"\\tjail attributes:\\n\"\n\tfor _a in $_POT_JAIL_RW_ATTRIBUTES ; do\n\t\t_value=$( _get_conf_var \"$_pname\" \"pot.attr.$_a\")\n\t\tif [ -z \"$_value\" ]; then\n\t\t\teval _value=\"\\$_POT_DEFAULT_${_a}_D\"\n\t\tfi\n\t\tprintf \"\\t\\t%s: %s\\n\" \"$_a\" \"${_value:-\"NO\"}\"\n\tdone\n\tif _is_verbose ; then\n\t\t_cpu=\"$( _get_conf_var \"$_pname\" pot.rss.cpus)\"\n\t\t_mem=\"$( _get_conf_var \"$_pname\" pot.rss.memory)\"\n\t\tif [ -n \"${_cpu}${_mem}\" ]; then\n\t\t\tprintf \"\\tresource limits:\\n\"\n\t\t\tif [ -n \"${_cpu}\" ]; then\n\t\t\t\tprintf \"\\t\\tmax amount cpus: %s\\n\" \"$_cpu\"\n\t\t\tfi\n\t\t\tif [ -n \"${_mem}\" ]; then\n\t\t\t\tprintf \"\\t\\tmax amount memory: %s\\n\" \"$_mem\"\n\t\t\tfi\n\t\tfi\n\tfi\n\techo\n}\n\n# $1 pot name\n_info_pot_snapshots()\n{\n\tlocal _pname _snaps\n\t_pname=\"$1\"\n\tif _is_verbose ; then\n\t\t_snaps=\"$( _get_pot_snaps \"$_pname\" )\"\n\t\tfor _s in $_snaps ; do\n\t\t\techo \"$_s: -> \" \"$( date -r \"$_s\" )\"\n\t\tdone\n\telse\n\t\t_get_pot_snaps \"$_pname\"\n\tfi\n}\n\n# $1 bridge name\n_info_bridge()\n{\n\tlocal _bname\n\t_bname=\"$1\"\n\tif _is_potnet_available ; then\n\t\tpotnet show -b \"$_bname\"\n\telse\n\t\t_error \"potnet is needed to show bridge information\"\n\tfi\n}\n\npot-info()\n{\n\tlocal _pname _quiet _run _bname _env_output _snaps\n\t_pname=\"\"\n\t_quiet=\"NO\"\n\t_run=\"NO\"\n\t_env_output=\"NO\"\n\t_snaps=\"NO\"\n\tOPTIND=1\n\twhile getopts \"hvqp:rB:Es\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tinfo-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"quiet\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tB)\n\t\t\t_bname=\"$OPTARG\"\n\t\t\t;;\n\t\tr)\n\t\t\t_run=\"YES\"\n\t\t\t;;\n\t\tE)\n\t\t\t_env_output=\"YES\"\n\t\t\t;;\n\t\ts)\n\t\t\t_snaps=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tinfo-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ] && [ -z \"$_bname\" ]; then\n\t\t_error \"Option -p or -b are mandatory\"\n\t\tinfo-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_pname\" ] && [ -n \"$_bname\" ]; then\n\t\t_error \"Option -p and -b are mutually exclusive\"\n\t\tinfo-help\n\t\t${EXIT} 1\n\tfi\n\tif [ \"$_quiet\" = \"quiet\" ] && _is_verbose ; then\n\t\t_error \"Option -q and -v are mutually exclusive\"\n\t\tinfo-help\n\t\t${EXIT} 1\n\tfi\n\tif [ \"$_env_output\" = \"YES\" ] && [ -z \"$_pname\" ]; then\n\t\t_error \"Environment variable output available for pot only\"\n\t\tinfo-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$_bname\" ] && [ \"$_snaps\" = \"YES\" ]; then\n\t\t_info \"Bridges has no snapshots - -s ignored\"\n\t\t_snaps=\"NO\"\n\tfi\n\tif [ -n \"$_pname\" ]; then\n\t\tif ! _is_pot \"$_pname\" quiet ; then\n\t\t\t_qerror \"$_quiet\" \"$_pname is not a pot\"\n\t\t\tinfo-help\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif [ \"$_run\" = \"YES\" ]; then\n\t\t\tif _is_pot_running \"$_pname\" ; then\n\t\t\t\t${EXIT} 0\n\t\t\telse\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\tfi\n\t\tif [ \"$_quiet\" = \"quiet\" ]; then\n\t\t\t${EXIT} 0\n\t\tfi\n\t\tif [ \"$_snaps\" = \"YES\" ]; then\n\t\t\t_info_pot_snapshots \"$_pname\"\n\t\telif [ \"$_env_output\" = \"YES\" ]; then\n\t\t\t_info_pot_env \"$_pname\"\n\t\telse\n\t\t\t_info_pot \"$_pname\"\n\t\tfi\n\tfi\n\tif [ -n \"$_bname\" ]; then\n\t\tif ! _is_bridge \"$_bname\" quiet ; then\n\t\t\t_qerror \"$_quiet\" \"$_bname is not a bridge\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif [ \"$_quiet\" = \"quiet\" ]; then\n\t\t\t${EXIT} 0\n\t\tfi\n\t\t_info_bridge \"$_bname\"\n\tfi\n}\n"
  },
  {
    "path": "share/pot/init.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\n# TODO\n# check the return code of all commands\n\ninit-help()\n{\n\tcat <<-\"EOH\"\n\tpot init [-hmsv] [-p pf_file]\n\t  -h print this help\n\t  -m minimal modifications (alias for `-sp ''`)\n\t  -p pf_file : write pot anchors to this file (empty to skip),\n\t               defaults to result of `sysrc -n pf_rules`\n\t  -f pf_file : alias for -p pf_file (deprecated)\n\t  -s do not alter syslogd config\n\t  -v verbose\n\tEOH\n}\n\npot-init()\n{\n\tlocal _pf_file _dataset _skip_alter_syslog\n\t_pf_file=\"$(sysrc -n pf_rules)\"\n\t_skip_alter_syslog=\n\tOPTIND=1\n\twhile getopts \"hmsvf:p:\" _o ; do\n\t\tcase \"$_o\" in\n\t\tf|p)\n\t\t\t_pf_file=\"$OPTARG\"\n\t\t\t;;\n\t\th)\n\t\t\tinit-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tm)\n\t\t\t_pf_file=\"\"\n\t\t\t_skip_alter_syslog=\"YES\"\n\t\t\t;;\n\t\ts)\n\t\t\t_skip_alter_syslog=\"YES\"\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\t*)\n\t\t\tinit-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _conf_check \"init\" ; then\n\t\t_qerror \"init\" \"Configuration not valid, please verify it\"\n\t\treturn 1 # false\n\tfi\n\n\tif ! _zfs_exist \"${POT_ZFS_ROOT}\" \"${POT_FS_ROOT}\" ; then\n\t\tif _zfs_dataset_valid \"${POT_ZFS_ROOT}\" ; then\n\t\t\t_error \"${POT_ZFS_ROOT} is an invalid POT root\"\n\t\t\treturn 1 # false\n\t\tfi\n\t\t# create the pot root\n\t\t_debug \"creating ${POT_ZFS_ROOT} file system (mountpoint ${POT_FS_ROOT}\"\n\t\tzfs create -o mountpoint=\"${POT_FS_ROOT}\" -o canmount=off -o compression=lz4 -o atime=off \"${POT_ZFS_ROOT}\"\n\telse\n\t\t_info \"${POT_ZFS_ROOT} already present\"\n\tfi\n\n\t# create the root directory\n\tif [ ! -d \"${POT_FS_ROOT}\" ]; then\n\t\tmkdir -p \"${POT_FS_ROOT}\"\n\t\tif [ ! -d \"${POT_FS_ROOT}\" ]; then\n\t\t\t_error \"Not able to create the dir ${POT_FS_ROOT}\"\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\n\t# set root directory permissions and ownership\n\tchmod 750 \"${POT_FS_ROOT}\" || ${EXIT} 1\n\tchown root:\"${POT_GROUP:-pot}\" \"${POT_FS_ROOT}\" || ${EXIT} 1\n\n\t# create mandatory datasets\n\tfor _dataset in bases jails fscomp; do\n\t\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/$_dataset\" ; then\n\t\t\t_debug \"creating ${POT_ZFS_ROOT}/$_dataset\"\n\t\t\tzfs create \"${POT_ZFS_ROOT}/$_dataset\" || ${EXIT} 1\n\t\tfi\n\t\tif ! _zfs_mounted \"${POT_ZFS_ROOT}/$_dataset\"; then\n\t\t\t_debug \"mounting ${POT_ZFS_ROOT}/$_dataset\"\n\t\t\tzfs mount \"${POT_ZFS_ROOT}/$_dataset\" || ${EXIT} 1\n\t\tfi\n\tdone\n\tif ! _zfs_exist \"${POT_ZFS_ROOT}/cache\" \"${POT_CACHE}\" ; then\n\t\t_debug \"creating ${POT_ZFS_ROOT}/cache mounted as ${POT_CACHE}\"\n\t\tif ! _zfs_dataset_valid \"${POT_ZFS_ROOT}/cache\" ; then\n\t\t\tzfs create -o mountpoint=\"${POT_CACHE}\" -o compression=off \"${POT_ZFS_ROOT}/cache\"\n\t\tfi\n\tfi\n\t# create the bridges folder\n\tmkdir -p \"${POT_FS_ROOT}/bridges\"\n\tif [ \"$_skip_alter_syslog\" != \"YES\" ]; then\n\t\t# create mandatory directories for logs\n\t\tmkdir -p /usr/local/etc/syslog.d\n\t\tmkdir -p /usr/local/etc/newsyslog.conf.d\n\t\tmkdir -p /var/log/pot\n\tfi\n\n\tif ! _is_pot_tmp_dir ; then\n\t\t_error \"The POT_TMP directory has not been created - aborting\"\n\t\t${EXIT} 1\n\tfi\n\n\tif ! potnet config-check ; then\n\t\t_error \"The network configuration in the pot configuration file is not valid\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_valid_netif \"$POT_EXTIF\" ; then\n\t\t_error \"The network interface $POT_EXTIF seems not valid [POT_EXTIF]\"\n\t\t${EXIT} 1\n\tfi\n\tif [ -n \"$POT_EXTIF_ADDR\" ]; then\n\t\tif ! potnet ip4check --host \"$POT_EXTIF_ADDR\" ; then\n\t\t\t_error \"The value $POT_EXTIF_ADDR [POT_EXTIF_ADDR] is not a valid IPv4 address\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! _is_valid_extif_addr \"$POT_EXTIF\" \"$POT_EXTIF_ADDR\" ; then\n\t\t\t_error \"The IP address $POT_EXTIF_ADDR [POT_EXTIF_ADDR] is not available on the network interface $POT_EXTIF [POT_EXTIF]\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\n\tfor extra_netif in $POT_EXTRA_EXTIF ; do\n\t\tif ! _is_valid_netif \"$extra_netif\" ; then\n\t\t\t_error \"The network interface $extra_netif seems not valid [POT_EXTRA_EXTIF]\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tdone\n\n\tif [ \"$_skip_alter_syslog\" != \"YES\" ]; then\n\t\tif [ -w /etc/rc.conf ]; then\n\t\t\techo \"Creating a backup of your /etc/rc.conf\"\n\t\t\tcp -v /etc/rc.conf /etc/rc.conf.bkp-pot\n\t\tfi\n\t\t# add proper syslogd flags and restart it\n\t\tsysrc -q syslogd_flags=\"-b 127.0.0.1 -b $POT_GATEWAY -a $POT_NETWORK\"\n\t\t# service syslogd restart\n\tfi\n\n\t# Add pot anchors if needed\n\tif [ -n \"$_pf_file\" ]; then\n\t\tif [ -r \"$_pf_file\" ] && [ \"$(grep -c '^nat-anchor pot-nat$' \"$_pf_file\" )\" -eq 1 ] && [ \"$(grep -c '^rdr-anchor \"pot-rdr/\\*\"$' \"$_pf_file\" )\" -eq 1 ] ; then\n\t\t\t_debug \"pf already properly configured\"\n\t\telse\n\t\t\tif [ -w \"$_pf_file\" ]; then\n\t\t\t\techo \"Creating a backup of your $_pf_file\"\n\t\t\t\tcp -v \"$_pf_file\" \"$_pf_file\".bkp-pot\n\t\t\t\t# delete incomplete/broken ancory entries - just in case\n\t\t\t\tsed -i '' '/^nat-anchor pot-nat$/d' \"$_pf_file\"\n\t\t\t\tsed -i '' '/^rdr-anchor \"pot-rdr\\/\\*\"$/d' \"$_pf_file\"\n\t\t\telse\n\t\t\t\ttouch \"$_pf_file\"\n\t\t\tfi\n\t\t\techo \"auto-magically editing your $_pf_file\"\n\t\t\tprintf \"%s\\n\" 0a \"nat-anchor pot-nat\" \"rdr-anchor \\\"pot-rdr/*\\\"\" . x | ex \"$_pf_file\"\n\t\t\techo \"Please, check that your PF configuration file $_pf_file is still valid and reload it!\"\n\t\tfi\n\telse\n\t\t_debug \"pf configuration skipped\"\n\tfi\n}\n"
  },
  {
    "path": "share/pot/last-run-stats.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nlast-run-stats-help()\n{\n\tcat <<-\"EOH\"\n\tpot last-run-stats [-hv] [-p pname]\n\t  -h print this help\n\t  -v verbose\n\t  -p pname : pot name\n\tEOH\n}\n\npot-last-run-stats()\n{\n\tlocal _pname\n\t_pname=\"\"\n\tOPTIND=1\n\twhile getopts \"hvp:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tlast-run-stats-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tlast-run-stats-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tlast-run-stats-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_pname\"; then\n\t\t_error \"$_pname is not a pot\"\n\t\t${EXIT} 1\n\tfi\n\t_confdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\tcat \"$_confdir/.last_run_stats\" 2>/dev/null || echo \"{}\"\n}\n"
  },
  {
    "path": "share/pot/list.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nlist-help()\n{\n\tcat <<-\"EOH\"\n\tpot list [-hpbfFa] [-qv]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\t  -p list pots (default)\n\t  -b list bases instead of pots\n\t  -f list fs components instead of pots\n\t  -F list available flavours\n\t  -B list available bridges (network type)\n\t  -a list everything (incompatible with -q)\n\tEOH\n}\n\n# $1 pot name\n_ls_info_pot()\n{\n\tlocal _pname _cdir _lvl\n\t_pname=$1\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_lvl=$( _get_conf_var \"$_pname\" pot.level)\n\tprintf \"pot name : %s\\\\n\" \"$_pname\"\n\tprintf \"\\\\tnetwork : %s\\\\n\" \"$( _get_conf_var \"$_pname\" network_type)\"\n\tif [ \"$( _get_conf_var \"$_pname\" network_type)\" != \"inherit\" ]; then\n\t\tprintf \"\\\\tip : %s\\\\n\" \"$( _get_ip_var \"$_pname\" )\"\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tprintf \"\\\\tactive : true\\\\n\"\n\telse\n\t\tprintf \"\\\\tactive : false\\\\n\"\n\tfi\n\tif _is_verbose ; then\n\t\tprintf \"\\\\tbase : %s\\\\n\" \"$( _get_conf_var \"$_pname\" pot.base)\"\n\t\tprintf \"\\\\tlevel : %s\\\\n\" \"$_lvl\"\n\t\tif [ \"$_lvl\" -eq 2 ]; then\n\t\t\tprintf \"\\\\tbase pot : %s\\\\n\" \"$( _get_conf_var \"$_pname\" pot.potbase)\"\n\t\tfi\n\t\tprintf \"\\\\tdatasets:\\\\n\"\n\t\t_print_pot_fscomp \"$_cdir/fscomp.conf\"\n\t\tprintf \"\\\\tsnapshot:\\\\n\"\n\t\t_print_pot_snaps \"$_pname\"\n\tfi\n\techo\n}\n\n_ls_pots()\n{\n\tlocal _pots _q\n\t_q=$1\n\t_pots=$( _get_pot_list )\n\tif [ -z \"$_pots\" ]; then\n\t\tif [ \"$_q\" != \"quiet\" ]; then\n\t\t\techo \"No pot created yet...\"\n\t\tfi\n\t\treturn\n\tfi\n\tfor _p in $_pots; do\n\t\tif [ \"$_q\" = \"quiet\" ]; then\n\t\t\techo \"$_p\"\n\t\telse\n\t\t\t_ls_info_pot \"$_p\"\n\t\tfi\n\tdone\n}\n\n_ls_bases()\n{\n\tlocal _bdir _bases _q\n\t_q=$1\n\t_bdir=\"${POT_FS_ROOT}/bases/\"\n\t# shellcheck disable=SC2011\n\t_bases=$(  ls -d \"$_bdir\"/*/ 2> /dev/null | xargs -I {} basename {} | tr '\\n' ' ' )\n\tif [ \"$_q\" = \"quiet\" ]; then\n\t\tfor _b in $_bases; do\n\t\t\t echo \"$_b\"\n\t\tdone\n\telse\n\t\tfor _b in $_bases; do\n\t\t\t echo \"bases: $_b\"\n\t\tdone\n\tfi\n}\n\n_ls_fscomp()\n{\n\tlocal _fscomps _q\n\t_q=$1\n\t_fscomps=$( zfs list -d 1 -Ho name \"${POT_ZFS_ROOT}/fscomp\" | sed '1d' | xargs -I {} basename {} | tr '\\n' ' ' )\n\tif [ \"$_q\" = \"quiet\" ]; then\n\t\tfor _f in $_fscomps; do\n\t\t\t echo \"$_f\"\n\t\tdone\n\telse\n\t\tfor _f in $_fscomps; do\n\t\t\t echo \"fscomp: $_f\"\n\t\tdone\n\tfi\n}\n\n_ls_flavour()\n{\n\tlocal _flv1 _flv2 _flv _q\n\t_q=$1\n\t# shellcheck disable=SC2010\n\t_flv1=$( ls \"${_POT_FLAVOUR_DIR}\" | grep -v .sh$ | xargs basename )\n\t# shellcheck disable=SC2011\n\t_flv2=$( ls \"${_POT_FLAVOUR_DIR}\"/*.sh | xargs basename | sed 's/\\.sh//' )\n\t# shellcheck disable=SC2086\n\t_flv=$( printf \"%s\\\\n%s\\\\n\" $_flv1 $_flv2 | sort -u | tr '\\n' ' ' )\n\tif [ \"$_q\" = \"quiet\" ]; then\n\t\tfor _f in $_flv ; do\n\t\t\techo \"$_f\"\n\t\tdone\n\telse\n\t\tfor _f in $_flv ; do\n\t\t\techo \"flavour: $_f\"\n\t\tdone\n\tfi\n}\n\n_ls_bridges()\n{\n\tlocal _bridges _q\n\t_q=$1\n\t_bridges=$( _get_bridge_list )\n\tif [ \"$_q\" = \"quiet\" ]; then\n\t\tfor _B in $_bridges; do\n\t\t\t echo \"$_B\"\n\t\tdone\n\telse\n\t\tfor _B in $_bridges; do\n\t\t\t echo \"bridge: $_B\"\n\t\tdone\n\tfi\n}\n\npot-list()\n{\n\tlocal _obj _q\n\t_obj=\"pots\"\n\t_q=\n\tOPTIND=1\n\twhile getopts \"hvbfFapqB\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tlist-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_q=\"quiet\"\n\t\t\t;;\n\t\tp)\n\t\t\tif [ \"$_obj\" != \"pots\" ]; then\n\t\t\t\t_error \"Options -b -p -f -F -B -a are mutually exclusive\"\n\t\t\t\tlist-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_obj=\"ppots\"\n\t\t\t;;\n\t\tb)\n\t\t\tif [ \"$_obj\" != \"pots\" ]; then\n\t\t\t\t_error \"Options -b -p -f -F -B -a are mutually exclusive\"\n\t\t\t\tlist-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_obj=\"bases\"\n\t\t\t;;\n\t\tf)\n\t\t\tif [ \"$_obj\" != \"pots\" ]; then\n\t\t\t\t_error \"Options -b -p -f -F -B -a are mutually exclusive\"\n\t\t\t\tlist-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_obj=\"fscomp\"\n\t\t\t;;\n\t\tF)\n\t\t\tif [ \"$_obj\" != \"pots\" ]; then\n\t\t\t\t_error \"Options -b -p -f -F -B -a are mutually exclusive\"\n\t\t\t\tlist-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_obj=\"flavour\"\n\t\t\t;;\n\t\tB)\n\t\t\tif [ \"$_obj\" != \"pots\" ]; then\n\t\t\t\t_error \"Options -b -p -f -F -B -a are mutually exclusive\"\n\t\t\t\tlist-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_obj=\"bridges\"\n\t\t\t;;\n\n\t\ta)\n\t\t\tif [ \"$_obj\" != \"pots\" ]; then\n\t\t\t\t_error \"Options -b -p -f -F -B -a are mutually exclusive\"\n\t\t\t\tlist-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_obj=\"all\"\n\t\t\t;;\n\t\t*)\n\t\t\tlist-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ \"$_obj\" = all ] && [ \"$_q\" = \"quiet\" ]; then\n\t\t_error \"Options -a and -q are incompatible\"\n\t\tlist-help\n\t\t${EXIT} 1\n\tfi\n\tcase $_obj in\n\t\t\"pots\"|\"ppots\")\n\t\t\t_ls_pots \"$_q\"\n\t\t\t;;\n\t\t\"bases\")\n\t\t\t_ls_bases \"$_q\"\n\t\t\t;;\n\t\t\"fscomp\")\n\t\t\t_ls_fscomp \"$_q\"\n\t\t\t;;\n\t\t\"flavour\")\n\t\t\t_ls_flavour \"$_q\"\n\t\t\t;;\n\t\t\"bridges\")\n\t\t\t_ls_bridges \"$_q\"\n\t\t\t;;\n\t\t\"all\")\n\t\t\t_ls_bases\n\t\t\t_ls_pots\n\t\t\t_ls_fscomp\n\t\t\t_ls_flavour\n\t\t\t_ls_bridges\n\t\t\t;;\n\tesac\n}\n"
  },
  {
    "path": "share/pot/mount-in.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nmount-in-help()\n{\n\tcat <<-\"EOH\"\n\tpot mount-in [-hvwr] -p pot -m mnt -f fscomp|-d dir|-z dataset\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -f fscomp : a fs component to be mounted\n\t  -z zfs dataset : a ZFS dataset to be mounted\n\t  -d dir : a directory on the host to be mounted,\n\t           absolute pathname\n\t  -m mnt : the mount point inside of the pot\n\t  -w : change the ZFS mount point instead of using nullfs,\n\t       potentially DANGEROUS and only usable with -z and -f\n\t  -r : mount-in read-only\n\tEOH\n}\n\n# $1 pot\n# $2 mount point\n_is_mountpoint_used()\n{\n\tlocal _pname _mnt_p _proot\n\t_pname=\"$1\"\n\t_mnt_p=\"${2#/}\"\n\t_conf=$POT_FS_ROOT/jails/$_pname/conf/fscomp.conf\n\t_proot=$POT_FS_ROOT/jails/$_pname/m\n\tif grep -q \" $_proot/$_mnt_p$\" \"$_conf\" ||\n\t\tgrep -q \" $_proot/$_mnt_p \" \"$_conf\" ; then\n\t\t# mount point already used\n\t\treturn 0 # true\n\tfi\n\tif grep -q \"$_proot/$_mnt_p \" \"$_conf\" ; then\n\t\t# mountpoint used as source directory ?? wtf\n\t\t_error \"The mountpoint is already used as source directory mount-in\"\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false, mountpoint not used\n}\n\n# $1 pot\n# $2 mount point\n_mountpoint_validation()\n{\n\tlocal _pname _mnt_p _mpdir _mounted _real_mnt\n\t_pname=\"$1\"\n\t_mnt_p=\"$2\"\n\t_mpdir=$POT_FS_ROOT/jails/$_pname/m\n\t_mounted=false # false\n\tif _is_mountpoint_used \"$_pname\" \"$_mnt_p\" ; then\n\t\t_error \"The mount point $_mnt_p is already in use\"\n\t\treturn 1 # false\n\tfi\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\t_mounted=true # true\n\t\tif ! _pot_mount \"$_pname\" >/dev/null ; then\n\t\t\t_error \"Pot $_pname failed to mount\"\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\t# if the mountpoint doesn't exist, make it\n\tif [ ! -d \"$_mpdir/$_mnt_p\" ]; then\n\t\tif ! mkdir -p \"$_mpdir/$_mnt_p\" ; then\n\t\t\tif eval $_mounted ; then\n\t\t\t\t_pot_umount \"$_pname\" >/dev/null\n\t\t\tfi\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\t_real_mnt=$( chroot \"$_mpdir\" /bin/realpath \"$_mnt_p\")\n\tif eval $_mounted ; then\n\t\t_pot_umount \"$_pname\" >/dev/null\n\tfi\n\techo \"$_real_mnt\"\n\treturn 0 # true\n}\n\n_directory_validation()\n{\n\tlocal _pname _dir  _proot _conf\n\t_pname=\"$1\"\n\t_dir=\"$2\"\n\t_proot=$POT_FS_ROOT/jails/$_pname\n\t_conf=$POT_FS_ROOT/jails/$_pname/conf/fscomp.conf\n\tif [ \"$_dir\" != \"${_dir%\"$_proot\"}\" ]; then\n\t\t# dir is inside the pot\n\t\treturn 1 # false\n\tfi\n\tif grep -q \"$_dir \" \"$_conf\" ; then\n\t\t# the directory is already used\n\t\treturn 1 # false\n\tfi\n\treturn 0 # true\n\n}\n\n# $1 zfs dataset\n# $2 pot\n# $3 mount point\n# $4 mount option (zfs-remount, ro)\n_mount_dataset()\n{\n\tlocal _dset _pname _mnt_p _pdir _opt\n\t_dset=\"$1\"\n\t_pname=\"$2\"\n\t# Removing the trailing /\n\t_mnt_p=\"${3#/}\"\n\t_opt=\"${4}\"\n\t_pdir=$POT_FS_ROOT/jails/$_pname\n\t_debug \"mount zfs dataset:$_dset mnt_p:$_pdir/m/$_mnt_p opt:$_opt\"\n\tif [ -z \"$_opt\" ]; then\n\t\t${ECHO} \"$_dset $_pdir/m/$_mnt_p\" >> \"$_pdir/conf/fscomp.conf\"\n\telse\n\t\t${ECHO} \"$_dset $_pdir/m/$_mnt_p $_opt\" >> \"$_pdir/conf/fscomp.conf\"\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif [ \"$_opt\" = \"zfs-remount\" ]; then\n\t\t\tzfs set mountpoint=\"$_pdir/m/$_mnt_p\" \"$_dset\"\n\t\telse\n\t\t\t_node=$( _get_zfs_mountpoint \"$_dset\" )\n\t\t\tif ! mount_nullfs -o \"${_opt:-rw}\" \"$_node\" \"$_pdir/m/$_mnt_p\" ; then\n\t\t\t\t_error \"Error mounting $_node on $_pname\"\n\t\t\telse\n\t\t\t\t_debug \"Mounted $_node on $_pname\"\n\t\t\tfi\n\t\tfi\n\tfi\n}\n\n# $1 directory\n# $2 pot\n# $3 mount point\n# $4 mount option (ro)\n_mount_dir()\n{\n\tlocal _dir _pname _mnt_p _pdir _opt\n\t_dir=\"$1\"\n\t_pname=\"$2\"\n\t# Removing the trailing /\n\t_mnt_p=\"${3#/}\"\n\t_opt=\"${4}\"\n\t_pdir=$POT_FS_ROOT/jails/$_pname\n\t_debug \"add directory:$_dir mnt_p:/$_mnt_p opt:$_opt\"\n\tif [ -z \"$_opt\" ]; then\n\t\t${ECHO} \"$_dir /$_mnt_p\" >> \"$_pdir/conf/fscomp.conf\"\n\telse\n\t\t${ECHO} \"$_dir /$_mnt_p $_opt\" >> \"$_pdir/conf/fscomp.conf\"\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif ! mount_nullfs -o \"${_opt:-rw}\" \"$_dir\" \"$_pdir/m/$_mnt_p\" ; then\n\t\t\t_error \"Error mounting $_dir on $_pname\"\n\t\telse\n\t\t\t_debug \"Mounted $_dir on $_pname\"\n\t\tfi\n\tfi\n}\n\npot-mount-in()\n{\n\tlocal _pname _fscomp _mnt_p _remount _readonly _opt _dir _real_mnt_p\n\tOPTIND=1\n\t_pname=\n\t_mnt_p=\n\t_remount=\"NO\"\n\t_readonly=\"NO\"\n\t_opt=\n\t_dir=\n\t_fscomp=\n\t_dset=\n\tlogger -t pot -p local0.debug -- \"mount-in: $*\"\n\twhile getopts \"hvf:d:z:p:m:wr\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tmount-in-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tf)\n\t\t\t_fscomp=\"$OPTARG\"\n\t\t\t;;\n\t\td)\n\t\t\t_dir=\"${OPTARG%/}\"\n\t\t\t;;\n\t\tz)\n\t\t\t_dset=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tm)\n\t\t\t_mnt_p=\"$OPTARG\"\n\t\t\t;;\n\t\tw)\n\t\t\t_remount=\"YES\"\n\t\t\t;;\n\t\tr)\n\t\t\t_readonly=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tmount-in-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_fscomp\" ] && [ -z \"$_dir\" ] && [ -z \"$_dset\" ] ; then\n\t\t_error \"One of -f|-d|-z option has to be used\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif [ -n \"$_fscomp\" ] && [ -n \"$_dir\" ]; then\n\t\t_error \"-f and -d options are mutually exclusive\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif [ -n \"$_fscomp\" ] && [ -n \"$_dset\" ]; then\n\t\t_error \"-f and -z options are mutually exclusive\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif [ -n \"$_dir\" ] && [ -n \"$_dset\" ]; then\n\t\t_error \"-d and -z options are mutually exclusive\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_mnt_p\" ]; then\n\t\t_error \"A mount point is mandatory\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif _contains_spaces \"$_mnt_p\" ; then\n\t\t_error \"The mountpoint cannot contain spaces\"\n\t\treturn 1\n\tfi\n\tif ! _is_absolute_path \"$_mnt_p\" ; then\n\t\t_error \"The mount point has to be an absolute pathname\"\n\t\treturn 1\n\tfi\n\tif [ \"${_mnt_p}\" = \"/\" ]; then\n\t\t_error \"/ is not a valid mount point\"\n\t\treturn 1\n\tfi\n\n\tif [ \"$_remount\" = \"YES\" ]; then\n\t\tif [ -n \"$_dir\" ]; then\n\t\t\t_error \"Remount cannot be used with directories, but with fscomp only\"\n\t\t\tmount-in-help\n\t\t\treturn 1\n\t\tfi\n\t\t_opt=\"zfs-remount\"\n\t\t# TODO: investigate\n\t\tif [ \"$_readonly\" = \"YES\" ]; then\n\t\t\t_info \"Readonly and remount are mutually exclusive: readonly considered, remount ignored\"\n\t\t\t_remount=\"NO\"\n\t\t\t_opt=\"ro\"\n\t\tfi\n\telse\n\t\tif [ \"$_readonly\" = \"YES\" ]; then\n\t\t\t_opt=\"ro\"\n\t\tfi\n\tfi\n\tif [ -n \"$_fscomp\" ]; then\n\t\tif ! _is_fscomp \"$_fscomp\" ; then\n\t\t\t_error \"fscomp $_fscomp is not valid\"\n\t\t\tmount-in-help\n\t\t\treturn 1\n\t\tfi\n\tfi\n\tif [ -n \"$_dset\" ]; then\n\t\tif ! _zfs_dataset_valid \"$_dset\" ; then\n\t\t\t_error \"dataset $_dset is not valid\"\n\t\t\tmount-in-help\n\t\t\treturn 1\n\t\tfi\n\tfi\n\t# TODO: check that the directory doesn't conflict with anything already mounted\n\tif [ -n \"$_dir\" ]; then\n\t\tif [ ! -d \"$_dir\" ]; then\n\t\t\t_error \"$_dir is not a directory\"\n\t\t\tmount-in-help\n\t\t\treturn 1\n\t\tfi\n\t\tif ! _is_absolute_path \"$_dir\" ; then\n\t\t\tif ! _dir=\"$(realpath -q \"$_dir\")\" > /dev/null ; then\n\t\t\t\t_error \"Not able to convert $_dir as an absolute pathname\"\n\t\t\t\tmount-in-help\n\t\t\t\treturn 1\n\t\t\tfi\n\t\tfi\n\t\tif ! _directory_validation \"$_pname\" \"$_dir\" ; then\n\t\t\t_error \"Directory $_dir not valid, already used or already part of the pot\"\n\t\t\treturn 1\n\t\tfi\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tmount-in-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif ! _real_mnt_p=\"$(_mountpoint_validation \"$_pname\" \"$_mnt_p\" )\" ; then\n\t\techo \"$_real_mnt_p\"\n\t\t_error \"The mountpoint is not valid!\"\n\t\treturn 1\n\tfi\n\tif [ -n \"$_dir\" ]; then\n\t\t_mount_dir \"$_dir\" \"$_pname\" \"$_real_mnt_p\" $_opt\n\t\treturn $?\n\tfi\n\tif [ -n \"$_dset\" ]; then\n\t\t_mount_dataset \"$_dset\" \"$_pname\" \"$_real_mnt_p\" $_opt\n\t\treturn $?\n\tfi\n\tif [ -n \"$_fscomp\" ]; then\n\t\t_mount_dataset \"$POT_ZFS_ROOT/fscomp/$_fscomp\" \"$_pname\" \"$_real_mnt_p\" $_opt\n\t\treturn $?\n\tfi\n}\n"
  },
  {
    "path": "share/pot/mount-out.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nmount-out-help()\n{\n\tcat <<-\"EOH\"\n\tpot mount-out [-hvwr] -p pot -m mnt\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -m mnt : the mount point inside the pot\n\tEOH\n}\n\n# $1 pot\n# $2 mount point\n_is_mountpoint_used()\n{\n\tlocal _pname _mnt_p _proot\n\t_pname=\"$1\"\n\t_mnt_p=\"${2}\"\n\t_conf=$POT_FS_ROOT/jails/$_pname/conf/fscomp.conf\n\t_proot=$POT_FS_ROOT/jails/$_pname/m\n\t## spaces in this sequences of grep have been introduced to detect exact matches only\n\t## a pattern like /mnt/test would match /mnt/test and /mnt/test2\n\t## with those spaces we try be more precise in detecting the exact match\n\tif grep -q \" $_mnt_p$\" \"$_conf\" ||\n\t\tgrep -q \" $_mnt_p \" \"$_conf\" ; then\n\t\t# mount point already used\n\t\treturn 0 # true\n\tfi\n\tif grep -q \"$_proot/$_mnt_p \" \"$_conf\" ; then\n\t\t# mountpoint used as source directory ?? wtf\n\t\t_error \"The mountpoint is already used as source directory mount-out\"\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false, mountpoint not used\n}\n\n# $1 pot\n# $2 mount point\n_mountpoint_validation()\n{\n\tlocal _pname _mnt_p _mpdir _mounted _real_mnt\n\t_pname=\"$1\"\n\t_mnt_p=\"$2\"\n\t_mpdir=$POT_FS_ROOT/jails/$_pname/m\n\t_mounted=false # false\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\t_mounted=true # true\n\t\tif ! _pot_mount \"$_pname\" >/dev/null ; then\n\t\t\t_error \"Pot $_pname failed to mount\"\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\t_real_mnt=$( chroot \"$_mpdir\" /bin/realpath \"$_mnt_p\")\n\tif eval $_mounted ; then\n\t\t_pot_umount \"$_pname\" >/dev/null\n\tfi\n\tif ! _is_mountpoint_used \"$_pname\" \"$_real_mnt\" ; then\n\t\t_error \"The mount point $_mnt_p is not in use\"\n\t\treturn 1 # false\n\tfi\n\techo \"$_real_mnt\"\n\treturn 0 # true\n}\n\n# $1 pot\n# $2 mount point\n_umount_mnt_p()\n{\n\tlocal _pname _mnt_p _pdir\n\t_pname=\"$1\"\n\t# Removing the trailing /\n\t_mnt_p=\"${2#/}\"\n\t_pdir=$POT_FS_ROOT/jails/$_pname\n\t# absolute pathname of the mount point with escape character\n\t_sed_string=\"$(echo \"$_pdir/m/$_mnt_p\" | sed 's#/#\\\\/#g')\"\n\t_debug \"umount_mnt_p: mnt_p:$_pdir/m/$_mnt_p\"\n\t${SED} -E -i '' \" $_sed_string$| $_sed_string /d\" \"$_pdir/conf/fscomp.conf\"\n\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif _umount \"$_pdir/m/$_mnt_p\" ; then\n\t\t\t_debug \"Umounted $_mnt_p on $_pname\"\n\t\telse\n\t\t\t_error \"Error umounting $_mnt_p on $_pname\"\n\t\tfi\n\tfi\n}\n\npot-mount-out()\n{\n\tlocal _pname _mnt_p _real_mnt_p\n\tOPTIND=1\n\t_pname=\n\t_mnt_p=\n\tlogger -t pot -p local0.debug -- \"mount-out: $*\"\n\twhile getopts \"hvp:m:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tmount-out-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tm)\n\t\t\t_mnt_p=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tmount-out-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tmount-out-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_mnt_p\" ]; then\n\t\t_error \"A mount point is mandatory\"\n\t\tmount-out-help\n\t\treturn 1\n\tfi\n\tif ! _is_absolute_path \"$_mnt_p\" ; then\n\t\t_error \"The mount point has to be an absolute pathname\"\n\t\treturn 1\n\tfi\n\tif [ \"${_mnt_p}\" = \"/\" ]; then\n\t\t_error \"/ is not a valid mount point\"\n\t\treturn 1\n\tfi\n\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tmount-out-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif ! _real_mnt_p=\"$(_mountpoint_validation \"$_pname\" \"$_mnt_p\" )\" ; then\n\t\techo \"$_real_mnt_p\"\n\t\t_error \"The mountpoint is not valid!\"\n\t\treturn 1\n\tfi\n\t_umount_mnt_p \"$_pname\" \"$_real_mnt_p\"\n\treturn $?\n}\n"
  },
  {
    "path": "share/pot/network.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n\n# tested\n_pot_bridge()\n{\n\t_pot_bridge_ipv4\n}\n\n_pot_bridge_ipv4()\n{\n\tlocal _bridges\n\t_bridges=$( ifconfig -g bridge )\n\tif [ -z \"$_bridges\" ]; then\n\t\treturn\n\tfi\n\tfor _b in $_bridges ; do\n\t\t_ip=$( ifconfig \"$_b\" inet | awk '/inet/ { print $2 }' )\n\t\tif [ \"$_ip\" = \"$POT_GATEWAY\" ]; then\n\t\t\techo \"$_b\"\n\t\t\treturn\n\t\tfi\n\tdone\n}\n\n_pot_bridge_ipv6()\n{\n\tlocal _bridges\n\t_bridges=$( ifconfig -g bridge )\n\tif [ -z \"$_bridges\" ]; then\n\t\treturn\n\tfi\n\tfor _b in $_bridges ; do\n\t\tif ifconfig \"$_b\" |grep -q \"member: $POT_EXTIF\" ; then\n\t\t\techo \"$_b\"\n\t\t\treturn\n\t\tfi\n\tdone\n}\n\n# $1 bridge name\n_private_bridge()\n{\n\tlocal _bridges _bridge _bridge_ip\n\t_bridge=\"$1\"\n\t_bridges=$( ifconfig -g bridge )\n\tif [ -z \"$_bridges\" ]; then\n\t\treturn\n\tfi\n\t_bridge_ip=\"$(_get_bridge_var \"$_bridge\" gateway)\"\n\tfor _b in $_bridges ; do\n\t\t_ip=$( ifconfig \"$_b\" inet | awk '/inet/ { print $2 }' )\n\t\tif [ \"$_ip\" = \"$_bridge_ip\" ]; then\n\t\t\techo \"$_b\"\n\t\t\treturn\n\t\tfi\n\tdone\n}\n\n_get_pot_rdr_anchor_name()\n{\n\tlocal _pname\n\t_pname=$1\n\tif [ \"${#_pname}\" -gt \"55\" ]; then\n\t\techo \"$_pname\" | awk '{ truncated = substr($1, length($1)-54); printf(\"%s\", truncated);}' | sed 's/^__*//'\n\telse\n\t\techo \"$_pname\"\n\tfi\n}\n\n_is_vnet_up()\n{\n\t_is_vnet_ipv4_up \"$1\"\n}\n\n# $1 bridge name (optional)\n_is_vnet_ipv4_up()\n{\n\tlocal _bridge\n\tif [ -z \"$1\" ]; then\n\t\t_bridge=$(_pot_bridge)\n\telse\n\t\t_bridge=\"$( _private_bridge \"$1\" )\"\n\tfi\n\tif [ -z \"$_bridge\" ]; then\n\t\treturn 1 # false\n\telif [ ! -c /dev/pf ]; then\n\t\treturn 1 # false\n\telif ! pfctl -s Anchors | grep -q '^[ \\t]*pot-nat$' ; then\n\t\treturn 1 # false\n\telif ! pfctl -s Anchors | grep -q '^[ \\t]*pot-rdr$' ; then\n\t\treturn 1 # false\n\telif [ -z \"$(pfctl -s nat -a pot-nat)\" ]; then\n\t\treturn 1 # false\n\telse\n\t\treturn 0 # true\n\tfi\n}\n\n_is_vnet_ipv6_up()\n{\n\tlocal _bridge\n\t_bridge=\"$(_pot_bridge_ipv6)\"\n\tif [ -z \"$_bridge\" ]; then\n\t\treturn 1 # false\n\tfi\n\treturn 0\n}\n\n# $1 the number to test\n_is_port_number()\n{\n\tlocal _port\n\t_port=$1\n\tif [ -z \"$_port\" ]; then\n\t\treturn 1\n\tfi\n\t# check if it's a number\n\tif [ -n \"$( echo \"$_port\" | sed 's/[0-9][0-9]*//' )\" ]; then\n\t\treturn 1\n\tfi\n\t# check if it's a 16 bit number\n\tif [ \"$_port\" -le 0 ] || [ \"$_port\" -gt 65535 ]; then\n\t\treturn 1 # false\n\tfi\n\treturn 0\n}\n\n# $1: the -e option argument\n_is_export_port_valid()\n{\n\tlocal _pot_port _host_port _arg\n\tif [ \"${1#tcp:}\" != \"${1}\" ]; then\n\t\t_arg=\"${1#tcp:}\"\n\telif [ \"${1#udp:}\" != \"${1}\" ]; then\n\t\t_arg=\"${1#udp:}\"\n\telse\n\t\t_arg=\"${1}\"\n\tfi\n\t_pot_port=\"$( echo \"${_arg}\" | cut -d':' -f 1)\"\n\tif [ \"$_arg\" = \"${_pot_port}\" ]; then\n\t\tif ! _is_port_number \"$_pot_port\" ; then\n\t\t\treturn 1 # false\n\t\tfi\n\telse\n\t\t_host_port=\"$( echo \"${_arg}\" | cut -d':' -f 2)\"\n\t\tif ! _is_port_number \"$_pot_port\" ; then\n\t\t\treturn 1 # false\n\t\tfi\n\t\tif ! _is_port_number \"$_host_port\" ; then\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n}\n\n# $1 name of the network interface\n_is_valid_netif()\n{\n\tlocal _netif\n\t_netif=\"$1\"\n\tif ifconfig \"$_netif\" > /dev/null 2> /dev/null ; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n_is_valid_extif_addr()\n{\n\tlocal _netif _ip\n\t_netif=\"$1\"\n\t_ip=\"$2\"\n\tifconfig \"$_netif\" | grep -F \"inet \" | grep -qF \" $_ip \"\n}\n\n# get the network stack defined in the global configuration\n_get_network_stack()\n{\n\tlocal _stack\n\t_stack=\"${POT_NETWORK_STACK:-ipv4}\"\n\tcase $_stack in\n\t\tipv4|ipv6|dual)\n\t\t\techo \"$_stack\"\n\t\t\t;;\n\t\t*)\n\t\t\techo ipv4\n\t\t\treturn 1\n\t\t\t;;\n\tesac\n}\n\n# get the network stack for the specific pot\n# $1 pot name\n_get_pot_network_stack()\n{\n\tlocal _stack _pname\n\t_pname=\"$1\"\n\t_stack=\"$( _get_conf_var \"$_pname\" pot.stack )\"\n\tif [ -z \"$_stack\" ]; then\n\t\t_get_network_stack\n\telse\n\t\techo \"$_stack\"\n\tfi\n}\n\n# $1 pot name\n# $2 ipaddr\n_get_alias_ipv4()\n{\n\tlocal _i _ip _nic _output\n\t_output=\n\tif [ \"$( _get_pot_network_stack \"$1\" )\" != \"ipv6\" ]; then\n\t\tfor _i in $2 ; do\n\t\t\tif echo \"$_i\" | grep -qF '|' ; then\n\t\t\t\t_nic=\"$( echo \"$_i\" | cut -f 1 -d '|' )\"\n\t\t\t\t_ip=\"$( echo \"$_i\" | cut -f 2 -d '|' )\"\n\t\t\telse\n\t\t\t\t_nic=\"$POT_EXTIF\"\n\t\t\t\t_ip=\"$_i\"\n\t\t\tfi\n\t\t\tif potnet ip4check -H \"$_ip\" 2> /dev/null ; then\n\t\t\t\tif [ -z \"$_output\" ]; then\n\t\t\t\t\t_output=\"$_nic|$_ip\"\n\t\t\t\telse\n\t\t\t\t\t_output=\"$_output,$_nic|$_ip\"\n\t\t\t\tfi\n\t\t\tfi\n\t\tdone\n\tfi\n\techo \"$_output\"\n}\n\n# $1 pot name\n# $2 ipaddr\n_get_alias_ipv6()\n{\n\tlocal _i _ip _nic _output\n\t_output=\n\tif [ \"$( _get_pot_network_stack \"$1\" )\" != \"ipv4\" ]; then\n\t\tfor _i in $2 ; do\n\t\t\tif echo \"$_i\" | grep -qF '|' ; then\n\t\t\t\t_nic=\"$( echo \"$_i\" | cut -f 1 -d '|' )\"\n\t\t\t\t_ip=\"$( echo \"$_i\" | cut -f 2 -d '|' )\"\n\t\t\telse\n\t\t\t\t_nic=\"$POT_EXTIF\"\n\t\t\t\t_ip=\"$_i\"\n\t\t\tfi\n\t\t\tif potnet ip6check -H \"$_ip\" 2> /dev/null ; then\n\t\t\t\tif [ -z \"$_output\" ]; then\n\t\t\t\t\t_output=\"$_nic|$_ip\"\n\t\t\t\telse\n\t\t\t\t\t_output=\"$_output,$_nic|$_ip\"\n\t\t\t\tfi\n\t\t\tfi\n\t\tdone\n\tfi\n\techo \"$_output\"\n}\n\n# $1 ipaddr\n# $2 network stack\n_validate_alias_ipaddr()\n{\n\tlocal _i _nic _ip _ipv4_empty _ipv6_empty _stack\n\t_stack=\"$2\"\n\t_ipv4_empty=\"YES\"\n\t_ipv6_empty=\"YES\"\n\tfor _i in $1 ; do\n\t\tif echo \"$_i\" | grep -qF '|' ; then\n\t\t\t_nic=\"$( echo \"$_i\" | cut -f 1 -d '|' )\"\n\t\t\t_ip=\"$( echo \"$_i\" | cut -f 2 -d '|' )\"\n\t\t\tif ! _is_valid_netif \"$_nic\" ; then\n\t\t\t\t_error \"$_nic is not a valid network interface\"\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\telse\n\t\t\t_ip=\"$_i\"\n\t\tfi\n\t\tif ! potnet ipcheck -H \"$_ip\" 2> /dev/null ; then\n\t\t\t_error \"$_ip is not a valid IP address\"\n\t\t\treturn 1 # false\n\t\tfi\n\t\tif potnet ip4check -H \"$_ip\" 2> /dev/null ; then\n\t\t\t_ipv4_empty=\"NO\"\n\t\tfi\n\t\tif potnet ip6check -H \"$_ip\" 2> /dev/null ; then\n\t\t\t_ipv6_empty=\"NO\"\n\t\tfi\n\tdone\n\tif [ \"$_stack\" = \"ipv4\" ] && [ \"$_ipv4_empty\" = \"YES\" ]; then\n\t\t_error \"Stack is ipv4 but not ipv4 address has been provided\"\n\t\treturn 1 # false\n\tfi\n\tif [ \"$_stack\" = \"ipv6\" ] && [ \"$_ipv6_empty\" = \"YES\" ]; then\n\t\t_error \"Stack is ipv6 but not ipv6 address has been provided\"\n\t\treturn 1 # false\n\tfi\n\treturn 0\n}\n\n# $1 network type\n# $2 ipaddr\n# $3 bridge-name (private-bridge only)\n# $4 network stack\n# if success, then print the ip addr (it could be empty)\n# otherwise it print the an error message\n_validate_network_param()\n{\n\tlocal _network_type _ipaddr _private_bridge\n\t_network_type=$1\n\t_ipaddr=$2\n\t_private_bridge=$3\n\t_network_stack=$4\n\tif [ -z \"$_network_stack\" ]; then\n\t\t_network_stack=\"$( _get_network_stack )\"\n\tfi\n\tcase \"$_network_type\" in\n\t\"inherit\")\n\t\t_ipaddr=\n\t\t;;\n\t\"alias\")\n\t\tif [ -z \"$_ipaddr\" ]; then\n\t\t\t_error \"option -i is mandatory with network type is alias\"\n\t\t\treturn 1\n\t\telif [ \"$_ipaddr\" = \"auto\" ]; then\n\t\t\t_error \"-i auto not usable with network type alias - a real IP address has to be provided\"\n\t\t\treturn 1\n\t\tfi\n\t\tif ! _validate_alias_ipaddr \"$_ipaddr\" \"$_network_stack\" ; then\n\t\t\t_error \"$_ipaddr is not a valid alias configuration\"\n\t\t\treturn 1\n\t\tfi\n\t\t;;\n\t\"public-bridge\")\n\t\tif ! _is_vnet_available ; then\n\t\t\t_error \"This kernel doesn't support VIMAGE! No vnet possible\"\n\t\t\treturn 1\n\t\tfi\n\t\tif [ \"$_ipaddr\" = \"auto\" ] || [ -z \"$_ipaddr\" ]; then\n\t\t\tif ! _is_potnet_available ; then\n\t\t\t   _error \"potnet is not available! It's needed by -i auto\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t_ipaddr=\"$(potnet next)\"\n\t\telse\n\t\t\tif ! potnet validate -H \"$_ipaddr\" 2> /dev/null ; then\n\t\t\t\t_error \"The $_ipaddr IP is not valid - run potnet validate -H $_ipaddr for more information\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\tfi\n\t\t;;\n\t\"private-bridge\")\n\t\tif ! _is_vnet_available ; then\n\t\t\t_error \"This kernel doesn't support VIMAGE! No vnet possible\"\n\t\t\treturn 1\n\t\tfi\n\t\tif [ \"$_network_stack\" = \"ipv6\" ]; then\n\t\t\t_error \"private-bridge network type is not supported on ipv6 stack only\"\n\t\t\treturn 1\n\t\tfi\n\t\tif [ -z \"$_private_bridge\" ]; then\n\t\t\t_error \"private-bridge network type requires -B option, to specify which private bridge to use\"\n\t\t\treturn 1\n\t\tfi\n\t\tif ! _is_bridge \"$_private_bridge\" ; then\n\t\t\t_error \"bridge $_private_bridge is not valid. Have you already created it?\"\n\t\t\treturn 1\n\t\tfi\n\t\tif [ \"$_ipaddr\" = \"auto\" ] || [ -z \"$_ipaddr\" ]; then\n\t\t\tif ! _is_potnet_available ; then\n\t\t\t   _error \"potnet is not available! It's needed by -i auto\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t_ipaddr=\"$(potnet next -b \"$_private_bridge\")\"\n\t\telif ! potnet validate -H \"$_ipaddr\" -b \"$_private_bridge\"  2> /dev/null ; then\n\t\t\t_error \"The $_ipaddr IP is not valid for bridge $_private_bridge - run potnet validate -H $_ipaddr -b $_private_bridge for more information\"\n\t\t\treturn 1\n\t\tfi\n\t\t;;\n\t*)\n\t\t_error \"Network type $_network_type not recognized\"\n\t\treturn 1\n\t\t;;\n\tesac\n\techo \"$_ipaddr\"\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/prepare.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nprepare-help()\n{\n\tcat <<-\"EOH\"\n\tpot prepare [-hvS] -p pot -U URL -t tag -a aID -n potname -c cmd\n\t            [-e [proto:]port[:pot_port]] [-N network-type]\n\t            [-i ipaddr] [-B bridge-name] [-C pubkey]\n\t  -h print this help\n\t  -h verbose\n\t  -p pot : the pot image\n\t  -U URL : the base URL where to find the image file\n\t  -t tag : the tag of the pot\n\t  -a aID : the allocation ID\n\t  -n potname : the new potname (used instead of pot_tag)\n\t  -c cmd : the command line to start the container\n\t  -N network-type : new network type of the imported pot\n\t  -i ipaddr : an ip address or the keyword auto (if applicable)\n\t  -e [proto:]port[:pot_port] : port(s) to export\n\t         This option can be repeated to export multiple ports.\n\t         See `pot help export-ports` for details.\n\t  -B bridge-name : the name of the private bridge to be used\n\t  -S network-stack : the network stack (ipv4, ipv6 or dual)\n\t  -d dns : change pot dns resolver configuration, one of\n\t           inherit       - inherit from jailhost\n\t           pot           - the pot configured in POT_DNS_NAME\n\t           custom:<file> - copy <file> into pot configuration\n\t           off           - leave resolver config unaltered\n\t  -s : start the newly generated pot immediately\n\t  -C pubkey : verify with public key 'pubkey' using signify(1)\n\t              on pot import\n\tEOH\n}\n\npot-prepare()\n{\n\tlocal _pname _o _URL _tag _tpname _cmd _ports _allocation_tag _new_pname\n\tlocal _auto_start _network_type _ipaddr _ipaddr_list _bridge_name _dns\n\tlocal _sign_pubkey\n\t_pname=\n\t_ports=\n\t_network_type=\n\t_ipaddr=\n\t_ipaddr_list=\n\t_auto_start=\"NO\"\n\t_bridge_name=\n\t_cmd=\n\t_dns=\n\t_sign_pubkey=\"$POT_DEFAULT_SIGNATURE_PUBKEY\"\n\tOPTIND=1\n\twhile getopts \"hvp:U:t:c:e:a:n:sN:i:B:S:d:C:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tprepare-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tU)\n\t\t\t_URL=\"$OPTARG\"\n\t\t\t;;\n\t\tt)\n\t\t\t_tag=\"$OPTARG\"\n\t\t\t;;\n\t\tc)\n\t\t\t_cmd=\"$OPTARG\"\n\t\t\t;;\n\t\ta)\n\t\t\t_allocation_tag=\"$OPTARG\"\n\t\t\t;;\n\t\tn)\n\t\t\t_tpname=\"$OPTARG\"\n\t\t\t;;\n\t\te)\n\t\t\tif ! _is_export_port_valid \"$OPTARG\" ; then\n\t\t\t\t_error \"$OPTARG is not a valid port number\"\n\t\t\t\tprepare-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\tif [ -z \"$_ports\" ]; then\n\t\t\t\t_ports=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_ports=\"$_ports $OPTARG\"\n\t\t\tfi\n\t\t\t;;\n\t\ts)\n\t\t\t_auto_start=\"YES\"\n\t\t\t;;\n\t\tN)\n\t\t\tif [ \"$OPTARG\" = \"host\" ]; then\n\t\t\t\t_network_type=\"inherit\"\n\t\t\telse\n\t\t\t\t_network_type=\"$OPTARG\"\n\t\t\tfi\n\t\t\t# shellcheck disable=SC2086\n\t\t\tif ! _is_in_list \"$_network_type\" $_POT_NETWORK_TYPES ; then\n\t\t\t\t_error \"Network type $_network_type not recognized\"\n\t\t\t\tprepare-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\tB)\n\t\t\t_bridge_name=\"$OPTARG\"\n\t\t\t;;\n\t\ti)\n\t\t\t_ipaddr_list=\"$_ipaddr_list $OPTARG\"\n\t\t\t;;\n\t\tS)\n\t\t\tif ! _is_in_list \"$OPTARG\" \"ipv4\" \"ipv6\" \"dual\" ; then\n\t\t\t\t_error \"Network stack $OPTARG not valid\"\n\t\t\t\tcreate-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t_network_stack=\"$OPTARG\"\n\t\t\t;;\n\t\td)\n\t\t\tcase $OPTARG in\n\t\t\t\tinherit|pot|off)\n\t\t\t\t\t_dns=$OPTARG\n\t\t\t\t\t;;\n\t\t\t\tcustom:*)\n\t\t\t\t\tif [ -r \"${OPTARG##custom:}\" ]; then\n\t\t\t\t\t\t_dns=$OPTARG\n\t\t\t\t\telse\n\t\t\t\t\t\t_error \"The file ${OPTARG##custom:} is not valid or readable\"\n\t\t\t\t\t\t${EXIT} 1\n\t\t\t\t\tfi\n\t\t\t\t\t;;\n\t\t\t\t*)\n\t\t\t\t\t_error \"'${OPTART}' is not a valid dns option\"\n\t\t\t\t\tprepare-help\n\t\t\t\t\t${EXIT} 1\n\t\t\tesac\n\t\t\t;;\n\t\tC)\n\t\t\t_sign_pubkey=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tprepare-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tprepare-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_tag\" ]; then\n\t\t_error \"A tag is mandatory\"\n\t\tprepare-help\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_allocation_tag\" ]; then\n\t\t_error \"An allocation id is mandatory\"\n\t\tprepare-help\n\t\t${EXIT} 1\n\tfi\n\tif [ \"$_network_type\" = \"private-bridge\" ] && [ -z \"$_bridge_name\" ]; then\n\t\t_error \"A bridge name has to be provided if private-bridge is selected as network-type\"\n\t\tprepare-help\n\t\t${EXIT} 1\n\tfi\n\t_imported_pname=\"${_pname}_${_tag}\"\n\t_imported_pname=\"$(echo \"$_imported_pname\" | tr '.' '_')\"\n\tif [ -z \"$_tpname\" ]; then\n\t\t_tpname=\"${_imported_pname}\"\n\tfi\n\t_new_pname=\"${_tpname}_${_allocation_tag}\"\n\t_new_pname=\"$(echo \"$_new_pname\" | tr '.' '_')\"\n\tif _is_pot \"$_new_pname\" quiet ; then\n\t\t_error \"A pot with name $_new_pname already exists\"\n\t\tprepare-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_imported_pname\" quiet ; then\n\t\tif ! pot-cmd import -U \"$_URL\" -t \"$_tag\" -p \"$_pname\" \\\n\t\t    -C \"$_sign_pubkey\"; then\n\t\t\t_error \"pot import failed\"\n\t\t\tpot-cmd stop \"$_imported_pname\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! _is_pot \"$_imported_pname\" quiet ; then\n\t\t\t_error \"imported pot is weirdly not found after import - cannot proceed\"\n\t\t\tpot-cmd destroy -p \"$_imported_pname\"\n\t\t\t${EXIT} 1\n\t\tfi\n\telse\n\t\t_debug \"pot $_imported_pname already imported - reusing it\"\n\tfi\n\t_clone_network_opt=\n\tif [ -n \"$_network_type\" ]; then\n\t\t_clone_network_opt=\"-N $_network_type\"\n\tfi\n\tif [ \"$_network_type\" = \"private-bridge\" ]; then\n\t\t_clone_network_opt=\"$_clone_network_opt -B $_bridge_name\"\n\tfi\n\tfor _ipaddr in $_ipaddr_list; do\n\t\t_clone_network_opt=\"$_clone_network_opt -i $_ipaddr\"\n\tdone\n\tif [ -n \"$_network_stack\" ]; then\n\t\t_clone_network_opt=\"$_clone_network_opt -S $_network_stack\"\n\tfi\n\tif [ -n \"$_dns\" ]; then\n\t\t_clone_network_opt=\"$_clone_network_opt -d $_dns\"\n\tfi\n\t# shellcheck disable=SC2086\n\tif ! pot-cmd clone -P \"${_imported_pname}\" -p \"${_new_pname}\" $_clone_network_opt ; then\n\t\t_error \"Not able to clone imported pot as $_new_pname\"\n\tfi\n\tif [ -n \"$_cmd\" ]; then\n\t\tif ! pot-cmd set-cmd -p \"$_new_pname\" -c \"$_cmd\" ; then\n\t\t\t_error \"Couldn't set the command $_cmd ot the pot - ignoring\"\n\t\tfi\n\tfi\n\tif ! pot-cmd set-attribute -A persistent -V OFF -p \"$_new_pname\" ; then\n\t\t_error \"Couldn't disable the persistent attribute - ignoring\"\n\tfi\n\tif ! pot-cmd set-attribute -A no-rc-script -V ON -p \"$_new_pname\" ; then\n\t\t_error \"Couldn't enable the no-rc-script attribute - ignoring\"\n\tfi\n\tif ! pot-cmd set-attribute -A prunable -V ON -p \"$_new_pname\" ; then\n\t\t_error \"Couldn't enable the no-rc-script attribute - ignoring\"\n\tfi\n\tif ! pot-cmd set-attribute -A localhost-tunnel -V YES -p \"$_new_pname\" ; then\n\t\t_error \"Couldn't enable the localhost-tunnel attribute - ignoring\"\n\tfi\n\tif ! pot-cmd set-attribute -A no-etc-hosts -V YES -p \"$_new_pname\" ; then\n\t\t_error \"Couldn't disable the enrichment of /etc/hosts - ignoring\"\n\tfi\n\tif ! pot-cmd set-attribute -A no-tmpfs -V YES -p \"$_new_pname\" ; then\n\t\t_error \"Couldn't disable tmpfs for /tmp - ignoring\"\n\tfi\n\n\tif [ -n \"$_ports\" ]; then\n\t\tfor _p in $_ports ; do\n\t\t\t_port_args=\"-e $_p $_port_args\"\n\t\tdone\n\t\t# shellcheck disable=SC2086\n\t\tif ! pot-cmd export-ports -p \"$_new_pname\" $_port_args ; then\n\t\t\t_error \"Couldn't export ports $_ports - ignoring\"\n\t\tfi\n\tfi\n\tif [ \"$_auto_start\" = \"YES\" ]; then\n\t\t_debug \"Auto starting the pot $_new_pname\"\n\t\tif ! pot-cmd start \"$_new_pname\" ; then\n\t\t\t_error \"pot $_new_pname failed to start\"\n\t\t\tpot-cmd stop \"$_new_pname\"\n\t\t\t${EXIT} 1\n\t\tfi\n\telse\n\t\t_info \"Prepared the pot $_new_pname\"\n\tfi\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/prune.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n\nprune-help()\n{\n\tcat <<-\"EOH\"\n\tpot prune [-hvq]\n\t  -h print this help\n\t  -v verbose\n\t  -q quite - prune with no output\n\t  -g grace_period - do not prune pots that just finished executing\n\t  -n dry-run - do not destroy anything\n\tEOH\n}\n\n# $1 pot name\n_prune_pot()\n{\n\tlocal _pname _quiet _dry_run _grace_period _confdir\n\t_pname=$1\n\t_dry_run=$2\n\t_quiet=$3\n\t_grace_period=$4\n\t_confdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\tif ! _is_pot_prunable \"$_pname\" ; then\n\t\t\treturn\n\t\tfi\n\t\tif [ \"$( _get_conf_var \"$_pname\" \"pot.attr.to-be-pruned\" )\" != \"YES\" ]; then\n\t\t\treturn\n\t\tfi\n\t\tif [ \"$_grace_period\" = \"YES\" ]; then\n\t\t\t# check if just finished running\n\t\t\tif find \"$_confdir/.last_run_stats\" -mtime -1m 2>/dev/null | \\\n\t\t\t    grep -q \".\"; then\n\t\t\t\treturn\n\t\t\tfi\n\n\t\t\tsleep 2 # give pot-start a chance to write .last_run_stats\n\n\t\t\t# check again if just finished running\n\t\t\tif find \"$_confdir/.last_run_stats\" -mtime -1m 2>/dev/null | \\\n\t\t\t    grep -q \".\"; then\n\t\t\t\treturn\n\t\t\tfi\n\n\t\t\tif _is_pot_running \"$_pname\" ; then\n\t\t\t\treturn\n\t\t\tfi\n\t\tfi\n\n\t\t_info \"Pruning $_pname\"\n\t\tif [ \"$_dry_run\" = \"YES\" ]; then\n\t\t\treturn\n\t\tfi\n\t\tif _is_pot_running \"$_pname\" ; then\n\t\t\tpot-cmd stop \"$_pname\"\n\t\tfi\n\t\tif ! pot-cmd destroy -p \"$_pname\" ; then\n\t\t\t_qerror \"$_quiet\" \"Error while pruning $_pname\"\n\t\telse\n\t\t\t_info \"Pruned $_pname\"\n\t\tfi\n\tfi\n}\n\n_prune_pots()\n{\n\tlocal _pots _dry_run _quiet _grace_period _p\n\t_dry_run=\"$1\"\n\t_quiet=\"$2\"\n\t_grace_period=\"$3\"\n\t_pots=\"$( _get_pot_list )\"\n\tfor _p in $_pots; do\n\t\t_prune_pot \"$_p\" \"$_dry_run\" \"$_quiet\" \"$_grace_period\"\n\tdone\n}\n\npot-prune()\n{\n\tlocal _quiet _dry_run\n\t_quiet=\n\t_grace_period=\"NO\"\n\t_dry_run=\"NO\"\n\tOPTIND=1\n\twhile getopts \"hvqgn\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tprune-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"quiet\"\n\t\t\t;;\n\t\tg)\n\t\t\t_grace_period=\"YES\"\n\t\t\t;;\n\t\tn)\n\t\t\t_dry_run=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tprune-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\t_prune_pots \"$_dry_run\" \"$_quiet\" \"$_grace_period\"\n}\n"
  },
  {
    "path": "share/pot/ps.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n\nps-help()\n{\n\tcat <<-\"EOH\"\n\tpot ps [-hvq]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet : only print pot names\n\tEOH\n}\n\n# $1 pot name\n_ps_pot()\n{\n\tlocal _pname _quiet\n\t_pname=$1\n\t_quiet=$2\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif [ \"$_quiet\" = \"quiet\" ]; then\n\t\t\techo \"$_pname\"\n\t\t\treturn\n\t\tfi\n\t\techo \"$_pname\"\n\tfi\n}\n\n_ps_pots()\n{\n\tlocal _pots _quiet _p\n\t_quiet=\"$1\"\n\t_pots=\"$( _get_pot_list )\"\n\tfor _p in $_pots ; do\n\t\t_ps_pot \"$_p\" \"$_quiet\"\n\tdone\n}\n\npot-ps()\n{\n\tlocal _quiet\n\t_quiet=\n\tOPTIND=1\n\twhile getopts \"hvq\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tps-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"quiet\"\n\t\t\t;;\n\t\t*)\n\t\t\tps-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_quiet\" ]; then\n\t\tif ! _is_uid0 quiet ; then\n\t\t\t_info \"Need privileges to read internal network status\"\n\t\telif _is_vnet_up ; then\n\t\t\t_info \"Internal network up\"\n\t\telse\n\t\t\t_info \"Internal network down\"\n\t\tfi\n\tfi\n\t_ps_pots \"$_quiet\"\n}\n"
  },
  {
    "path": "share/pot/purge-snapshots.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\npurge-snapshots-help()\n{\n\tcat <<-\"EOH\"\n\tpot purge-snapshots [-hva] -p potname|-f fscomp\n\t  -h print this help\n\t  -v verbose\n\t  -p potname : the pot target of the purge-snapshots\n\t  -f fscomp : the fs component target of the purge-snapshots\n\t  -a remove all snapshot, including the latest one\n\tEOH\n}\n\n# $1 zfs dataset\n_zfs_old_snapshots()\n{\n\tlocal _dset\n\t_output=\"$(zfs list -d 1 -H -t snap \"$_dset\" | sort -r | sed '1d' | sort | cut -d'@' -f2 | cut -f1 )\"\n\techo \"$_output\"\n}\n\n# $1 zfs dataset\n_zfs_all_snapshots()\n{\n\tlocal _dset\n\t_output=\"$(zfs list -d 1 -H -t snap \"$_dset\" | sort | cut -d'@' -f2 | cut -f1 )\"\n\techo \"$_output\"\n}\n\n_purge_dset()\n{\n\tlocal _dset _snaps _all_snap\n\t_dset=$1\n\t_all_snap=${2:-\"NO\"}\n\tif [ \"$_all_snap\" = \"YES\" ]; then\n\t\t_snaps=\"$(_zfs_all_snapshots \"$_dset\")\"\n\telse\n\t\t_snaps=\"$(_zfs_old_snapshots \"$_dset\")\"\n\tfi\n\tif [ -z \"$_snaps\" ]; then\n\t\treturn\n\tfi\n\tfor _s in $_snaps ; do\n\t\tzfs destroy -r \"${_dset}@${_s}\"\n\tdone\n}\n\npot-purge-snapshots()\n{\n\tlocal _obj _objname _all_snap\n\t_all_snap=\"NO\"\n\t_obj=\"\"\n\tOPTIND=1\n\twhile getopts \"hvp:f:a\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tpurge-snapshots-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\tif [ -z \"$_obj\" ]; then\n\t\t\t\t_obj=\"pot\"\n\t\t\t\t_objname=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"-p|-f are exclusive\"\n\t\t\t\tpurge-snapshots-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\tf)\n\t\t\tif [ -z \"$_obj\" ]; then\n\t\t\t\t_obj=\"fscomp\"\n\t\t\t\t_objname=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"-p|-f are exclusive\"\n\t\t\t\tpurge-snapshots-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\ta)\n\t\t\t_all_snap=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tpurge-snapshots-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_obj\" ]; then\n\t\t_error \"one of -p|-f has to be used\"\n\t\tpurge-snapshots-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_objname\" ]; then\n\t\t_error \"-p|-f options need an argument\"\n\t\tpurge-snapshots-help\n\t\treturn 1\n\tfi\n\tcase $_obj in\n\t\"pot\")\n\t\tif ! _is_pot \"$_objname\" ; then\n\t\t\t_error \"$_objname is not a pot!\"\n\t\t\tpurge-snapshots-help\n\t\t\treturn 1\n\t\tfi\n\t\t_purge_dset \"${POT_ZFS_ROOT}/jails/$_objname\" \"$_all_snap\"\n\t\t;;\n\t\"fscomp\")\n\t\tif ! _zfs_exist \"${POT_ZFS_ROOT}/fscomp/$_objname\" \"${POT_FS_ROOT}/fscomp/$_objname\" ; then\n\t\t\t_error \"$_objname is not a valid fscomp\"\n\t\t\tpurge-snapshots-help\n\t\t\treturn 1\n\t\tfi\n\t\tif ! _is_uid0 ; then\n\t\t\treturn 1\n\t\tfi\n\t\t_purge_dset \"${POT_ZFS_ROOT}/fscomp/$_objname\" \"$_all_snap\"\n\t\t;;\n\tesac\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/rename.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nrename-help()\n{\n\tcat <<-\"EOH\"\n\tpot rename [-hv] -p oldname -n newname\n\t  -h print this help\n\t  -v verbose\n\t  -p oldname : the name of an existing pot to rename\n\t  -n newname : the new name for an existing pot\n\tEOH\n}\n\n_rn_conf()\n{\n\tlocal _pname _newname _cdir\n\t_pname=$1\n\t_newname=$2\n\t_cdir=${POT_FS_ROOT}/jails/$_pname/conf\n\t${SED} -i '' -e \"s%/jails/$_pname/%/jails/$_newname/%g\" \"$_cdir/fscomp.conf\"\n\t${SED} -i '' -e \"/^host.hostname=.*/d\" \"$_cdir/pot.conf\"\n\techo \"host.hostname=\\\"${_newname}.$( hostname )\\\"\" >> \"$_cdir/pot.conf\"\n\tif [ -w /usr/local/etc/syslog.d/\"${_pname}\".conf ]; then\n\t\tmv /usr/local/etc/syslog.d/\"${_pname}\".conf /usr/local/etc/syslog.d/\"${_newname}\".conf\n\t\t${SED} -i '' \"s/$_pname.log/$_newname.log/\" /usr/local/etc/syslog.d/\"${_newname}\".conf\n\t\ttouch \"/var/log/pot/$_newname.log\"\n\t\tservice syslogd reload\n\tfi\n\tif [ -w /usr/local/etc/newsyslog.conf.d/\"${_pname}\".conf ]; then\n\t\tmv /usr/local/etc/newsyslog.conf.d/\"${_pname}\".conf /usr/local/etc/newsyslog.conf.d/\"${_newname}\".conf\n\t\t${SED} -i '' \"s%pot/$_pname.log%pot/$_newname.log%\" /usr/local/etc/newsyslog.conf.d/\"${_newname}\".conf\n\tfi\n}\n\n_rn_zfs()\n{\n\tlocal _pname _newname _dset _nset _type\n\t_pname=$1\n\t_newname=$2\n\t_dset=${POT_ZFS_ROOT}/jails/$_pname\n\t_nset=${POT_ZFS_ROOT}/jails/$_newname\n\t_type=$( _get_pot_type \"$_pname\" )\n\tif [ \"$_type\" = \"multi\" ]; then\n\t#sudo zfs umount zroot/pot/jails/dns1/usr.local\n\t#sudo zfs set mountpoint=/opt/pot/jails/dns2/usr.local zroot/pot/jails/dns2/usr.local\n\t#sudo zfs umount zroot/pot/jails/dns1/custom\n\t#sudo zfs set mountpoint=/opt/pot/jails/dns2/custom zroot/pot/jails/dns2/custom\n\t#sudo zfs umount zroot/pot/jails/dns1\n\t\tif _zfs_dataset_valid \"$_dset/usr.local\" ; then\n\t\t\t_debug \"Preparing $_dset/usr.local\"\n\t\t\tzfs umount -f \"$_dset/usr.local\"\n\t\t\tzfs set mountpoint=\"${POT_FS_ROOT}/jails/$_newname/usr.local\" \"$_dset/usr.local\"\n\t\tfi\n\t\tif _zfs_dataset_valid \"$_dset/custom\" ; then\n\t\t\t_debug \"Preparing $_dset/custom\"\n\t\t\tzfs umount -f \"$_dset/custom\"\n\t\t\tzfs set mountpoint=\"${POT_FS_ROOT}/jails/$_newname/custom\" \"$_dset/custom\"\n\t\tfi\n\t\tif _zfs_dataset_valid \"$_dset\" ; then\n\t\t\t_debug \"Preparing $_dset\"\n\t\t\tzfs umount -f \"$_dset\"\n\t\tfi\n\t#sudo zfs rename zroot/pot/jails/dns1 zroot/pot/jails/dns2\n\t\t_debug \"Renaming $_dset in $_nset\"\n\t\tzfs rename \"$_dset\" \"$_nset\"\n\n\t#sudo zfs mount zroot/pot/jails/dns2\n\t\t_debug \"Mount $_nset\"\n\t\tzfs mount \"$_nset\"\n\t#sudo zfs mount zroot/pot/jails/dns2/custom\n\t#sudo zfs mount zroot/pot/jails/dns2/usr.local\n\t\tzfs mount \"$_nset/custom\"\n\t\tif _zfs_dataset_valid \"$_nset/usr.local\" ; then\n\t\t\tzfs mount \"$_nset/usr.local\"\n\t\tfi\n\telse # type single\n\t\tif _zfs_dataset_valid \"$_dset/m\" ; then\n\t\t\t_debug \"Preparing $_dset/m\"\n\t\t\tzfs umount -f \"$_dset/m\"\n\t\t\tzfs set mountpoint=\"${POT_FS_ROOT}/jails/$_newname/m\" \"$_dset/m\"\n\t\tfi\n\t\tif _zfs_dataset_valid \"$_dset\" ; then\n\t\t\t_debug \"Preparing $_dset\"\n\t\t\tzfs umount -f \"$_dset\"\n\t\tfi\n\t\t_debug \"Renaming $_dset in $_nset\"\n\t\tzfs rename \"$_dset\" \"$_nset\"\n\t\t_debug \"Mount $_nset\"\n\t\tzfs mount \"$_nset\"\n\t\tif _zfs_dataset_valid \"$_nset/m\" ; then\n\t\t\tzfs mount \"$_nset/m\"\n\t\tfi\n\tfi\n}\n\n# rename also on all lvl2 and dependencies\n_rn_recursive()\n{\n\tlocal _pname _newname _pots _cdir\n\t_pname=$1\n\t_newname=$2\n\t_pots=$( _get_pot_list )\n\tfor _p in $_pots ; do\n\t\t_cdir=${POT_FS_ROOT}/jails/$_p/conf\n\t\t${SED} -i '' -e \"s%/jails/$_pname/%/jails/$_newname/%g\" \"$_cdir/fscomp.conf\"\n\t\t${SED} -i '' -e \"s/^pot.potbase=$_pname$/pot.potbase=$_newname/\" \"$_cdir/pot.conf\"\n\t\t${SED} -i '' -e \"s/^pot.depend=$_pname$/pot.depend=$_newname/\" \"$_cdir/pot.conf\"\n\tdone\n}\n\npot-rename()\n{\n\tlocal _pname _newname\n\t_pname=\n\t_newname=\n\tOPTIND=1\n\twhile getopts \"hvp:n:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\trename-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tn)\n\t\t\t_newname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\trename-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"pot name is missing (-p)\"\n\t\trename-help\n\t\t$EXIT 1\n\tfi\n\tif [ -z \"$_newname\" ]; then\n\t\t_error \"new name is missing (-n)\"\n\t\trename-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"$_pname is not a valid pot\"\n\t\t${EXIT} 1\n\tfi\n\tif _is_pot \"$_newname\" quiet ; then\n\t\t_error \"pot $_newname exists already\"\n\t\t${EXIT} 1\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\t_error \"pot $_pname is still running\"\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\t_rn_conf \"$_pname\" \"$_newname\"\n\t_rn_zfs \"$_pname\" \"$_newname\"\n\t_rn_recursive \"$_pname\" \"$_newname\"\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/revert.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nrevert-help()\n{\n\tcat <<-\"EOH\"\n\tpot revert [-hv] -p potname|-f fscomp\n\t  -h print this help\n\t  -v verbose\n\t  -p potname : the pot target of the revert\n\t  -f fscomp : the fs component target of the revert\n\tEOH\n}\n\n# $1 pot name\n_pot_zfs_rollback()\n{\n\tlocal _pname _pdset _snap\n\t_pname=$1\n\t_pdset=${POT_ZFS_ROOT}/jails/$_pname\n\tfor _dset in $( zfs list -o name -H -r \"$_pdset\" | sort -r | tr '\\n' ' ') ; do\n\t\t_snap=\"$( _zfs_last_snap \"$_dset\")\"\n\t\tif [ -z \"$_snap\" ]; then\n\t\t\t_info \"$_dset has not snapshot - no possible rollback\"\n\t\t\tcontinue\n\t\tfi\n\t\tzfs rollback \"$_dset\"@\"$_snap\"\n\tdone\n}\n\n_fscomp_zfs_rollback()\n{\n\tlocal _fscomp _fdset _snap\n\t_fscomp=$1\n\t_fdset=${POT_ZFS_ROOT}/fscomp/$_fscomp\n\tfor _dset in $( zfs list -o name -H -r \"$_fdset\" | sort -r | tr '\\n' ' ') ; do\n\t\t_snap=\"$( _zfs_last_snap \"$_dset\")\"\n\t\tif [ -z \"$_snap\" ]; then\n\t\t\t_info \"$_dset has not snapshot - no possible rollback\"\n\t\t\tcontinue\n\t\tfi\n\t\tzfs rollback \"$_dset@$_snap\"\n\tdone\n}\n\npot-revert()\n{\n\tlocal _obj\n\t_obj=\n\tOPTIND=1\n\twhile getopts \"hvp:f:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\trevert-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\tif [ -z \"$_obj\" ]; then\n\t\t\t\t_obj=\"pot\"\n\t\t\t\t_objname=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"-p|-f are exclusive\"\n\t\t\t\trevert-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\tf)\n\t\t\tif [ -z \"$_obj\" ]; then\n\t\t\t\t_obj=\"fscomp\"\n\t\t\t\t_objname=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"-p|-f are exclusive\"\n\t\t\t\trevert-help\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\t\t;;\n\t\t?)\n\t\t\trevert-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_obj\" ]; then\n\t\t_error \"one of -p|-f has to be used\"\n\t\trevert-help\n\t\t$EXIT 1\n\tfi\n\tif [ -z \"$_objname\" ]; then\n\t\t_error \"-p|-f options need an argument\"\n\t\trevert-help\n\t\t${EXIT} 1\n\tfi\n\tcase $_obj in\n\t\"pot\")\n\t\tif ! _is_pot \"$_objname\" ; then\n\t\t\t_error \"$_objname is not a pot!\"\n\t\t\trevert-help\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif _is_pot_running \"$_objname\" ; then\n\t\t\t_error \"The pot $_objname is still running. Revert is possible only for stopped pots\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! _is_uid0 ; then\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_pot_zfs_rollback \"$_objname\"\n\t\t;;\n\t\"fscomp\")\n\t\tif ! _zfs_exist \"${POT_ZFS_ROOT}/fscomp/$_objname\" \"${POT_FS_ROOT}/fscomp/$_objname\" ; then\n\t\t\t_error \"$_objname is not a valid fscomp\"\n\t\t\trevert-help\n\t\t\t${EXIT} 1\n\t\tfi\n\t\tif ! _is_uid0 ; then\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_fscomp_zfs_rollback \"$_objname\"\n\t\t;;\n\tesac\n}\n"
  },
  {
    "path": "share/pot/set-attribute.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nset-attribute-help()\n{\n\tcat <<-EOH\n\tpot set-attribute [-hv] -p pot -A attr -V value\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -A attribute : one of\n\t$(echo \"$_POT_RW_ATTRIBUTES $_POT_JAIL_RW_ATTRIBUTES\" |\n\t  xargs -n1 echo \"     +\" | sort)\n\t  -V value : the new value for \"attribute\"\n\tEOH\n}\n\n# $1 pot name\n# $2 attribute name\n# $3 value\n_set_boolean_attribute()\n{\n\tlocal _pname _value _cdir\n\t_pname=$1\n\t_attr=$2\n\t_value=$3\n\tif ! _value=$(_normalize_true_false \"$_value\") ; then\n\t\t_error \"value $_value is not a valid boolean value\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\t_cdir=\"$POT_FS_ROOT/jails/$_pname/conf\"\n\t${SED} -i '' -e \"/^pot.attr.$_attr=.*/d\" \"$_cdir/pot.conf\"\n\techo \"pot.attr.$_attr=$_value\" >> \"$_cdir/pot.conf\"\n}\n\n# $1 pot name\n# $2 attribute name\n# $3 value\n_set_uint_attribute()\n{\n\tlocal _pname _value _cdir\n\t_pname=$1\n\t_attr=$2\n\t_value=$3\n\n\tif [ -n \"$(printf '%s' \"${_value}\" | tr -d '0-9')\" ] ; then\n\t\t_error \"value $_value is not a valid uint value\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\t_cdir=\"$POT_FS_ROOT/jails/$_pname/conf\"\n\t${SED} -i '' -e \"/^pot.attr.$_attr=.*/d\" \"$_cdir/pot.conf\"\n\techo \"pot.attr.$_attr=$_value\" >> \"$_cdir/pot.conf\"\n}\n\n# $1 pot name\n# $2 attribute name\n# $3 value\n_set_string_attribute()\n{\n\tlocal _pname _value _cdir\n\t_pname=$1\n\t_attr=$2\n\t_value=$3\n\n\t_cdir=\"$POT_FS_ROOT/jails/$_pname/conf\"\n\t${SED} -i '' -e \"/^pot.attr.$_attr=.*/d\" \"$_cdir/pot.conf\"\n\techo \"pot.attr.$_attr=$_value\" >> \"$_cdir/pot.conf\"\n}\n\n# $1 pot name\n# $2 attribute name\n# $3 value\n_set_sysvopt_attribute()\n{\n\tlocal _pname _value _cdir\n\t_pname=$1\n\t_attr=$2\n\t_value=$3\n\n\tif [ \"$_value\" != \"new\" ] && [ \"$_value\" != \"inherit\" ] && \\\n\t    [ \"$_value\" != \"disable\" ]; then\n\t\t_error \"value must be one of 'new', 'inherit', 'disable'\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\n\t_cdir=\"$POT_FS_ROOT/jails/$_pname/conf\"\n\t${SED} -i '' -e \"/^pot.attr.$_attr=.*/d\" \"$_cdir/pot.conf\"\n\techo \"pot.attr.$_attr=$_value\" >> \"$_cdir/pot.conf\"\n}\n\n_ignored_parameter()\n{\n\tlocal _attr\n\t_attr=$1\n\t_info \"The attribute $_attr is not implemented and it will be ignored\"\n}\n\npot-set-attribute()\n{\n\tlocal _pname _attr _value _type\n\t_pname=\n\t_attr=\n\t_value=\n\tOPTIND=1\n\twhile getopts \"hvp:A:V:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-attribute-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tV)\n\t\t\t_value=\"$OPTARG\"\n\t\t\t;;\n\t\tA)\n\t\t\t_attr=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tset-attribute-help\n\t\t\treturn 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_attr\" ]; then\n\t\t_error \"Option -A is mandatory\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_value\" ]; then\n\t\t_error \"Option -V is mandatory\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"$_pname is not a valid pot\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\t# shellcheck disable=SC2086\n\tif ! _is_in_list \"$_attr\" $_POT_RW_ATTRIBUTES ${_POT_JAIL_RW_ATTRIBUTES} ; then\n\t\t_error \"$_attr is not a valid attribute\"\n\t\tset-attribute-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tcase $_attr in\n\t\t\"start-at-boot\"|\\\n\t\t\"early-start-at-boot\"|\\\n\t\t\"persistent\"|\\\n\t\t\"no-rc-script\"|\\\n\t\t\"no-etc-hosts\"|\\\n\t\t\"prunable\"|\\\n\t\t\"localhost-tunnel\")\n\t\t\t_cmd=_set_boolean_attribute\n\t\t\t;;\n\t\t\"no-tmpfs\")\n\t\t\tif [ \"$(_get_conf_var \"$_pname\" pot.type)\" = \"single\" ] ; then\n\t\t\t\tif ! _is_pot_running \"$_pname\" ; then\n\t\t\t\t\t_cmd=_set_boolean_attribute\n\t\t\t\telse\n\t\t\t\t\t_error \"pot $_pname is still running\"\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\t_error \"Attribute no-tmpfs is only usable with single type pot\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\t# shellcheck disable=SC1083,2086\n\t\t\teval _type=\\\"\\${_POT_DEFAULT_${_attr}_T}\\\"\n\t\t\tcase \"${_type}\" in\n\t\t\t(bool)\n\t\t\t\t_cmd=_set_boolean_attribute\n\t\t\t\t;;\n\t\t\t(uint)\n\t\t\t\t_cmd=_set_uint_attribute\n\t\t\t\t;;\n\t\t\t(string)\n\t\t\t\t_cmd=_set_string_attribute\n\t\t\t\t;;\n\t\t\t(sysvopt)\n\t\t\t\t_cmd=_set_sysvopt_attribute\n\t\t\t\t;;\n\t\t\t(*)\n\t\t\t\t_ignored_parameter \"$_attr\"\n\t\t\t        return 0\n\t\t\t\t;;\n\t\t\tesac\n\t\t\t;;\n\tesac\n\n\tif ! $_cmd \"$_pname\" \"$_attr\" \"$_value\" ; then\n\t\treturn 1 # false\n\tfi\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/set-cmd.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nset-cmd-help() {\n\tcat <<-\"EOH\"\n\tpot set-cmd [-hv] -p pot -c cmd\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -c cmd : the command line to start the container\n\tEOH\n}\n\npot-set-cmd()\n{\n\tlocal _pname _cmd\n\t_cmd=\n\t_pname=\n\tOPTIND=1\n\twhile getopts \"hvp:c:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-cmd-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tc)\n\t\t\t_cmd=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tset-cmd-help\n\t\t\treturn 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-cmd-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_cmd\" ]; then\n\t\t_error \"A command is mandatory\"\n\t\tset-cmd-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tset-cmd-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\t_set_command \"$_pname\" \"$_cmd\"\n}\n"
  },
  {
    "path": "share/pot/set-env.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nset-env-help() {\n\tcat <<-\"EOH\"\n\tpot set-env [-hv] -p pot -E env\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -E var=value : the variable and the value to be added\n\t     this option can be repeated more than once\n\tEOH\n}\n\n# $1 pot\n# $2 env\n_set_environment()\n{\n\tlocal _pname _tmpfile _cfile\n\t_pname=\"$1\"\n\t_tmpfile=\"$2\"\n\t_cfile=$POT_FS_ROOT/jails/$_pname/conf/pot.conf\n\t${SED} -i '' -e \"/^pot.env=.*/d\" \"$_cfile\"\n\tsed 's/.*/pot.env=&/g' \"$_tmpfile\" >> \"$_cfile\"\n}\n\npot-set-env()\n{\n\tlocal _pname _env _tmpfile\n\t_env=\n\t_pname=\n\tif ! _is_pot_tmp_dir ; then\n\t\t_error \"Failed to create the POT_TMP directory\"\n\t\treturn 1\n\tfi\n\t_tmpfile=\"$(mktemp \"${POT_TMP:-/tmp}/pot-set-env${POT_MKTEMP_SUFFIX}\")\" || exit 1\n\tOPTIND=1\n\twhile getopts \"hvp:E:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-env-help\n\t\t\trm -f \"$_tmpfile\"\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tE)\n\t\t\tif [ \"$OPTARG\" = \"${OPTARG#*=}\" ]; then\n\t\t\t\t# the argument doesn't have an equal sign\n\t\t\t\t_error \"$OPTARG not in a valid form\"\n\t\t\t\t_error \"VARIABLE=value is accetped\"\n\t\t\t\tset-env-help\n\t\t\t\trm -f \"$_tmpfile\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t_tmp=\"$( echo \"$OPTARG\" | sed 's%\"%\\\\\"%g' )\"\n\t\t\techo \"\\\"$_tmp\\\"\" >> \"$_tmpfile\"\n\t\t\t_env=1\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tset-env-help\n\t\t\trm -f \"$_tmpfile\"\n\t\t\treturn 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-env-help\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\tif [ -z \"$_env\" ]; then\n\t\t_error \"A command is mandatory\"\n\t\tset-env-help\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tset-env-help\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\t_set_environment \"$_pname\" \"$_tmpfile\"\n\trm -f \"$_tmpfile\"\n}\n"
  },
  {
    "path": "share/pot/set-hook.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nset-hook-help() {\n\tcat <<-\"EOH\"\n\tpot set-hook [-hv] -p pot [-s hook]\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -s hook : the pre-start hook\n\t  -S hook : the post-start hook\n\t  -t hook : the pre-stop hook\n\t  -T hook : the post-stop hook\n\tEOH\n}\n\n# $1 pot\n# $2 script name\n# $3 hook type\n_set_hook()\n{\n\tlocal _pname _script\n\t_pname=\"$1\"\n\t_script=\"$2\"\n\t_hooktype=\"$3\"\n\tcp \"$_script\" \"$POT_FS_ROOT/jails/$_pname/conf/${_hooktype}.sh\"\n}\n\n# $1 hook script\n_is_valid_hook()\n{\n\tif [ -x \"$1\" ]; then\n\t\treturn 0 # true\n\tfi\n\t_error \"$1 not a valid hook\"\n\treturn 1 # false\n}\n\npot-set-hook()\n{\n\tlocal _pname _prestart _poststart _prestop _poststop\n\t_pname=\n\t_prestart=\n\t_poststart=\n\t_prestop=\n\t_poststop=\n\tOPTIND=1\n\twhile getopts \"hvp:s:S:t:T:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-hook-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\ts)\n\t\t\tif _is_valid_hook \"${OPTARG}\" ; then\n\t\t\t\t_prestart=\"${OPTARG}\"\n\t\t\tfi\n\t\t\t;;\n\t\tS)\n\t\t\tif _is_valid_hook \"${OPTARG}\" ; then\n\t\t\t\t_poststart=\"${OPTARG}\"\n\t\t\tfi\n\t\t\t;;\n\t\tt)\n\t\t\tif _is_valid_hook \"${OPTARG}\" ; then\n\t\t\t\t_prestop=\"${OPTARG}\"\n\t\t\tfi\n\t\t\t;;\n\t\tT)\n\t\t\tif _is_valid_hook \"${OPTARG}\" ; then\n\t\t\t\t_poststop=\"${OPTARG}\"\n\t\t\tfi\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tset-hook-help\n\t\t\treturn 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-hook-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tset-hook-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_prestart\" ] && [ -z \"$_poststart\" ] &&\n\t\t[ -z \"$_prestop\" ] && [ -z \"$_poststop\" ]; then\n\t\t_error \"No hooks provided - at least one hook as to be set\"\n\t\tset-hook-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif [ -n \"$_prestart\" ]; then\n\t\t_set_hook \"$_pname\" \"$_prestart\" \"prestart\"\n\tfi\n\tif [ -n \"$_poststart\" ]; then\n\t\t_set_hook \"$_pname\" \"$_poststart\" \"poststart\"\n\tfi\n\tif [ -n \"$_prestop\" ]; then\n\t\t_set_hook \"$_pname\" \"$_prestop\" \"prestop\"\n\tfi\n\tif [ -n \"$_poststop\" ]; then\n\t\t_set_hook \"$_pname\" \"$_poststop\" \"poststop\"\n\tfi\n}\n"
  },
  {
    "path": "share/pot/set-hosts.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nset-hosts-help() {\n\tcat <<-\"EOH\"\n\tpot set-hosts [-hv] -p pot -H hostname:IP\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -H hostname:IP : hostname-to-IP resolution to be added\n\t                   to /etc/hosts, can be used multiple times\n\tEOH\n}\n\n# $1 pot\n# $2 hostfile\n_set_hosts()\n{\n\tlocal _pname _tmpfile _cfile\n\t_pname=\"$1\"\n\t_tmpfile=\"$2\"\n\t_cfile=$POT_FS_ROOT/jails/$_pname/conf/pot.conf\n\t${SED} -i '' -e \"/^pot.hosts=.*/d\" \"$_cfile\"\n\tsed 's/.*/pot.hosts=&/g' \"$_tmpfile\" >> \"$_cfile\"\n}\n\npot-set-hosts()\n{\n\tlocal _pname _tmpfile _ip _hostname\n\t_pname=\n\tif ! _is_pot_tmp_dir ; then\n\t\t_error \"Failed to create the POT_TMP directory\"\n\t\treturn 1\n\tfi\n\t_tmpfile=\"$(mktemp \"${POT_TMP:-/tmp}/pot-set-hosts${POT_MKTMP_SUFFIX}\")\" || exit 1\n\tOPTIND=1\n\twhile getopts \"hvp:H:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-hosts-help\n\t\t\trm -f \"$_tmpfile\"\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tH)\n\t\t\tif [ \"$OPTARG\" = \"${OPTARG#*:}\" ]; then\n\t\t\t\t# the argument doesn't have an equal sign\n\t\t\t\t_error \"$OPTARG not in a valid form\"\n\t\t\t\t_error \"hostname:IP is accepted\"\n\t\t\t\tset-hosts-help\n\t\t\t\trm -f \"$_tmpfile\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t# validate IP address\n\t\t\t_ip=\"${OPTARG#*:}\"\n\t\t\t_hostname=\"${OPTARG%%:*}\"\n\t\t\tif [ -z \"$_ip\" ] || [ -z \"$_hostname\" ]; then\n\t\t\t\t_error \"Submitted ip or hostname are empty\"\n\t\t\t\tset-hosts-help\n\t\t\t\trm -f \"$_tmpfile\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\tif ! potnet ipcheck -H \"$_ip\" ; then\n\t\t\t\t_error \"Submitted ip $_ip is not a valid one\"\n\t\t\t\tset-hosts-help\n\t\t\t\trm -f \"$_tmpfile\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\techo \"$_ip $_hostname\" >> \"$_tmpfile\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tset-hosts-help\n\t\t\trm -f \"$_tmpfile\"\n\t\t\treturn 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-hosts-help\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\tset-hosts-help\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\trm -f \"$_tmpfile\"\n\t\treturn 1\n\tfi\n\t_set_hosts \"$_pname\" \"$_tmpfile\"\n\trm -f \"$_tmpfile\"\n}\n"
  },
  {
    "path": "share/pot/set-rss.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nset-rss-help()\n{\n\tcat <<-\"EOH\"\n\tpot set-rss [-hv] -p pot [-C cpus] [-M memory]\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -C cpus : the max amount of CPUs\n\t  -M memory : max memory usable (integer values)\n\tEOH\n}\n\n# $1 pot\n# $2 rss name\n# $3 rss limit\n_set_rss()\n{\n\tlocal _rssname _rsslimit _pname _cdir\n\t_pname=\"$1\"\n\t_rssname=\"$2\"\n\t_rsslimit=\"$3\"\n\t_cdir=$POT_FS_ROOT/jails/$_pname/conf\n\t${SED} -i '' -e \"/^pot.rss.$_rssname=.*/d\" \"$_cdir/pot.conf\"\n\techo \"pot.rss.$_rssname=$_rsslimit\" >> \"$_cdir/pot.conf\"\n}\n\n# $1 the amount of memory\n_memory_validation()\n{\n\t: # Implement\n\tlocal _number\n\tif ! echo \"$1\" | grep -q -E '^[0-9]+[bBkKmMgG]?$' ; then\n\t\t_error \"$1 is not a valid memory constraint\"\n\t\treturn 1\n\tfi\n\t_number=\"$( echo \"$1\" | sed 's/[bBkKmMgG]$//')\"\n\tif ! echo \"$_number\" | grep -q -E '^[0-9]+' ; then\n\t\t_error \"$1 has wrong suffix or format\"\n\t\treturn 1\n\tfi\n\tif echo \"$_number\" | grep -q '^00*$' ; then\n\t\t_error \"Memory constraint has to be greater than zero\"\n\t\treturn 1\n\tfi\n\treturn 0\n}\n# $1 pot\n# $2 cpus amount\n_set_cpu()\n{\n\tlocal _pname _cpus\n\t_pname=$1\n\t_cpus=$2\n\tif _is_natural_number \"$_cpus\" ; then\n\t\tif [ \"$_cpus\" -gt 0 ]; then\n\t\t\t_set_rss \"$_pname\" cpus \"$_cpus\"\n\t\t\treturn 0 # true\n\t\tfi\n\tfi\n\treturn 1 # false\n}\n\n_set_memory()\n{\n\tlocal _pname _memory\n\t_pname=$1\n\t_memory=$2\n\t_set_rss \"$_pname\" memory \"$_memory\"\n}\n\npot-set-rss()\n{\n\tlocal _pname _cpus _memory\n\t_pname=\n\t_cpus=\n\t_memory=\n\tOPTIND=1\n\twhile getopts \"hvp:C:M:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-rss-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tC)\n\t\t\t_cpus=\"$OPTARG\"\n\t\t\t;;\n\t\tM)\n\t\t\tif _memory_validation \"$OPTARG\"  ; then\n\t\t\t\t_memory=\"$OPTARG\"\n\t\t\telse\n\t\t\t\tset-rss-help\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\tset-rss-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-rss-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"$_pname is not a valid pot name\"\n\t\tset-rss-help\n\t\treturn 1\n\tfi\n\tif [ -z \"${_cpus}${_memory}\" ]; then\n\t\t_error \"One resource has to be specified (-C or -M)\"\n\t\tset-rss-help\n\t\treturn 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif [ -n \"$_cpus\" ]; then\n\t\tif ! _set_cpu \"$_pname\" \"$_cpus\" ; then\n\t\t\t_error \"$_cpus is a not valid amount of CPUs!\"\n\t\t\treturn 1\n\t\tfi\n\tfi\n\tif [ -n \"$_memory\" ]; then\n\t\t_set_memory \"$_pname\" \"$_memory\"\n\tfi\n}\n"
  },
  {
    "path": "share/pot/set-status.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\n: \"${_POT_INTERNAL_STATUS:=\"starting doa started stopping stopped\"}\"\n\nset-status-help()\n{\n\tcat <<-EOH\n\tInternal command, DO NOT USE IF YOU DON'T KNOW WHAT YOU ARE DOING!\n\tThis command is meant to be invoked using lockf\n\tpot set-status [-hv] [-p pname] [-s status]\n\t  -h print this help\n\t  -v verbose\n\t  -i interface(s) : network interface (epaira)\n\t  -p pname : pot name\n\t  -s status : the status [$_POT_INTERNAL_STATUS]\n\tEOH\n}\n\n# $1 pot name\n_get_status()\n{\n\tlocal _pname _status_file _uptime _mod_time\n\t_pname=\"$1\"\n\t_status_file=\"${POT_TMP:-/tmp}/pot_status_${_pname}\"\n\n\tif [ ! -e \"$_status_file\" ]; then\n\t\treturn\n\tfi\n\n\t_mod_time=$(stat -f \"%m\" \"$_status_file\")\n\t_uptime=$(_get_system_uptime)\n\n\tif [ \"$_uptime\" -gt \"$_mod_time\" ]; then\n\t\t>&2 _debug \"Ignoring outdated status file $_status_file of pot $_pname\"\n\t\treturn\n\tfi\n\n\t_value=\"$(grep \"^pot.status=\" \"$_status_file\" | tail -n 1 \\\n\t\t|tr -d ' \\t\"' | cut -f2 -d'=' )\"\n\techo \"$_value\"\n}\n\n# $1 pot name\n# $2 new status\n_set_status()\n{\n\tlocal _pname _status_file _new_status\n\t_pname=\"$1\"\n\t_new_status=\"$2\"\n\t_status_file=\"${POT_TMP:-/tmp}/pot_status_${_pname}\"\n\n\techo \"pot.status=$_new_status\" >> \"$_status_file\"\n\t# remove first (and outdated) occurrence of pot.status\n\tif [ \"$(grep -c \"^pot\\.status=\" \"$_status_file\")\" -gt 1 ]; then\n\t\t${SED} -i '' -n -e \":a\" \\\n\t\t\t-e '/^pot\\.status=/{n;bc' -e ':c' -e 'p;n;bc' -e '}' \\\n\t\t\t-e \"p;n;ba\" \"$_status_file\"\n\tfi\n}\n\npot-set-status()\n{\n\tlocal _pname _new_status _tmp _current_status _current_ifnames _conf\n\tlocal _ifnames\n\t_ifnames=\"\"\n\t_pname=\"\"\n\t_new_status=\"\"\n\tOPTIND=1\n\twhile getopts \"hvp:i:s:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tset-status-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\ti)\n\t\t\t_ifnames=\"$OPTARG\"\n\t\t\t;;\n\t\ts)\n\t\t\t# shellcheck disable=SC2086\n\t\t\tif _is_in_list \"$OPTARG\" $_POT_INTERNAL_STATUS ; then\n\t\t\t\t_new_status=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"$OPTARG is not a valid status\"\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\tset-status-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tset-status-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\"; then\n\t\t_error \"$_pname is not a pot\"\n\t\treturn 1\n\tfi\n\n\t_tmp=$(_get_status \"$_pname\")\n\t_current_status=$(echo \"$_tmp\" | cut -d, -f1)\n\t_current_ifnames=$(echo \"$_tmp\" | cut -d, -f2)\n\t# if current status is equal to new status, it means that some other pot command is\n\t# taking care of the execution of the transition and an exit code 2 is returned\n\tif [ \"$_current_status\" = \"$_new_status\" ]; then\n\t\treturn 2\n\tfi\n\t# new status can only be accepted from a specific current status\n\t# any other case, the command return an exit code 1\n\tcase \"$_new_status\" in\n\t\t\"starting\")\n\t\t\tif [ -n \"$_current_status\" ] && [ \"$_current_status\" != \"stopped\" ]; then\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t_ifnames=\"\"\n\t\t\t;;\n\t\t\"started\" | \"doa\")\n\t\t\tif [ \"$_current_status\" != \"starting\" ]; then\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t;;\n\t\t\"stopping\")\n\t\t\t# you can always stop a stopped pot (for cleanup reasons)\n\t\t\tif [ \"$_current_status\" != \"started\" ] && \\\n\t\t\t   [ \"$_current_status\" != \"doa\" ] &&\n\t\t\t   [ \"$_current_status\" != \"stopped\" ]; then\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t_ifnames=\"$_current_ifnames\"\n\t\t\techo \"$_ifnames\"\n\t\t\t;;\n\t\t\"stopped\")\n\t\t\tif [ \"$_current_status\" != \"stopping\" ]; then\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t_ifnames=\"\"\n\t\t\t;;\n\tesac\n\t_set_status \"$_pname\" \"$_new_status,$_ifnames\"\n}\n"
  },
  {
    "path": "share/pot/show.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nshow-help()\n{\n\tcat <<-\"EOH\"\n\tpot show [-hvq] [-a|-r|-p potname]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\t  -a all pots\n\t  -r all running pots (default)\n\t  -p potname : select pot by name\n\tEOH\n}\n\n# show pot static information\n_show_pot()\n{\n\tlocal _pname _bname line _dset\n\t_pname=$1\n\tprintf \"pot %s\\\\n\" \"$_pname\"\n\tprintf \"\\\\tdisk usage      : %s\\\\n\" \"$( zfs list -o used -H \"${POT_ZFS_ROOT}/jails/$_pname\")\"\n\n\tif _is_verbose ; then\n\t\t# TODO show external dataset usage\n\t\t_bname=$( _get_pot_base \"$_pname\" )\n\t\tif [ \"$( _get_pot_type \"$_pname\")\" = \"multi\" ]; then\n\t\t\tprintf \"\\\\tbase usage      : %s\\\\n\" \"$( zfs list -o used -H \"${POT_ZFS_ROOT}/bases/$_bname\")\"\n\t\tfi\n\t\twhile read -r line ; do\n\t\t\t_dset=$( echo \"$line\" | awk '{print $1}' )\n\t\t\tif _is_absolute_path \"$_dset\" ; then\n\t\t\t\t# dset is a folder mounted via nullfs\n\t\t\t\tcontinue;\n\t\t\tfi\n\t\t\tif [ \"$_dset\" = \"${_dset#\"${POT_ZFS_ROOT}/jails/$_pname\"}\" ] &&\n\t\t\t\t[ \"$_dset\" = \"${_dset#\"${POT_ZFS_ROOT}/bases/$_bname\"}\" ]; then\n\t\t\t\tprintf \"\\\\tdataset %s usage  : %s\\\\n\" \"${_dset##\"${POT_ZFS_ROOT}\"/}\" \"$( zfs list -o used -H \"$_dset\")\"\n\t\t\tfi\n\t\tdone < \"${POT_FS_ROOT}/jails/$_pname/conf/fscomp.conf\"\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\t_show_pot_run \"$_pname\"\n\tfi\n}\n\n# show pot runtime information\n# $1 pot name\n_show_pot_run()\n{\n\tlocal _pname _res _vm _pm _ip _network_type _aname\n\t_pname=$1\n\tif ! _is_uid0 quiet; then\n\t\t_info \"some runtime information requires root privileges\"\n\t\treturn\n\tfi\n\tif ! _is_rctl_available ; then\n\t\t_info \"runtime memory usage require rctl enabled\"\n\telse\n\t\t_res=\"$(rctl -hu jail:\"$_pname\" )\"\n\t\t_vm=\"$(echo \"$_res\" | tr ' ' '\\n' | grep ^vmemoryuse | cut -d'=' -f2)\"\n\t\t_pm=\"$(echo \"$_res\" | tr ' ' '\\n' | grep ^memoryuse | cut -d'=' -f2)\"\n\t\tprintf \"\\\\tvirtual memory  : %s\\\\n\" \"$_vm\"\n\t\tprintf \"\\\\tphysical memory : %s\\\\n\" \"$_pm\"\n\tfi\n\t_cpus=\"$( _get_conf_var \"$_pname\" pot.rss.cpus)\"\n\tif [ -n \"$_cpus\" ]; then\n\t\tprintf \"\\tmax amount of CPUs: %s\\n\" \"$_cpus\"\n\t\t_cpu_allocation=\"$( cpuset -g -j \"$_pname\" | grep -F -v domain | cut -f 2 -d ':' | tr -d '[:blank:]')\"\n\t\tprintf \"\\tallocated CPUs    : %s\\n\" \"$_cpu_allocation\"\n\tfi\n\t_network_type=\"$(_get_pot_network_type \"$_pname\" )\"\n\t_ip=\"$( _get_ip_var \"$_pname\" )\"\n\tif [ \"$_network_type\" = \"public-bridge\" ]; then\n\t\t_aname=\"$( _get_pot_rdr_anchor_name \"$_pname\")\"\n\t\tif pfctl -a \"pot-rdr\" -s Anchors 2>/dev/null | grep -q \"pot-rdr/${_aname}$\" ; then\n\t\t\tprintf \"\\\\n\\\\tNetwork port redirection\\\\n\"\n\t\t\tpfctl -a \"pot-rdr/$_aname\" -s nat -P | grep -F \\ \"${_ip}\"\\  | sed 's/rdr pass on .* inet proto tcp from any to //g' | sed 's/ =//g' | while read -r rule ; do\n\t\t\t\tprintf \"\\\\t\\\\t%s\\\\n\" \"$rule\"\n\t\t\tdone\n\t\tfi\n\tfi\n}\n\n_show_running_pots()\n{\n\tlocal _pots _p _q\n\t_q=$1\n\t_pots=$( _get_pot_list )\n\tfor _p in $_pots; do\n\t\tif _is_pot_running \"$_p\" ; then\n\t\t\tif [ \"$_q\" = \"YES\" ]; then\n\t\t\t\techo \"$_p\"\n\t\t\telse\n\t\t\t\t_show_pot \"$_p\"\n\t\t\tfi\n\t\tfi\n\tdone\n}\n\n_show_all_pots()\n{\n\tlocal _pots _p _q\n\t_q=$1\n\t_pots=$( _get_pot_list )\n\tfor _p in $_pots; do\n\t\tif [ \"$_q\" = \"YES\" ]; then\n\t\t\techo \"$_p\"\n\t\telse\n\t\t\t_show_pot \"$_p\"\n\t\tfi\n\tdone\n}\n\npot-show()\n{\n\tlocal _pname _running _all\n\t_pname=\n\t_running=\n\t_all=\n\t_quiet=\"NO\"\n\tOPTIND=1\n\twhile getopts \"hvp:arq\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tshow-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\tr)\n\t\t\t_running=\"YES\"\n\t\t\t;;\n\t\ta)\n\t\t\t_all=\"YES\"\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tshow-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\t# shellcheck disable=SC2030,SC2031,SC2235\n\tif ( [ -n \"$_pname\" ] && [ -n \"$_all\" ] ) ||\n\t\t( [ -n \"$_pname\" ] && [ -n \"$_running\" ] ) ||\n\t\t( [ -n \"$_all\" ] && [ -n \"$_running\" ] ); then\n\t\t_error \"-p -r -a are mutually exclusive\"\n\t\tshow-help\n\t\t${EXIT} 1\n\tfi\n\t# shellcheck disable=SC2031\n\tif [ -z \"$_pname\" ] &&\n\t\t[ -z \"$_all\" ] &&\n\t\t[ -z \"$_running\" ]; then\n\t\t_running=\"YES\"\n\tfi\n\tif [ -n \"$_all\" ]; then\n\t\t_show_all_pots $_quiet\n\telif [ -n \"$_running\" ]; then\n\t\t_show_running_pots $_quiet\n\telse\n\t\tif ! _is_pot \"$_pname\" ; then\n\t\t\t_error \"$_pname is not a valid pot\"\n\t\t\t${EXIT} 1\n\t\tfi\n\t\t_show_pot \"$_pname\"\n\tfi\n}\n"
  },
  {
    "path": "share/pot/signal.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nsignal-help()\n{\n\tcat <<-\"EOH\"\n\tpot signal [-hvflC] [-s signal] [-P pid] [-m pattern] -p pot\n\t  -h print this help\n\t  -v verbose\n\t  -C : check/dry-run: show processes that would match\n\t  -f : force - always returns success, even if signalling failed\n\t  -l : list supported signals\n\t  -s signal : the symbolic name of the signal to send to the process,\n\t              defaults to SIGINFO\n\t  -P pid : the pid inside the pot to send the signal to\n\t  -m pattern : A pattern to match\n\t  -p pot : the pot image\n\n\t  Parameters -P and -m are mutually exclusive. If neither of them is\n\t  is specified and the pot is non-persistent, the signal is delivered\n\t  to the main process of the pot.\n\n\t  For persistent pots, specifying one of -P and -m is mandatory.\n\tEOH\n}\n\n# Get a list of supported signal names\n_get_signal_names()\n{\n\tkillall -l | xargs\n}\n\n# Validate if symbolic signal name is supported\n_validate_signal_name()\n{\n\tlocal _signame\n\t_signame=\"$1\"\n\n\tif ! _get_signal_names | xargs | tr ' ' '\\n' |\\\n\t    sed 's/^\\(.*\\)$/\\1\\nSIG\\1/g' | grep -qFx \"$_signame\"; then\n\t\treturn 1\n\tfi\n}\n\n# Validate if a pid is syntactically acceptable\n_validate_pid()\n{\n\tcase \"$_pid\" in\n\t''|*[!0-9]*)\n\t\treturn 1\n\t\t;;\n\t*)\n\t\t;;\n\tesac\n}\n\n# Actually send signal to process inside pot\n# $1 pot name\n# $2 signal\n# $3 pid\n# $4 match\n# $5 force (YES/NO)\n# $6 dry-run (YES/NO)\n_send_signal()\n{\n\tlocal _pname _signal _pid _match _force _dry_run\n\tlocal _cmd _tmpfile _persist _ret\n\n\t_pname=\"$1\"\n\t_signal=\"$2\"\n\t_pid=\"$3\"\n\t_match=\"$4\"\n\t_force=\"$5\"\n\t_dry_run=\"$6\"\n\n\tif [ \"$_dry_run\" = \"YES\" ]; then\n\t\t_cmd=$(_save_params \"pgrep\")\n\telse\n\t\t_cmd=$(_save_params \"pkill\" \"-$_signal\")\n\tfi\n\n\t# load kill command into $@\n\teval \"set -- $_cmd\"\n\n\tif [ -n \"$_match\" ]; then\n\t\t_info \"Sending $_signal by pattern to pot $_pname\"\n\t\t\"$@\" -j \"$_pname\" \"$_match\"\n\t\t_ret=$?\n\telif [ -n \"$_pid\" ]; then\n\t\t_info \"Sending $_signal to pid $_pid in pot $_pname\"\n\t\t_tmpfile=$(mktemp \\\n\t\t  \"${POT_TMP:-/tmp}/pot_sigpid_${_pname}${POT_MKTEMP_SUFFIX}\"\n\t\t  ) || ${EXIT} 1\n\t\techo \"$_pid\" >\"$_tmpfile\" || ${EXIT} 1\n\t\t\"$@\" -j \"$_pname\" -F \"$_tmpfile\"\n\t\t_ret=$?\n\t\trm -f \"$_tmpfile\"\n\telse\n\t\t_info \"Sending $_signal to main process of pot $_pname\"\n\t\t_persist=\"$(_get_conf_var \"$_pname\" \"pot.attr.persistent\")\"\n\t\tif [ \"$_persist\" != \"NO\" ]; then\n\t\t\tif [ \"$_force\" = \"YES\" ]; then\n\t\t\t\t_info \"Persistent pots have no main process\"\n\t\t\t\treturn 0\n\t\t\telse\n\t\t\t\t_error \"Persistent pots have no main process\"\n\t\t\t\treturn 1\n\t\t\tfi\n\t\tfi\n\t\t\"$@\" -j \"$_pname\" -F \"${POT_TMP:-/tmp}/pot_main_pid_${_pname}\"\n\t\t_ret=$?\n\tfi\n\n\tif [ $_ret -ne 0 ]; then\n\t\tif [ \"$_force\" = \"YES\" ]; then\n\t\t\t_info \"Sending signal failed\"\n\t\t\t_ret=0\n\t\telse\n\t\t\t_error \"Sending signal failed\"\n\t\tfi\n\tfi\n\n\treturn $_ret\n}\n\npot-signal()\n{\n\tlocal _pname _signal _pid _match _force _dry_run\n\t_pname=\n\t_pid=\n\t_match=\n\t_signal=\"SIGINFO\"\n\t_force=\"NO\"\n\t_dry_run=\"NO\"\n\tOPTIND=1\n\twhile getopts \"hvflCs:P:m:p:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tsignal-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tl)\n\t\t\t_get_signal_names\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tf)\n\t\t\t_force=\"YES\"\n\t\t\t;;\n\t\tC)\n\t\t\t_dry_run=\"YES\"\n\t\t\t;;\n\t\ts)\n\t\t\t_signal=\"$OPTARG\"\n\t\t\t;;\n\t\tP)\n\t\t\t_pid=\"$OPTARG\"\n\t\t\t;;\n\t\tm)\n\t\t\t_match=\"$OPTARG\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tsignal-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tsignal-help\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _validate_signal_name \"$_signal\"; then\n\t\t_error \"Invalid signal, valid signals: $(_get_signal_names)\"\n\t\t${EXIT} 1\n\tfi\n\n\tif [ -n \"$_pid\" ] && [ -n \"$_match\" ]; then\n\t\t_error \"Process ID and pattern match are mutually exclusive\"\n\t\t${EXIT} 1\n\tfi\n\n\tif [ -n \"$_pid\" ] && ! _validate_pid \"$_pid\"; then\n\t\t_error \"Invalid pid\"\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\tif [ \"$_force\" = \"YES\" ]; then\n\t\t\t_info \"The pot is not running\"\n\t\t\treturn 0\n\t\tfi\n\t\t_error \"The pot is not running\"\n\t\t${EXIT} 1\n\tfi\n\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\n\t_send_signal \"$_pname\" \"$_signal\" \"$_pid\" \"$_match\" \"$_force\" \"$_dry_run\"\n}\n"
  },
  {
    "path": "share/pot/snapshot.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nsnapshot-help()\n{\n\tcat <<-\"EOH\"\n\tpot snapshot [-hv] -p potname|-f fscomp\n\t  -h print this help\n\t  -v verbose\n\t  -r replace the oldest available snapshot with the new one\n\t  -p potname : the pot target of the snapshot\n\t  -f fscomp : the fs component target of the snapshot\n\tEOH\n}\n\npot-snapshot()\n{\n\tlocal _full_pot _obj _objname\n\t_full_pot=\"NO\"\n\t_obj=\"\"\n\t_objname=\n\t_replace=\n\tOPTIND=1\n\twhile getopts \"hvp:f:r\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tsnapshot-help\n\t\t\treturn 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tr)\n\t\t\t_replace=\"YES\"\n\t\t\t;;\n\t\tp)\n\t\t\tif [ -z \"$_obj\" ]; then\n\t\t\t\t_obj=\"pot\"\n\t\t\t\t_objname=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"-p|-f are exclusive\"\n\t\t\t\tsnapshot-help\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t;;\n\t\tf)\n\t\t\tif [ -z \"$_obj\" ]; then\n\t\t\t\t_obj=\"fscomp\"\n\t\t\t\t_objname=\"$OPTARG\"\n\t\t\telse\n\t\t\t\t_error \"-p|-f are exclusive\"\n\t\t\t\tsnapshot-help\n\t\t\t\treturn 1\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\tsnapshot-help\n\t\t\treturn 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_obj\" ]; then\n\t\t_error \"one of -p|-f has to be used\"\n\t\tsnapshot-help\n\t\treturn 1\n\tfi\n\tif [ -z \"$_objname\" ]; then\n\t\t_error \"-p|-f options need an argument\"\n\t\tsnapshot-help\n\t\treturn 1\n\tfi\n\tcase $_obj in\n\t\"pot\")\n\t\tif ! _is_pot \"$_objname\" ; then\n\t\t\t_error \"$_objname is not a pot!\"\n\t\t\tsnapshot-help\n\t\t\treturn 1\n\t\tfi\n\t\tif _is_pot_running \"$_objname\" ; then\n\t\t\t_error \"The pot $_objname is still running. Snapshot is possible only for stopped pots\"\n\t\t\treturn 1\n\t\tfi\n\t\tif ! _is_uid0 ; then\n\t\t\treturn 1\n\t\tfi\n\n\t\tif [ \"$_full_pot\" = \"YES\" ]; then\n\t\t\t_pot_zfs_snap_full \"$_objname\"\n\t\telse\n\t\t\tif [ \"$_replace\" = \"YES\" ]; then\n\t\t\t\t_remove_oldest_pot_snap \"$_objname\"\n\t\t\tfi\n\t\t\t_pot_zfs_snap \"$_objname\"\n\t\tfi\n\t\t;;\n\t\"fscomp\")\n\t\tif ! _zfs_exist \"${POT_ZFS_ROOT}/fscomp/$_objname\" \"${POT_FS_ROOT}/fscomp/$_objname\" ; then\n\t\t\t_error \"$_objname is not a valid fscomp\"\n\t\t\tsnapshot-help\n\t\t\treturn 1\n\t\tfi\n\t\tif ! _is_uid0 ; then\n\t\t\treturn 1\n\t\tfi\n\t\tif [ \"$_replace\" = \"YES\" ]; then\n\t\t\t_remove_oldest_fscomp_snap \"$_objname\"\n\t\tfi\n\t\t_fscomp_zfs_snap \"$_objname\"\n\t\t;;\n\tesac\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/start.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nstart-help()\n{\n\tcat <<-\"EOH\"\n\tpot start [-h] -p potname [pname]\n\t  -h print this help\n\t  -v verbose\n\t  -s take a snapshot before starting the pot\n\t     snapshots are identified by the epoch\n\t     all ZFS datasets under the jail dataset are considered\n\t  -S take a snapshot before starting the pot [DEPRECATED]\n\t     snapshots are identified by the epoch\n\t     all ZFS datasets mounted in rw are considered (full)\n\t  -p potname : the pot to be started\n\n\t  pname : the pot to be started if \"-p potname\" not given\n\tEOH\n}\n\n# $1 pot name\n# $2 the network interface, if created\nstart-cleanup()\n{\n\tlocal _pname _epaira _epaira2 _ifaces\n\t_pname=$1\n\t_epaira=$2\n\t_epaira2=$3\n\t_ifaces=\n\tif [ -z \"$_pname\" ]; then\n\t\treturn\n\tfi\n\t# doa state will only be set if pot is in state \"starting\"\n\t_set_pot_status \"$_pname\" doa\n\tif [ -n \"$_epaira\" ] && _is_valid_netif \"$_epaira\" ; then\n\t\t_ifaces=\"$_epaira\"\n\tfi\n\tif [ -n \"$_epaira2\" ] && _is_valid_netif \"$_epaira2\" ; then\n\t\t_ifaces=\"$_ifaces:$_epaira2\"\n\tfi\n\t_ifaces=\"${_ifaces#:}\"\n\n\tif [ -n \"$_ifaces\" ]; then\n\t\tpot-cmd stop -p \"$_pname\" -i \"$_ifaces\" -s\n\telse\n\t\tpot-cmd stop -p \"$_pname\" -s\n\tfi\n}\n\n# $1 pot name\n_js_dep()\n{\n\tlocal _pname _depPot\n\t_pname=$1\n\t_depPot=\"$( _get_conf_var \"$_pname\" pot.depend )\"\n\tif [ -z \"$_depPot\" ]; then\n\t\treturn 0 # true\n\tfi\n\tfor _d in $_depPot ; do\n\t\tpot-start \"$_d\"\n\tdone\n\treturn 0 # true\n}\n\n# $1 pot name\n_js_resolv()\n{\n\tlocal _pname _jdir _dns\n\t_pname=\"$1\"\n\t_jdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\t_dns=\"$(_get_conf_var \"$_pname\" pot.dns)\"\n\tif [ -z \"$_dns\" ]; then\n\t\t_dns=inherit\n\tfi\n\tcase \"$_dns\" in\n\t\"inherit\")\n\t\tif [ ! -r /etc/resolv.conf ]; then\n\t\t\t_error \"No resolv.conf found in /etc\"\n\t\t\treturn 1 # false\n\t\tfi\n\t\tif [ -d \"$_jdir/m/etc\" ]; then\n\t\t\tcp /etc/resolv.conf \"$_jdir/m/etc\"\n\t\telse\n\t\t\t_info \"No custom etc directory found, resolv.conf not loaded\"\n\t\tfi\n\t\t;;\n\t\"pot\" ) # resolv.conf generation\n\t\t_domain=\"$( _get_conf_var \"$_pname\" host.hostname | cut -f 2 -d'.' )\"\n\t\techo \"# Generated by pot\" > \"$_jdir/m/etc/resolv.conf\"\n\t\techo \"search $_domain\" >> \"$_jdir/m/etc/resolv.conf\"\n\t\techo \"nameserver ${POT_DNS_IP}\" >> \"$_jdir/m/etc/resolv.conf\"\n\t\t;;\n\t\"custom\")\n\t\tif [ ! -r \"$_jdir/conf/resolv.conf\" ]; then\n\t\t\t_error \"No custom resolv.conf! pot configuration corrupted?\"\n\t\t\treturn 1\n\t\tfi\n\t\tif [ -d \"$_jdir/m/etc\" ]; then\n\t\t\tcp \"$_jdir/conf/resolv.conf\" \"$_jdir/m/etc\"\n\t\telse\n\t\t\t_info \"No custom etc directory found, resolv.conf not loaded\"\n\t\tfi\n\t\t;;\n\t\"off\")\n\t\t;;\n\tesac\n\treturn 0\n}\n\n# tests in start4.sh\n# $1 pot name\n_js_etc_hosts()\n{\n\tlocal _pname _phosts _hostname _bridge_name _cfile\n\t_pname=\"$1\"\n\t_phosts=\"${POT_FS_ROOT}/jails/$_pname/m/etc/hosts\"\n\t_hostname=\"$( _get_conf_var \"$_pname\" host.hostname )\"\n\tprintf \"::1 localhost %s\\n\" \"$_hostname\" > \"$_phosts\"\n\tprintf \"127.0.0.1 localhost %s\\n\" \"$_hostname\" >> \"$_phosts\"\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-etc-hosts\")\" = \"YES\" ]; then\n\t\t_debug \"Attribute no-etchosts: no additional /etc/hosts entries injected\"\n\telse\n\t\tcase \"$( _get_conf_var \"$_pname\" network_type )\" in\n\t\t\"public-bridge\")\n\t\t\tpotnet etc-hosts >> \"$_phosts\"\n\t\t\t;;\n\t\t\"private-bridge\")\n\t\t\t_bridge_name=\"$( _get_conf_var \"$_pname\" bridge )\"\n\t\t\tpotnet etc-hosts -b \"$_bridge_name\" >> \"$_phosts\"\n\t\t\t;;\n\t\tesac\n\tfi\n\t_cfile=\"${POT_FS_ROOT}/jails/$_pname/conf/pot.conf\"\n\tgrep '^pot.hosts=' \"$_cfile\" | sed 's/^pot.hosts=//g' >> \"$_phosts\"\n}\n\n# returns interface names of epaira and epairb\n# $1 pot name\n# $2 prefix (optional)\n_js_create_epair()\n{\n\tlocal _epaira _epaira_renamed _epairb _pname _prefix\n\n\t_pname=\"$1\"\n\t_prefix=\"$2\"\n\t_epaira=$(ifconfig epair create descr \"$_pname\" group \"pot\")\n\n\tif [ -z \"${_epaira}\" ]; then\n\t\t_error \"ifconfig epair failed\" >&2\n\t\tstart-cleanup \"$_pname\"\n\t\t${EXIT} 1 # false\n\tfi\n\n\t_epairb=\"${_epaira%a}b\"\n\t_epaira_renamed=$(ifconfig \"$_epaira\" name \\\n\t    \"$(printf \"p%s%x%x\" \"$_prefix\" \"$(date +%s)\" \"$$\")\")\n\n\tif [ -z \"${_epaira_renamed}\" ]; then\n\t\t_error \"ifconfig epair rename failed\" >&2\n\t\tstart-cleanup \"$_pname\" \"$_epaira\"\n\t\t${EXIT} 1 # false\n\tfi\n\n\techo \"$_epaira_renamed\"\n\techo \"$_epairb\"\n}\n\n# $1 pot name\n# $2 epaira interface\n# $3 epairb interface\n_js_vnet()\n{\n\tlocal _pname _bridge _epaira _epairb _ip _param\n\t_pname=$1\n\tif ! _is_vnet_ipv4_up ; then\n\t\t_info \"Internal network not found! Calling vnet-start to fix the issue\"\n\t\tpot-cmd vnet-start\n\tfi\n\t_bridge=$(_pot_bridge_ipv4)\n\t_epaira=$2\n\t_epairb=$3\n\tifconfig \"$_epaira\" up\n\t_param=$(_save_params \"addm\" \"$_epaira\")\n\tif [ \"$(_normalize_true_false \"$POT_ISOLATE_VNET_POTS\")\" = \"YES\" ]; then\n\t\t_param=\"$_param\"$(_save_params \"private\" \"$_epaira\")\n\tfi\n\teval \"set -- $_param\"\n\tifconfig \"$_bridge\" \"$@\"\n\t_ip=$( _get_ip_var \"$_pname\" )\n\t## if norcscript - write an ad-hoc one\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" = \"YES\" ]; then\n\t\tcat >>\"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\" <<-EOT\n\t\tif ! ifconfig ${_epairb} >/dev/null 2>&1; then\n\t\t    sleep 1\n\t\t    if ! ifconfig ${_epairb} >/dev/null 2>&1; then\n\t\t        >&2 echo \"Interface ${_epairb} does not exist\"\n\t\t        exit 1\n\t\t    fi\n\t\tfi\n\t\tifconfig ${_epairb} inet $_ip netmask $POT_NETMASK\n\t\troute add default $POT_GATEWAY\n\t\tEOT\n\telse # use rc scripts\n\t\t# set the network configuration in the pot's rc.conf\n\t\tif [ -w \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\" ]; then\n\t\t\tsed -i '' '/ifconfig_epair[0-9][0-9]*[ab]=/d' \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\"\n\t\tfi\n\t\techo \"ifconfig_${_epairb}=\\\"inet $_ip netmask $POT_NETMASK\\\"\" >> \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\"\n\t\tsysrc -f \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\" defaultrouter=\"$POT_GATEWAY\"\n\tfi\n}\n\n# $1 pot name\n# $2 epaira interface\n# $3 epairb interface\n# $4 stack (ipv6 or dual)\n_js_vnet_ipv6()\n{\n\tlocal _pname _bridge _epaira _epairb _ip _param\n\t_pname=$1\n\tif ! _is_vnet_ipv6_up ; then\n\t\t_info \"Internal network not found! Calling vnet-start to fix the issue\"\n\t\tpot-cmd vnet-start\n\tfi\n\t_bridge=$(_pot_bridge_ipv6)\n\t_epaira=$2\n\t_epairb=$3\n\tifconfig \"$_epaira\" up\n\t_param=$(_save_params \"addm\" \"$_epaira\")\n\tif [ \"$(_normalize_true_false \"$POT_ISOLATE_VNET_POTS\")\" = \"YES\" ]; then\n\t\t_param=\"$_param\"$(_save_params \"private\" \"$_epaira\")\n\tfi\n\teval \"set -- $_param\"\n\tifconfig \"$_bridge\" \"$@\"\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" = \"YES\" ]; then\n\t\tcat >>\"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\" <<-EOT\n\t\tif ! ifconfig ${_epairb} >/dev/null 2>&1; then\n\t\t    sleep 1\n\t\t    if ! ifconfig ${_epairb} >/dev/null 2>&1; then\n\t\t        >&2 echo \"Interface ${_epairb} does not exist\"\n\t\t        exit 1\n\t\t    fi\n\t\tfi\n\t\tifconfig ${_epairb} inet6 up accept_rtadv -ifdisabled\n\t\t/sbin/rtsol -d ${_epairb}\n\t\tEOT\n\telse # use rc scripts\n\t\t# set the network configuration in the pot's rc.conf\n\t\tif [ -w \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\" ]; then\n\t\t\tsed -i '' '/ifconfig_epair[0-9][0-9]*[ab]_ipv6/d' \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\"\n\t\tfi\n\t\techo \"ifconfig_${_epairb}_ipv6=\\\"inet6 accept_rtadv auto_linklocal -ifdisabled\\\"\" >> \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\"\n\t\tsysrc -f \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\" rtsold_enable=\"YES\"\n\t\t# Fix a bug in the rtsold rc script in 11.3\n\t\tsed -i '' 's/nojail/nojailvnet/' \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.d/rtsold\"\n\tfi\n}\n\n# $1 pot name\n# $2 epaira interface\n# $3 epairb interface\n_js_private_vnet()\n{\n\tlocal _pname _bridge_name _bridge _epaira _epairb _ip _net_size\n\tlocal _gateway _param\n\t_pname=$1\n\t_bridge_name=\"$( _get_conf_var \"$_pname\" bridge )\"\n\tif ! _is_vnet_ipv4_up \"$_bridge_name\" ; then\n\t\t_debug \"No pot bridge found! Calling vnet-start to fix the issue\"\n\t\tpot-cmd vnet-start -B \"$_bridge_name\"\n\tfi\n\t_bridge=\"$(_private_bridge \"$_bridge_name\")\"\n\t_epaira=$2\n\t_epairb=$3\n\tifconfig \"$_epaira\" up\n\t_param=$(_save_params \"addm\" \"$_epaira\")\n\tif [ \"$(_normalize_true_false \"$POT_ISOLATE_VNET_POTS\")\" = \"YES\" ]; then\n\t\t_param=\"$_param\"$(_save_params \"private\" \"$_epaira\")\n\tfi\n\teval \"set -- $_param\"\n\tifconfig \"$_bridge\" \"$@\"\n\tifconfig \"$_bridge\" addm \"$_epaira\"\n\t_ip=$( _get_ip_var \"$_pname\"  )\n\t_net_size=\"$(_get_bridge_var \"$_bridge_name\" net)\"\n\t_net_size=\"${_net_size##*/}\"\n\t_gateway=\"$(_get_bridge_var \"$_bridge_name\" gateway)\"\n\t## if norcscript - write an ad-hoc one\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" = \"YES\" ]; then\n\t\tcat >>\"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\" <<-EOT\n\t\tif ! ifconfig ${_epairb} >/dev/null 2>&1; then\n\t\t    sleep 1\n\t\t    if ! ifconfig ${_epairb} >/dev/null 2>&1; then\n\t\t        >&2 echo \"Interface ${_epairb} does not exist\"\n\t\t        exit 1\n\t\t    fi\n\t\tfi\n\t\tifconfig ${_epairb} inet $_ip/$_net_size\n\t\troute add default $_gateway\n\t\tEOT\n\telse # use rc scripts\n\t\t# set the network configuration in the pot's rc.conf\n\t\tif [ -w \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.con\"f ]; then\n\t\t\tsed -i '' '/ifconfig_epair/d' \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\"\n\t\tfi\n\t\techo \"ifconfig_${_epairb}=\\\"inet $_ip/$_net_size\\\"\" >> \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\"\n\t\tsysrc -f \"${POT_FS_ROOT}/jails/$_pname/m/etc/rc.conf\" defaultrouter=\"$_gateway\"\n\tfi\n}\n\n# $1: exclude list\n_js_get_free_rnd_port()\n{\n\tlocal _min _max excl_ports used_ports rdr_ports rand\n\texcl_ports=\"$1\"\n\t_min=$( sysctl -n net.inet.ip.portrange.reservedhigh )\n\t_min=$(( _min + 1 ))\n\t_max=$( sysctl -n net.inet.ip.portrange.first )\n\t_max=$(( _max - 1 ))\n\tused_ports=\"$(sockstat -p ${_min}-${_max} -4l | awk '!/USER/ { n=split($6,a,\":\"); if ( n == 2 ) { print a[2]; }}' | sort -u)\"\n\tanchors=\"$(pfctl -a pot-rdr -s Anchors)\"\n\tfor a in $anchors ; do\n\t\tnew_ports=\"$( pfctl -a \"$a\" -s nat -P | awk '/rdr/ { n=split($0,a,\" \"); for(i=1;i<=n;i++) { if (a[i] == \"=\" ) { print a[i+1];break;}}}')\"\n\t\trdr_ports=\"$rdr_ports $new_ports\"\n\tdone\n\trand=$_min\n\twhile [ $rand -le $_max ]; do\n\t\tfor p in $excl_ports $used_ports $rdr_ports ; do\n\t\t\tif [ \"$p\" = \"$rand\" ]; then\n\t\t\t\trand=$(( rand + 1 ))\n\t\t\t\tcontinue 2\n\t\t\tfi\n\t\tdone\n\t\techo $rand\n\t\tbreak\n\tdone\n}\n\n# $1 pot name\n_js_export_ports()\n{\n\tlocal _pname _ip _ports _excl_list _pot_port _host_port _proto_port _aname _pdir _ncat_opt _to_arg _bridge\n\t_pname=$1\n\t_ip=\"$( _get_ip_var \"$_pname\" )\"\n\t_ports=\"$( _get_pot_export_ports \"$_pname\" )\"\n\tif [ -z \"$_ports\" ]; then\n\t\treturn\n\tfi\n\t_pfrules=$(mktemp \"${POT_TMP:-/tmp}/pot_pfrules_${_pname}${POT_MKTEMP_SUFFIX}\") || exit 1\n\t_lo_tunnel=\"$(_get_conf_var \"$_pname\" \"pot.attr.localhost-tunnel\")\"\n\t_bridge=$(_pot_bridge_ipv4)\n\tfor _port in $_ports ; do\n\t\t_proto_port=\"tcp\"\n\t\tif [ \"${_port#udp:}\" != \"${_port}\" ]; then\n\t\t\t_proto_port=\"udp\"\n\t\t\t_port=\"${_port#udp:}\"\n\t\t\t_ncat_opt=\"-u\"\n\t\telif [ \"${_port#tcp:}\" != \"${_port}\" ]; then\n\t\t\t_proto_port=\"tcp\"\n\t\t\t_port=\"${_port#tcp:}\"\n\t\tfi\n\t\t_pot_port=\"$( echo \"${_port}\" | cut -d':' -f 1)\"\n\t\t_host_port=\"$( echo \"${_port}\" | cut -d':' -f 2)\"\n\t\tif [ \"$_pot_port\" = \"$_port\" ]; then\n\t\t\t_host_port=$( _js_get_free_rnd_port \"$_excl_list\" )\n\t\tfi\n\t\tif [ -n \"$POT_EXTIF_ADDR\" ]; then\n\t\t\t_to_arg=\"$POT_EXTIF_ADDR\"\n\t\telse\n\t\t\t_to_arg=\"($POT_EXTIF)\"\n\t\tfi\n\n\t\t_debug \"Redirect: from $_to_arg : $_proto_port:$_host_port to $_ip : $_proto_port:$_pot_port\"\n\t\tif [ -n \"$POT_EXPORT_PORTS_PF_RULES_HOOK\" ]; then\n\t\t\t\"$POT_EXPORT_PORTS_PF_RULES_HOOK\" \\\n\t\t\t  \"$POT_EXTIF\" \"$_bridge\" \"$POT_NETWORK\" \"$POT_GATEWAY\" \\\n\t\t\t  \"$_proto_port\" \"$_host_port\" \"$_ip\" \"$_pot_port\" >> \"$_pfrules\"\n\t\telse\n\t\t\techo \"rdr pass on $POT_EXTIF proto $_proto_port from any to $_to_arg port $_host_port -> $_ip port $_pot_port\" >> \"$_pfrules\"\n\n\t\t\t_excl_list=\"$_excl_list $_host_port\"\n\t\t\tif [ -n \"$POT_EXTRA_EXTIF\" ]; then\n\t\t\t\tfor extra_netif in $POT_EXTRA_EXTIF ; do\n\t\t\t\t\techo \"rdr pass on $extra_netif proto $_proto_port from any to ($extra_netif) port $_host_port -> $_ip port $_pot_port\" >> \"$_pfrules\"\n\t\t\t\tdone\n\t\t\tfi\n\t\t\tif [ \"$_lo_tunnel\" = \"YES\" ]; then\n\t\t\t\t_pdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\t\t\t\tif [ -x \"/usr/local/bin/ncat\" ]; then\n\t\t\t\t\tcp /usr/local/bin/ncat \"$_pdir/ncat-$_pname-$_pot_port\"\n\t\t\t\t\tdaemon -f -p \"$_pdir/ncat-$_pot_port.pid\" \"$_pdir/ncat-$_pname-$_pot_port\" -lk $_ncat_opt \"$_host_port\" -c \"/usr/local/bin/ncat $_ncat_opt $_ip $_pot_port\"\n\t\t\t\telse\n\t\t\t\t\t_error \"nmap package is missing, localhost-tunnel attribute ignored\"\n\t\t\t\tfi\n\t\t\tfi\n\t\tfi\n\tdone\n\t_aname=\"$( _get_pot_rdr_anchor_name \"$_pname\" )\"\n\tif ! pfctl -a \"pot-rdr/$_aname\" -f \"$_pfrules\" ; then\n\t\t_error \"pfctl failed to apply redirection rules - ignoring but no redirection is performed\"\n\t\tif _is_verbose ; then\n\t\t\tcat \"$_pfrules\"\n\t\tfi\n\tfi\n\trm -f \"$_pfrules\"\n}\n\n# $1 jail name\n_js_rss()\n{\n\tlocal _pname _jid _cpus _cpuset _memory\n\t_pname=$1\n\t_cpus=\"$( _get_conf_var \"$_pname\" pot.rss.cpus)\"\n\t_memory=\"$( _get_conf_var \"$_pname\" pot.rss.memory)\"\n\tif [ -n \"$_cpus\" ]; then\n\t\t_jid=\"$( jls -j \"$_pname\" | sed 1d | awk '{ print $1 }' )\"\n\t\t_cpuset=\"$( potcpu get-cpu -n \"$_cpus\" )\"\n\t\tcpuset -l \"$_cpuset\" -j \"$_jid\"\n\tfi\n\tif [ -n \"$_memory\" ]; then\n\t\tif ! _is_rctl_available ; then\n\t\t\t_info \"memory constraint cannot be applies because rctl is not enabled - ignoring\"\n\t\telse\n\t\t\trctl -a jail:\"$_pname\":memoryuse:deny=\"$_memory\"\n\t\tfi\n\tfi\n}\n\n# $1 pot name\n_js_get_cmd()\n{\n\tlocal _pname _cdir _value\n\t_pname=\"$1\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_value=\"$( grep \"^pot.cmd=\" \"$_cdir/pot.conf\" | sed 's/^pot.cmd=//' )\"\n\t[ -z \"$_value\" ] && _value=\"sh /etc/rc\"\n\techo \"$_value\"\n}\n\n_js_norc()\n{\n\tlocal _pname\n\t_pname=\"$1\"\n\t_cmd=\"$(_js_get_cmd \"$_pname\")\"\n\tcase \"$( _get_conf_var \"$_pname\" network_type )\" in\n\t\"public-bridge\"|\\\n\t\"private-bridge\")\n\t\techo \"ifconfig lo0 inet 127.0.0.1 alias\" >> \"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\"\n\t\t;;\n\tesac\n\techo \"exec $_cmd\" >> \"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\"\n\tchmod a+x \"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\"\n}\n\n_js_env()\n{\n\tlocal _pname _shfile _cfile\n\t_pname=\"$1\"\n\t_cfile=\"${POT_FS_ROOT}/jails/$_pname/conf/pot.conf\"\n\t_shfile=$(mktemp \"${POT_TMP:-/tmp}/pot_environment_${_pname}${POT_MKTEMP_SUFFIX}\") || exit 1\n\tgrep '^pot.env=' \"$_cfile\" | sed 's/^pot.env=/export /g' > \"$_shfile\"\n\tpot-cmd info -E -p \"$_pname\" >> \"$_shfile\"\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" = \"YES\" ]; then\n\t\tcat \"$_shfile\" >> \"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\"\n\telse\n\t\tcp \"$_shfile\" \"${POT_FS_ROOT}/jails/$_pname/m/tmp/environment.sh\"\n\tfi\n\trm -f \"$_shfile\"\n}\n\n# $1 jail name\n_js_start()\n{\n\tlocal _pname _confdir _epaira _epairb _ipv6_epaira _ipv6_epairb\n\tlocal _ifaces _hostname _osrelease _param _ip _cmd _persist\n\tlocal _stack _value _name _type _wait_pid _exit_code _tmp\n\tlocal _default\n\t_pname=\"$1\"\n\t_confdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_param=$(_save_params \"allow.set_hostname=false\" \"allow.raw_sockets\" \\\n\t         \"allow.socket_af\" \"allow.chflags\" \"exec.clean\" \"mount.devfs\")\n\n\tfor _attr in ${_POT_JAIL_RW_ATTRIBUTES} ; do\n\t\t# shellcheck disable=SC1083,2086\n\t\teval _name=\\\"\\${_POT_DEFAULT_${_attr}_N}\\\"\n\t\t# shellcheck disable=SC1083,2086\n\t\teval _type=\\\"\\${_POT_DEFAULT_${_attr}_T}\\\"\n\t\t# shellcheck disable=SC1083,2086\n\t\teval _default=\\\"\\${_POT_DEFAULT_${_attr}_D}\\\"\n\t\tif [ \"$_type\" = \"string\" ]; then\n\t\t\t_value=\"$(_get_conf_var_string \"$_pname\" \"pot.attr.${_attr}\")\"\n\t\telse\n\t\t\t_value=\"$(_get_conf_var \"$_pname\" \"pot.attr.${_attr}\")\"\n\t\tfi\n\n\t\tif [ \"$_type\" = \"bool\" ] && [ \"$_value\" = \"YES\" ]; then\n\t\t\t_param=\"$_param\"$(_save_params \"$_name\")\n\t\telif [ \"$_type\" != \"bool\" ] && [ -n \"$_value\" ]; then\n\t\t\t_param=\"$_param\"$(_save_params \"$_name=$_value\")\n\t\telif [ \"$_type\" = \"sysvopt\" ] && [ -z \"$_value\" ]; then\n\t\t\t_param=\"$_param\"$(_save_params \"$_name=$_default\")\n\t\tfi\n\tdone\n\n\t_hostname=\"$( _get_conf_var \"$_pname\" host.hostname )\"\n\t_osrelease=\"$( _get_os_release \"$_pname\" )\"\n\t_param=\"$_param\"$(_save_params \"name=$_pname\" \\\n\t                  \"host.hostname=$_hostname\" \\\n\t                  \"osrelease=$_osrelease\" \\\n\t                  \"path=${POT_FS_ROOT}/jails/$_pname/m\")\n\n\t_persist=\"$(_get_conf_var \"$_pname\" \"pot.attr.persistent\")\"\n\tif [ \"$_persist\" != \"NO\" ]; then\n\t\t_param=\"$_param\"$(_save_params \"persist\")\n\telse\n\t\t_param=\"$_param\"$(_save_params \"nopersist\")\n\tfi\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" = \"YES\" ]; then\n\t\tif [ \"$( _get_pot_network_stack \"$_pname\" )\" = \"ipv4\" ]; then\n\t\t\tprec=100\n\t\telse\n\t\t\tprec=35\n\t\tfi\n\t\tcat >\"${POT_FS_ROOT}/jails/$_pname/m/tmp/tinirc\" <<-EOT\n\t\t# created automatically by pot, changes will be overwritten\n\t\techo \\$\\$ >/tmp/tinirc.pid\n\t\tif sysctl -n kern.features.inet6 >/dev/null 2>&1; then\n\t\t        ip6addrctl flush >/dev/null 2>&1\n\t\t        ip6addrctl install /dev/stdin <<EOF\n\t\t        ::1/128\t\t 50\t 0\n\t\t        ::/0\t\t 40\t 1\n\t\t        ::ffff:0:0/96\t $prec\t 4\n\t\t        2002::/16\t 30\t 2\n\t\t        2001::/32\t  5\t 5\n\t\t        fc00::/7\t  3\t13\n\t\t        ::/96\t\t  1\t 3\n\t\t        fec0::/10\t  1\t11\n\t\t        3ffe::/16\t  1\t12\n\t\tEOF\n\t\tfi\n\t\tEOT\n\tfi\n\tcase \"$( _get_conf_var \"$_pname\" network_type )\" in\n\t\"inherit\")\n\t\tcase \"$( _get_pot_network_stack \"$_pname\" )\" in\n\t\t\t\"dual\")\n\t\t\t\t_param=\"$_param\"$(_save_params \\\n\t\t\t\t                  \"ip4=inherit\" \"ip6=inherit\")\n\t\t\t\t;;\n\t\t\t\"ipv4\")\n\t\t\t\t_param=\"$_param\"$(_save_params \"ip4=inherit\")\n\t\t\t\t;;\n\t\t\t\"ipv6\")\n\t\t\t\t_param=\"$_param\"$(_save_params \"ip6=inherit\")\n\t\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"alias\")\n\t\tlocal _ip4addr _ip6addr\n\t\t_ip=$( _get_ip_var \"$_pname\" )\n\t\tcase \"$( _get_pot_network_stack \"$_pname\" )\" in\n\t\t\t\"dual\")\n\t\t\t\t_ip4addr=\"$( _get_alias_ipv4 \"$_pname\" \"$_ip\" )\"\n\t\t\t\t_ip6addr=\"$( _get_alias_ipv6 \"$_pname\" \"$_ip\" )\"\n\t\t\t\tif [ -n \"$_ip4addr\" ]; then\n\t\t\t\t\t_param=\"$_param\"$(_save_params \"ip4.addr=$_ip4addr\")\n\t\t\t\tfi\n\t\t\t\tif [ -n \"$_ip6addr\" ]; then\n\t\t\t\t\t_param=\"$_param\"$(_save_params \"ip6.addr=$_ip6addr\")\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t\"ipv4\")\n\t\t\t\t_ip4addr=\"$( _get_alias_ipv4 \"$_pname\" \"$_ip\" )\"\n\t\t\t\tif [ -n \"$_ip4addr\" ]; then\n\t\t\t\t\t_param=\"$_param\"$(_save_params \"ip4.addr=$_ip4addr\")\n\t\t\t\telse\n\t\t\t\t\t_error \"No ipv4 address found for $_pname\"\n\t\t\t\t\tstart-cleanup \"$_pname\"\n\t\t\t\t\treturn 1 # false\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\t\"ipv6\")\n\t\t\t\t_ip6addr=\"$( _get_alias_ipv6 \"$_pname\" \"$_ip\" )\"\n\t\t\t\tif [ -n \"$_ip6addr\" ]; then\n\t\t\t\t\t_param=\"$_param\"$(_save_params \"ip6.addr=$_ip6addr\")\n\t\t\t\telse\n\t\t\t\t\t_error \"No ipv6 address found for $_pname\"\n\t\t\t\t\tstart-cleanup \"$_pname\"\n\t\t\t\t\treturn 1 # false\n\t\t\t\tfi\n\t\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"public-bridge\")\n\t\t_param=\"$_param\"$(_save_params \"vnet\")\n\t\t_stack=\"$( _get_pot_network_stack \"$_pname\" )\"\n\t\tif [ \"$_stack\" = \"dual\" ] || [ \"$_stack\" = \"ipv4\" ]; then\n\t\t\t_tmp=\"$( _js_create_epair \"$_pname\" '4' )\" || return 1\n\t\t\t# shellcheck disable=SC2086\n\t\t\tset -- $_tmp\n\n\t\t\t_epaira=$1\n\t\t\t_epairb=$2\n\t\t\t_js_vnet \"$_pname\" \"$_epaira\" \"$_epairb\"\n\t\t\t_param=\"$_param\"$(_save_params \"vnet.interface=$_epairb\")\n\t\t\t_js_export_ports \"$_pname\"\n\t\tfi\n\t\tif [ \"$_stack\" = \"dual\" ] || [ \"$_stack\" = \"ipv6\" ]; then\n\t\t\t_tmp=\"$( _js_create_epair \"$_pname\" '6' )\" || return 1\n\t\t\t# shellcheck disable=SC2086\n\t\t\tset -- $_tmp\n\n\t\t\t_ipv6_epaira=$1\n\t\t\t_ipv6_epairb=$2\n\t\t\t_js_vnet_ipv6 \"$_pname\" \"$_ipv6_epaira\" \\\n\t\t\t  \"$_ipv6_epairb\" \"$_stack\"\n\t\t\t_param=\"$_param\"$(_save_params \"vnet.interface=$_ipv6_epairb\")\n\t\tfi\n\t\t;;\n\t\"private-bridge\")\n\t\t_tmp=\"$( _js_create_epair \"$_pname\" '4' )\" || return 1\n\t\t# shellcheck disable=SC2086\n\t\tset -- $_tmp\n\n\t\t_epaira=$1\n\t\t_epairb=$2\n\t\t_js_private_vnet \"$_pname\" \"$_epaira\" \"$_epairb\"\n\t\t_param=\"$_param\"$(_save_params \"vnet\" \"vnet.interface=$_epairb\")\n\t\t_js_export_ports \"$_pname\"\n\t\t;;\n\tesac\n\t_ifaces=\"$_epaira:$_ipv6_epaira\"\n\t_ifaces=\"${_ifaces#:}\"\n\t_js_env \"$_pname\"\n\tif [ \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" = \"YES\" ]; then\n\t\t_js_norc \"$_pname\"\n\t\t_cmd=/tmp/tinirc\n\telse\n\t\t_cmd=\"$( _js_get_cmd \"$_pname\" )\"\n\tfi\n\tif [ -x \"$_confdir/prestart.sh\" ]; then\n\t\t_info \"Executing the pre-start script for the pot $_pname\"\n\t\t(\n\t\t\t# shellcheck disable=SC2046\n\t\t\teval $( pot info -E -p \"$_pname\" )\n\t\t\t\"$_confdir/prestart.sh\"\n\t\t)\n\tfi\n\n\trm -f \"${POT_TMP:-/tmp}/pot_main_pid_${_pname}\"\n\n\t_info \"Starting the pot $_pname\"\n\t# execute command\n\teval \"set -- $_param\"\n\t_debug \"Pot $_pname jail params are: $*\"\n\tjail -c \"$@\" exec.start=\"sh -c 'sleep 1234&'\"\n\n\tif [ -e \"$_confdir/pot.conf\" ] && _is_pot_prunable \"$_pname\" ; then\n\t\t# set-attr cannot be used for read-only attributes\n\t\t${SED} -i '' -e \"/^pot.attr.to-be-pruned=.*/d\" \\\n\t\t    \"$_confdir/pot.conf\"\n\t\techo \"pot.attr.to-be-pruned=YES\" >> \"$_confdir/pot.conf\"\n\tfi\n\n\tif _is_pot_running \"$_pname\" ; then\n\t\t_js_rss \"$_pname\"\n\tfi\n\n\t# shellcheck disable=SC2086\n\tjexec \"$_pname\" $_cmd &\n\t_wait_pid=$!\n\n\tif [ -x \"$_confdir/poststart.sh\" ]; then\n\t\t_info \"Executing the post-start script for the pot $_pname\"\n\t\t(\n\t\t\t# shellcheck disable=SC2046\n\t\t\teval $( pot info -E -p \"$_pname\" )\n\t\t\t\"$_confdir/poststart.sh\"\n\t\t)\n\tfi\n\n\tsleep 0.5\n\tpkill -f -j \"$_pname\" \"^sleep 1234$\"\n\n\tif [ \"$_persist\" = \"NO\" ]; then\n\t\techo \"$_wait_pid\" >\"${POT_TMP:-/tmp}/pot_main_pid_${_pname}\"\n\tfi\n\t# Here is where the pot is marked as started\n\t_set_pot_status \"$_pname\" started \"$_ifaces\"\n\trc=$?\n\tif [ $rc -eq 2 ]; then\n\t\t_info \"pot $_pname is already started (???)\"\n\telif [ $rc -eq 1 ]; then\n\t\t# should we retry (in case it's stopping?)\n\t\t_error \"pot $_pname is not in a state where it can be started\"\n\t\t# not returning, it could be catastrophic, but the situation is quite messed up\n\tfi\n\n\twait \"$_wait_pid\"\n\t_exit_code=$?\n\n\techo \"{ \\\"ExitCode\\\": $_exit_code }\" > \"$_confdir/.last_run_stats\"\n\n\tif [ \"$_persist\" = \"NO\" ]; then\n\t\trm -f \"${POT_TMP:-/tmp}/pot_main_pid_${_pname}\"\n\t\t# non-persistent jails always need to die\n\t\t# Here is where the pot is stopping\n\t\t_set_pot_status \"$_pname\" stopping\n\t\trc=$?\n\t\tif [ $rc -eq 2 ]; then\n\t\t\t_debug \"pot $_pname is already stopping (maybe by a pot stop)\"\n\t\t\treturn 0\n\t\telif [ $rc -eq 1 ]; then\n\t\t\t# should we retry (in case it's stopping?)\n\t\t\t_error \"pot $_pname is not in a state where it can be stopped\"\n\t\t\t# returning, but the situation is quite messed up\n\t\t\treturn 1\n\t\tfi\n\t\tstart-cleanup \"$_pname\" \"${_epaira}\" \"${_ipv6_epaira}\"\n\t\tif [ \"$_exit_code\" -ne 0 ]; then\n\t\t\t# return code to signal application exit error\n\t\t\treturn 125\n\t\tfi\n\telif ! _is_pot_running \"$_pname\" ; then\n\t\t# persistent jail didn't come up, this is an error\n\t\t_set_pot_status \"$_pname\" stopping\n\t\trc=$?\n\t\tif [ $rc -eq 2 ]; then\n\t\t\t_debug \"pot $_pname is already stopping (maybe by a pot stop?)\"\n\t\t\treturn 0\n\t\tfi\n\t\tif [ $rc -eq 1 ]; then\n\t\t\t# should we retry (in case it's stopping?)\n\t\t\t_error \"pot $_pname is not in a state where it can be stopped\"\n\t\t\t# returning, but the situation is quite messed up\n\t\t\treturn 1\n\t\tfi\n\t\tstart-cleanup \"$_pname\" \"${_epaira}\" \"${_ipv6_epaira}\"\n\t\treturn 1\n\tfi\n}\n\npot-start()\n{\n\tlocal _pname _snap _start_result\n\t_snap=none\n\t_pname=\n\tOPTIND=1\n\twhile getopts \"hvsSp:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tstart-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\ts)\n\t\t\t_snap=normal\n\t\t\t;;\n\t\tS)\n\t\t\t_snap=full\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\tstart-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_pname=\"$( eval echo \\$$OPTIND)\"\n\tfi\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tstart-help\n\t\treturn 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\treturn 1\n\tfi\n\tif _is_pot_running \"$_pname\" ; then\n\t\t_debug \"pot $_pname is already running\"\n\t\treturn 0\n\tfi\n\t## detect obsolete config parameter\n\tif [ -n \"$(_get_conf_var \"$_pname\" \"pot.export.static.ports\")\" ] ||\n\t\t[ -n \"$(_get_conf_var \"$_pname\" \"ip4\")\" ]; then\n\t\t_error \"Configuration file for $_pname contains obsolete elements\"\n\t\t_error \"Please run pot update-config -p $_pname to fix\"\n\t\treturn 1\n\tfi\n\tif [ -n \"$(_get_conf_var \"$_pname\" \"pot.rss.cpuset\")\" ]; then\n\t\t_info \"Found old cpuset rss limitation - it will be ignored\"\n\t\t_info \"Please run pot update-config -p $_pname to clean up the configuration\"\n\tfi\n\n\tif [ \"$( _get_pot_network_stack \"$_pname\" )\" = \"ipv6\" ] && [ \"$( _get_conf_var \"$_pname\" network_type )\" = \"private-bridge\" ]; then\n\t\t_error \"The framework is configured to run ipv6 only and private-bridge are supported only on ipv4 - abort\"\n\t\treturn 1\n\tfi\n\tif [ \"$( _get_pot_network_stack \"$_pname\" )\" = \"dual\" ] && [ \"$( _get_conf_var \"$_pname\" network_type )\" = \"private-bridge\" ]; then\n\t\t_info \"The framework is configured to run dual stack, but private-bridge are supported only on ipv4 - ipv6 ignored\"\n\tfi\n\tif _is_pot_vnet \"$_pname\" ; then\n\t\tif ! _is_vnet_available ; then\n\t\t\t_error \"This kernel doesn't support VIMAGE! No vnet possible - abort\"\n\t\t\treturn 1\n\t\tfi\n\tfi\n\tif ! _is_uid0 ; then\n\t\treturn 1\n\tfi\n\tif ! _is_pot_tmp_dir ; then\n\t\t_error \"failed to create the POT_TMP directory\"\n\t\treturn 1\n\tfi\n\n\t# Here is where the pot is starting\n\t_set_pot_status \"$_pname\" starting\n\trc=$?\n\tif [ $rc -eq 2 ]; then\n\t\t_error \"pot $_pname is already starting\"\n\t\treturn 1\n\tfi\n\tif [ $rc -eq 1 ]; then\n\t\t# should we retry (in case it's stopping?)\n\t\t_error \"pot $_pname is not in a state where it can start\"\n\t\treturn 1\n\tfi\n\n\tif ! _js_dep \"$_pname\" ; then\n\t\t_error \"dependecy failed to start\"\n\tfi\n\tcase $_snap in\n\t\tnormal)\n\t\t\t_pot_zfs_snap \"$_pname\"\n\t\t\t;;\n\t\tfull)\n\t\t\t_pot_zfs_snap_full \"$_pname\"\n\t\t\t;;\n\t\tnone|*)\n\t\t\t;;\n\tesac\n\tif ! _pot_mount \"$_pname\" ; then\n\t\t_error \"Mount failed \"\n\t\tstart-cleanup \"$_pname\"\n\t\treturn 1\n\tfi\n\tif ! _js_resolv \"$_pname\" ; then\n\t\tstart-cleanup \"$_pname\"\n\t\treturn 1\n\tfi\n\t_js_etc_hosts \"$_pname\"\n\t_js_start \"$_pname\"\n\t_start_result=$?\n\tif [ $_start_result -eq 125 ]; then\n\t\t_error \"$_pname reported application error\"\n\t\treturn 125\n\telif [ $_start_result -ne 0 ]; then\n\t\t_error \"$_pname failed to start\"\n\t\treturn 1\n\tfi\n\treturn 0\n}\n"
  },
  {
    "path": "share/pot/stop.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nstop-help()\n{\n\tcat <<-\"EOH\"\n\tpot stop [-hv] -p potname | potname\n\t  -h print this help\n\t  -v verbose\n\t  -i interface(s) : network interface (epaira) (INTERNAL USE ONLY)\n\t  -s called from start (INTERNAL USE ONLY)\n\t  -p potname : the pot to be stopped\n\t     the -p can be omitted and the last argument will be interpreted\n\t     as the potname\n\n\t  The option -i is intended to be used only by internal cleanup\n\t  functions that knows in advance what interface pot is/was using.\n\t  Usually, -i is NOT needed and it SHOULDN'T be used by users\n\tEOH\n}\n\n_js_cpu_rebalance()\n{\n\tif ! _tmpfile=$(mktemp -t \"${POT_TMP:-/tmp}/potcpu.XXXXXX\") ; then\n\t\t_error \"not able to create temporary file - umount failed\"\n\t\treturn\n\tfi\n\tpotcpu rebalance > \"$_tmpfile\"\n\twhile read -r cpuset_cmd ; do\n\t\teval \"$cpuset_cmd\"\n\tdone < \"$_tmpfile\"\n}\n\n# $1 pot name\n_js_stop()\n{\n\tlocal _pname _pdir _epaira _epaira_ifs _ip _aname _from_start\n\tlocal _exec_stop _stop_timeout\n\t_pname=\"$1\"\n\t_from_start=\"$2\"\n\t_epaira_ifs=\"$3\"\n\t_pdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\t_network_type=$( _get_pot_network_type \"$_pname\" )\n\tif _is_pot_running \"$_pname\" ; then\n\t\tif [ -x \"$_pdir/conf/prestop.sh\" ]; then\n\t\t\t_info \"Executing the pre-stop script for the pot $_pname\"\n\t\t\t(\n\t\t\t\t# shellcheck disable=SC2086,2046\n\t\t\t\teval $( pot info -E -p \"$_pname\" )\n\t\t\t\t\"$_pdir\"/conf/prestop.sh\n\t\t\t)\n\t\tfi\n\t\t_debug \"Stop the pot $_pname\"\n\n\t\t_exec_stop=\"$(_get_conf_var_string \"$_pname\" \"pot.attr.exec_stop\")\"\n\t\t_stop_timeout=\"$(_get_conf_var \"$_pname\" \"pot.attr.stop_timeout\")\"\n\t\t(\n\t\t\techo \"$_pname {\"\n\t\t\tif [ -n \"$_exec_stop\" ]; then\n\t\t\t\tprintf \"  %s=%s;\\n\" \"exec.stop\" \\\n\t\t\t\t       \"$(echo \"$_exec_stop\" | sed 's/[\"\\]/\\\\&/g; s/.*/\"&\"/')\"\n\n\t\t\t\t# balance quotes for cheap syntax highlighting editors'\n\t\t\tfi\n\t\t\tif [ -n \"$_stop_timeout\" ]; then\n\t\t\t\tprintf \"  %s=%s;\\n\" \"stop.timeout\" \"$_stop_timeout\"\n\t\t\tfi\n\t\t\techo \"}\"\n\t\t) | jail -f- -q -r \"$_pname\"\n\tfi\n\t# those are clean up operations for a pot already stopped\n\tif [ -n \"$_epaira_ifs\" ]; then\n\t\tfor _epaira in $(echo \"$_epaira_ifs\" | tr : ' '); do\n\t\t\t_debug \"Remove ${_epaira} epair network interfaces\"\n\t\t\tsleep 1 # try to avoid a race condition in the epair driver,\n\t\t\t\t# potentially causing a kernel panic, which should\n\t\t\t\t# be fixed in FreeBSD 13.1:\n\t\t\t\t# https://cgit.freebsd.org/src/commit/?h=stable/13&id=f4aba8c9f0c\n\t\t\tifconfig \"${_epaira}\" destroy\n\t\tdone\n\telif [ \"$_network_type\" = \"alias\" ]; then\n\t\t_ip=$( _get_ip_var \"$_pname\" )\n\t\t_debug \"Remove $_ip aliases\"\n\n\t\tfor _i in $_ip ; do\n\t\t\tif echo \"$_i\" | grep -qF '|' ; then\n\t\t\t\t_nic=\"$( echo \"$_i\" | cut -f 1 -d '|' )\"\n\t\t\t\t_ipaddr=\"$( echo \"$_i\" | cut -f 2 -d '|' )\"\n\t\t\telse\n\t\t\t\t_nic=\"$POT_EXTIF\"\n\t\t\t\t_ipaddr=\"$_i\"\n\t\t\tfi\n\t\t\tif potnet ip4check -H \"$_ipaddr\" ; then\n\t\t\t\tif ifconfig \"${_nic}\" | grep -q \"inet $_ipaddr \" ; then\n\t\t\t\t\tifconfig \"${_nic}\" inet \"$_ipaddr\" -alias\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\tif ifconfig \"${_nic}\" | grep -q \"inet6 $_ipaddr \" ; then\n\t\t\t\t\tifconfig \"${_nic}\" inet6 \"$_ipaddr\" -alias\n\t\t\t\tfi\n\t\t\tfi\n\t\tdone\n\tfi\n\tif [ -c \"/dev/pf\" ]; then\n\t\t_aname=\"$( _get_pot_rdr_anchor_name \"$_pname\" )\"\n\t\tpfctl -a \"pot-rdr/$_aname\" -F nat -q\n\tfi\n\n\t_ports=\"$( _get_pot_export_ports \"$_pname\" )\"\n\tif [ -n \"$_ports\" ]; then\n\t\tfor _port in $_ports ; do\n\t\t\t_pot_port=\"$( echo \"${_port}\" | cut -d':' -f 1)\"\n\t\t\tif [ -r \"$_pdir/ncat-$_pot_port.pid\" ]; then\n\t\t\t\tpkill -F \"$_pdir/ncat-$_pot_port.pid\" -f \"ncat-$_pname-$_pot_port\"\n\t\t\t\trm -f \"$_pdir/ncat-$_pot_port.pid\"\n\t\t\telif pgrep -q -f \"$_pdir/ncat-$_pname-$_pot_port\" ; then\n\t\t\t\tpkill -f \"$_pdir/ncat-$_pname-$_pot_port\"\n\t\t\tfi\n\t\tdone\n\tfi\n\t# For compatibility reason with the previous implementations\n\tif [ -r \"$_pdir/ncat.pid\" ]; then\n\t\tpkill -F \"$_pdir/ncat.pid\" -f \"ncat-$_pname\"\n\t\trm -f \"$_pdir/ncat.pid\"\n\telif pgrep -q -f \"$_pdir/ncat-$_pname\" ; then\n\t\tpkill -f \"$_pdir/ncat-$_pname\"\n\tfi\n\n\t# Garbage collect POSIX shared memory\n\tif command -v posixshmcontrol >/dev/null; then\n\t\t_shm_paths=$( posixshmcontrol ls | cut -f 5 | grep \"^$_pdir/\" )\n\t\tfor _shm_path in $_shm_paths ; do\n\t\t\tposixshmcontrol rm \"$_shm_path\"\n\t\tdone\n\tfi\n\n\tif [ -x \"$_pdir/conf/poststop.sh\" ]; then\n\t\t_info \"Executing the post-stop script for the pot $_pname\"\n\t\t(\n\t\t\t# shellcheck disable=SC2086,2046\n\t\t\teval $( pot info -E -p \"$_pname\" )\n\t\t\t\"${_pdir}\"/conf/poststop.sh\n\t\t)\n\tfi\n\trm -f \"${POT_TMP:-/tmp}/pot_pfrules_${_pname}*\"\n\trm -f \"${POT_TMP:-/tmp}/pot_environment_${_pname}*.sh\"\n\treturn 0 # true\n}\n\n# $1 pot name\n_js_rm_resolv()\n{\n\tlocal _pname _jdir _dns\n\t_pname=\"$1\"\n\t_jdir=\"${POT_FS_ROOT}/jails/$_pname\"\n\tif [ -f \"$_jdir/m/etc/resolv.conf\" ]; then\n\t\t_dns=\"$(_get_conf_var \"$_pname\" pot.dns)\"\n\t\tif [ \"$_dns\" != \"off\" ]; then\n\t\t\trm -f \"$_jdir/m/etc/resolv.conf\"\n\t\tfi\n\tfi\n}\n\npot-stop()\n{\n\tlocal _pname _ifnames _from_start\n\t_pname=\n\t_ifnames=\n\t_from_start=\"NO\"\n\n\tOPTIND=1\n\twhile getopts \"hvp:i:s\" _o; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tstop-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\ti)\n\t\t\t_ifnames=\"$OPTARG\"\n\t\t\t;;\n\t\ts)\n\t\t\t_from_start=\"YES\"\n\t\t\t;;\n\t\t?)\n\t\t\tstop-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_pname=\"$( eval echo \\$$OPTIND)\"\n\tfi\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tstop-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_pname\" quiet ; then\n\t\t_error \"The pot $_pname is not a valid pot\"\n\t\t${EXIT} 0\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\n\t# Here is where the pot is stopping\n\t_epaira_ifs=\"$(_set_pot_status \"$_pname\" stopping)\"\n\trc=$?\n\tif [ $rc -eq 2 ]; then\n\t\tif [ $_from_start = \"YES\" ]; then\n\t\t\t_debug \"pot $_pname is already stopping, but we are cleaning up from start-cleanup\"\n\t\telse\n\t\t\t_error \"pot $_pname is already stopping!\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif [ $rc -eq 1 ]; then\n\t\t_error \"pot $_pname is not in a state where it can be stopped\"\n\t\t${EXIT} 1\n\tfi\n\tif [ -z \"$_ifnames\" ]; then\n\t\t_ifnames=\"$_epaira_ifs\"\n\tfi\n\n\tif ! _js_stop \"$_pname\" \"$_from_start\" \"$_ifnames\"; then\n\t\t_error \"Stop the pot $_pname failed\"\n\t\t${EXIT} 1\n\tfi\n\t_js_rm_resolv \"$_pname\"\n\t_pot_umount \"$_pname\"\n\t_set_pot_status \"$_pname\" stopped\n\trc=$?\n\tif [ $rc -eq 2 ]; then\n\t\t_error \"pot $_pname is already stopped!\"\n\t\t${EXIT} 1\n\tfi\n\tif [ $rc -eq 1 ]; then\n\t\t_error \"pot $_pname is not in a state where it can marked as stopped\"\n\t\t${EXIT} 1\n\tfi\n}\n"
  },
  {
    "path": "share/pot/term.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nterm-help()\n{\n\tcat <<-\"EOH\"\n\tpot term [-hvf] -p potname [pname]\n\tpot run [-hv] -p potname [pname]\n\t  -h print this help\n\t  -v verbose\n\t  -f : start the pot if it is not running\n\t  -p potname : the pot to open terminal in\n\n\t  pname : pot to open terminal in if \"-p potname\" not given\n\tEOH\n}\n\n# TODO a configurable shell or a login shell\n# $1 pot name\n_term()\n{\n\tlocal _pname\n\t_pname=\"$1\"\n\tjexec -l -U root \"$_pname\"\n\t# This would perform a login (poudriere approach)\n\t# jexec \"$_pname\" env -i TERM=\"$TERM\" /usr/bin/login -fp root\n}\n\npot-term()\n{\n\tlocal _pname _force\n\t_pname=\n\t_force=\n\n\tOPTIND=1\n\twhile getopts \"hvfp:\" _o; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tterm-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tf)\n\t\t\t_force=\"YES\"\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tbreak\n\t\t\t;;\n\t\tesac\n\tdone\n\tif [ -z \"$_pname\" ]; then\n\t\t_pname=\"$(eval echo \\$$OPTIND)\"\n\tfi\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\tterm-help\n\t\t${EXIT} 1\n\tfi\n\t# shellcheck disable=2086\n\tif ! _is_pot_running $_pname ; then\n\t\tif [ \"$_force\" = \"YES\" ]; then\n\t\t\tif ! _is_uid0 ; then\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\n\t\t\tpot-cmd start \"$_pname\"\n\t\t\tif ! _is_pot_running \"$_pname\" ; then\n\t\t\t\t_error \"The pot $_pname doesn't start\"\n\t\t\t\t${EXIT} 1\n\t\t\tfi\n\t\telse\n\t\t\t_error \"The pot $_pname is not running\"\n\t\t\t${EXIT} 1\n\t\tfi\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\n\t_term \"$_pname\"\n}\n"
  },
  {
    "path": "share/pot/top.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\ntop-help()\n{\n\tcat <<-\"EOH\"\n\tpot top [-h] -p pot\n\t  -h print this help\n\t  -p pot : the working pot\n\tEOH\n}\n\npot-top()\n{\n\tlocal _pname _o\n\t_pname=\n\tOPTIND=1\n\twhile getopts \"hp:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\ttop-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\ttop-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif [ -z \"$_pname\" ]; then\n\t\t_error \"A pot name is mandatory\"\n\t\ttop-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"pot $_pname is not valid\"\n\t\ttop-help\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot_running \"$_pname\" ; then\n\t\t_error \"pot $_pname is not in execution\"\n\t\ttop-help\n\t\t${EXIT} 1\n\tfi\n\ttop -J \"$_pname\"\n}\n"
  },
  {
    "path": "share/pot/update-config.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nupdate-config-help()\n{\n\tcat <<-\"EOH\"\n\tpot update-config [-h] -p pot|-a\n\t  -h print this help\n\t  -v verbose\n\t  -p pot : the working pot\n\t  -a : apply to all pots\n\tEOH\n}\n\n# $1 pname\n_get_conf_static_ports()\n{\n\tlocal _pname _cdir _value\n\t_pname=\"$1\"\n\t_cdir=\"${POT_FS_ROOT}/jails/$_pname/conf\"\n\t_value=\"$( grep \"^pot.export.static.ports=\" \"$_cdir/pot.conf\" | cut -f2 -d'=' )\"\n\techo \"$_value\"\n}\n\n# $1 pname\n_update_one_pot()\n{\n\tlocal _pname _conf _attr _value\n\t_pname=\"$1\"\n\tif ! _is_pot \"$_pname\" ; then\n\t\t_error \"Invalid pot name\"\n\t\treturn 1\n\tfi\n\t_conf=\"${POT_FS_ROOT}/jails/${_pname}/conf/pot.conf\"\n\n\t# default configuration values\n\tif [ -z \"$(_get_conf_var \"$_pname\" pot.dns)\" ]; then\n\t\t_debug \"pot.dns=inherit\"\n\t\techo \"pot.dns=inherit\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" pot.cmd)\" ]; then\n\t\t_debug \"pot.cmd=sh /etc/rc\"\n\t\techo \"pot.cmd=sh /etc/rc\" >> \"$_conf\"\n\tfi\n\n\t# default attributes values\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.no-rc-script\")\" ]; then\n\t\t_debug \"pot.attr.no-rc-script=NO\"\n\t\techo \"pot.attr.no-rc-script=NO\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.persistent\")\" ]; then\n\t\t_debug \"pot.attr.persistent=YES\"\n\t\techo \"pot.attr.persistent=YES\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.start-at-boot\")\" ]; then\n\t\t_debug \"pot.attr.start-at-boot=NO\"\n\t\techo \"pot.attr.start-at-boot=NO\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.early.start-at-boot\")\" ]; then\n\t\t_debug \"pot.attr.early.start-at-boot=NO\"\n\t\techo \"pot.attr.early.start-at-boot=NO\" >> \"$_conf\"\n\tfi\n\n\tfor _attr in ${_POT_JAIL_RW_ATTRIBUTES} ; do\n\t\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.${_attr}\")\" ]; then\n\t\t\t# shellcheck disable=SC1083,2086\n\t\t\teval _value=\\\"\\${_POT_DEFAULT_${_attr}_D}\\\"\n\t\t\t_debug \"pot.attr.${_attr}=${_value}\"\n\t\t\techo \"pot.attr.${_attr}=${_value}\" >> \"$_conf\"\n\t\tfi\n\tdone\n\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.prunable\")\" ]; then\n\t\t_debug \"pot.attr.prunable=NO\"\n\t\techo \"pot.attr.prunable=NO\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.localhost-tunnel\")\" ]; then\n\t\t_debug \"pot.attr.localhost-tunnel=NO\"\n\t\techo \"pot.attr.localhost-tunnel=NO\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.no-tmpfs\")\" ]; then\n\t\t_debug \"pot.attr.no-tmpfs=NO\"\n\t\techo \"pot.attr.no-tmpfs=NO\" >> \"$_conf\"\n\tfi\n\tif [ -z \"$(_get_conf_var \"$_pname\" \"pot.attr.no-etc-hosts\")\" ]; then\n\t\t_debug \"pot.attr.no-etc-hosts=NO\"\n\t\techo \"pot.attr.no-etc-hosts=NO\" >> \"$_conf\"\n\tfi\n\n\t# convert pot.export.static.ports=80 to the new format pot.export.ports=80:80\n\t# being aware that pot.export.ports may already exist\n\tif [ -n \"$(_get_conf_static_ports \"$_pname\")\" ]; then\n\t\t_debug \"converting exported static ports using the new format\"\n\t\t_static_ports=\"$( _get_conf_static_ports \"$_pname\")\"\n\t\t${SED} -i '' -e \"/pot.export.static.ports=.*/d\" \"$_conf\"\n\t\t_new_ports=\n\t\tfor p in $_static_ports ; do\n\t\t\tif [ -z \"$_new_ports\" ]; then\n\t\t\t\t_new_ports=\"$p:$p\"\n\t\t\telse\n\t\t\t\t_new_ports=\"$_new_ports $p:$p\"\n\t\t\tfi\n\t\tdone\n\t\tif [ -n \"$(_get_pot_export_ports \"$_pname\")\" ]; then\n\t\t\t_ports=\"$(_get_pot_export_ports \"$_pname\")\"\n\t\t\t_new_ports=\"$_ports $_new_ports\"\n\t\t\t${SED} -i '' -e \"/pot.export.ports=.*/d\" \"$_conf\"\n\t\tfi\n\t\techo \"pot.export.ports=$_new_ports\" >> \"$_conf\"\n\tfi\n\n\t# convert ip4 and static entries with the new network_type and ip\n\tif [ -n \"$(_get_conf_var \"$_pname\" \"ip4\")\" ]; then\n\t\t_debug \"converting the network configuration using the new format\"\n\t\t_ip4=\"$(_get_conf_var \"$_pname\" \"ip4\")\"\n\t\t_vnet=\"$(_get_conf_var \"$_pname\" \"vnet\")\"\n\t\t${SED} -i '' -e \"/ip4=.*/d\" \"$_conf\"\n\t\tif [ \"$_ip4\" = \"inherit\" ]; then\n\t\t\techo \"network_type=inherit\" >> \"$_conf\"\n\t\telse\n\t\t\tif [ \"$_vnet\" = \"false\" ]; then\n\t\t\t\techo \"network_type=alias\" >> \"$_conf\"\n\t\t\telse\n\t\t\t\techo \"network_type=public-bridge\" >> \"$_conf\"\n\t\t\tfi\n\t\t\techo \"ip=$_ip4\" >> \"$_conf\"\n\t\tfi\n\tfi\n\n\t# remove the fixed cpuset rss allocation\n\tif [ -n \"$(_get_conf_var \"$_pname\" \"pot.rss.cpuset\")\" ]; then\n\t\t_info \"Removing cpuset rss allocation: $(_get_conf_var \"$_pname\" \"pot.rss.cpuset\")\"\n\t\t_info \"rss.cpuset has been deprecated; please use the more generic rss.cpus\"\n\t\t${SED} -i '' -e \"/pot.rss.cpuset=.*/d\" \"$_conf\"\n\tfi\n\n\t# remove the base pot path from mountpoints in fscomp.conf\n\t_update_fscomp \"$_pname\"\n}\n\n_update_all_pots()\n{\n\tlocal _pots\n\t_pots=\"$( _get_pot_list )\"\n\tfor _pname in $_pots ; do\n\t\tif ! _update_one_pot \"$_pname\" ; then\n\t\t\treturn 1\n\t\telse\n\t\t\t_debug \"Updated $_pname configuration\"\n\t\tfi\n\tdone\n}\n\npot-update-config()\n{\n\tlocal _pname _o _all\n\t_pname=\n\t_all=\n\tOPTIND=1\n\twhile getopts \"hvp:a\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tupdate-config-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tp)\n\t\t\t_pname=\"$OPTARG\"\n\t\t\t;;\n\t\ta)\n\t\t\t_all=\"YES\"\n\t\t\t;;\n\t\t*)\n\t\t\tupdate-config-help\n\t\t\t${EXIT} 1\n\t\tesac\n\tdone\n\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\n\tif [ -n \"$_pname\" ]; then\n\t\tif ! _update_one_pot \"$_pname\" ; then\n\t\t\t${EXIT} 1\n\t\tfi\n\telif [ \"$_all\" = \"YES\" ]; then\n\t\tif ! _update_all_pots ; then\n\t\t\t${EXIT} 1\n\t\tfi\n\telse\n\t\t_error \"A pot name or -a are mandatory\"\n\t\tupdate-config-help\n\t\t${EXIT} 1\n\tfi\n\t${EXIT} 0\n}\n"
  },
  {
    "path": "share/pot/version.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nversion-help()\n{\n\tcat <<-\"EOH\"\n\tpot version [-hvq]\n\t  -h print this help\n\t  -v verbose\n\t  -q quiet\n\tEOH\n}\n\n\npot-version()\n{\n\tlocal _quiet\n\t_quiet=\"NO\"\n\tOPTIND=1\n\twhile getopts \"hvq\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tversion-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tq)\n\t\t\t_quiet=\"YES\"\n\t\t\t;;\n\t\t?)\n\t\t\tversion-help\n\t\t\t${EXIT} 1\n\t\t\t;;\n\t\t*)\n\t\t\t;;\n\t\tesac\n\tdone\n\n\tif [ \"$_quiet\" = \"YES\" ]; then\n\t\t${ECHO} \"${_POT_VERSION}\"\n\t\t${EXIT} 0\n\tfi\n\techo \"pot version: $_POT_VERSION\"\n}\n"
  },
  {
    "path": "share/pot/vnet-start.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3033,SC3040,SC3043\n:\n\nvnet-start-help()\n{\n\tcat <<-\"EOH\"\n\tpot vnet-start [-hv] [-B bridge-name]\n\t  -h print this help\n\t  -v verbose\n\t  -B bridge-name (optional)\n\tEOH\n}\n\n_public_bridge_start()\n{\n\tlocal _bridge\n\t_bridge=$(_pot_bridge)\n\tif [ -z \"$_bridge\" ]; then\n\t\tif _bridge=$(ifconfig bridge create descr \"pot public bridge\" group \"pot\") ; then\n\t\t\t_debug \"Bridge created $_bridge\"\n\t\telse\n\t\t\t_error \"Bridge not created\"\n\t\tfi\n\t\tif ! ifconfig \"$_bridge\" inet \"$POT_GATEWAY\" netmask \"$POT_NETMASK\" ; then\n\t\t\t_error \"Error during bridge configuration ($_bridge)\"\n\t\telse\n\t\t\t_debug \"Bridge $_bridge configured with IP $POT_GATEWAY netmask $POT_NETMASK\"\n\t\tfi\n\telse\n\t\t_debug \"Bridge $_bridge already present\"\n\tfi\n}\n\n# $1 bridge_name\n_private_bridge_start()\n{\n\tlocal _bridge_name _bridge _gateway _bridge_net\n\t_bridge_name=\"$1\"\n\t_bridge=$(_private_bridge \"$_bridge_name\")\n\tif [ -z \"$_bridge\" ]; then\n\t\tif _bridge=$(ifconfig bridge create descr \"pot private bridge\" group \"pot\") ; then\n\t\t\t_debug \"Bridge created $_bridge\"\n\t\telse\n\t\t\t_error \"Bridge not created\"\n\t\tfi\n\t\t_gateway=\"$(_get_bridge_var \"$_bridge_name\" gateway)\"\n\t\t_bridge_net=\"$(_get_bridge_var \"$_bridge_name\" net)\"\n\t\t_bridge_net=\"${_bridge_net##*/}\"\n\t\tif ! ifconfig \"$_bridge\" inet \"${_gateway}/${_bridge_net}\" ; then\n\t\t\t_error \"Error during bridge configuration ($_bridge)\"\n\t\telse\n\t\t\t_debug \"Bridge $_bridge configured with IP ${_gateway}/${_bridge_net}\"\n\t\tfi\n\telse\n\t\t_debug \"Bridge $_bridge already present\"\n\tfi\n}\n\n_ipv4_start()\n{\n\tlocal _bridge_name pf_file _nat_rules _ext_addr\n\t_bridge_name=\"$1\"\n\t# activate ip forwarding\n\tif _is_verbose ; then\n\t\tsysctl net.inet.ip.forwarding=1\n\telse\n\t\tsysctl -qn net.inet.ip.forwarding=1 > /dev/null\n\tfi\n\tif [ -z \"$_bridge_name\" ]; then\n\t\t_public_bridge_start\n\telif _is_bridge \"$_bridge_name\" quiet ; then\n\t\t_private_bridge_start \"$_bridge_name\"\n\telse\n\t\t_error \"$_bridge_name is not a valid bridge\"\n\t\treturn\n\tfi\n\n\t# load pf module\n\tkldload -n pf\n\tpf_file=\"$(sysrc -n pf_rules)\"\n\t# check anchors\n\tif ! pfctl -s Anchors | grep -q '^[ \\t]*pot-nat$' ||\n\t\t! pfctl -s Anchors | grep -q '^[ \\t]*pot-rdr$' ; then\n\t\t_debug \"Pot anchors are missing - load $pf_file\"\n\t\tpfctl -f \"$pf_file\"\n\tfi\n\t_nat_rules=\"${POT_TMP:-/tmp}/pot_pf_nat_rules\"\n\tif [ -w \"$_nat_rules\" ]; then\n\t\trm -f \"$_nat_rules\"\n\tfi\n\tif [ -n \"$POT_EXTIF_ADDR\" ]; then\n\t\tif ! potnet ip4check --host \"$POT_EXTIF_ADDR\" ; then\n\t\t\t_info \"The value $POT_EXTIF_ADDR [POT_EXTIF_ADDR] is not a valid IPv4 address - ignoring\"\n\t\t\t_ext_addr=\n\t\telif ! _is_valid_extif_addr \"$POT_EXTIF\" \"$POT_EXTIF_ADDR\" ; then\n\t\t\t_info \"The IP address $POT_EXTIF_ADDR [POT_EXTIF_ADDR] is not available on the network interface $POT_EXTIF [POT_EXTIF]    \"\n\t\t\t_ext_addr=\n\t\telse\n\t\t\t_ext_addr=$POT_EXTIF_ADDR\n\t\tfi\n\tfi\n\t# NAT rules\n\t(\n\t\techo \"ext_if = \\\"${POT_EXTIF}\\\"\"\n\t\techo \"localnet = \\\"${POT_NETWORK}\\\"\"\n\t\tif [ -n \"$_ext_addr\" ]; then\n\t\t\techo \"ext_addr = \\\"${_ext_addr}\\\"\"\n\t\t\techo \"nat on \\$ext_if from \\$localnet to any -> \\$ext_addr\"\n\t\telse\n\t\t\techo \"nat on \\$ext_if from \\$localnet to any -> (\\$ext_if:0)\"\n\t\tfi\n\t) > \"$_nat_rules\"\n\n\t# EXTRA_EXTIF NAT rules\n\tif [ -n \"$POT_EXTRA_EXTIF\" ]; then\n\t\tfor extra_netif in $POT_EXTRA_EXTIF ; do\n\t\t\teval extra_net=\"\\$POT_NETWORK_$extra_netif\"\n\t\t\t# shellcheck disable=SC2154\n\t\t\tif [ -n \"$extra_net\" ]; then\n\t\t\t\techo \"nat on $extra_netif from \\$localnet to $extra_net -> ($extra_netif:0)\" >> \"$_nat_rules\"\n\t\t\tfi\n\t\tdone\n\tfi\n\t# VPN NAT rules\n\tif [ -n \"$POT_VPN_EXTIF\" ] && [ -n \"$POT_VPN_NETWORKS\" ]; then\n\t\tfor net in $POT_VPN_NETWORKS ; do\n\t\t\techo \"nat on $POT_VPN_EXTIF from \\$localnet to $net -> ($POT_VPN_EXTIF:0)\" >> \"$_nat_rules\"\n\t\tdone\n\tfi\n\n\tpfctl -a pot-nat -f \"$_nat_rules\"\n\trm -f \"$_nat_rules\"\n\t# load the rules\n\tif _is_verbose ; then\n\t\tpfctl -s nat -a pot-nat\n\tfi\n\tpfctl -e\n}\n\n_ipv6_bridge_start()\n{\n\tlocal _bridge\n\t_bridge=$(_pot_bridge_ipv6)\n\n\tif [ -z \"$_bridge\" ]; then\n\t\tif _bridge=$(ifconfig bridge create descr \"pot ipv6 bridge\" group \"pot\") ; then\n\t\t\t_debug \"Bridge created $_bridge\"\n\t\telse\n\t\t\t_error \"Bridge not created\"\n\t\tfi\n\t\tif ! ifconfig \"$_bridge\" inet6 up ; then\n\t\t\t_error \"Error during bridge configuration ($_bridge)\"\n\t\telse\n\t\t\t_debug \"Bridge $_bridge inet6 up\"\n\t\tfi\n\t\tif ! ifconfig \"$_bridge\" addm \"$POT_EXTIF\" ; then\n\t\t\t_error \"Error while adding $POT_EXTIF to the bridge ($_bridge)\"\n\t\telse\n\t\t\t_debug \"Bridge $_bridge addm $POT_EXTIF\"\n\t\tfi\n\telse\n\t\t_debug \"Bridge $_bridge already present\"\n\tfi\n}\n\n_ipv6_start()\n{\n\t_ipv6_bridge_start\n}\n\npot-vnet-start()\n{\n\tlocal _bridge_name\n\tOPTIND=1\n\twhile getopts \"hvB:\" _o ; do\n\t\tcase \"$_o\" in\n\t\th)\n\t\t\tvnet-start-help\n\t\t\t${EXIT} 0\n\t\t\t;;\n\t\tv)\n\t\t\t_POT_VERBOSITY=$(( _POT_VERBOSITY + 1))\n\t\t\t;;\n\t\tB)\n\t\t\t_bridge_name=\"$OPTARG\"\n\t\t\t;;\n\t\t?)\n\t\t\tbreak\n\t\t\t;;\n\t\tesac\n\tdone\n\n\t# Check configuration\n\tif [ -z \"${POT_NETWORK}\" ] || [ -z \"${POT_GATEWAY}\" ]; then\n\t\t_error \"No network or gateway defined\"\n\t\texit 1\n\tfi\n\tif [ -z \"${POT_EXTIF}\" ]; then\n\t\t_error \"No external interface defined\"\n\t\texit 1\n\tfi\n\tif ! _is_uid0 ; then\n\t\t${EXIT} 1\n\tfi\n\tif ! _is_pot_tmp_dir ; then\n\t\t_error \"The POT_TMP directory is not available - aborting\"\n\t\t${EXIT} 1\n\tfi\n\n\tcase \"$( _get_network_stack )\" in\n\t\tipv4)\n\t\t\t_ipv4_start \"$_bridge_name\"\n\t\t\t;;\n\t\tdual)\n\t\t\t_ipv4_start \"$_bridge_name\"\n\t\t\t_ipv6_start\n\t\t\t;;\n\t\tipv6)\n\t\t\t_ipv6_start\n\t\t\t;;\n\tesac\n}\n"
  },
  {
    "path": "share/zsh/site-functions/_pot",
    "content": "#compdef pot\n\n: ${POT_FS_ROOT:=$( pot config -qg fs_root )}\n\n_pot_pots() {\n        _values \"pot pots\" ${${(f)\"$(${service} ls -qp)\"}%% *}\n}\n\n_pot_run_pots() {\n        _values \"pot pots\" ${${(f)\"$(${service} ps -q)\"}%% *}\n}\n\n_pot_bases() {\n        _values \"pot pots\" ${${(f)\"$(${service} ls -qb)\"}%% *}\n}\n\n_pot_fscomps() {\n        _values \"pot flavors\" ${${(f)\"$(${service} ls -qf)\"}%% *}\n}\n\n_pot_bridges() {\n        _values \"pot bridges\" ${${(f)\"$(${service} ls -qB)\"}%% *}\n}\n\n_pot_flavours() {\n        _values \"pot flavors\" ${${(f)\"$(${service} ls -qF)\"}%% *}\n}\n\n_pot_attributes() {\n\t_values \"pot attributes\" 'start-at-boot' 'early-start-at-boot' 'persistent' 'no-rc-script' 'prunable' 'localhost-tunnel' 'no-tmpfs' 'no-etc-hosts' 'enforce_statfs' 'mount' 'fdescfs' 'linprocfs' 'nullfs' 'procfs' 'tmpfs' 'zfs' 'children'\n}\n\n_pot_network_type() {\n\t_values \"pot network type\" \"inherit\" \"alias\" \"public-bridge\" \"private-bridge\" \"private-bridge\"\n}\n\n_pot_network_stack_type() {\n\t_values \"pot network stack type\" \"ipv4\" \"ipv6\" \"dual\"\n}\n\n_pot() {\n\t_arguments \\\n\t\t'1: :_pot_cmds' \\\n\t\t'*:: :->args'\n\n\tcase $state in\n\t\targs)\n\t\t\tcase $words[1] in\n\t\t\t\tinit)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]'\n\t\t\t\t\t;;\n\t\t\t\tvnet-start)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_pot_bridges'\n\t\t\t\t\t;;\n\t\t\t\tconfig)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet output]' \\\n\t\t\t\t\t\t'-g[Element name]:config element name:(fs_root zfs_root gateway syslogd pot_prefix fscomp_prefix network_stack)'\n\t\t\t\t\t;;\n\t\t\t\tde-init)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-f[Force stop of all running pots]'\n\t\t\t\t\t;;\n\t\t\t\tversion|ps)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet output]'\n\t\t\t\t\t;;\n\t\t\t\tlist|ls)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet output]' \\\n\t\t\t\t\t\t'-p[List pots]' \\\n\t\t\t\t\t\t'-b[List bases]' \\\n\t\t\t\t\t\t'-f[List fscomps]' \\\n\t\t\t\t\t\t'-B[List bridges]' \\\n\t\t\t\t\t\t'-F[List flavours]' \\\n\t\t\t\t\t\t'-a[List them all]'\n\t\t\t\t\t;;\n\t\t\t\tinfo)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_pot_bridges' \\\n\t\t\t\t\t\t'-r[Check only if the pos is running]' \\\n\t\t\t\t\t\t'-s[List only the available snapshots of the pot]' \\\n\t\t\t\t\t\t'-E[Print few pot information as environment variables]'\n\t\t\t\t\t;;\n\t\t\t\tshow)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet output]' \\\n\t\t\t\t\t\t'-a[All pots]' \\\n\t\t\t\t\t\t'-r[All running pots]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots'\n\t\t\t\t\t;;\n\t\t\t\tcreate-base)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-r[Release number]:supported releases:_normal' \\\n\t\t\t\t\t\t'-b[base name]:base name:_normal'\n\t\t\t\t\t;;\n\t\t\t\tcreate-fscomp)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-f[fscomp name]:fscomp name:_normal'\n\t\t\t\t\t;;\n\t\t\t\tcreate-private-bridge)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-S[host number]:host number:_normal' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_normal'\n\t\t\t\t\t;;\n\t\t\t\tcreate)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-k[keep pot if it fails]' \\\n\t\t\t\t\t\t'-t[pot type]:pot type:(single multi)' \\\n\t\t\t\t\t\t'-N[network type]:network type:_pot_network_type' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_normal' \\\n\t\t\t\t\t\t'-P[pot reference]:pot reference name:_pot_pots' \\\n\t\t\t\t\t\t'-b[base version]:base version:_pot_bases' \\\n\t\t\t\t\t\t'-l[pot level]:level:(0 1 2)' \\\n\t\t\t\t\t\t'-t[pot type]:type:(multi single)' \\\n\t\t\t\t\t\t'*-i[network config]::_normal' \\\n\t\t\t\t\t\t'-d[dns type]:dns types:(inherit pot off custom:)' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_pot_bridges' \\\n\t\t\t\t\t\t'-S[network stack]:network stack:_pot_network_stack_type' \\\n\t\t\t\t\t\t'*-f[flavour name]:flavour name:_pot_flavours'\n\t\t\t\t\t;;\n\t\t\t\tclone-fscomp)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-f[fscomp name]::_normal' \\\n\t\t\t\t\t\t'-F[fscomp reference]:fscomp reference name:_pot_fscomps'\n\t\t\t\t\t;;\n\t\t\t\tclone)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-k[keep pot if it fails]' \\\n\t\t\t\t\t\t'-p[pot name]::_normal' \\\n\t\t\t\t\t\t'-P[pot reference]:pot reference name:_pot_pots' \\\n\t\t\t\t\t\t'*-f[flavour name]:flavour name:_pot_flavours' \\\n\t\t\t\t\t\t'-N[network type]:network type:_pot_network_type' \\\n\t\t\t\t\t\t'-i[network config]::_normal' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_pot_bridges' \\\n\t\t\t\t\t\t'-S[network stack]:network stack:_pot_network_stack_type' \\\n\t\t\t\t\t\t'-F[force snapshot of the pot reference]'\n\t\t\t\t\t;;\n\t\t\t\trename)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-n[pot new name]::_normal' \\\n\t\t\t\t\t\t'-p[pot old name]:pot old name:_pot_pots'\n\t\t\t\t\t;;\n\t\t\t\tdestroy)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet output]' \\\n\t\t\t\t\t\t'-F[Force the pot to stop]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-b[base name]:base name:_pot_bases' \\\n\t\t\t\t\t\t'-f[fscomp name]:fscomp name:_pot_fscomps' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_pot_bridges' \\\n\t\t\t\t\t\t'-r[Recursive destroying]'\n\t\t\t\t\t;;\n\t\t\t\tprune)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-q[Quiet outpu]' \\\n\t\t\t\t\t\t'-n[dry-run]'\n\t\t\t\t\t;;\n\t\t\t\tcopy-in)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-F[Force with running pots]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-s[source]:source:_normal' \\\n\t\t\t\t\t\t'-d[destination]:destination:_normal'\n\t\t\t\t\t;;\n\t\t\t\tcopy-out)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-F[Force with running pots]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-s[source]:source:_normal' \\\n\t\t\t\t\t\t'-d[destination]:destination:_normal'\n\t\t\t\t\t;;\n\t\t\t\tmount-in)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-m[mount point]:mount point:' \\\n\t\t\t\t\t\t'-d[directory]:directory:' \\\n\t\t\t\t\t\t'-z[zfs dataset]:zfs dataset:' \\\n\t\t\t\t\t\t'-f[fscomp name]:fscomp name:_pot_fscomps' \\\n\t\t\t\t\t\t'-w[zfs remount]' \\\n\t\t\t\t\t\t'-r[readonly]'\n\t\t\t\t\t;;\n\t\t\t\tmount-out)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-m[mount point]:mount point:'\n\t\t\t\t\t;;\n\t\t\t\tadd-dep)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-P[dependency pot name]:dependency pot name:_pot_pots'\n\t\t\t\t\t;;\n\t\t\t\tset-rss)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-C[Cpuset config]::_normal' \\\n\t\t\t\t\t\t'-M[Memory size]::_normal'\n\t\t\t\t\t;;\n\t\t\t\tget-rss)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-J[JSON output]'\n\t\t\t\t\t;;\n\t\t\t\tset-cmd)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-c[command]::_normal'\n\t\t\t\t\t;;\n\t\t\t\tset-env)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'*-E[variable list]::_normal'\n\t\t\t\t\t;;\n\t\t\t\tset-hosts)\n\t\t\t\t\t_arguments \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'*-H[hosts entry]::_normal'\n\t\t\t\t\t;;\n\t\t\t\tset-hook)\n\t\t\t\t\t_arguments \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-s[prestart hook]:prestart hook:_normal' \\\n\t\t\t\t\t\t'-S[poststart hook]:poststart hook:_normal' \\\n\t\t\t\t\t\t'-t[prestop hook]:prestop hook:_normal' \\\n\t\t\t\t\t\t'-T[poststop hook]:poststop hook:_normal'\n\t\t\t\t\t;;\n\t\t\t\tset-attr|set-attribute)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-A[attribute]:attribute:_pot_attributes' \\\n\t\t\t\t\t\t'-V[value]:value:_normal'\n\t\t\t\t\t;;\n\t\t\t\tget-attr|get-attribute)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-A[attribute]:attribute:_pot_attributes' \\\n\t\t\t\t\t\t'-q[Quiet output]'\n\t\t\t\t\t;;\n\t\t\t\texport-ports)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'*-e[port to be exported]::_normal'\n\t\t\t\t\t;;\n\t\t\t\tsnap|snapshot)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-r[replace the oldest snapshot]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-f[fscomp name]:fscomp name:_pot_fscomps'\n\t\t\t\t\t;;\n\t\t\t\trevert|rollback)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-f[fscomp name]:fscomp name:_pot_fscomps'\n\t\t\t\t\t;;\n\t\t\t\tpurge-snapshots)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-f[fscomp name]:fscomp name:_pot_fscomps' \\\n\t\t\t\t\t\t'-a[all snapshots, instead of the old ones]'\n\t\t\t\t\t;;\n\t\t\t\tupdate-config)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-a[all pots]'\n\t\t\t\t\t;;\n\t\t\t\texport)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t\t'-t[tag name]::_normal' \\\n\t\t\t\t\t\t'-D[target directory]:target directory:_normal' \\\n\t\t\t\t\t\t'-l[compression level]:compression level:(0 1 2 3 4 5 6 7 8 9)'\n\t\t\t\t\t;;\n\t\t\t\timport)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:' \\\n\t\t\t\t\t\t'-t[tag name]::_normal' \\\n\t\t\t\t\t\t'-U[URL]:URL:_normal'\n\t\t\t\t\t;;\n\t\t\t\tprepare)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-v[Verbose output]' \\\n\t\t\t\t\t\t'-S[auto start]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:' \\\n\t\t\t\t\t\t'-t[tag name]::_normal' \\\n\t\t\t\t\t\t'-a[allocation id]::_normal' \\\n\t\t\t\t\t\t'-n[the new pot name]::_normal' \\\n\t\t\t\t\t\t'-U[URL]:URL:_normal' \\\n\t\t\t\t\t\t'-N[network type]:network type:(inherit alias public-bridge)' \\\n\t\t\t\t\t\t'-B[bridge name]:bridge name:_pot_bridges' \\\n\t\t\t\t\t\t'-i[network config]::_normal' \\\n\t\t\t\t\t\t'*-e[port to be exported]::_normal' \\\n\t\t\t\t\t\t'-c[command]::_normal'\n\t\t\t\t\t;;\n\t\t\t\ttop)\n\t\t\t\t\t_arguments -s \\\n\t\t\t\t\t\t'-h[Show help]' \\\n\t\t\t\t\t\t'-p[pot name]:pot name:_pot_pots' \\\n\t\t\t\t\t;;\n\t\t\t\tstop)\n\t\t\t\t\t_arguments '1:pot name:_pot_run_pots'\n\t\t\t\t\t;;\n\t\t\t\tstart|term|run)\n\t\t\t\t\t_arguments '1:pot name:_pot_pots'\n\t\t\t\t\t;;\n\t\t\tesac\n\t\t\tcase \"$state\" in\n\t\t\t\tpot_names)\n\t\t\t\t\t_files -/ -W \"${POT_FS_ROOT}/jails/\" -S' '\n\t\t\t\t\t;;\n\t\t\t\tfscomp_names)\n\t\t\t\t\t_files -/ -W \"${POT_FS_ROOT}/fscomp/\" -S' '\n\t\t\t\t\t;;\n\t\t\t\tbase_names)\n\t\t\t\t\t_files -/ -W \"${POT_FS_ROOT}/bases/\" -S' '\n\t\t\t\t\t;;\n\t\t\tesac\n\tesac\n}\n\n_pot_cmds() {\n\tlocal -a commands;\n\tcommands=(\n\t'help:Show help'\n\t'version:Show version'\n\t'config:Show framework config values'\n\t'top:Run top in pot'\n\t'ls:List elements'\n\t'list:List elements'\n\t'show:Show pot resources'\n\t'info:Show info on pot'\n\t'top:Show processes (top) running in the pot'\n\t'ps:Show running pots'\n\t'init:Init ZFS'\n\t'de-init:Remove all ZFS datasets'\n\t'vnet-start:Start the vnet configuration'\n\t'create-base:Create a new base image'\n\t'create-fscomp:Create a new fs component'\n\t'create-private-bridge:Create a new private bridge'\n\t'create:Create a new pot'\n\t'clone:Clone a pot'\n\t'clone-fscomp:Clone a fs component'\n\t'rename:Rename a pot'\n\t'destroy:Destroy a pot'\n\t'prune:Destroy not running prunable pots'\n\t'copy-in:Copy a file or a directory into a pot'\n\t'mount-in:Mount a directory, a zfs dataset or a fscomp into a pot'\n\t'add-dep:Add a dependency to a pot'\n\t'set-rss:Set a resource constraint to a pot'\n\t'get-rss:Get the current resource usage'\n\t'set-cmd:Set the initial command of a pot'\n\t'set-env:Set environment variables inside a pot'\n\t'set-hosts:Set etc/hosts entries inside a pot'\n\t'set-hook:Set hook scripts for a pot'\n\t'set-attr:Set the value of a pot attribute'\n\t'set-attribute:Set the value of a pot attribute'\n\t'get-attr:Get the value of a pot attribute'\n\t'get-attribute:Get the value of a pot attribute'\n\t'export-ports:export ports of a pot'\n\t'start:Start a pot'\n\t'stop:Stop a pot'\n\t'run:Start a pot and open a shell in it'\n\t'term:Open a shell in a pot'\n\t'snap:Take a snapshot of a pot'\n\t'snapshot:Take a snapshot of a pot'\n\t'revert:Restore the last snapshot of a pot'\n\t'rollback:Restore the last snapshot of a pot'\n\t'purge-snapshots:Remove old or all snapshots'\n\t'export:Export a single-type pot'\n\t'import:Import a single-type pot'\n\t'prepare:Import and prepare a pot - designed for jail orchestrator'\n\t'update-config:Update the configuration of a pot'\n\t)\n\t_describe 'command' commands\n}\n\n_pot\n"
  },
  {
    "path": "tests/CI/resolv.conf-dual",
    "content": "nameserver 1.1.1.1\nnameserver 1.0.0.1\nnameserver 2606:4700:4700::1111\nnameserver 2606:4700:4700::1001\n\n"
  },
  {
    "path": "tests/CI/resolv.conf-ipv4",
    "content": "nameserver 1.1.1.1\nnameserver 1.0.0.1\n\n"
  },
  {
    "path": "tests/CI/resolv.conf-ipv6",
    "content": "nameserver 2606:4700:4700::1111\nnameserver 2606:4700:4700::1001\n\n"
  },
  {
    "path": "tests/CI/run.sh",
    "content": "#!/bin/sh\n\nexport POT_PATH=$( realpath $( dirname $(realpath $0))/../..)\nexport PATH=$POT_PATH/bin:$PATH\ntimestamp=\"$(date +%Y%m%d%H%M)\"\nexport logfile=\"pot-ci-${timestamp}\"\n\nerror() {\n\ttest_name=\"${1:-unknown}\"\n\techo \"Test ${test_name} failed ($2)\" >> $logfile\n\tend\n\texit 1\n}\n\nbegin()\n{\n\techo \"Start pot-ci at $(date)\" > $logfile\n\tif [ ! -d /var/cache/pot ]; then\n\t\tmkdir -p /var/cache/pot\n\tfi\n\tif [ ! -d /var/cache/pot ]; then\n\t\techo \"pot's cache cannot be generated - aborting\"\n\t\texit 1\n\tfi\n}\n\nend()\n{\n\techo \"End pot-ci at $(date)\" >> $logfile\n}\n\nsuccess()\n{\n\techo \"The test execution was succesfull :+1:\"\n}\n\nempty_check() {\n\tif [ -n \"$(pot ls -q)\" ]; then\n\t\techo \"POT LS IS:\"\n\t\tpot ls -q\n\t\tls -al /opt/pot/jails\n\t\tls -al /opt/pot/jails/*\n\t\tzfs list\n\t\terror \"$1\" \"pot not deleted\"\n\tfi\n\tif [ -n \"$(pot ls -qb)\" ]; then\n\t\terror \"$1\" \"base not deleted\"\n\tfi\n\tif [ -n \"$(pot ls -qf)\" ]; then\n\t\terror \"$1\" \"fscomp not deleted\"\n\tfi\n\tif [ -n \"$(pot ls -qB)\" ]; then\n\t\terror \"$1\" \"bridge not deleted\"\n\tfi\n}\n\nset_stack() {\n\tlocal s=$1\n\tlocal conf=$POT_PATH/etc/pot/pot.conf\n\tif grep -q ^POT_NETWORK_STACK $conf ; then\n\t\tif [ -L $conf ]; then\n\t\t\techo POT_NETWORK_STACK=$s >> $conf\n\t\telse\n\t\t\tsed -i '' -e \"s/POT_NETWORK_STACK=.*$/POT_NETWORK_STACK=$s/\" $conf\n\t\tfi\n\telse\n\t\techo POT_NETWORK_STACK=$s >> $conf\n\tfi\n}\n\n# $1 type\n# $2 base_version\n# $3 network\n# $4 stack\nget_pot_name() {\n\tt=$1\n\tb=$( echo $2 | tr '.' '_' )\n\tn=$3\n\ts=$4\n\techo $t-$b-$n-$s-test\n}\n\n# $1 type\n# $2 base_version\n# $3 network type\n# $4 stack\ncreate_test() {\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tlocal fopt\n\tt=$1\n\tb=$2\n\tn=$3\n\ts=$4\n\tf=$5\n\tfopt=\n\tif [ \"$t\" = \"multi\" ]; then\n\t\tif ! pot create-base -v -r $b ; then\n\t\t\terror $name create-base\n\t\tfi\n\telif [ \"$f\" = \"slim\" ]; then\n\t\tfopt=\"-f slim\"\n\tfi\n\tcase $n in\n\t\talias)\n\t\t\tif ! pot create -v -p $name -t $t -b $b -N $n -i fdf2:f389:1f56:164b::1 -i 172.20.135.253 $fopt ; then\n\t\t\t\terror $name create\n\t\t\tfi\n\t\t\t;;\n\t\tprivate-bridge)\n\t\t\t# create bridge\n\t\t\tif ! pot create-private-bridge -v -B testprivate -S 5 ; then\n\t\t\t\terror $name create-private-bridge\n\t\t\tfi\n\t\t\tif [ \"$s\" = \"ipv6\" ]; then\n\t\t\t\tif pot create -v -p $name -t $t -b $b -N $n -B testprivate $fopt ; then\n\t\t\t\t\terror $name create\n\t\t\t\tfi\n\t\t\t\tif ! pot destroy -B testprivate ; then\n\t\t\t\t\terror $name destroy-bridge-after-nocreate\n\t\t\t\tfi\n\t\t\t\tif [ \"$t\" = \"multi\" ]; then\n\t\t\t\t\tif ! pot destroy -v -b $b ; then\n\t\t\t\t\t\terror $name destroy-base-after-nocreate\n\t\t\t\t\tfi\n\t\t\t\tfi\n\t\t\telse\n\t\t\t\tif ! pot create -v -p $name -t $t -b $b -N $n -B testprivate -d custom:resolv.conf-ipv4 $fopt ; then\n\t\t\t\t\terror $name create\n\t\t\t\tfi\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\tif ! pot create -v -p $name -t $t -b $b -N $n -d custom:resolv.conf-$s $fopt ; then\n\t\t\t\terror $name create\n\t\t\tfi\n\tesac\n}\n\n# $1 name\n# $2 type\nsnap_test() {\n\tlocal name=${1}\n\tcase $2 in\n\tsingle)\n\t\tsnaps=2\n\t\t;;\n\tmulti)\n\t\tsnaps=3\n\t\t;;\n\tesac\n\tif ! pot snap -p $name ; then\n\t\terror $name snap\n\tfi\n\tif [ \"$(pot info -v -p $name | grep -A 10 snapshot | grep -Fv snapshot | grep -Fc $name )\" -ne $snaps ]; then\n\t\terror $name snap-info\n\tfi\n}\n\n# $1 pot name\n# $2 type\nexport_test() {\n\tlocal name=$1\n\tlocal type=$2\n\tcase $type in\n\tsingle)\n\t\tif ! pot export -p $name -t 0 -l 0; then\n\t\t\terror $name export-single\n\t\tfi\n\t\t;;\n\tmulti)\n\t\tif pot export -p $name -l 0; then\n\t\t\terror $name export-no-multi\n\t\tfi\n\t\treturn\n\t\t;;\n\tesac\n\tif ! pot import -p $name -t 0 -U file://. ; then\n\t\terror $name import\n\tfi\n\tif ! pot destroy -p ${name}_0 ; then\n\t\terror $name import-destroy\n\tfi\n\trm -rf *.xz*\n\trm -rf /var/cache/pot/*.xz*\n}\n\n# $1 pot name\nfscomp_test() {\n\tlocal name=$1\n\tif ! pot create-fscomp -f fscomp ; then\n\t\terror $name create-fscomp\n\tfi\n\tif ! pot mount-in -p $name -f fscomp -m /media ; then\n\t\terror $name mount-in\n\tfi\n}\n\ncopy_test() {\n\tlocal name=$1\n\tif ! pot copy-in -p $name -s /etc/protocols -d /root ; then\n\t\terror $name copy-in\n\tfi\n}\n\n# $1 pot name\n_get_ip() {\n\tlocal name=$1\n\tpot info -p $name | grep \"ip \" | awk '{ print $3 }'\n}\n\n# $1 pot name\n# $2 network\n# $3 stack\nstartstop_test() {\n\tlocal name=$1\n\tlocal n=$2\n\tlocal s=$3\n\tif [ $s = \"ipv6\" ] && [ $n = \"private-bridge\" ]; then\n\t\tif pot start $name ; then\n\t\t\terror $name no-start\n\t\tfi\n\t\treturn 0\n\tfi\n\tif ! pot start $name ; then\n\t\terror $name start\n\tfi\n\tif [ \"$4\" = \"check-copy-in\" ]; then\n\t\tif ! jexec $name test -f /root/protocols ; then\n\t\t\terror $name no-copied-file\n\t\tfi\n\tfi\n\t# runtime checks\n\tif [ \"$(pot show | grep -c $name)\" -ne 1 ]; then\n\t\terror $name show\n\tfi\n\tif [ $s = \"ipv4\" ] || [ $s = \"dual\" ]; then\n\t\tif [ $n = \"public-bridge\" ] || [ $n = \"private-bridge\" ] ; then\n\t\t\tip4=\"$( _get_ip $name )\"\n\t\t\tif ! ping -c 1 $ip4 ; then\n\t\t\t\terror $name ping-bridge\n\t\t\tfi\n\t\tfi\n\t\t# temporary disable ping tests for alias\n\t\tif [ \"$n\" = \"alias\" ]; then\n\t\t\tif ! pot stop $name ; then\n\t\t\t\terror $name stop\n\t\t\tfi\n\t\t\treturn 0\n\t\tfi\n\t\t# test ICMP\n\t\tif ! jexec $name ping -c 1 1.1.1.1 ; then\n\t\t\terror $name ping-nat\n\t\tfi\n\t\tif ! jexec $name drill google.com @1.1.1.1 A ; then\n\t\t\terror $name udp-nat\n\t\tfi\n\t\tif ! jexec $name fetch -4 -o /dev/null http://neverssl.com  ; then\n\t\t\terror $name tcp-nat\n\t\tfi\n\tfi\n\tif [ $s = \"ipv6\" ] || [ $s = \"dual\" ]; then\n\t\t# temporary disable ping tests for alias\n\t\tif [ \"$n\" = \"alias\" ]; then\n\t\t\tif ! pot stop $name ; then\n\t\t\t\terror $name stop\n\t\t\tfi\n\t\t\treturn 0\n\t\tfi\n\t\tif [ $n != \"private-bridge\" ]; then\n\t\t\tif ! jexec $name ping6 -c 1 2606:4700:4700::1111 ; then\n\t\t\t\terror $name ping6-ipv6\n\t\t\tfi\n\t\t\tif ! jexec $name drill google.com @2606:4700:4700::1111 AAAA ; then\n\t\t\t\terror $name ping6-ipv6\n\t\t\tfi\n\t\t\tif ! jexec $name fetch -6 -o /dev/null http://www.google.com  ; then\n\t\t\t\terror $name tcp-nat\n\t\t\tfi\n\t\tfi\n\tfi\n\tif [ \"$name\" != \"${name%%clone}\" ]; then\n\t\tif ! jexec $name /usr/local/sbin/pkg -v ; then\n\t\t\terror $name flavor on clone\n\t\tfi\n\tfi\n\tif ! pot stop $name ; then\n\t\terror $name stop\n\tfi\n}\n\n# $1 type\n# $2 base\n# $3 network\n# $4 stack\ndestroy_test() {\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tcase $1 in\n\tsingle)\n\t\tif ! pot destroy -p $name ; then\n\t\t\terror $name destroy\n\t\tfi\n\t\t;;\n\tmulti)\n\t\tif pot destroy -b $2 ; then\n\t\t\terror $name no-destroy-base-$2\n\t\tfi\n\t\tif ! pot destroy -rb $2 ; then\n\t\t\terror $name destroy-base-$2\n\t\tfi\n\t\t;;\n\tesac\n\tif ! pot destroy -f fscomp ; then\n\t\terror $name destroy-fscomp\n\tfi\n\tif [ \"$3\" = \"private-bridge\" ]; then\n\t\tif ! pot destroy -B testprivate ; then\n\t\t\terror $name destroy-bridge\n\t\tfi\n\tfi\n}\n\n# $1 type\n# $2 base\n# $3 network\ndestroy_corrupted_test() {\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tcase $1 in\n\tsingle)\n\t\tif pot destroy -p $name ; then\n\t\t\terror $name not-destroy-corrupted\n\t\tfi\n\t\tif ! pot destroy -p $name -F ; then\n\t\t\terror $name destroy-corrupted\n\t\tfi\n\t\t;;\n\tmulti)\n\t\tif pot destroy -p $name ; then\n\t\t\terror $name not-destroy-corrupted\n\t\tfi\n\t\tif ! pot destroy -p $name -F ; then\n\t\t\terror $name destroy-corrupted\n\t\tfi\n\t\tif ! pot destroy -rb $2 ; then\n\t\t\terror $name destroy-base-$2\n\t\tfi\n\t\t;;\n\tesac\n\tif [ \"$3\" = \"private-bridge\" ]; then\n\t\tif ! pot destroy -B testprivate ; then\n\t\t\terror $name destroy-bridge\n\t\tfi\n\tfi\n}\n\n# $1 pot name\n# $2 new name\nrename_test() {\n\tlocal name=$1\n\tlocal new_name=$2\n\tif ! pot rename -p $name -n $new_name ; then\n\t\terror $name rename\n\tfi\n\tif [ \"$( pot ls -q | grep -c \"^${name}$\")\" != \"0\" ]; then\n\t\terror $name rename-not-renamed\n\tfi\n\tif [ \"$( pot ls -q | grep -c \"^${new_name}$\")\" != \"1\" ]; then\n\t\terror $name rename-no-new-name\n\tfi\n}\n\n# $1 pot name\n# $2 type\n# $3 base\n# $4 network\ndestroy_rename_test() {\n\tlocal name=${1}\n\tlocal t=${2}\n\tlocal b=${3}\n\tlocal n=${4}\n\tcase $t in\n\tsingle)\n\t\tif ! pot destroy -p $name ; then\n\t\t\terror $name destroy\n\t\tfi\n\t\t;;\n\tmulti)\n\t\tif pot destroy -b $b ; then\n\t\t\terror $name no-destroy-base-$b\n\t\tfi\n\t\tif ! pot destroy -rb $b ; then\n\t\t\terror $name destroy-base-$b\n\t\tfi\n\t\t;;\n\tesac\n\tif ! pot destroy -f fscomp ; then\n\t\terror $name destroy-fscom\n\tfi\n\tif [ \"$n\" = \"private-bridge\" ]; then\n\t\tif ! pot destroy -B testprivate ; then\n\t\t\terror $name destroy-bridge\n\t\tfi\n\tfi\n}\n\n# $1 base pot name\n# $2 network\n# $3 stack\nclone_test() {\n\tlocal name=${1}\n\tlocal cloned_name=${1}-clone\n\tlocal n=${2}\n\tlocal s=${3}\n\n\tflv_dir=$POT_PATH/etc/pot/flavours\n\t# add a flavour\n\t(\n\tcat << PKG_FLV\n#!/bin/sh\nASSUME_ALWAYS_YES=yes pkg bootstrap\nPKG_FLV\n) > $flv_dir/pkg.sh\n\tchmod a+x $flv_dir/pkg.sh\n\tif [ \"$n\" = \"private-bridge\" ]; then\n\t\tif ! pot clone -p $cloned_name -P $name -f pkg -F -B testprivate ; then\n\t\t\terror $name clone\n\t\tfi\n\telse\n\t\tif ! pot clone -p $cloned_name -P $name -f pkg -F ; then\n\t\t\terror $name clone\n\t\tfi\n\tfi\n\tstartstop_test $cloned_name $n $s\n\tif ! pot destroy -p $cloned_name ; then\n\t\terror $name destroy\n\tfi\n\trm $flv_dir/pkg.sh\n}\n\n# $1 type\n# $2 base_version\n# $3 network\n# $4 stack\npot_test() {\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tlogger -p local2.info -t pot-CI \"pot_test: $name\"\n\tcreate_test $1 $2 $3 $4 slim\n\tif [ $4 = \"ipv6\" ] && [ $3 = \"private-bridge\" ]; then\n\t\treturn\n\tfi\n\tcopy_test $name\n\tsnap_test $name $1\n\texport_test $name $1\n\tfscomp_test $name\n\tstartstop_test $name $3 $4 check-copy-in\n\tlocal new_name=${name}_new\n\trename_test $name $new_name\n\tstartstop_test $new_name $3 $4\n\tdestroy_rename_test $new_name $1 $2 $3\n\tempty_check $name\n}\n\n# $1 type\n# $2 base_version\n# $3 network\n# $4 stack\npot_corrupted_test() {\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tlogger -p local2.info -t pot-CI \"pot_corrupted_test: $name\"\n\tcreate_test $1 $2 $3 $4\n\tclone_test $name $3 $4\n\trm -rf /opt/pot/jails/$name/conf\n\tdestroy_corrupted_test $1 $2 $3 $4\n\tempty_check $name\n}\n\n# $1 type\n# $2 base_version\n# $3 network\n# $4 stack\npot_rename_test()\n{\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tlogger -p local2.info -t pot-CI \"pot_rename_test: $name\"\n\tlocal new_name=${name}_new\n\tcreate_test $1 $2 $3 $4\n\trename_test $name $new_name\n\tstartstop_test $new_name $3 $4\n\tdestroy_rename_test $new_name $1 $2 $3\n\tempty_check $name\n}\n\n# $1 type\n# $2 base_version\n# $3 network\n# $4 stack\npot_create_fail_test()\n{\n\tlocal name=$( get_pot_name $1 $2 $3 $4 )\n\tlogger -p local2.info -t pot-CI \"pot_create_fail_test: $name\"\n\tlocal flv_dir\n\tif [ \"$3\" != \"inherit\" ]; then\n\t\treturn 0\n\tfi\n\tflv_dir=$POT_PATH/etc/pot/flavours\n\t# add a broken flavour\n\t(\n\tcat << BROKEN_FLV\n#!/bin/sh\n\nfalse\nBROKEN_FLV\n) > $flv_dir/broken.sh\n\tchmod a+x $flv_dir/broken.sh\n\tif [ \"$1\" = \"multi\" ]; then\n\t\tif ! pot create-base -v -r $b ; then\n\t\t\terror $name create-base\n\t\tfi\n\tfi\n\n\tif pot create -p -v -p $name -t $1 -b $2 -N $3 -f broken ; then\n\t\terror $name create_fail\n\tfi\n\trm $flv_dir/broken.sh\n\tif [ \"$1\" = \"multi\" ]; then\n\t\tpot destroy -b $2\n\tfi\n\tempty_check $name\n}\n\nSTACKS=\"ipv4\"\nif ping6 -c3 www.kame.net; then\n\techo \"IPv6 seems to work, add dual and ipv6 stacks\"\n\tSTACKS=\"$STACKS dual ipv6\"\nelse\n\techo \"IPv6 not available, only testing $STACKS\"\nfi\n\nVERSIONS=\"12.3 13.1\"\nTYPES=\"single multi\"\n#NETWORKS=\"alias inherit public-bridge private-bridge\"\nNETWORKS=\"inherit public-bridge private-bridge\"\nbegin\n\nempty_check initial_check\npfctl -F all\nfor s in $STACKS ; do\n\tset_stack $s\n\tfor b in $VERSIONS ; do\n\t\tfor t in $TYPES ; do\n\t\t\tfor n in $NETWORKS ; do\n\t\t\t\techo \"testing $t $b $n $s $(date)\" >> $logfile\n\t\t\t\tpot_test $t $b $n $s\n\t\t\t\tif [ $n = \"private-bridge\" ] && [ $s = \"ipv6\" ]; then\n\t\t\t\t\tcontinue\n\t\t\t\tfi\n\t\t\t\tpot_corrupted_test $t $b $n $s\n\t\t\t\tpot_create_fail_test $t $b $n $s\n\t\t\t\techo \"tested $t $b $n $s $(date)\" >> $logfile\n\t\t\tdone\n\t\tdone\n\tdone\ndone\n\nend\nsuccess\n"
  },
  {
    "path": "tests/add-dep1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/add-dep.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nadd-dep-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_add_dependency()\n{\n\t__monitor ADDDEP \"$@\"\n}\n\ntest_pot_add_dep_001()\n{\n\tpot-add-dep\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n}\n\ntest_pot_add_dep_002()\n{\n\tpot-add-dep -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -P test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -P test-pot -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -p test-pot -P test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"2\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n\n\tsetUp\n\tpot-add-dep -P test-pot -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"0\" ADDDEP_CALLS\n}\n\ntest_pot_add_dep_020()\n{\n\tpot-add-dep -P test-pot -p test-pot-2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"2\" ISPOT_CALLS\n\tassertEqualsMon \"_add_dependency calls\" \"1\" ADDDEP_CALLS\n\tassertEqualsMon \"pot name \" \"test-pot-2\" ADDDEP_CALL1_ARG1\n\tassertEqualsMon \"run time dependency\" \"test-pot\" ADDDEP_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/clone-fscomp1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/clone-fscomp.sh\n\n# common stubs\n. common-stub.sh\n\n_zfs_dataset_valid()\n{\n\t__monitor ZDSET \"$@\"\n\tif [ \"$1\" = \"/fscomp/test-fscomp\" ]; then\n\t\treturn 0 # true\n\tfi\n\tif [ \"$1\" = \"/fscomp/test-fscomp2\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n# app specific stubs\nclone-fscomp-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_cf_zfs()\n{\n\t__monitor CFZFS \"$@\"\n\treturn 0 # true\n}\n\ntest_pot_add_fscomp_001()\n{\n\tpot-clone-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-clone-fscomp -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-clone-fscomp -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-clone-fscomp -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_add_fscomp_002()\n{\n\tpot-clone-fscomp -f new-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cf_zfs calls\" \"0\" CFZFS_CALLS\n\n\tsetUp\n\tpot-clone-fscomp -F test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cf_zfs calls\" \"0\" CFZFS_CALLS\n}\n\ntest_pot_add_fscomp_003()\n{\n\tpot-clone-fscomp -f new-fscomp -F test-no-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"2\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cf_zfs calls\" \"0\" CFZFS_CALLS\n\n\tsetUp\n\tpot-clone-fscomp -f test-fscomp2 -F test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"1\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cf_zfs calls\" \"0\" CFZFS_CALLS\n}\n\ntest_pot_add_fscomp_020()\n{\n\tpot-clone-fscomp -f new-fscomp -F test-fscomp\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"2\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cf_zfs calls\" \"1\" CFZFS_CALLS\n\tassertEqualsMon \"_cf_zfs arg1\" \"new-fscomp\" CFZFS_CALL1_ARG1\n\tassertEqualsMon \"_cf_zfs arg2\" \"test-fscomp\" CFZFS_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/clone1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npotnet()\n{\n\t# no monitor, potnet is called in a subshell\n\tif [ \"$1\" = \"next\" ]; then\n\t\tif [ \"$2\" = \"-b\" ] && [ \"$3\" = \"test-bridge\" ]; then\n\t\t\techo \"10.1.3.4\"\n\t\telse\n\t\t\techo \"10.123.123.123\"\n\t\tfi\n\t\treturn 0 # true\n\tfi\n\tif [ \"$1\" = \"validate\" ] && [ \"$2\" = \"-H\" ] ; then\n\t\tif [ \"$4\" = \"-b\" ] && [ \"$5\" = \"test-bridge\" ]; then\n\t\t\tif [ \"$3\" = \"10.1.3.4\" ]; then\n\t\t\t\treturn 0 # true\n\t\t\tfi\n\t\tfi\n\t\tif [ \"$3\" = \"10.123.123.123\" ] || [ \"$3\" = \"10.1.2.4\" ]; then\n\t\t\treturn 0 # true\n\t\tfi\n\tfi\n\tif [ \"$1\" = \"ipcheck\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n. pipefail-stub.sh\n\n# UUT\n. ../share/pot/clone.sh\n\n# common stubs\n. common-stub.sh\n\n_is_potnet_available()\n{\n\treturn 0 # true\n}\n\n_is_vnet_available()\n{\n\treturn 0 # true\n}\n\n_get_pot_snaps()\n{\n\techo 12341234\n\techo 12345678\n}\n# app specific stubs\n_cj_zfs()\n{\n\t__monitor CJZFS \"$@\"\n}\n\n_cj_conf()\n{\n\t__monitor CJCONF \"$@\"\n}\n\n_exec_flv()\n{\n\t__monitor EXEC_FLV \"$@\"\n}\n\nclone-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_clone_001()\n{\n\tpot-clone\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-clone -vL\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-clone -L bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-clone -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-clone -S\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_002()\n{\n\tpot-clone -p new-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-clone -P test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_003()\n{\n\tpot-clone -p new-pot -P no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-clone -p test-pot -P test-pot-2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_004()\n{\n\t# missing -i parameter when needed\n\tpot-clone -p new-pot -P test-pot-3\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_006()\n{\n\t# ip address already in use\n\tpot-clone -p new-pot -P test-pot-2 -i 10.1.2.3\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_007()\n{\n\t# invalid pot name\n\tpot-clone -p new.pot -P test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_020()\n{\n\tpot-clone -p new-pot -P test-pot-0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_021()\n{\n\tpot-clone -p new-pot -P test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"test-pot\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"NO\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_022()\n{\n\tpot-clone -p new-pot-2 -P test-pot-2 -i 10.1.2.4\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-2\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-2\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-2\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-2\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.4\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_023()\n{\n\tpot-clone -p new-pot -P test-pot -F\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"test-pot\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"YES\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_024()\n{\n\tpot-clone -p new-pot-2 -P test-pot-2 -i auto\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-2\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-2\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-2\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-2\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.123.123.123\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_040()\n{\n\tpot-clone -p new-pot-single -P test-pot-single -i auto\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-single\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-single\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-single\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-single\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.123.123.123\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_041()\n{\n\tpot-clone -p new-pot-single -P test-pot-single -f flop\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-single\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-single\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-single\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-single\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.123.123.123\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"1\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_exec_flv arg1\" \"new-pot-single\" EXEC_FLV_CALL1_ARG1\n\tassertEqualsMon \"_exec_flv arg2\" \"flop\" EXEC_FLV_CALL1_ARG2\n}\n\ntest_pot_clone_041()\n{\n\tpot-clone -p new-pot-single -P test-pot-single -f flip -f flop\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-single\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-single\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-single\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-single\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.123.123.123\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"2\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_exec_flv arg1\" \"new-pot-single\" EXEC_FLV_CALL1_ARG1\n\tassertEqualsMon \"_exec_flv arg2\" \"flip\" EXEC_FLV_CALL1_ARG2\n\tassertEqualsMon \"_exec_flv arg1\" \"new-pot-single\" EXEC_FLV_CALL2_ARG1\n\tassertEqualsMon \"_exec_flv arg2\" \"flop\" EXEC_FLV_CALL2_ARG2\n}\n\ntest_pot_clone_060()\n{\n\tpot-clone -p new-pot-public -P test-pot-multi-private -N public-bridge\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-public\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-multi-private\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-public\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-multi-private\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.123.123.123\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_061()\n{\n\tpot-clone -p new-pot-private -P test-pot-multi-private -N private-bridge -B test-bridge\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-private\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-multi-private\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-private\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-multi-private\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"private-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.3.4\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"test-bridge\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_062()\n{\n\tpot-clone -p new-pot-private -P test-pot-3 -N private-bridge -B test-bridge\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg0\" \"new-pot-private\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg1\" \"test-pot-3\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot-private\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot-3\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"private-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.3.4\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"test-bridge\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_clone_080()\n{\n\tpot-clone -p new-pot -P test-pot -s 12345678\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"test-pot\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"NO\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"12345678\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"test-pot\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/clone2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nzfs()\n{\n\t__monitor ZFS \"$@\"\n}\n\nECHO=echo_stub\necho_stub()\n{\n\t__monitor ECHO \"$@\"\n}\n\nmkdir()\n{\n\t__monitor MKDIR \"$@\"\n\t/bin/mkdir $@\n}\n\ndate()\n{\n\t__monitor DATE \"$@\"\n\tif [ \"$1\" = '+%s' ]; then\n\t\techo \"55555\"\n\tfi\n}\n\n. pipefail-stub.sh\n\n# UUT\n. ../share/pot/clone.sh\n\n# common stubs\n. common-stub.sh\n. conf-stub.sh\n\n_zfs_dataset_valid()\n{\n\t__monitor ZFSDATASETVALID \"$@\"\n\tcase \"$1\" in\n\t${POT_ZFS_ROOT}/jails/test-pot|\\\n\t${POT_ZFS_ROOT}/jails/test-pot/usr.local|\\\n\t${POT_ZFS_ROOT}/jails/test-pot/custom|\\\n\t${POT_ZFS_ROOT}/jails/test-pot-single)\n\t\treturn 0 # true\n\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_zfs_last_snap()\n{\n\t__monitor ZFSLASTSNAP \"$@\"\n\tcase $1 in\n\t${POT_ZFS_ROOT}/bases/11.1/usr.local|\\\n\t${POT_ZFS_ROOT}/bases/11.1/custom)\n\t\techo 1234\n\t\t;;\n\t${POT_ZFS_ROOT}/jails/test-pot/usr.local|\\\n\t${POT_ZFS_ROOT}/jails/test-pot/custom|\\\n\t${POT_ZFS_ROOT}/jails/test-pot-2/custom)\n\t\techo 4321\n\t\t;;\n\t${POT_ZFS_ROOT}/jails/test-pot-single/m|\\\n\t${POT_ZFS_ROOT}/jails/test-pot-single-run/m)\n\t\techo 6688\n\t\t;;\n\tesac\n}\n\n_cj_undo_clone()\n{\n\t__monitor UNDO_CLONE \"$@\"\n}\n\n_update_fscomp()\n{\n\t:\n}\n\ntest_cj_zfs_001()\n{\n\t_cj_zfs new-pot test-pot NO\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"3\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir c1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir c2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot/usr.local@4321\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL2_ARG5\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/custom\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot/custom@4321\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL3_ARG5\n}\n\ntest_cj_zfs_002()\n{\n\t_cj_zfs new-pot test-pot-2 NO\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"2\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir c1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir c2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/custom\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-2/custom@4321\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL2_ARG5\n}\n\ntest_cj_zfs_003()\n{\n\t_cj_zfs new-pot test-pot YES\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"3\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir c1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir c2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot/usr.local@4321\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL2_ARG5\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/custom\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot/custom@4321\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL3_ARG5\n}\n\ntest_cj_zfs_004()\n{\n\t_cj_zfs new-pot test-pot-2 YES\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"2\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir c1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir c2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/custom\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-2/custom@4321\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL2_ARG5\n}\n\ntest_cj_zfs_005()\n{\n\t_cj_zfs new-pot test-pot-nosnap YES\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"5\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir c1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir c2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"snapshot\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/test-pot-nosnap/usr.local@55555\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-nosnap/usr.local@55555\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL3_ARG5\n\tassertEqualsMon \"zfs arg1\" \"snapshot\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/test-pot-nosnap/custom@55555\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/custom\" ZFS_CALL5_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-nosnap/custom@55555\" ZFS_CALL5_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL5_ARG5\n}\n\ntest_cj_zfs_020()\n{\n\t_cj_zfs new-pot test-pot-nosnap NO\n\tassertNotEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"1\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"undo_clone calls\" \"1\" UNDO_CLONE_CALLS\n}\n\ntest_cj_zfs_040()\n{\n\t_cj_zfs new-pot test-pot-single NO\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"2\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-single/m@6688\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG5\n}\n\ntest_cj_zfs_041()\n{\n\t_cj_zfs new-pot test-pot-single-run NO\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"2\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-single-run/m@6688\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG5\n}\n\ntest_cj_zfs_060()\n{\n\t_cj_zfs new-pot test-pot-single NO 12345678\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"2\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot-single/m@12345678\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG5\n\tassertEqualsMon \"zfs last snap calls\" \"0\" ZFSLASTSNAP_CALLS\n}\n\ntest_cj_zfs_061()\n{\n\t_cj_zfs new-pot test-pot NO 12345678\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"3\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir c1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir c2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"zfs arg1\" \"clone\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot/usr.local@12345678\" ZFS_CALL2_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL2_ARG5\n\tassertEqualsMon \"zfs arg3\" \"mountpoint=${POT_FS_ROOT}/jails/new-pot/custom\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs arg4\" \"${POT_ZFS_ROOT}/jails/test-pot/custom@12345678\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs arg5\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL3_ARG5\n\tassertEqualsMon \"zfs last snap calls\" \"0\" ZFSLASTSNAP_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tconf_setUp\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\tconf_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common-flv1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n. monitor.sh\n\n# UUT\n. ../share/pot/common-flv.sh\n\n# app specific stubs\n\n_get_flavour_cmd_file()\n{\n\tcase \"$1\" in\n\t\ttest)\n\t\t\techo test ;;\n\t\ttestnoscript)\n\t\t\techo testnoscript ;;\n\t\t*)\n\t\t\t;;\n\tesac\n}\n\n_get_flavour_script()\n{\n\tcase \"$1\" in\n\t\ttest)\n\t\t\techo test.sh ;;\n\t\ttestnocmd)\n\t\t\techo testnocmd.sh ;;\n\t\t*)\n\t\t\t;;\n\tesac\n}\n\ntest_is_cmd_flavorable_01()\n{\n\t_is_cmd_flavorable\n\tassertNotEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable help\n\tassertNotEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable help create\n\tassertNotEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable create -p help\n\tassertNotEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable add-fscomp\n\tassertNotEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable add-file\n\tassertNotEquals \"$?\" \"0\"\n}\n\ntest_is_cmd_flavorable_02()\n{\n\t_is_cmd_flavorable add-dep\n\tassertEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable add-dep -v -p me -P you\n\tassertEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable set-rss\n\tassertEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable copy-in\n\tassertEquals \"$?\" \"0\"\n\n\t_is_cmd_flavorable mount-in\n\tassertEquals \"$?\" \"0\"\n}\n\ntest_is_flavour_001()\n{\n\tassertTrue \"_is_flavour test\"\n\tassertTrue \"_is_flavour testnoscript\"\n\tassertTrue \"_is_flavour testnocmd\"\n\tassertFalse \"_is_flavour notest\"\n}\n\nsetUp()\n{\n\t__mon_init\n\t_POT_VERBOSITY=1\n}\n\ntearDown()\n{\n\t__mon_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common-stub.sh",
    "content": "#!/bin/sh\n. ../share/pot/common.sh\n. ../share/pot/common-flv.sh\n. ../share/pot/network.sh\nEXIT=\"return\"\n\n# common stubs\n. monitor.sh\n\n##### recognized pots\n# name\t\t\t\t\t\trunning\ttype\tlevel\tip\t\t\tvnet\tnetwork_type\n# test-pot\t\t\t\t\tno\t\tmulti\t1\t\tinherit\t\tundef\tinherit\n# test-pot-2\t\t\t\tno\t\tmulti\t2\t\t10.1.2.3\tyes\t\tpublic-bridge\n# test-pot-run\t\t\t\tyes\t\tmulti\t1\t\tundef\t\tundef\tundef\n# test-pot-run-2\t\t\tyes\t\tmulti\t2\t\tundef\t\tundef\tundef\n# test-pot-0\t\t\t\tno\t\tmulti\t0\t\tinherit\t\tundef\tinherit\n# test-pot-nosnap\t\t\tno\t\tmulti\t1\t\tinherit\t\tundef\tinherit\n# test-pot-single\t\t\tno\t\tsingle\t0\t\t10.1.2.3\tyes\t\tpublic-bridge\n# test-pot-single-run\t\tyes\t\tsingle\t0\t\tundef\t\tyes\t\tpublic-bridge\n# test-pot-single-2\t\t\tno\t\tsingle\t0\t\t10.1.2.3\tyes\t\tpublic-bridge\n# test-pot-single-0\t\t\tno\t\tsingle\t0\t\t10.1.2.3\tyes\t\tpublic-bridge\n# test-pot-3\t\t\t\tno\t\tmulti\t1\t\t10.1.2.3\tno\t\talias\n\n# test-pot-multi-inherit\tno\t\tmulti\t1\t\t\t\t\tno\t\tinherit\n# test-pot-multi-private\tno\t\tmulti\t1\t\t10.1.3.3\tyes\t\tprivate-bridge\n\n# test-pot-dns-inherit\n# test-pot-dns-pot\n# test-pot-dns-custom\n# test-pot-dns-off\n##### recognized bridges\n# name\t\t\t\t\t\tnet\t\t\t\tgateway\n# test-bridge\t\t\t\t10.1.3.0/28\t\t10.1.3.1\n\n_error()\n{\n\t__monitor ERROR \"$@\"\n\t[ \"$ERROR_DEBUG\" = \"YES\" ]  && echo \"_error: $*\"\n}\n\n_info()\n{\n\t__monitor INFO \"$@\"\n\t[ \"$INFO_DEBUG\" = \"YES\" ] && echo \"_info: $*\"\n}\n\n_debug()\n{\n\t__monitor DEBUG \"$@\"\n\t[ \"$DEBUG_DEBUG\" = \"YES\" ] && echo \"_debug: $*\"\n}\n\n_is_verbose() {\n\tif [ $_POT_VERBOSITY -gt 1 ]; then\n\t\treturn 0\n\telse\n\t\treturn 1\n\tfi\n}\n\n_is_uid0()\n{\n\t__monitor ISUID0 \"$@\"\n\treturn 0 # true\n}\n\n_is_flavourdir()\n{\n\t__monitor ISFLVDIR \"$@\"\n\treturn 0 # true\n}\n\n_is_pot()\n{\n\t__monitor ISPOT \"$@\"\n\tcase \"$1\" in\n\t\ttest-pot|test-pot-run|\\\n\t\ttest-pot-2|test-pot-run-2|\\\n\t\ttest-pot-0|test-pot-nosnap|test-pot-3|\\\n\t\ttest-pot-single|test-pot-single-run|test-pot-single-2|test-pot-single-0|\\\n\t\ttest-pot-multi-inherit|test-pot-multi-private|\\\n\t\t${POT_DNS_NAME})\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_is_pot_running()\n{\n\t__monitor ISPOTRUN \"$@\"\n\tcase \"$1\" in\n\t\ttest-pot-run|test-pot-run-2|\\\n\t\ttest-pot-single-run)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_is_base()\n{\n\t__monitor ISBASE \"$@\"\n\tcase \"$1\" in\n\t\ttest-base|11.1)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_is_fscomp()\n{\n\t__monitor ISFSCOMP \"$@\"\n\tcase \"$1\" in\n\t\ttest-fscomp)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_is_flavour()\n{\n\tcase $1 in\n\t\tdefault|flap|flap2|flip|flop)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_get_conf_var()\n{\n\t__monitor GETCONFVAR \"$@\"\n\tcase \"$2\" in\n\t\"pot.level\")\n\t\tcase \"$1\" in\n\t\ttest-pot|test-pot-run|test-pot-3|\\\n\t\ttest-pot-nosnap|test-pot-multi-inherit|\\\n\t\ttest-pot-multi-private)\n\t\t\techo \"1\"\n\t\t\t;;\n\t\ttest-pot-2|test-pot-run-2)\n\t\t\techo \"2\"\n\t\t\t;;\n\t\ttest-pot-0|test-pot-single|test-pot-single-run|\\\n\t\ttest-pot-single-2|test-pot-single-0)\n\t\t\techo \"0\"\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"pot.potbase\")\n\t\tcase \"$1\" in\n\t\ttest-pot-2)\n\t\t\techo \"test-pot\"\n\t\t\t;;\n\t\ttest-pot-run-2)\n\t\t\techo \"test-pot-run\"\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"ip\")\n\t\tcase $1 in\n\t\ttest-pot|test-pot-0)\n\t\t\techo \"\"\n\t\t\t;;\n\t\ttest-pot-2|test-pot-3|\\\n\t\ttest-pot-single|test-pot-single-2|test-pot-single-0)\n\t\t\techo \"10.1.2.3\"\n\t\t\t;;\n\t\ttest-pot-multi-private)\n\t\t\techo \"10.1.3.3\"\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"network_type\")\n\t\tcase $1 in\n\t\ttest-pot|test-pot-0|\\\n\t\ttest-pot-multi-inherit)\n\t\t\techo \"inherit\"\n\t\t\t;;\n\t\ttest-pot-3)\n\t\t\techo \"alias\"\n\t\t\t;;\n\t\ttest-pot-2|test-pot-single-run|\\\n\t\ttest-pot-single|test-pot-single-2|test-pot-single-0)\n\t\t\techo \"public-bridge\"\n\t\t\t;;\n\t\ttest-pot-multi-private)\n\t\t\techo \"private-bridge\"\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"pot.type\")\n\t\tcase $1 in\n\t\ttest-pot|test-pot-0|test-pot-3|\\\n\t\ttest-pot-run|test-pot-nosnap|\\\n\t\ttest-pot-2|test-pot-run-2|\\\n\t\ttest-pot-multi-inherit|test-pot-multi-private)\n\t\t\techo \"multi\"\n\t\t\t;;\n\t\ttest-pot-single|test-pot-single-run|test-pot-single-2|test-pot-single-0)\n\t\t\techo \"single\"\n\t\tesac\n\t\t;;\n\t\"vnet\")\n\t\tcase $1 in\n\t\ttest-pot-2|test-pot-single|test-pot-single-run|\\\n\t\ttest-pot-multi-private|test-pot-single-2|test-pot-single-0)\n\t\t\techo \"true\"\n\t\t\t;;\n\t\ttest-pot-3|test-pot-multi-inherit)\n\t\t\techo \"false\"\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"bridge\")\n\t\tcase $1 in\n\t\ttest-pot-multi-private)\n\t\t\techo \"test-bridge\"\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"host.hostname\")\n\t\techo \"$1.test-domain\"\n\t\t;;\n\t\"pot.dns\")\n\t\tcase $1 in\n\t\ttest-pot-dns-inherit)\n\t\t\techo \"inherit\"\n\t\t\t;;\n\t\ttest-pot-dns-pot)\n\t\t\techo \"pot\"\n\t\t\t;;\n\t\ttest-pot-dns-custom)\n\t\t\techo \"custom\"\n\t\t\t;;\n\t\ttest-pot-dns-off)\n\t\t\techo \"off\"\n\t\t\t;;\n\t\tesac\n\tesac\n}\n\n_get_pot_base()\n{\n\t__monitor GETPOTBASE \"$@\"\n\tcase \"$1\" in\n\t\ttest-pot|test-pot-run|\\\n\t\ttest-pot-2|test-pot-run-2|\\\n\t\ttest-pot-single|test-pot-single-run)\n\t\t\techo \"11.1\"\n\t\t\t;;\n\tesac\n}\n\n_zfs_exist()\n{\n\t__monitor ZFSEXIST \"$@\"\n\tcase \"$1\" in\n\t\t/fscomp/test-fscomp)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_pot_zfs_snap()\n{\n\t__monitor POTZFSSNAP \"$@\"\n}\n\n_remove_oldest_pot_snap()\n{\n\t__monitor RMVPOTSNAP \"$@\"\n}\n\n_pot_zfs_snap_full()\n{\n\t__monitor POTZFSSNAPFULL \"$@\"\n}\n\n_fscomp_zfs_snap()\n{\n\t__monitor FSCOMPZFSSNAP \"$@\"\n}\n\n_remove_oldest_fscomp_snap()\n{\n\t__monitor RMVFSCOMPSNAP \"$@\"\n}\n\n_is_valid_release()\n{\n\tcase \"$1\" in\n\t\t10.1|10.4|11.0|11.1)\n\t\t   return 0 # true\n\t\t   ;;\n\t   *)\n\t\t   return 1 # false\n\t\t   ;;\n\tesac\n}\n\n_is_valid_netif()\n{\n\tif [ \"$1\" = \"lagg0\" ]; then\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n_is_bridge()\n{\n\tcase \"$1\" in\n\t\ttest-bridge)\n\t\t\treturn 0 # return true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n_get_bridge_var()\n{\n\t__monitor GETBRIDGEVAR \"$@\"\n\tcase \"$2\" in\n\t\tname)\n\t\t\tcase \"$1\" in\n\t\t\t\ttest-bridge)\n\t\t\t\t\techo \"test-bridge\"\n\t\t\t\t\t;;\n\t\t\tesac\n\t\t\t;;\n\t\tnet)\n\t\t\tcase \"$1\" in\n\t\t\t\ttest-bridge)\n\t\t\t\t\techo \"10.1.3.0/28\"\n\t\t\t\t\t;;\n\t\t\tesac\n\t\t\t;;\n\t\tgateway)\n\t\t\tcase \"$1\" in\n\t\t\t\ttest-bridge)\n\t\t\t\t\techo \"10.1.3.1\"\n\t\t\t\t\t;;\n\t\t\tesac\n\t\t\t;;\n\tesac\n}\n\ncommon_setUp()\n{\n\t__mon_init\n\t_POT_VERBOSITY=1\n\tPOT_DNS_NAME=dns\n}\n\ncommon_tearDown()\n{\n\t__mon_tearDown\n}\n\n# can be overridden by tests\ntearDown()\n{\n\tcommon_tearDown\n}\n"
  },
  {
    "path": "tests/common-zfs1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nzfs()\n{\n\tif [ \"$2\" = \"zfs-dataset\" ]; then\n\t\treturn 0 # true\n\tfi\n\tif [ \"$2\" = \"-H\" ]; then\n\t\tif [ \"$5\" = \"zfs-dataset\" ]; then\n\t\t\techo \"/path/to/mnt\"\n\t\t\treturn 0 # true\n\t\tfi\n\tfi\n\tif [ \"$2\" = \"-o\" ]; then\n\t\tcase \"$5\" in\n\t\tzfs-dataset)\n\t\t\techo zfs-dataset\n\t\t\t;;\n\t\t/path/to/mnt)\n\t\t\techo zfs-dataset\n\t\t\t;;\n\t\tesac\n\tfi\n\treturn 1 # false\n}\n\n# UUT\n. ../share/pot/common.sh\n\n# app specific stubs\n\ntest_zfs_exist_001()\n{\n\t_zfs_exist\n\tassertNotEquals \"0\" \"$?\"\n\n\t_zfs_exist zfs-nodataset\n\tassertNotEquals \"0\" \"$?\"\n\n\t_zfs_exist zfs-dataset\n\tassertNotEquals \"0\" \"$?\"\n}\n\ntest_zfs_exist_002()\n{\n\t_zfs_exist zfs-nodataset /path/to/mnt\n\tassertNotEquals \"0\" \"$?\"\n\n\t_zfs_exist zfs-dataset /path/to/chaos\n\tassertNotEquals \"0\" \"$?\"\n\n\t_zfs_exist zfs-dataset /path/to/mnt\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_zfs_dataset_valid_001()\n{\n\t_zfs_dataset_valid\n\tassertNotEquals \"0\" \"$?\"\n\n\t_zfs_dataset_valid zfs-nodataset\n\tassertNotEquals \"0\" \"$?\"\n\n\t_zfs_dataset_valid /path/to/mnt\n\tassertNotEquals \"0\" \"$?\"\n}\n\ntest_zfs_dataset_valid_002()\n{\n\t_zfs_dataset_valid zfs-dataset\n\tassertEquals \"0\" \"$?\"\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common-zfs2.sh",
    "content": "#!/bin/sh\n\n. monitor.sh\n# system utilities stubs\n\nzfs()\n{\n\t__monitor ZFS \"$@\"\n}\n\ndate()\n{\n\techo \"123454321\"\n}\n\n# UUT\n. ../share/pot/common.sh\n\n# app specific stubs\n\ntest_fscomp_zfs_snap_001()\n{\n\t_fscomp_zfs_snap fscomp_name\n\tassertEqualsMon \"zfs calls\" \"1\" ZFS_CALLS\n\tassertEqualsMon \"zfs args\" \"/zroot/fscomp/fscomp_name@123454321\" ZFS_CALL1_ARG2\n}\n\ntest_fscomp_zfs_snap_002()\n{\n\t# the argument \"new_snap\" is ignored\n\t_fscomp_zfs_snap fscomp_name new_snap\n\tassertEqualsMon \"zfs calls\" \"1\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"snapshot\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"/zroot/fscomp/fscomp_name@123454321\" ZFS_CALL1_ARG2\n}\n\nsetUp()\n{\n\t__mon_init\n\tPOT_ZFS_ROOT=/zroot\n}\n\ntearDown()\n{\n\t__mon_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n. monitor.sh\n\nmount()\n{\n\tcat << EOF--\nzroot on /zroot (zfs, local, noatime, nfsv4acls)\nzroot/ROOT/default on / (zfs, local, noatime, nfsv4acls)\ndevfs on /dev (devfs, local, multilabel)\nzroot/tmp on /tmp (zfs, local, noatime, nosuid, nfsv4acls)\nzroot/usr/home on /usr/home (zfs, local, noatime, nfsv4acls)\nzroot/usr/src on /usr/src (zfs, local, noatime, nfsv4acls)\nzroot/var/audit on /var/audit (zfs, local, noatime, noexec, nosuid, nfsv4acls)\nzroot/var/crash on /var/crash (zfs, local, noatime, noexec, nosuid, nfsv4acls)\nzroot/var/log on /var/log (zfs, local, noatime, noexec, nosuid, nfsv4acls)\nzroot/var/mail on /var/mail (zfs, local, nfsv4acls)\nzroot/var/tmp on /var/tmp (zfs, local, noatime, nosuid, nfsv4acls)\n/opt/pot/fscomp/distfiles on /opt/distfiles (nullfs, local)\nEOF--\n}\n\numount()\n{\n\t__monitor UMOUNT \"$@\"\n}\n\nfetch()\n{\n\t__monitor FETCH \"$@\"\n}\n\njls()\n{\n\tif [ \"$1\" = \"-j\" ]; then\n\t\tcase \"$2\" in\n\t\t\"pot-test\"|\\\n\t\t\"pot-test-2\")\n\t\t\treturn 0 ## return true\n\t\tesac\n\t\treturn 1\n\tfi\n\tcat << EOF--\n JID             IP Address      Hostname                      Path\n pot-test                  pot-test.pot-net       /opt/pot/jails/pot-test/m\n pot-test-2                pot-test-2.pot-net     /opt/pot/jails/pot-test-2/m\nEOF--\n}\n\nsysctl()\n{\n\tif [ -n \"$SYSCTL_OUTPUT\" ]; then\n\t\techo $SYSCTL_OUTPUT\n\tfi\n\treturn $SYSCTL_RC\n}\n\nwhich()\n{\n\tif [ \"$1\" = potnet ]; then\n\t\tif [ \"$WHICH_POTNET_FAIL\" = \"YES\" ]; then\n\t\t\treturn 1 # false\n\t\telse\n\t\t\treturn 0 # true\n\t\tfi\n\tfi\n}\n\n\n# UUT\n. ../share/pot/common.sh\n\n# app specific stubs\n\ntest_is_verbose()\n{\n\t_is_verbose\n\tassertNotEquals \"0\" \"$?\"\n\n\t_POT_VERBOSITY=2\n\t_is_verbose\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_is_pot_running()\n{\n\t_is_pot_running\n\tassertNotEquals \"0\" \"$?\"\n\n\t_is_pot_running pot\n\tassertNotEquals \"0\" \"$?\"\n\n\t_is_pot_running pot-test\n\tassertNotEquals \"1\" \"$?\"\n\n\t_is_pot_running pot-test-2\n\tassertNotEquals \"1\" \"$?\"\n}\n\ntest_is_valid_potname()\n{\n\t_is_valid_potname \"test-pot\"\n\tassertEquals \"Refusing valid name\" \"0\" \"$?\"\n\n\t_is_valid_potname \"test.pot\"\n\tassertNotEquals \"Invalid name not detected\" \"0\" \"$?\"\n}\n\ntest_is_in_list()\n{\n\t_is_in_list\n\tassertNotEquals \"0\" \"$?\"\n\t_is_in_list \"asdf\"\n\tassertNotEquals \"0\" \"$?\"\n\t_is_in_list \"asdf\" \"\"\n\tassertNotEquals \"0\" \"$?\"\n\t_is_in_list \"asdf\" \"asdf1 asdf2\"\n\tassertNotEquals \"0\" \"$?\"\n\n\t_is_in_list \"val\" \"val val1 val2\"\n\tassertEquals \"0\" \"$?\"\n\t_is_in_list \"val\" \"val1 val val2\"\n\tassertEquals \"0\" \"$?\"\n\t_is_in_list \"val\" \"val1 val2 val\"\n\tassertEquals \"0\" \"$?\"\n\t_is_in_list \"val\" \"val\"\n\tassertEquals \"0\" \"$?\"\n\t_is_in_list \"val\" \"val val\"\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_is_mounted()\n{\n\t_is_mounted\n\tassertNotEquals \"0\" \"$?\"\n\t_is_mounted /path/to/the/error\n\tassertNotEquals \"0\" \"$?\"\n\t_is_mounted /path/to/the/error ignored\n\tassertNotEquals \"0\" \"$?\"\n\t_is_mounted zroot/var/log\n\tassertNotEquals \"0\" \"$?\"\n\n\t_is_mounted /opt/distfiles\n\tassertEquals \"0\" \"$?\"\n\t_is_mounted /opt/distfiles ignored\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_umount()\n{\n\t_umount\n\tassertEqualsMon \"umount calls1\" \"0\" UMOUNT_CALLS\n\n\t_umount /path/to/the/error\n\tassertEqualsMon \"umount calls2\" \"0\" UMOUNT_CALLS\n\n\t_umount /opt/distfiles\n\tassertEqualsMon \"umount calls3\" \"1\" UMOUNT_CALLS\n\tassertEqualsMon \"umount c1 arg1\" \"-f\" UMOUNT_CALL1_ARG1\n\tassertEqualsMon \"umount c1 arg2\" \"/opt/distfiles\" UMOUNT_CALL1_ARG2\n}\n\ntest_is_rctl_available()\n{\n\t_is_rctl_available\n\tassertEquals \"$?\" \"0\"\n\n\tSYSCTL_OUTPUT=\"0\"\n\t_is_rctl_available\n\tassertNotEquals \"$?\" \"0\"\n\n\tSYSCTL_OUTPUT=\"\"\n\tSYSCTL_RC=1\n\t_is_rctl_available\n\tassertNotEquals \"$?\" \"0\"\n}\n\ntest_is_potnet_available()\n{\n\t_is_potnet_available\n\tassertEquals \"$?\" \"0\"\n\n\tWHICH_POTNET_FAIL=\"YES\"\n\t_is_potnet_available\n\tassertNotEquals \"$?\" \"0\"\n}\n\ntest_is_absolute_path()\n{\n\t_is_absolute_path\n\tassertEquals \"$?\" \"1\"\n\n\t_is_absolute_path \"../blah\"\n\tassertEquals \"$?\" \"1\"\n\n\t_is_absolute_path \"/blah\"\n\tassertEquals \"$?\" \"0\"\n}\n\nsetUp()\n{\n\t__mon_init\n\t_POT_VERBOSITY=1\n\tSYSCTL_OUTPUT=\"1\"\n\tSYSCTL_RC=0\n\tWHICH_POTNET_FAIL=\"NO\"\n}\n\ntearDown()\n{\n\t__mon_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nif [ \"$(uname)\" = \"Linux\" ]; then\n\tTEST=/usr/bin/[\nelse\n\tTEST=/bin/[\nfi\n\n[()\n{\n\tif ${TEST} \"$1\" = \"!\" ]; then\n\t\tif ${TEST} \"$2\" = \"-d\" ]; then\n\t\t\tif ${TEST} \"$3\" = \"/jails/pot-test\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test-single\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test-nodset\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test-noconf\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test/m\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test-single/m\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/bases/base-test\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/bases/base-test-nodset\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/fscomp/fscomp-test\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/fscomp/fscomp-test-nodset\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telse\n\t\t\t\treturn 0 # true\n\t\t\tfi\n\t\tfi\n\t\tif ${TEST} \"$2\" = \"-r\" ]; then\n\t\t\tif ${TEST} \"$3\" = \"/jails/pot-test/conf/pot.conf\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test/conf/fscomp.conf\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test-single/conf/pot.conf\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/jails/pot-test-single/conf/fscomp.conf\" ]; then\n\t\t\t\treturn 0 # true\n\t\t\telse\n\t\t\t\treturn 0\n\t\t\tfi\n\t\tfi\n\tfi\n\t${TEST} \"$@\"\n\treturn $?\n}\n\n\n# UUT\n. ../share/pot/common.sh\n\n# app specific stubs\nPOT_FS_ROOT=\nPOT_ZFS_ROOT=\n\n_error()\n{\n\t:\n}\n\n_zfs_dataset_valid()\n{\n\tif ${TEST} \"$1\" = \"/jails/pot-test\" ]; then\n\t\treturn 0 # true\n\telif ${TEST} \"$1\" = \"/jails/pot-test-single\" ]; then\n\t\treturn 0 # true\n\telif ${TEST} \"$1\" = \"/jails/pot-test-noconf\" ]; then\n\t\treturn 0 # true\n\tfi\n\tif ${TEST} \"$1\" = \"/bases/base-test\" ]; then\n\t\treturn 0\n\tfi\n\tif ${TEST} \"$1\" = \"/fscomp/fscomp-test\" ]; then\n\t\treturn 0\n\tfi\n\treturn 1 # false\n}\n\n_get_pot_type()\n{\n\tif ${TEST} \"$1\" = \"pot-test\" ]; then\n\t\techo \"multi\"\n\tfi\n\tif ${TEST} \"$1\" = \"pot-test-single\" ]; then\n\t\techo \"single\"\n\tfi\n}\n\ntest_is_pot()\n{\n\t_is_pot\n\tassertEquals \"1\" \"$?\"\n\n\t_is_pot nopot\n\tassertEquals \"1\" \"$?\"\n\n\t_is_pot pot-test-nodset\n\tassertEquals \"2\" \"$?\"\n\n\t_is_pot pot-test-noconf\n\tassertEquals \"3\" \"$?\"\n\n\t_is_pot pot-test\n\tassertEquals \"0\" \"$?\"\n\n\t_is_pot pot-test-single\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_is_base()\n{\n\t_is_base\n\tassertEquals \"1\" \"$?\"\n\n\t_is_base nobase\n\tassertEquals \"1\" \"$?\"\n\n\t_is_base base-test-nodset\n\tassertEquals \"2\" \"$?\"\n\n\t_is_base base-test\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_is_fscomp()\n{\n\t_is_fscomp\n\tassertEquals \"1\" \"$?\"\n\n\t_is_fscomp nofscomp\n\tassertEquals \"1\" \"$?\"\n\n\t_is_fscomp fscomp-test-nodset\n\tassertEquals \"2\" \"$?\"\n\n\t_is_fscomp fscomp-test\n\tassertEquals \"0\" \"$?\"\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common4.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/common.sh\n\n# common stubs\n. ./monitor.sh\n\n_qerror()\n{\n\t__monitor QERR $*\n}\n\n_zfs_exist()\n{\n\tif [ \"$1\" = \"zpot\" ] && [ \"$2\" = \"/opt\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1\n}\n\n_zfs_dataset_valid()\n{\n\treturn 0\n}\n\n# app specific stubs\n\ntest_is_init_001()\n{\n\tPOT_ZFS_ROOT=\n\t_is_init quiet\n\tassertEquals \"1\" \"$?\"\n}\n\ntest_is_init_002()\n{\n\tPOT_FS_ROOT=\n\t_is_init quiet\n\tassertEquals \"1\" \"$?\"\n}\n\ntest_is_init_003()\n{\n\tPOT_FS_ROOT=/usr/local/pot\n\t_is_init quiet\n\tassertEquals \"1\" \"$?\"\n}\n\ntest_is_init_004()\n{\n\tPOT_ZFS_ROOT=zroot\n\t_is_init quiet\n\tassertEquals \"1\" \"$?\"\n}\n\ntest_is_init_020()\n{\n\t_is_init quiet\n\tassertEquals \"0\" \"$?\"\n}\n\nsetUp()\n{\n\t__mon_init\n\tPOT_ZFS_ROOT=zpot\n\tPOT_FS_ROOT=/opt\n\tPOT_GROUP=\"$(id -ng)\"\n}\n\ntearDown()\n{\n\t__mon_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common5.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nif [ \"$(uname)\" = \"Linux\" ]; then\n\tTEST=/usr/bin/[\nelse\n\tTEST=/bin/[\nfi\n\n[()\n{\n\t#echo test: \"$@\" >&2\n\n\tif ${TEST} \"$1\" = \"!\" ]; then\n\t\tif ${TEST} \"$__didfetch\" != \"1\" ]; then\n\t\t\t# pretend these files don't exist yet\n\t\t\treturn 0 # false\n\t\tfi\n\n\t\tif ${TEST} \"$2\" = \"-r\" ]; then\n\t\t\tif ${TEST} \"$3\" = \"/tmp/11.1-RELEASE_base.txz\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/tmp/12.0-RC3_base.txz\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/tmp/12.0-RELEASE_base.txz\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/tmp/8.1-RELEASE_base.txz\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\telif ${TEST} \"$3\" = \"/tmp/2.1-RELEASE_base.txz\" ]; then\n\t\t\t\treturn 0 # true\n\t\t\tfi\n\t\tfi\n\telif ${TEST} \"$1\" = \"-r\" ]; then\n\t\tif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-11.1-RELEASE\" ]; then\n\t\t\treturn 0 # true\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-12.0-RELEASE\" ]; then\n\t\t\treturn 0 # true\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-12.0-RC3\" ]; then\n\t\t\treturn 0 # true\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-8.1-RELEASE\" ]; then\n\t\t\treturn 1 # false\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-11.1-RELEASE\" ]; then\n\t\t\treturn 0 # true\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-12.0-RELEASE\" ]; then\n\t\t\treturn 0 # true\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-12.0-RC3\" ]; then\n\t\t\treturn 0 # true\n\t\telif ${TEST} \"$2\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-8.1-RELEASE\" ]; then\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\t${TEST} \"$@\"\n\treturn $?\n}\n\nfetch()\n{\n\t__didfetch=\"1\"\n\t#echo fetch: \"$@\" >&2\n\n\t__monitor FETCH \"$@\"\n}\n\nsha256()\n{\n\tif [ \"$__arch\" = \"amd64\" ]; then\n\t\tif [ \"$2\" = /tmp/11.1-RELEASE_base.txz ]; then\n\t\t\techo \"0123456789abcdef\"\n\t\telif [ \"$2\" = /tmp/12.0-RELEASE_base.txz ]; then\n\t\t\techo \"fedcba9876543210\"\n\t\telif [ \"$2\" = /tmp/12.0-RC3_base.txz ]; then\n\t\t\techo \"aaaaaaaaaaaaaaaa\"\n\t\telse\n\t\t\techo \"\"\n\t\tfi\n\telse\n\t\tif [ \"$2\" = /tmp/11.1-RELEASE_base.txz ]; then\n\t\t\techo \"other0123456789abcdef\"\n\t\telif [ \"$2\" = /tmp/12.0-RELEASE_base.txz ]; then\n\t\t\techo \"otherfedcba9876543210\"\n\t\telif [ \"$2\" = /tmp/12.0-RC3_base.txz ]; then\n\t\t\techo \"otheraaaaaaaaaaaaaaaa\"\n\t\telse\n\t\t\techo \"\"\n\t\tfi\n\tfi\n}\n\nsysctl()\n{\n\tif [ \"$2\" = \"hw.machine_arch\" ]; then\n\t\techo \"$__arch\"\n\telif [ \"$2\" = \"hw.machine\" ]; then\n\t\techo \"$__machine\"\n\telse\n\t\treturn 1        # failure\n\tfi\n}\n\ncat()\n{\n\tif [ \"$1\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-12.0-RELEASE\" ]; then\n\t\techo \"base.txz 0123456789abcdef\"\n\telif [ \"$1\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-11.1-RELEASE\" ]; then\n\t\techo \"base.txz 0123456789abcdef\"\n\telif [ \"$1\" = \"/usr/local/share/freebsd/MANIFESTS/amd64-amd64-12.0-RC3\" ]; then\n\t\techo \"base.txz aaaaaaaaaaaaaaaa\"\n\telif [ \"$1\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-12.0-RELEASE\" ]; then\n\t\techo \"base.txz other0123456789abcdef\"\n\telif [ \"$1\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-11.1-RELEASE\" ]; then\n\t\techo \"base.txz other0123456789abcdef\"\n\telif [ \"$1\" = \"/usr/local/share/freebsd/MANIFESTS/arm64-aarch64-12.0-RC3\" ]; then\n\t\techo \"base.txz otheraaaaaaaaaaaaaaaa\"\n\telse\n\t\t/bin/cat \"$@\"\n\tfi\n}\n\nrm()\n{\n\t__monitor RM \"$@\"\n}\n\n# UUT\n. ../share/pot/create-base.sh\n\n# common stubs\n. common-stub.sh\n\ntest_fetch_freebsd_001()\n{\n\t# not downloaded\n\t_fetch_freebsd 2.1\n\tassertEquals \"return code\" \"1\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"2\" FETCH_CALLS\n\tassertEqualsMon \"fetch arg4\" \"/tmp/2.1-RELEASE_base.txz\" FETCH_CALL1_ARG4\n\tassertEqualsMon \"error calls\" \"0\" ERROR_CALLS\n}\n\ntest_fetch_freebsd_002()\n{\n\t# No Manifest file\n\t_fetch_freebsd 8.1\n\tassertEquals \"return code\" \"1\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"0\" FETCH_CALLS\n\tassertEqualsMon \"error calls\" \"2\" ERROR_CALLS\n}\n\ntest_fetch_freebsd_003()\n{\n\t# Wrong sha\n\t_fetch_freebsd 12.0\n\tassertEquals \"return code\" \"1\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"0\" FETCH_CALLS\n\tassertEqualsMon \"error calls\" \"2\" ERROR_CALLS\n}\n\ntest_fetch_freebsd_004()\n{\n\t# Everything fine\n\t_fetch_freebsd 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"0\" FETCH_CALLS\n\tassertEqualsMon \"error calls\" \"0\" ERROR_CALLS\n}\n\ntest_fetch_freebsd_005()\n{\n\t# Everything fine\n\t_fetch_freebsd 12.0-RC3\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"0\" FETCH_CALLS\n\tassertEqualsMon \"error calls\" \"0\" ERROR_CALLS\n}\n\ntest_fetch_freebsd_006()\n{\n\t# Need fetch first\n\t__didfetch=\"0\"\n\t_fetch_freebsd 12.0-RC3\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"1\" FETCH_CALLS\n\tassertEqualsMon \"fetch arg1\" \"-m\" FETCH_CALL1_ARG1\n\tassertEqualsMon \"fetch arg2\" \"https://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/12.0-RC3/base.txz\" FETCH_CALL1_ARG2\n\tassertEqualsMon \"fetch arg3\" \"-o\" FETCH_CALL1_ARG3\n\tassertEqualsMon \"fetch arg4\" \"/tmp/12.0-RC3_base.txz\" FETCH_CALL1_ARG4\n\tassertEqualsMon \"error calls\" \"0\" ERROR_CALLS\n}\n\ntest_fetch_freebsd_007()\n{\n\t# Need fetch first\n\t__machine=\"arm64\"\n\t__arch=\"aarch64\"\n\t__didfetch=\"0\"\n\t_fetch_freebsd 12.0-RC3\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"fetch calls\" \"1\" FETCH_CALLS\n\tassertEqualsMon \"fetch arg2\" \"https://ftp.freebsd.org/pub/FreeBSD/releases/arm64/aarch64/12.0-RC3/base.txz\" FETCH_CALL1_ARG2\n\tassertEqualsMon \"error calls\" \"0\" ERROR_CALLS\n}\n\nsetUp()\n{\n\t__machine=\"amd64\"\t# default to amd64\n\t__arch=\"amd64\"\n\t__didfetch=\"1\"\n\tcommon_setUp\n\tPOT_CACHE=\"/tmp\"\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common6.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/common.sh\n\n# common stubs\n. conf-stub.sh\n\ntest_get_conf_vnet_001()\n{\n\trc=$(_get_conf_var test-pot-vnet-ip4 vnet )\n\tassertEquals \"vnet value\" \"true\" \"$rc\"\n}\n\ntest_is_pot_vnet()\n{\n\t_is_pot_vnet test-pot-vnet-ip4\n\trc=$?\n\tassertEquals \"is_pot_vnet\" \"0\" \"$rc\"\n}\n\nsetUp()\n{\n\tconf_setUp\n}\n\ntearDown()\n{\n\tconf_tearDown\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common7.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nfind()\n{\n\tcat << MANIFEST-EOF\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-12.0-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-10.0-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-10.4-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-11.0-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-9.1-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-9.0-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-10.1-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-11.1-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-9.2-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-10.3-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-11.2-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-10.2-RELEASE\n/usr/local/share/freebsd/MANIFESTS/amd64-amd64-9.3-RELEASE\nMANIFEST-EOF\n}\n\nsysctl()\n{\n\tif [ \"$2\" = \"hw.machine_arch\" ]; then\n\t\techo \"$__arch\"\n\telif [ \"$2\" = \"hw.machine\" ]; then\n\t\techo \"$__machine\"\n\telse\n\t\treturn 1\t# failure\n\tfi\n}\n\nhostname()\n{\n\techo \"test-host\"\n}\n\n# UUT\n. ../share/pot/common.sh\n\n# common stubs\n. ./monitor.sh\n\n# app specific stubs\n\n\ntest_get_arch_001()\n{\n\tresult=\"$(_get_arch)\"\n\tassertEquals \"amd64-amd64\" \"$result\"\n\n\t__machine=\"i386\"\n\t__arch=\"i386\"\n\tresult=\"$(_get_arch)\"\n\tassertEquals \"i386-i386\" \"$result\"\n\n\t__machine=\"arm64\"\n\t__arch=\"aarch64\"\n\tresult=\"$(_get_arch)\"\n\tassertEquals \"arm64-aarch64\" \"$result\"\n}\n\ntest_get_valid_releases_001()\n{\n\tresult=\"$( _get_valid_releases )\"\n\tassertEquals \"9.0 9.1 9.2 9.3 10.0 10.1 10.2 10.3 10.4 11.0 11.1 11.2 12.0 \" \"$result\"\n}\n\ntest_is_valid_release_001()\n{\n\t# valid release\n\t_is_valid_release 11.0\n\tassertEquals \"0\" \"$?\"\n}\n\ntest_is_valid_release_002()\n{\n\t# invalid release\n\t_is_valid_release 10.8\n\tassertEquals \"1\" \"$?\"\n\n\t# invalid call\n\t_is_valid_release\n\tassertEquals \"1\" \"$?\"\n}\n\ntest_get_usable_hostname_001()\n{\n\tresult=\"$( _get_usable_hostname pot-short-name )\"\n\tassertEquals \"pot-short-name.test-host\" \"$result\"\n\n}\n\ntest_get_usable_hostname_002()\n{\n\tresult=\"$( _get_usable_hostname pot-long-name-01234567890123456789012345678901234567890123456789 )\"\n\tassertEquals \"pot-long-name-01234567890123456789012345678901234567890123456789\" \"$result\"\n}\n\ntest_get_usable_hostname_003()\n{\n\tresult=\"$( _get_usable_hostname pot-long-name-012345678901234567890123456789012345678901234567890123456789 )\"\n\tassertEquals \"pot-long-name-01234567890123456789012345678901234567890123456789\" \"$result\"\n}\n\ntest_get_usable_hostname_004()\n{\n\texport POT_HOSTNAME_MAX_LENGTH=62\n\tresult=\"$( _get_usable_hostname pot-long-name-012345678901234567890123456789012345678901234567890123456789 )\"\n\tassertEquals \"pot-long-name-012345678901234567890123456789012345678901234567\" \"$result\"\n}\n\nsetUp()\n{\n\t__mon_init\n\t__machine=\"amd64\"\n\t__arch=\"amd64\"\n}\n\ntearDown()\n{\n\t__mon_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/common8.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/common.sh\n\ntest_is_natural_number_001()\n{\n\t_is_natural_number 123\n\tassertTrue \"number is not a number\" \"$?\"\n}\n\ntest_contains_spaces_001()\n{\n\t_contains_spaces \"no-spaces\"\n\tassertFalse \"found spaces in a string with no spaces\" \"$?\"\n}\n\ntest_contains_spaces_002()\n{\n\t_contains_spaces \"with spaces\"\n\tassertTrue \"not found spaces in a string with spaces\" \"$?\"\n\n\t_contains_spaces \"/mnt/with space\"\n\tassertTrue \"not found spaces in a string with spaces\" \"$?\"\n\n\t_contains_spaces \"/mnt/space \"\n\tassertTrue \"not found spaces in a string with spaces\" \"$?\"\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/conf-stub.sh",
    "content": "#!/bin/sh\n\nconf_setUp()\n{\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n\n\t/bin/mkdir -p /tmp/jails/test-pot/conf\n\t{\n\t\techo \"zpot/bases/11.1 /tmp/jails/test-pot/m ro\"\n\t\techo \"zpot/jails/test-pot/usr.local /tmp/jails/test-pot/m/usr/local zfs-remount\"\n\t\techo \"zpot/jails/test-pot/custom /tmp/jails/test-pot/m/opt/custom zfs-remount\"\n\t} > /tmp/jails/test-pot/conf/fscomp.conf\n\t{\n\t\techo \"host.hostname=\\\"test-pot.test\\\"\"\n\t\techo \"pot.potbase=\"\n\t} > /tmp/jails/test-pot/conf/pot.conf\n\n\t/bin/mkdir -p /tmp/jails/test-pot-2/conf\n\t{\n\t\techo \"zpot/bases/11.1 /tmp/jails/test-pot-2/m ro\"\n\t\techo \"zpot/jails/test-pot/usr.local /tmp/jails/test-pot-2/m/usr/local ro\"\n\t\techo \"zpot/jails/test-pot-2/custom /tmp/jails/test-pot-2/m/opt/custom zfs-remount\"\n\t} > /tmp/jails/test-pot-2/conf/fscomp.conf\n\t{\n\t\techo \"host.hostname=\\\"test-pot-2.test\\\"\"\n\t\techo \"pot.potbase=test-pot\"\n\t} > /tmp/jails/test-pot-2/conf/pot.conf\n\n\t/bin/mkdir -p /tmp/jails/test-pot-nosnap/conf\n\t{\n\t\techo \"zpot/bases/11.1 /tmp/jails/test-pot-nosnap/m ro\"\n\t\techo \"zpot/jails/test-pot-nosnap/usr.local /tmp/jails/test-pot-nosnap/m/usr/local zfs-remount\"\n\t\techo \"zpot/jails/test-pot-nosnap/custom /tmp/jails/test-pot-nosnap/m/opt/custom zfs-remount\"\n\t} > /tmp/jails/test-pot-nosnap/conf/fscomp.conf\n\t{\n\t\techo \"host.hostname=\\\"test-pot-nosnap.test\\\"\"\n\t\techo \"pot.potbase=\"\n\t\techo \"pot.depend=test-pot\"\n\t} > /tmp/jails/test-pot-nosnap/conf/pot.conf\n\n\t/bin/mkdir -p /tmp/jails/test-pot-single/conf\n\ttouch /tmp/jails/test-pot-single/conf/fscomp.conf\n\t{\n\t\techo \"host.hostname=\\\"test-pot-single.test\\\"\"\n\t\techo \"pot.potbase=\"\n\t} > /tmp/jails/test-pot-single/conf/pot.conf\n\n\t/bin/mkdir -p /tmp/jails/test-pot-single-run/conf\n\t{\n\t\techo \"zpot/fscomp/examples /tmp/jails/test-pot-single-run/m/tmp/examples ro\"\n\t} > /tmp/jails/test-pot-single-run/conf/fscomp.conf\n\t{\n\t\techo \"host.hostname=\\\"test-pot-single-run.test\\\"\"\n\t\techo \"pot.potbase=\"\n\t} > /tmp/jails/test-pot-single-run/conf/pot.conf\n\n\t/bin/mkdir -p /tmp/jails/test-pot-vnet-ip4/conf\n\ttouch /tmp/jails/test-pot-vnet-ip4/conf/fscomp.conf\n\t{\n\t\techo \"pot.level=0\"\n\t\techo \"pot.type=single\"\n\t\techo \"pot.base=12.0\"\n\t\techo \"pot.potbase=\"\n\t\techo \"pot.dns=inherit\"\n\t\techo \"pot.cmd=sh /etc/rc\"\n\t\techo \"host.hostname=\\\"test-pot-vnet-ip4.test\\\"\"\n\t\techo \"0\"\n\t\techo \"osrelease=\\\"12.0-RELEASE\\\"\"\n\t\techo \"ip=10.192.0.3\"\n\t\techo \"network_type=public-network\"\n\t\techo \"vnet=true\"\n\t\techo \"pot.export.ports=80 443\"\n\t} > /tmp/jails/test-pot-vnet-ip4/conf/pot.conf\n}\n\nconf_tearDown()\n{\n\trm -rf /tmp/jails\n}\n\n"
  },
  {
    "path": "tests/config1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/config.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nconfig-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_config_echo()\n{\n\t__monitor CONFECHO \"$@\"\n}\n\ntest_pot_config_001()\n{\n\tpot-config\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"config_echo calls\" \"0\" CONFECHO_CALLS\n\n\tsetUp\n\tpot-config -k bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"config_echo calls\" \"0\" CONFECHO_CALLS\n\n\tsetUp\n\tpot-config -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"config_echo calls\" \"0\" CONFECHO_CALLS\n}\n\ntest_pot_config_002()\n{\n\tpot-config -q\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"config_echo calls\" \"0\" CONFECHO_CALLS\n}\n\ntest_pot_config_010()\n{\n\tpot-config -g noname\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"config_echo calls\" \"0\" CONFECHO_CALLS\n}\n\ntest_pot_config_020()\n{\n\tpot-config -g gateway\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"config_echo calls\" \"1\" CONFECHO_CALLS\n\tassertEqualsMon \"config_echo arg\" \"NO\" CONFECHO_CALL1_ARG1\n\tassertEqualsMon \"config_echo arg\" \"gateway\" CONFECHO_CALL1_ARG2\n\tassertEqualsMon \"config_echo arg\" \"10.1.2.3\" CONFECHO_CALL1_ARG3\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tPOT_GATEWAY=\"10.1.2.3\"\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/copy-in1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nif [ \"$(uname)\" = \"Linux\" ]; then\n\tTEST=/usr/bin/[\nelse\n\tTEST=/bin/[\nfi\n\n[()\n{\n\tif ${TEST} \"$1\" = \"-f\" ]; then\n\t\tif ${TEST} \"$2\" = \"test-file\" ]; then\n\t\t\treturn 0 # false\n\t\tfi\n\tfi\n\t${TEST} \"$@\"\n\treturn $?\n}\n\njexec() {\n\t__monitor JEXEC \"$@\"\n}\n\njail() {\n\t__monitor JAIL \"$@\"\n}\n\nmktemp() {\n\t__monitor MKTEMP \"$@\"\n\techo /tmp/copy-in.asdf\n}\n\numount() {\n\t__monitor UMOUNT \"$@\"\n}\n\nrmdir() {\n\t__monitor RMDIR \"$@\"\n}\n\n# UUT\n. ../share/pot/copy-in.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\ncopy-in-help()\n{\n\t__monitor HELP \"$@\"\n\treturn 0 # true\n}\n\n_source_validation()\n{\n\t__monitor SRCVALID \"$@\"\n\tif [ \"$1\" = \"test-file\" ]; then\n\t\treturn 0 # true\n\telif [ \"$1\" = \"test-dir\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_mount_source_into_potroot()\n{\n\treturn 0 # true\n}\n\n_pot_mount()\n{\n\t__monitor PMOUNT \"$@\"\n}\n\n_pot_umount()\n{\n\t__monitor PUMOUNT \"$@\"\n}\n\ntest_pot_copy_in_001()\n{\n\tpot-copy-in\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-copy-in -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-copy-in -b bb\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-copy-in -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n}\n\ntest_pot_copy_in_002()\n{\n\tpot-copy-in -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-in -s test-file\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-in -d test-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-in -p test-pot -s test-file\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-in -d test-mnt -s test-file\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-in -d test-mnt -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n}\n\ntest_pot_copy_in_003()\n{\n\tpot-copy-in -p test-no-pot -s test-no-file -d /test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n}\n\ntest_pot_copy_in_004()\n{\n\tpot-copy-in -p test-no-pot -s test-file -d /test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_copy_in_005()\n{\n\tpot-copy-in -p test-pot -s test-no-file -d /test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_source_validation calls\" \"1\" SRCVALID_CALLS\n}\n\ntest_pot_copy_in_006()\n{\n\tpot-copy-in -p test-pot-run -s test-file -d /test-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_source_validation calls\" \"1\" SRCVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"0\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"0\" JEXEC_CALLS\n\tassertEqualsMon \"_jail calls\" \"0\" JAIL_CALLS\n}\n\ntest_pot_copy_in_020()\n{\n\tpot-copy-in -p test-pot -s test-file -d /test-mnt\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_source_validation calls\" \"1\" SRCVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"1\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"0\" JEXEC_CALLS\n\tassertEqualsMon \"_jail calls\" \"1\" JAIL_CALLS\n\tassertEqualsMon \"_jail args\" \"-c\" JAIL_CALL1_ARG1\n\tassertEqualsMon \"_jail args\" \"/tmp/copy-in.asdf/test-file\" JAIL_CALL1_ARG5\n\tassertEqualsMon \"_jail args\" \"/test-mnt\" JAIL_CALL1_ARG6\n\tassertEqualsMon \"_pot_umount calls\" \"1\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"0\" RMDIR_CALLS\n}\n\ntest_pot_copy_in_021()\n{\n\tpot-copy-in -p test-pot-run -s test-file -d /test-mnt -F\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_source_validation calls\" \"1\" SRCVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"0\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"1\" JEXEC_CALLS\n\tassertEqualsMon \"_jexec args\" \"test-pot-run\" JEXEC_CALL1_ARG1\n\tassertEqualsMon \"_jexec args\" \"-a\" JEXEC_CALL1_ARG3\n\tassertEqualsMon \"_jexec args\" \"/tmp/copy-in.asdf/test-file\" JEXEC_CALL1_ARG4\n\tassertEqualsMon \"_jexec args\" \"/test-mnt\" JEXEC_CALL1_ARG5\n\tassertEqualsMon \"_jail calls\" \"0\" JAIL_CALLS\n\tassertEqualsMon \"_pot_umount calls\" \"0\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"1\" RMDIR_CALLS\n}\n\ntest_pot_copy_in_022()\n{\n\tpot-copy-in -p test-pot-run -s test-file -d /test-mnt -vF\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_source_validation calls\" \"1\" SRCVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"0\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"1\" JEXEC_CALLS\n\tassertEqualsMon \"_jexec args\" \"test-pot-run\" JEXEC_CALL1_ARG1\n\tassertEqualsMon \"_jexec args\" \"-va\" JEXEC_CALL1_ARG3\n\tassertEqualsMon \"_jexec args\" \"/tmp/copy-in.asdf/test-file\" JEXEC_CALL1_ARG4\n\tassertEqualsMon \"_jexec args\" \"/test-mnt\" JEXEC_CALL1_ARG5\n\tassertEqualsMon \"_jail calls\" \"0\" JAIL_CALLS\n\tassertEqualsMon \"_pot_umount calls\" \"0\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"1\" RMDIR_CALLS\n}\n\ntest_pot_copy_in_023()\n{\n\tpot-copy-in -p test-pot -s test-dir -d /test-mnt -v\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_source_validation calls\" \"1\" SRCVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"1\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"0\" JEXEC_CALLS\n\tassertEqualsMon \"_jail calls\" \"1\" JAIL_CALLS\n\tassertEqualsMon \"_jail args\" \"-c\" JAIL_CALL1_ARG1\n\tassertEqualsMon \"_jail args\" \"/tmp/copy-in.asdf\" JAIL_CALL1_ARG5\n\tassertEqualsMon \"_jail args\" \"/test-mnt\" JAIL_CALL1_ARG6\n\tassertEqualsMon \"_pot_umount calls\" \"1\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"0\" RMDIR_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tERROR_DEBUG=\"NO\"\n\tDEBUG_DEBUG=\"NO\"\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/copy-out1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nif [ \"$(uname)\" = \"Linux\" ]; then\n\tTEST=/usr/bin/[\nelse\n\tTEST=/bin/[\nfi\n\n[()\n{\n\tif ${TEST} \"$1\" = \"-f\" ]; then\n\t\tif ${TEST} \"$2\" = \"test-file\" ]; then\n\t\t\treturn 0 # false\n\t\tfi\n\tfi\n\t${TEST} \"$@\"\n\treturn $?\n}\n\njexec() {\n\t__monitor JEXEC \"$@\"\n}\n\njail() {\n\t__monitor JAIL \"$@\"\n}\n\nmktemp() {\n\t__monitor MKTEMP \"$@\"\n\techo /tmp/copy-out.asdf\n}\n\nrmdir() {\n\t__monitor RMDIR \"$@\"\n}\n\numount() {\n\t__monitor UMOUNT \"$@\"\n}\n\n# UUT\n. ../share/pot/copy-out.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\ncopy-out-help()\n{\n\t__monitor HELP \"$@\"\n\treturn 0 # true\n}\n\n_destination_validation()\n{\n\t__monitor DSTVALID \"$@\"\n\tif [ \"$1\" = \"test-mnt\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_mount_destination_into_potroot()\n{\n\treturn 0 # true\n}\n\n_pot_mount()\n{\n\t__monitor PMOUNT \"$@\"\n}\n\n_pot_umount()\n{\n\t__monitor PUMOUNT \"$@\"\n}\n\ntest_pot_copy_out_001()\n{\n\tpot-copy-out\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-copy-out -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-copy-out -b bb\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-copy-out -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n}\n\ntest_pot_copy_out_002()\n{\n\tpot-copy-out -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-out -s test-file\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-out -d test-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-out -p test-pot -s test-file\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-out -d test-mnt -s test-file\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\n\tsetUp\n\tpot-copy-out -d test-mnt -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n}\n\ntest_pot_copy_out_003()\n{\n\tpot-copy-out -p test-no-pot -s /test-no-file -d test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n}\n\ntest_pot_copy_out_004()\n{\n\tpot-copy-out -p test-no-pot -s /test-file -d test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_copy_out_005()\n{\n\tpot-copy-out -p test-pot -s /test-no-file -d test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_destination_validation calls\" \"1\" DSTVALID_CALLS\n}\n\ntest_pot_copy_out_006()\n{\n\tpot-copy-out -p test-pot-run -s /test-file -d test-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_destination_validation calls\" \"1\" DSTVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"0\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"0\" JEXEC_CALLS\n\tassertEqualsMon \"_jail calls\" \"0\" JAIL_CALLS\n}\n\ntest_pot_copy_out_020()\n{\n\tpot-copy-out -p test-pot -s /test-file -d test-mnt\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_destination_validation calls\" \"1\" DSTVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"1\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"0\" JEXEC_CALLS\n\tassertEqualsMon \"_jail calls\" \"1\" JAIL_CALLS\n\tassertEqualsMon \"_jail args\" \"-c\" JAIL_CALL1_ARG1\n\tassertEqualsMon \"_jail args\" \"/test-file\" JAIL_CALL1_ARG5\n\tassertEqualsMon \"_jail args\" \"/tmp/copy-out.asdf\" JAIL_CALL1_ARG6\n\tassertEqualsMon \"_pot_umount calls\" \"1\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"0\" RMDIR_CALLS\n}\n\ntest_pot_copy_out_021()\n{\n\tpot-copy-out -p test-pot-run -s /test-file -d test-mnt -F\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_destination_validation calls\" \"1\" DSTVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"0\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"1\" JEXEC_CALLS\n\tassertEqualsMon \"_jexec args\" \"test-pot-run\" JEXEC_CALL1_ARG1\n\tassertEqualsMon \"_jexec args\" \"-a\" JEXEC_CALL1_ARG3\n\tassertEqualsMon \"_jexec args\" \"/test-file\" JEXEC_CALL1_ARG4\n\tassertEqualsMon \"_jexec args\" \"/tmp/copy-out.asdf\" JEXEC_CALL1_ARG5\n\tassertEqualsMon \"_jail calls\" \"0\" JAIL_CALLS\n\tassertEqualsMon \"_pot_umount calls\" \"0\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"1\" RMDIR_CALLS\n}\n\ntest_pot_copy_out_022()\n{\n\tpot-copy-out -p test-pot-run -s /test-file -d test-mnt -vF\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_destination_validation calls\" \"1\" DSTVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"0\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"1\" JEXEC_CALLS\n\tassertEqualsMon \"_jexec args\" \"test-pot-run\" JEXEC_CALL1_ARG1\n\tassertEqualsMon \"_jexec args\" \"-va\" JEXEC_CALL1_ARG3\n\tassertEqualsMon \"_jexec args\" \"/test-file\" JEXEC_CALL1_ARG4\n\tassertEqualsMon \"_jexec args\" \"/tmp/copy-out.asdf\" JEXEC_CALL1_ARG5\n\tassertEqualsMon \"_jail calls\" \"0\" JAIL_CALLS\n\tassertEqualsMon \"_pot_umount calls\" \"0\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"1\" RMDIR_CALLS\n}\n\ntest_pot_copy_out_023()\n{\n\tpot-copy-out -p test-pot -s /test-dir -d test-mnt -v\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_destination_validation calls\" \"1\" DSTVALID_CALLS\n\tassertEqualsMon \"_pot_mount calls\" \"1\" PMOUNT_CALLS\n\tassertEqualsMon \"_jexec calls\" \"0\" JEXEC_CALLS\n\tassertEqualsMon \"_jail calls\" \"1\" JAIL_CALLS\n\tassertEqualsMon \"_jail args\" \"-c\" JAIL_CALL1_ARG1\n\tassertEqualsMon \"_jail args\" \"/test-dir\" JAIL_CALL1_ARG5\n\tassertEqualsMon \"_jail args\" \"/tmp/copy-out.asdf\" JAIL_CALL1_ARG6\n\tassertEqualsMon \"_pot_umount calls\" \"1\" PUMOUNT_CALLS\n\tassertEqualsMon \"_rmdir calls\" \"0\" RMDIR_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tERROR_DEBUG=\"NO\"\n\tDEBUG_DEBUG=\"NO\"\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/create-base1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/create-base.sh\n\n# common stubs\n. common-stub.sh\n\n_is_init()\n{\n\t__monitor ISINIT \"$@\"\n}\n\n# app specific stubs\n\ncreate-base-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_fetch_freebsd()\n{\n\t__monitor FETCHBSD \"$@\"\n\tif [ \"$1\" = \"10.1\" ]; then\n\t\treturn 1 # false\n\tfi\n}\n\n_cb_zfs()\n{\n\t__monitor CBZFS \"$@\"\n\tif [ \"$1\" = \"11.0\" ]; then\n\t\treturn 1 # false\n\tfi\n}\n\n_cb_tar_dir()\n{\n\t__monitor CBTAR \"$@\"\n}\n\n_cb_base_pot()\n{\n\t__monitor CBPOT \"$@\"\n}\n\ntest_base_create_base_001()\n{\n\tpot-create-base\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n\n\tsetUp\n\tpot-create-base -vL\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n\n\tsetUp\n\tpot-create-base -L bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n\n\tsetUp\n\tpot-create-base -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_002()\n{\n\tpot-create-base -r 1234\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_003()\n{\n\tpot-create-base -b 104x64\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_004()\n{\n\t# base name is invalid\n\tpot-create-base -r 11.1 -b 10.4\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_010()\n{\n\t# simulate fetch issue\n\tpot-create-base -r 10.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"1\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_011()\n{\n\t# simulate zfs issue\n\tpot-create-base -r 11.0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"1\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"1\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_012()\n{\n\tpot-create-base -r 11.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_013()\n{\n\tpot-create-base -r 11.1 -b test-base\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"0\" FETCHBSD_CALLS\n\tassertEqualsMon \"_cb_zfs calls\" \"0\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_tar_dir calls\" \"0\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_base_pot calls\" \"0\" CBPOT_CALLS\n}\n\ntest_base_create_base_020()\n{\n\tpot-create-base -r 11.1 -b new-test-base\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_fetch calls\" \"1\" FETCHBSD_CALLS\n\tassertEqualsMon \"_fetch arg\" \"11.1\" FETCHBSD_CALL1_ARG1\n\tassertEqualsMon \"_cb_zfs calls\" \"1\" CBZFS_CALLS\n\tassertEqualsMon \"_cb_zfs arg\" \"new-test-base\" CBZFS_CALL1_ARG1\n\tassertEqualsMon \"_cb_tar_dir calls\" \"1\" CBTAR_CALLS\n\tassertEqualsMon \"_cb_tar_dir arg\" \"11.1\" CBTAR_CALL1_ARG1\n\tassertEqualsMon \"_cb_tar_dir arg\" \"new-test-base\" CBTAR_CALL1_ARG2\n\tassertEqualsMon \"_cb_base_pot calls\" \"1\" CBPOT_CALLS\n\tassertEqualsMon \"_cb_base_pot arg\" \"new-test-base\" CBPOT_CALL1_ARG1\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/create-fscomp1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nzfs()\n{\n\t__monitor ZFS \"$@\"\n\treturn 0 # true\n}\n\n# UUT\n. ../share/pot/create-fscomp.sh\n\n# common stubs\n. common-stub.sh\n\n_zfs_dataset_valid()\n{\n\t__monitor ZDSET \"$@\"\n\tif [ \"$1\" = \"/fscomp/test-fscomp\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_is_init()\n{\n\treturn 0 # true\n}\n\n# app specific stubs\ncreate-fscomp-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_create_fscomp_001()\n{\n\tpot-create-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-create-fscomp -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-create-fscomp -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-create-fscomp -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_fscomp_002()\n{\n\tpot-create-fscomp -f test-fscomp\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"1\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"zfs calls\" \"0\" ZFS_CALLS\n}\n\ntest_pot_create_fscomp_020()\n{\n\tpot-create-fscomp -f new-fscomp\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"1\" ZDSET_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"zfs calls\" \"1\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"/fscomp/new-fscomp\" ZFS_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/create-private-bridge1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nmkdir()\n{\n\t__monitor MKDIR \"$@\"\n}\n\n# UUT\n. ../share/pot/create-private-bridge.sh\n\n# common stubs\n. common-stub.sh\n\n_is_potnet_available()\n{\n\treturn 0 # true\n}\n\n_is_bridge()\n{\n\tif [ \"$1\" = \"test-bridge\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1\n}\n\n# app specific stubs\n\ncreate-private-bridge-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ncreate-bridge()\n{\n\t__monitor CB \"$@\"\n}\n\ntest_create_private_bridge_001()\n{\n\tpot-create-private-bridge\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-create-private-bridge -vL\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-create-private-bridge -L bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\n\tsetUp\n\tpot-create-private-bridge -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_create_private_bridge_002()\n{\n\tpot-create-private-bridge -B test-bridge\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_create_bridge calls\" \"0\" CB_CALLS\n}\n\ntest_create_private_bridge_003()\n{\n\tpot-create-private-bridge -S 5\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_create_bridge calls\" \"0\" CB_CALLS\n}\n\ntest_create_private_bridge_010()\n{\n\t# bridge already exists\n\tpot-create-private-bridge -B test-bridge -S 5\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_create_bridge calls\" \"0\" CB_CALLS\n}\n\ntest_create_private_bridge_020()\n{\n\tpot-create-private-bridge -B new-test-bridge -S 5\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_create_bridge calls\" \"1\" CB_CALLS\n\tassertEqualsMon \"_create_bridge arg1\" \"new-test-bridge\" CB_CALL1_ARG1\n\tassertEqualsMon \"_create_bridge arg2\" \"5\" CB_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/create1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npotnet()\n{\n\t__monitor POTNET \"$@\"\n\tif [ \"$1\" = \"next\" ]; then\n\t\techo \"10.192.123.123\"\n\t\treturn 0 # true\n\tfi\n\tif [ \"$1\" = \"validate\" ] && [ \"$2\" = \"-H\" ] ; then\n\t\tif [ \"$3\" = \"10.192.123.123\" ] || [ \"$3\" = \"10.1.2.3\" ]; then\n\t\t\treturn 0 # true\n\t\tfi\n\tfi\n\tif [ \"$1\" = \"ipcheck\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n. pipefail-stub.sh\n\n# UUT\n. ../share/pot/create.sh\n\n# common stubs\n. common-stub.sh\n\n. ../share/pot/network.sh\n\n_is_vnet_available()\n{\n\t__monitor ISVNETAVAIL \"$@\"\n\treturn 0 # true\n}\n\n_is_potnet_available()\n{\n\t__monitor ISPOTNETAVAIL \"$@\"\n\treturn 0 # true\n}\n\n_fetch_freebsd()\n{\n\t__monitor FETCHBSD \"$@\"\n\treturn 0 # true\n}\n\n_get_network_stack()\n{\n\techo \"dual\"\n}\n\n# app specific stubs\n_cj_zfs()\n{\n\t__monitor CJZFS \"$@\"\n}\n\n_cj_conf()\n{\n\t__monitor CJCONF \"$@\"\n}\n\n_cj_internal_conf()\n{\n\t__monitor CJICONF \"$@\"\n}\n\n_cj_single_install()\n{\n\t__monitor CJSINGLE \"$@\"\n}\n\n_exec_flv()\n{\n\t__monitor EXEC_FLV \"$@\"\n}\n\ncreate-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_create_001()\n{\n\tpot-create\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -vL\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -L bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -S\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_002()\n{\n\tpot-create -p test-pot -b 11.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_003()\n{\n\tpot-create -p new-pot -P test-pot -l 0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -p new-pot -b 11.1 -P test-pot -l 0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_004()\n{\n\tpot-create -p new-pot -P test-pot2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -p new-pot -P test-pot2 -l 1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -p new-pot -b 11.1 -l 2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_005()\n{\n\tpot-create -p new-pot -b 12.1 -N alias -I\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\n\tsetUp\n\tpot-create -p new-pot -b 12.1 -N alias -I removed-option\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_006()\n{\n\tpot-create -p new-pot -b 12.1 -N alias -S no-valid-stack\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_007()\n{\n\tpot-create -p new.pot -b 12.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_020()\n{\n\tpot-create -p new-pot -b 11.1\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"multi\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_021()\n{\n\tpot-create -p new-pot -P test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"multi\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"test-pot\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"test-pot\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_022()\n{\n\tpot-create -p new-pot -P test-pot -S\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_023()\n{\n\tpot-create -p new-pot -P test-pot -b 10.4\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_024()\n{\n\tpot-create -p new-pot -P test-pot-0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_025()\n{\n\tpot-create -p new-pot -b 11.1\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"multi\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_026()\n{\n\tpot-create -p new-pot -b 11.1 -f flap\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"multi\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"1\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_exec_flv arg2\" \"flap\" EXEC_FLV_CALL1_ARG2\n}\n\ntest_pot_create_027()\n{\n\tpot-create -p new-pot -b 11.1 -S ipv6 -f flap\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"multi\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"ipv6\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"1\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_exec_flv arg2\" \"flap\" EXEC_FLV_CALL1_ARG2\n}\n\ntest_pot_create_028()\n{\n\tpot-create -p new-pot -b 11.1 -f flap -f flap2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"multi\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"2\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_exec_flv arg2\" \"flap\" EXEC_FLV_CALL1_ARG2\n\tassertEqualsMon \"_exec_flv arg2\" \"flap2\" EXEC_FLV_CALL2_ARG2\n}\n\ntest_pot_create_030()\n{\n\tpot-create -p new-pot -b 11.1 -f no-flav\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\ntest_pot_create_040()\n{\n\tpot-create -p new-pot -P test-pot -l 2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"2\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"test-pot\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"2\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"test-pot\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_041()\n{\n\tpot-create -p new-pot -b 11.1 -P test-pot -l 2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"2\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"test-pot\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"2\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"test-pot\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_042()\n{\n\tpot-create -p new-pot -P test-pot -b 10.4 -l 2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_060()\n{\n\tpot-create -p new-pot -b 11.1 -N inherit\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"0\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_potnet calls\" \"0\" POTNET_CALLS\n}\n\ntest_pot_create_061()\n{\n\tpot-create -p new-pot -b 11.1 -N inherit -s\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_062()\n{\n\tpot-create -p new-pot -b 11.1 -N public-bridge -i 10.1.2.3\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.3\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_063()\n{\n\tpot-create -p new-pot -b 11.1 -N alias -i 10.1.2.3\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"0\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"alias\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.3\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_064()\n{\n\tpot-create -p new-pot -b 11.1 -N public-bridge -i auto\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.192.123.123\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_065()\n{\n\t# -s is ignored in this case\n\tpot-create -p new-pot -b 11.1 -N alias -i auto\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\t# an empty error message is printed because _error is re-implemented in the stub\n}\n\ntest_pot_create_080()\n{\n\tpot-create -p new-pot -b 11.1 -d asdf\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"0\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_conf calls\" \"0\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_081()\n{\n\tpot-create -p new-pot -b 11.1 -d pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"1\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"pot\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_082()\n{\n\tpot-create -p new-pot -b 11.1 -N public-bridge -i 10.1.2.3 -d pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"2\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.3\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"pot\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_083()\n{\n\tpot-create -p new-pot -b 11.1 -N alias -i 10.1.2.3 -d pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"1\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"alias\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.3\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"pot\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_084()\n{\n\tpot-create -p new-pot -b 11.1 -N public-bridge -i 10.1.2.3 -d off\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"1\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg3\" \"1\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.3\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"1\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"off\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"multi\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"0\" CJICONF_CALLS\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\n\ntest_pot_create_100()\n{\n\tpot-create -p new-pot -t single\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_101()\n{\n\tpot-create -p new-pot -t single -b no-base\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_102()\n{\n\tpot-create -p new-pot -t single -P no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_103()\n{\n\tpot-create -p new-pot -t single -P test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_104()\n{\n\tpot-create -p test-pot -t single -b 11.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_105()\n{\n\tpot-create -p new-pot -t single -P test-pot-0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_106()\n{\n\tpot-create -p new-pot -t single -P test-pot-single -b 10.3\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_107()\n{\n\tpot-create -p new-pot -t single -b 11.1 -l 1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n}\n\ntest_pot_create_120()\n{\n\tpot-create -p new-pot -b 11.1 -t single\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"0\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"single\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"0\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"0\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"single\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"1\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_single_install arg1\" \"new-pot\" CJSINGLE_CALL1_ARG1\n\tassertEqualsMon \"_cj_single_install arg2\" \"11.1\" CJSINGLE_CALL1_ARG2\n\tassertEqualsMon \"_cj_interal_conf calls\" \"1\" CJICONF_CALLS\n\tassertEqualsMon \"_cj_interal_conf arg1\" \"new-pot\" CJICONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_interal_conf arg2\" \"single\" CJICONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_interal_conf arg3\" \"0\" CJICONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_interal_conf arg4\" \"\" CJICONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_121()\n{\n\tpot-create -p new-pot -b 11.1 -t single -N public-bridge -i 10.1.2.3\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"single\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"0\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"public-bridge\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"10.1.2.3\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"0\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"single\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"1\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"1\" CJICONF_CALLS\n\tassertEqualsMon \"_cj_single_install arg1\" \"new-pot\" CJSINGLE_CALL1_ARG1\n\tassertEqualsMon \"_cj_single_install arg2\" \"11.1\" CJSINGLE_CALL1_ARG2\n\tassertEqualsMon \"_cj_interal_conf arg1\" \"new-pot\" CJICONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_interal_conf arg2\" \"single\" CJICONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_interal_conf arg3\" \"0\" CJICONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_interal_conf arg4\" \"10.1.2.3\" CJICONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n}\n\ntest_pot_create_122()\n{\n\tpot-create -p new-pot -P test-pot-single -t single\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_is_vnet_available calls\" \"0\" ISVNETAVAIL_CALLS\n\tassertEqualsMon \"_cj_zfs calls\" \"1\" CJZFS_CALLS\n\tassertEqualsMon \"_cj_zfs arg1\" \"new-pot\" CJZFS_CALL1_ARG1\n\tassertEqualsMon \"_cj_zfs arg2\" \"single\" CJZFS_CALL1_ARG2\n\tassertEqualsMon \"_cj_zfs arg3\" \"0\" CJZFS_CALL1_ARG3\n\tassertEqualsMon \"_cj_zfs arg4\" \"11.1\" CJZFS_CALL1_ARG4\n\tassertEqualsMon \"_cj_zfs arg5\" \"test-pot-single\" CJZFS_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf calls\" \"1\" CJCONF_CALLS\n\tassertEqualsMon \"_cj_conf arg1\" \"new-pot\" CJCONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_conf arg2\" \"11.1\" CJCONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_conf arg3\" \"inherit\" CJCONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_conf arg4\" \"\" CJCONF_CALL1_ARG4\n\tassertEqualsMon \"_cj_conf arg5\" \"0\" CJCONF_CALL1_ARG5\n\tassertEqualsMon \"_cj_conf arg6\" \"inherit\" CJCONF_CALL1_ARG6\n\tassertEqualsMon \"_cj_conf arg7\" \"single\" CJCONF_CALL1_ARG7\n\tassertEqualsMon \"_cj_conf arg8\" \"\" CJCONF_CALL1_ARG8\n\tassertEqualsMon \"_cj_conf arg9\" \"test-pot-single\" CJCONF_CALL1_ARG9\n\tassertEqualsMon \"_cj_conf_arg10\" \"dual\" CJCONF_CALL1_ARG10\n\tassertEqualsMon \"_cj_single_install calls\" \"0\" CJSINGLE_CALLS\n\tassertEqualsMon \"_cj_interal_conf calls\" \"1\" CJICONF_CALLS\n\tassertEqualsMon \"_cj_interal_conf arg1\" \"new-pot\" CJICONF_CALL1_ARG1\n\tassertEqualsMon \"_cj_interal_conf arg2\" \"single\" CJICONF_CALL1_ARG2\n\tassertEqualsMon \"_cj_interal_conf arg3\" \"0\" CJICONF_CALL1_ARG3\n\tassertEqualsMon \"_cj_interal_conf arg4\" \"\" CJICONF_CALL1_ARG4\n\tassertEqualsMon \"_exec_flv calls\" \"0\" EXEC_FLV_CALLS\n\tassertEqualsMon \"_potnet calls\" \"0\" POTNET_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/create2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nzfs()\n{\n\t__monitor ZFS \"$@\"\n}\n\nECHO=echo_stub\necho_stub()\n{\n\t__monitor ECHO \"$@\"\n}\n\nmkdir()\n{\n\t__monitor MKDIR \"$@\"\n}\n\nchmod()\n{\n\t__monitor CHMOD \"$@\"\n\tif [ \"$2\" = \"/tmp/jails/new-pot/m/tmp\" ]; then\n\t\treturn 0 # true\n\tfi\n\tif [ \"$2\" = \"/tmp/jails/test-pot/m/tmp\" ]; then\n\t\treturn 0 # true\n\tfi\n\t/bin/chmod $@\n}\n\n. pipefail-stub.sh\n\n# UUT\n. ../share/pot/create.sh\n\n# common stubs\n. common-stub.sh\n\n_zfs_dataset_valid()\n{\n\t__monitor ZFSDATASETVALID \"$@\"\n\tcase \"$1\" in\n\t${POT_ZFS_ROOT}/jails/test-pot|\\\n\t${POT_ZFS_ROOT}/jails/test-pot/usr.local|\\\n\t${POT_ZFS_ROOT}/jails/test-pot/custom)\n\t\treturn 0 # true\n\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n_zfs_last_snap()\n{\n\t__monitor ZFSLASTSNAP \"$@\"\n\tcase $1 in\n\t${POT_ZFS_ROOT}/bases/11.1/usr.local|\\\n\t${POT_ZFS_ROOT}/bases/11.1/custom)\n\t\techo 1234\n\t\t;;\n\t${POT_ZFS_ROOT}/jails/test-pot/usr.local|\\\n\t${POT_ZFS_ROOT}/jails/test-pot/custom)\n\t\techo 4321\n\t\t;;\n\t${POT_ZFS_ROOT}/jails/test-pot/m)\n\t\techo 9999\n\t\t;;\n\tesac\n}\n\ntest_cj_zfs_001()\n{\n\t# level 0\n\t_c_zfs_multi new-pot 0 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"1\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_002()\n{\n\t_c_zfs_multi new-pot 1 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"9\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c2 arg1\" \"send\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"${POT_ZFS_ROOT}/bases/11.1/usr.local@1234\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c3 arg1\" \"get\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-o\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"property\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c3 arg4\" \"all\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs c3 arg5\" \"${POT_ZFS_ROOT}\" ZFS_CALL3_ARG5\n\tassertEqualsMon \"zfs c4 arg1\" \"receive\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs c5 arg1\" \"destroy\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs c5 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local@1234\" ZFS_CALL5_ARG2\n\tassertEqualsMon \"zfs c6 arg1\" \"send\" ZFS_CALL6_ARG1\n\tassertEqualsMon \"zfs c6 arg2\" \"${POT_ZFS_ROOT}/bases/11.1/custom@1234\" ZFS_CALL6_ARG2\n\tassertEqualsMon \"zfs c7 arg1\" \"get\" ZFS_CALL7_ARG1\n\tassertEqualsMon \"zfs c7 arg2\" \"-o\" ZFS_CALL7_ARG2\n\tassertEqualsMon \"zfs c7 arg3\" \"property\" ZFS_CALL7_ARG3\n\tassertEqualsMon \"zfs c7 arg4\" \"all\" ZFS_CALL7_ARG4\n\tassertEqualsMon \"zfs c7 arg5\" \"${POT_ZFS_ROOT}\" ZFS_CALL7_ARG5\n\tassertEqualsMon \"zfs c8 arg1\" \"receive\" ZFS_CALL8_ARG1\n\tassertEqualsMon \"zfs c8 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL8_ARG2\n\tassertEqualsMon \"zfs c9 arg1\" \"destroy\" ZFS_CALL9_ARG1\n\tassertEqualsMon \"zfs c9 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom@1234\" ZFS_CALL9_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_003()\n{\n\t_c_zfs_multi new-pot 1 11.1 test-pot\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"9\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c2 arg1\" \"send\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot/usr.local@4321\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c3 arg1\" \"get\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-o\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"property\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c3 arg4\" \"all\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs c3 arg5\" \"${POT_ZFS_ROOT}\" ZFS_CALL3_ARG5\n\tassertEqualsMon \"zfs c4 arg1\" \"receive\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs c5 arg1\" \"destroy\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs c5 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local@4321\" ZFS_CALL5_ARG2\n\tassertEqualsMon \"zfs c6 arg1\" \"send\" ZFS_CALL6_ARG1\n\tassertEqualsMon \"zfs c6 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot/custom@4321\" ZFS_CALL6_ARG2\n\tassertEqualsMon \"zfs c7 arg1\" \"get\" ZFS_CALL7_ARG1\n\tassertEqualsMon \"zfs c7 arg2\" \"-o\" ZFS_CALL7_ARG2\n\tassertEqualsMon \"zfs c7 arg3\" \"property\" ZFS_CALL7_ARG3\n\tassertEqualsMon \"zfs c7 arg4\" \"all\" ZFS_CALL7_ARG4\n\tassertEqualsMon \"zfs c7 arg5\" \"${POT_ZFS_ROOT}\" ZFS_CALL7_ARG5\n\tassertEqualsMon \"zfs c8 arg1\" \"receive\" ZFS_CALL8_ARG1\n\tassertEqualsMon \"zfs c8 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL8_ARG2\n\tassertEqualsMon \"zfs c9 arg1\" \"destroy\" ZFS_CALL9_ARG1\n\tassertEqualsMon \"zfs c9 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom@4321\" ZFS_CALL9_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_004()\n{\n\t_c_zfs_multi new-pot 2 11.1 test-pot\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"5\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c2 arg1\" \"send\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot/custom@4321\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c3 arg1\" \"get\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-o\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"property\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c3 arg4\" \"all\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs c3 arg5\" \"${POT_ZFS_ROOT}\" ZFS_CALL3_ARG5\n\tassertEqualsMon \"zfs c4 arg1\" \"receive\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs c5 arg1\" \"destroy\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs c5 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom@4321\" ZFS_CALL5_ARG2\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_021()\n{\n\t_cj_zfs test-pot multi 0 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"0\" ZFS_CALLS\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/test-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"info calls\" \"1\" INFO_CALLS\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_022()\n{\n\t_cj_zfs test-pot multi 1 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"0\" ZFS_CALLS\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/test-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"info calls\" \"3\" INFO_CALLS\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_023()\n{\n\t_cj_zfs test-pot multi 2 11.1 test-pot2\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"0\" ZFS_CALLS\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/test-pot/m\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"info calls\" \"2\" INFO_CALLS\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\ntest_cj_zfs_041()\n{\n\t_cj_zfs new-pot single 0 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"2\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c2 arg1\" \"create\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/m\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir 1 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m/tmp\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir 2 arg2\" \"${POT_FS_ROOT}/jails/new-pot/m/dev\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"chmod calls\" \"1\" CHMOD_CALLS\n\tassertEqualsMon \"chmod arg1\" \"1777\" CHMOD_CALL1_ARG1\n\tassertEqualsMon \"chmod arg2\" \"${POT_FS_ROOT}/jails/new-pot/m/tmp\" CHMOD_CALL1_ARG2\n}\n\ntest_cj_zfs_042()\n{\n\t_cj_zfs test-pot single 0 11.1\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"1\" ZFS_CALLS\n\tassertEqualsMon \"zfs arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs arg2\" \"${POT_ZFS_ROOT}/jails/test-pot/m\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"mkdir calls\" \"2\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir 1 arg2\" \"${POT_FS_ROOT}/jails/test-pot/m/tmp\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"mkdir 2 arg2\" \"${POT_FS_ROOT}/jails/test-pot/m/dev\" MKDIR_CALL2_ARG2\n\tassertEqualsMon \"chmod calls\" \"1\" CHMOD_CALLS\n\tassertEqualsMon \"chmod arg1\" \"1777\" CHMOD_CALL1_ARG1\n\tassertEqualsMon \"chmod arg2\" \"${POT_FS_ROOT}/jails/test-pot/m/tmp\" CHMOD_CALL1_ARG2\n}\n\ntest_cj_zfs_043()\n{\n\t_cj_zfs new-pot single 0 11.1 test-pot\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEqualsMon \"zfs calls\" \"4\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"create\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c2 arg1\" \"send\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot/m@9999\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c3 arg1\" \"get\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-o\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"property\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c3 arg4\" \"all\" ZFS_CALL3_ARG4\n\tassertEqualsMon \"zfs c3 arg5\" \"${POT_ZFS_ROOT}\" ZFS_CALL3_ARG5\n\tassertEqualsMon \"zfs c4 arg1\" \"receive\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/m\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"mkdir calls\" \"0\" MKDIR_CALLS\n\tassertEqualsMon \"chmod calls\" \"0\" CHMOD_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/create3.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nmkdir()\n{\n\t__monitor MKDIR \"$@\"\n\t/bin/mkdir \"$@\"\n}\n\nSED=sed_stub\nsed_stub()\n{\n\t__monitor SED \"$@\"\n\tif [ \"$4\" = \"${POT_FS_ROOT}/jails/$_pname/custom/etc/crontab\" ]; then\n\t\treturn 0 # true\n\tfi\n\tif [ \"$4\" = \"${POT_FS_ROOT}/jails/$_pname/custom/etc/syslog.conf\" ]; then\n\t\treturn 0 # true\n\tfi\n\tif [ \"$(uname)\" = \"Linux\" ]; then\n\t\tsed -i'' \"$3\" \"$4\"\n\telse\n\t\tsed \"$@\"\n\tfi\n}\n\nsysrc()\n{\n\t__monitor SYSRC \"$@\"\n}\n\nservice()\n{\n\t__monitor SERVICE \"$@\"\n}\n\ncat()\n{\n\tif [ \"$1\" = \"${POT_FS_ROOT}/bases/11.1/.osrelease\" ]; then\n\t\techo 11.1\n\tfi\n}\n\ncp()\n{\n\t__monitor CP \"$@\"\n}\n\n. pipefail-stub.sh\n\n# UUT\n. ../share/pot/create.sh\n\n# common stubs\n. common-stub.sh\n\n_cj_internal_conf()\n{\n\t__monitor ICONF \"$@\"\n}\n\ntest_cj_conf_001()\n{\n\t# level 0\n\t_cj_conf new-pot 11.1 inherit \"\" 0 inherit multi\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 /\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/bases/11.1/usr.local /usr/local\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/bases/11.1/custom /opt/custom\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=0\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=inherit\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"0\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"\" ICONF_CALL1_ARG4\n}\n\ntest_cj_conf_002()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 1 inherit multi\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=1\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=inherit\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"1\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_003()\n{\n\t/bin/mkdir -p /tmp/jails/test-pot/conf\n\techo \"zpot/bases/11.1 / ro\" >> /tmp/jails/test-pot/conf/fscomp.conf\n\techo \"zpot/jails/test-pot/usr.local /usr/local zfs-remount\" >> /tmp/jails/test-pot/conf/fscomp.conf\n\techo \"zpot/jails/test-pot/custom /opt/custom zfs-remount\" >> /tmp/jails/test-pot/conf/fscomp.conf\n\t_cj_conf new-pot 11.1 inherit \"\" 1 inherit multi \"\" test-pot\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=1\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=test-pot\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=inherit\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"1\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_004()\n{\n\t/bin/mkdir -p /tmp/jails/test-pot/conf\n\techo \"zpot/bases/11.1 / ro\" >> /tmp/jails/test-pot/conf/fscomp.conf\n\techo \"zpot/jails/test-pot/usr.local /usr/local zfs-remount\" >> /tmp/jails/test-pot/conf/fscomp.conf\n\techo \"zpot/jails/test-pot/custom /opt/custom zfs-remount\" >> /tmp/jails/test-pot/conf/fscomp.conf\n\t_cj_conf new-pot 11.1 inherit \"\" 2 inherit multi \"\" test-pot\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/test-pot/usr.local /usr/local ro\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=2\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=test-pot\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"2\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"1\" SED_CALLS\n}\n\ntest_cj_conf_005()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 2 inherit multi \"\" test-pot-2\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/test-pot/usr.local /usr/local ro\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=2\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=test-pot-2\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=inherit\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"2\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_006()\n{\n\t_cj_conf new-pot 11.1 public-bridge 10.1.2.3 1 inherit multi\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=1\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=public-bridge\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"ip=10.1.2.3\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=true\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"1\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"10.1.2.3\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_007()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 1 pot multi\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=1\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=inherit\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"pot.depend=${POT_DNS_NAME}\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"1\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"\" ICONF_CALL1_ARG4\n}\n\ntest_cj_conf_008()\n{\n\t_cj_conf new-pot 11.1 public-bridge 10.1.2.3 1 pot multi\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=1\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=public-bridge\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"ip=10.1.2.3\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=true\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"pot.depend=${POT_DNS_NAME}\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"1\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"10.1.2.3\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_009()\n{\n\t_cj_conf new-pot 11.1 alias 10.1.2.3 1 pot multi\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 / ro\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=1\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=alias\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"ip=10.1.2.3\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"pot.depend=${POT_DNS_NAME}\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"1\" ICONF_CALLS\n\tassertEqualsMon \"internal_conf arg1\" \"new-pot\" ICONF_CALL1_ARG1\n\tassertEqualsMon \"internal_conf arg2\" \"multi\" ICONF_CALL1_ARG2\n\tassertEqualsMon \"internal_conf arg3\" \"1\" ICONF_CALL1_ARG3\n\tassertEqualsMon \"internal_conf arg4\" \"10.1.2.3\" ICONF_CALL1_ARG4\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_020()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 0 pot single\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.level\" \"pot.level=0\" \"$(grep ^pot.level /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.base\" \"pot.base=11.1\" \"$(grep ^pot.base /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"osrelease\" \"osrelease=\\\"11.1-RELEASE\\\"\" \"$(grep ^osrelease /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.potbase\" \"pot.potbase=\" \"$(grep ^pot.potbase /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"network_type\" \"network_type=inherit\" \"$(grep ^network_type= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"ip\" \"\" \"$(grep ^ip= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"vnet\" \"vnet=false\" \"$(grep ^vnet= /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"pot.depend=${POT_DNS_NAME}\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"mkdir calls\" \"1\" MKDIR_CALLS\n\tassertEqualsMon \"mkdir arg2\" \"${POT_FS_ROOT}/jails/new-pot/conf\" MKDIR_CALL1_ARG2\n\tassertEqualsMon \"internal_conf calls\" \"0\" ICONF_CALLS\n\tassertEqualsMon \"sed calls\" \"0\" SED_CALLS\n}\n\ntest_cj_conf_040()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 0 pot single\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.dns\" \"pot.dns=pot\" \"$(grep ^pot.dns /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"pot.depend=${POT_DNS_NAME}\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"cp calls\" \"0\" CP_CALLS\n}\n\ntest_cj_conf_041()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 0 off single\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.dns\" \"pot.dns=off\" \"$(grep ^pot.dns /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"cp calls\" \"0\" CP_CALLS\n}\n\ntest_cj_conf_042()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 0 inherit single\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.dns\" \"pot.dns=inherit\" \"$(grep ^pot.dns /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"cp calls\" \"0\" CP_CALLS\n}\n\ntest_cj_conf_043()\n{\n\t_cj_conf new-pot 11.1 inherit \"\" 0 custom:/etc/resolv.conf single\n\tassertEquals \"return code\" \"0\" \"$?\"\n\tassertEquals \"fscomp args1\" \"\" \"$(sed '1!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"\" \"$(sed '2!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"\" \"$(sed '3!d' /tmp/jails/new-pot/conf/fscomp.conf)\"\n\tassertEquals \"pot.dns\" \"pot.dns=custom\" \"$(grep ^pot.dns /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEquals \"pot.depend\" \"\" \"$(grep ^pot.depend /tmp/jails/new-pot/conf/pot.conf)\"\n\tassertEqualsMon \"cp calls\" \"1\" CP_CALLS\n\tassertEqualsMon \"cp arg1\" \"/etc/resolv.conf\" CP_CALL1_ARG1\n\tassertEqualsMon \"cp arg2\" \"/tmp/jails/new-pot/conf/resolv.conf\" CP_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n\tPOT_DNS_NAME=foobar-dns\n\t/bin/mkdir -p /tmp/jails/new-pot/custom/etc/syslog.d\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\trm -rf /tmp/jails\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/destroy1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nls()\n{\n\tcat << LS_EOL\n/opt/pot/jails/base-11_1/\n/opt/pot/jails/test-pot/\n/opt/pot/jails/test-pot-2/\n/opt/pot/jails/test-pot-run/\n/opt/pot/jails/test-pot-run-2/\nLS_EOL\n}\n\n# UUT\n. ../share/pot/destroy.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\ndestroy-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_zfs_dataset_valid() {\n\t__monitor ZFSDATASETVALID \"$@\"\n\tif [ \"$1\" = \"/fscomp/test-fscomp\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_zfs_dataset_destroy()\n{\n\t__monitor ZFSDDESTROY \"$@\"\n}\n\n_pot_zfs_destroy()\n{\n\t__monitor POTDESTROY \"$@\"\n\tif [ \"$1\" = \"test-pot-run-2\" ]; then\n\t\tif [ \"$2\" != \"YES\" ]; then\n\t\t\treturn 1 # false\n\t\tfi\n\tfi\n\treturn 0 # true\n}\n\n_base_zfs_destroy()\n{\n\t__monitor BASEDESTROY \"$@\"\n}\n\n_fscomp_zfs_destroy()\n{\n\t__monitor FSCOMPDESTROY \"$@\"\n}\n\ntest_pot_destroy_001()\n{\n\tpot-destroy\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n\n\tsetUp\n\tpot-destroy -k bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n\n\tsetUp\n\tpot-destroy -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n\n\tsetUp\n\tpot-destroy -va\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_002()\n{\n\tpot-destroy -p test-pot -b 11.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_003()\n{\n\tpot-destroy -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_004()\n{\n\tpot-destroy -p test-pot-0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_005()\n{\n\tpot-destroy -p test-pot-2 -f test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_006()\n{\n\tpot-destroy -f test-fscomp -b 11.1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_010()\n{\n\t# error - recursion is needed\n\tpot-destroy -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_011()\n{\n\t# error - still running, force is needed\n\tpot-destroy -p test-pot-run-2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"1\" POTDESTROY_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy arg1\" \"test-pot-run-2\" POTDESTROY_CALL1_ARG1\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_020()\n{\n\tpot-destroy -p test-pot -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"2\" POTDESTROY_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy arg1\" \"test-pot-2\" POTDESTROY_CALL1_ARG1\n\tassertEqualsMon \"_pot_zfs_destroy arg2\" \"\" POTDESTROY_CALL1_ARG2\n\tassertEqualsMon \"_pot_zfs_destroy arg1\" \"test-pot\" POTDESTROY_CALL2_ARG1\n\tassertEqualsMon \"_pot_zfs_destroy arg2\" \"\" POTDESTROY_CALL2_ARG2\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_021()\n{\n\tpot-destroy -p test-pot-run-2 -F\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"1\" POTDESTROY_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy arg1\" \"test-pot-run-2\" POTDESTROY_CALL1_ARG1\n\tassertEqualsMon \"_pot_zfs_destroy arg2\" \"YES\" POTDESTROY_CALL1_ARG2\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_022()\n{\n\tpot-destroy -p test-pot-2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"1\" POTDESTROY_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy arg1\" \"test-pot-2\" POTDESTROY_CALL1_ARG1\n\tassertEqualsMon \"_pot_zfs_destroy arg2\" \"\" POTDESTROY_CALL1_ARG2\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_060()\n{\n\tpot-destroy -f test-no-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"0\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy arg1\" \"\" FSCOMPDESTROY_CALL1_ARG1\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\n\ntest_pot_destroy_061()\n{\n\tpot-destroy -f test-fscomp\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_destroy calls\" \"0\" POTDESTROY_CALLS\n\tassertEqualsMon \"_base_zfs_destroy calls\" \"0\" BASEDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy calls\" \"1\" FSCOMPDESTROY_CALLS\n\tassertEqualsMon \"_fscomp_zfs_destroy arg1\" \"test-fscomp\" FSCOMPDESTROY_CALL1_ARG1\n\tassertEqualsMon \"_zfs_dataset_destroy calls\" \"0\" ZFSDDESTROY_CALLS\n}\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/export-ports1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/export-ports.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nexport-ports-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_export_ports()\n{\n\t__monitor EXPORTS \"$@\"\n}\n\ntest_pot_export_ports_001()\n{\n\tpot-export-ports -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n\n\tsetUp\n\tpot-export-ports -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_020()\n{\n\tpot-export-ports -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_021()\n{\n\tpot-export-ports -p \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_022()\n{\n\tpot-export-ports -p no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_023()\n{\n\tpot-export-ports -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_024()\n{\n\tpot-export-ports -e\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_025()\n{\n\tpot-export-ports -e \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_026()\n{\n\tpot-export-ports -p test-pot -e http\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_027()\n{\n\tpot-export-ports -p test-pot -e \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_027()\n{\n\tpot-export-ports -p test-pot -e -1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_028()\n{\n\tpot-export-ports -p test-pot -e \"12 34\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_029()\n{\n\tpot-export-ports -p test-pot -e 65536\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_030()\n{\n\tpot-export-ports -p test-pot -e 80:\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_031()\n{\n\tpot-export-ports -p test-pot -e :80\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_032()\n{\n\tpot-export-ports -p test-pot -e 80:100000\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_ports_033()\n{\n\tpot-export-ports -p test-pot -e 100000:80\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n}\n\n#test_pot_export_ports_034()\n#{\n#\tpot-export-ports -p test-pot -e 80:80:\n#\tassertEquals \"Exit rc\" \"1\" \"$?\"\n#\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n#\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n#\tassertEqualsMon \"_export_ports calls\" \"0\" EXPORTS_CALLS\n#}\n\ntest_pot_export_ports_040()\n{\n\tpot-export-ports -p test-pot-2 -e 80\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export_ports arg1\" \"test-pot-2\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export_ports arg2\" \"80\" EXPORTS_CALL1_ARG2\n}\n\ntest_pot_export_ports_041()\n{\n\tpot-export-ports -p test-pot-2 -e 80 -e 443\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export_ports arg1\" \"test-pot-2\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export_ports arg2\" \"80 443\" EXPORTS_CALL1_ARG2\n}\n\ntest_pot_export_ports_042()\n{\n\tpot-export-ports -p test-pot-2 -e 80:8080\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export_ports arg1\" \"test-pot-2\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export_ports arg2\" \"80:8080\" EXPORTS_CALL1_ARG2\n}\n\ntest_pot_export_ports_043()\n{\n\tpot-export-ports -p test-pot-2 -e 80:8080 -e 443:30443\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export_ports arg1\" \"test-pot-2\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export_ports arg2\" \"80:8080 443:30443\" EXPORTS_CALL1_ARG2\n}\n\ntest_pot_export_ports_044()\n{\n\tpot-export-ports -p test-pot-multi-private -e 80:8080 -e 443:30443\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export_ports calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export_ports arg1\" \"test-pot-multi-private\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export_ports arg2\" \"80:8080 443:30443\" EXPORTS_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/export1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/export.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# only has to exist, isn't called in tests\nsignify()\n{\n\ttrue\n}\n\n_is_zfs_pot_snap()\n{\n\t__monitor ISZFSSNAP \"$@\"\n\tif [ \"$1\" = \"test-pot-single\" ] && [ \"$2\" = \"666\" ]; then\n\t\treturn 0\n\telse\n\t\treturn 1\n\tfi\n}\n\n_zfs_last_snap()\n{\n\t__monitor ZFSLASTSNAP \"$@\"\n\tif [ \"$1\" = \"/jails/test-pot-single\" ]; then\n\t\techo 1234321\n\telif [ \"$1\" = \"/jails/test-pot-single-2\" ]; then\n\t\techo 4321234\n\telif [ \"$1\" = \"/jails/test-pot-single-0\" ]; then\n\t\tif [ -e /tmp/pot_test_last_snap ]; then\n\t\t\techo 123123123\n\t\t\trm -f /tmp/pot_test_last_snap\n\t\telse\n\t\t\ttouch /tmp/pot_test_last_snap\n\t\tfi\n\tfi\n}\n\n_zfs_count_snap()\n{\n\tif [ \"$1\" = \"/jails/test-pot-single-2\" ]; then\n\t\techo 2\n\telse\n\t\techo 1\n\tfi\n}\n\npot-cmd()\n{\n\t__monitor POTCMD \"$@\"\n}\n\n# app specific stubs\nexport-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_export_pot()\n{\n\t__monitor EXPORTS \"$@\"\n\treturn 0 # true\n}\n\ntest_pot_export_001()\n{\n\tpot-export -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n\n\tsetUp\n\tpot-export -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_020()\n{\n\tpot-export -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_021()\n{\n\tpot-export -p \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_022()\n{\n\tpot-export -p no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_023()\n{\n\tpot-export -s\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_024()\n{\n\tpot-export -s \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_025()\n{\n\t# correct snapshot, but no pot\n\tpot-export -s 666\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_026()\n{\n\t# pot is not single\n\tpot-export -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_027()\n{\n\t# snapshot already existing\n\tpot-export -p test-pot-single -s 666\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_028()\n{\n\t# directory doesn't exist\n\tpot-export -p test-pot-single -D asdfasdf\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_029()\n{\n\t# wrong compression level\n\tpot-export -p test-pot-single -l max\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_030()\n{\n\t# wrong compression level\n\tpot-export -p test-pot-single -l 10\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_031()\n{\n\t# wrong number of snapshost\n\tpot-export -p test-pot-single-2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_032()\n{\n\t# no snapshosts available\n\tpot-export -p test-pot-single-0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_040()\n{\n\tpot-export -p test-pot-single\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_zfs_pot_snap calls\" \"0\" ISZFSSNAP_CALLS\n\tassertEqualsMon \"_export calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export arg1\" \"test-pot-single\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export arg2\" \"1234321\" EXPORTS_CALL1_ARG2\n\tassertEqualsMon \"_export arg3\" \"1234321\" EXPORTS_CALL1_ARG3\n\tassertEqualsMon \"_export arg4\" \"\" EXPORTS_CALL1_ARG4\n\tassertEqualsMon \"_export arg5\" \".\" EXPORTS_CALL1_ARG5\n}\n\ntest_pot_export_041()\n{\n\tpot-export -p test-pot-single -t v1.0\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_zfs_pot_snap calls\" \"0\" ISZFSSNAP_CALLS\n\tassertEqualsMon \"_export calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export arg1\" \"test-pot-single\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export arg2\" \"1234321\" EXPORTS_CALL1_ARG2\n\tassertEqualsMon \"_export arg3\" \"v1.0\" EXPORTS_CALL1_ARG3\n\tassertEqualsMon \"_export arg4\" \"\" EXPORTS_CALL1_ARG4\n\tassertEqualsMon \"_export arg5\" \".\" EXPORTS_CALL1_ARG5\n}\n\ntest_pot_export_042()\n{\n\tpot-export -p test-pot-single -s 1234\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_043()\n{\n\tpot-export -p test-pot-single -s 1234 -t 1.0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_044()\n{\n\tpot-export -p test-pot-single -s 1234 -t 1.0 -D /tmp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_export calls\" \"0\" EXPORTS_CALLS\n}\n\ntest_pot_export_050()\n{\n\tpot-export -p test-pot-single-2 -t 1.0 -F\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_zfs_pot_snap calls\" \"0\" ISZFSSNAP_CALLS\n\tassertEqualsMon \"_export calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export arg1\" \"test-pot-single-2\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export arg2\" \"4321234\" EXPORTS_CALL1_ARG2\n\tassertEqualsMon \"_export arg3\" \"1.0\" EXPORTS_CALL1_ARG3\n\tassertEqualsMon \"_export arg4\" \"\" EXPORTS_CALL1_ARG4\n\tassertEqualsMon \"_export arg5\" \".\" EXPORTS_CALL1_ARG5\n}\n\ntest_pot_export_051()\n{\n\tpot-export -p test-pot-single-2 -t 1.0 -A\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_zfs_pot_snap calls\" \"0\" ISZFSSNAP_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"1\" POTCMD_CALLS\n\tassertEqualsMon \"pot-cmd arg1\" \"purge-snapshots\" POTCMD_CALL1_ARG1\n\tassertEqualsMon \"_export calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export arg1\" \"test-pot-single-2\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export arg2\" \"4321234\" EXPORTS_CALL1_ARG2\n\tassertEqualsMon \"_export arg3\" \"1.0\" EXPORTS_CALL1_ARG3\n\tassertEqualsMon \"_export arg4\" \"\" EXPORTS_CALL1_ARG4\n\tassertEqualsMon \"_export arg5\" \".\" EXPORTS_CALL1_ARG5\n}\n\ntest_pot_export_052()\n{\n\tpot-export -p test-pot-single-0 -t 1.0 -A\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_zfs_pot_snap calls\" \"0\" ISZFSSNAP_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"1\" POTCMD_CALLS\n\tassertEqualsMon \"pot-cmd arg1\" \"snapshot\" POTCMD_CALL1_ARG1\n\tassertEqualsMon \"_export calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export arg1\" \"test-pot-single-0\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export arg2\" \"123123123\" EXPORTS_CALL1_ARG2\n\tassertEqualsMon \"_export arg3\" \"1.0\" EXPORTS_CALL1_ARG3\n\tassertEqualsMon \"_export arg4\" \"\" EXPORTS_CALL1_ARG4\n\tassertEqualsMon \"_export arg5\" \".\" EXPORTS_CALL1_ARG5\n}\n\ntest_pot_export_053()\n{\n\tpot-export -p test-pot-single-0 -t 1.0 -A -S export1.sh\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_zfs_pot_snap calls\" \"0\" ISZFSSNAP_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"1\" POTCMD_CALLS\n\tassertEqualsMon \"pot-cmd arg1\" \"snapshot\" POTCMD_CALL1_ARG1\n\tassertEqualsMon \"_export calls\" \"1\" EXPORTS_CALLS\n\tassertEqualsMon \"_export arg1\" \"test-pot-single-0\" EXPORTS_CALL1_ARG1\n\tassertEqualsMon \"_export arg2\" \"123123123\" EXPORTS_CALL1_ARG2\n\tassertEqualsMon \"_export arg3\" \"1.0\" EXPORTS_CALL1_ARG3\n\tassertEqualsMon \"_export arg4\" \"\" EXPORTS_CALL1_ARG4\n\tassertEqualsMon \"_export arg5\" \".\" EXPORTS_CALL1_ARG5\n}\n\ntest_pot_export_054()\n{\n\tpot-export -p test-pot-single-0 -t 1.0 -A -S nonexistent\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\trm -f /tmp/pot_test_last_snap\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/get-rss1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/get-rss.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nget-rss-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_is_rctl_available()\n{\n\treturn 0 # true\n}\n\nprint_rss()\n{\n\t__monitor PRINT \"$@\"\n}\n\ntest_pot_get_rss_001()\n{\n\tpot-get-rss\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"print_rss calls\" \"0\" PRINT_CALLS\n\n\tsetUp\n\tpot-get-rss -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"print_rss calls\" \"0\" PRINT_CALLS\n\n\tsetUp\n\tpot-get-rss -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"print_rss calls\" \"0\" PRINT_CALLS\n}\n\ntest_pot_get_rss_002()\n{\n\tpot-get-rss -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"print_rss calls\" \"0\" PRINT_CALLS\n}\n\ntest_pot_get_rss_020()\n{\n\tpot-get-rss -p test-pot-run\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"print_rss calls\" \"1\" PRINT_CALLS\n\tassertEqualsMon \"print_rss arg1\" \"test-pot-run\" PRINT_CALL1_ARG1\n\tassertEqualsMon \"print_rss arg2\" \"\" PRINT_CALL1_ARG2\n}\n\ntest_pot_get_rss_021()\n{\n\tpot-get-rss -p test-pot-run-2 -J\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"print_rss calls\" \"1\" PRINT_CALLS\n\tassertEqualsMon \"print_rss arg1\" \"test-pot-run-2\" PRINT_CALL1_ARG1\n\tassertEqualsMon \"print_rss arg2\" \"YES\" PRINT_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/import1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/import.sh\n\n. ../share/pot/common.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nimport-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_fetch_pot()\n{\n\t__monitor FETCHPOT \"$@\"\n}\n\n_import_pot()\n{\n\t__monitor IMPORTS \"$@\"\n}\n\n# only has to exist, isn't called in tests\nsignify()\n{\n\ttrue\n}\n\ntest_pot_import_001()\n{\n\tpot-import -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n\n\tsetUp\n\tpot-import -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_020()\n{\n\tpot-import -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_021()\n{\n\tpot-import -p \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_022()\n{\n\tpot-import -p no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_023()\n{\n\tpot-import -t\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_024()\n{\n\tpot-import -t \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_025()\n{\n\t# correct snapshot, but no pot\n\tpot-import -t 666\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_026()\n{\n\tpot-import -p test-pot-single -t 1.0 -U\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_027()\n{\n\tpot-import -p test-pot-single -t 1.0 -U \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"0\" FETCHPOT_CALLS\n\tassertEqualsMon \"_import calls\" \"0\" IMPORTS_CALLS\n}\n\ntest_pot_import_040()\n{\n\tpot-import -p test-pot-single -t 1.0\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"1\" FETCHPOT_CALLS\n\tassertEqualsMon \"_fetch_pot arg1\" \"test-pot-single\" FETCHPOT_CALL1_ARG1\n\tassertEqualsMon \"_fetch_pot arg2\" \"1.0\" FETCHPOT_CALL1_ARG2\n\tassertEqualsMon \"_fetch_pot arg3\" \"\" FETCHPOT_CALL1_ARG3\n\tassertEqualsMon \"_import calls\" \"1\" IMPORTS_CALLS\n\tassertEqualsMon \"_import arg1\" \"test-pot-single\" IMPORTS_CALL1_ARG1\n\tassertEqualsMon \"_import arg2\" \"1.0\" IMPORTS_CALL1_ARG2\n\tassertEqualsMon \"_import arg3\" \"test-pot-single_1_0\" IMPORTS_CALL1_ARG3\n}\n\ntest_pot_import_041()\n{\n\tpot-import -p test-pot-single -t v1.0\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"1\" FETCHPOT_CALLS\n\tassertEqualsMon \"_fetch_pot arg1\" \"test-pot-single\" FETCHPOT_CALL1_ARG1\n\tassertEqualsMon \"_fetch_pot arg2\" \"v1.0\" FETCHPOT_CALL1_ARG2\n\tassertEqualsMon \"_fetch_pot arg3\" \"\" FETCHPOT_CALL1_ARG3\n\tassertEqualsMon \"_import calls\" \"1\" IMPORTS_CALLS\n\tassertEqualsMon \"_import arg1\" \"test-pot-single\" IMPORTS_CALL1_ARG1\n\tassertEqualsMon \"_import arg2\" \"v1.0\" IMPORTS_CALL1_ARG2\n\tassertEqualsMon \"_import arg3\" \"test-pot-single_v1_0\" IMPORTS_CALL1_ARG3\n}\n\ntest_pot_import_042()\n{\n\tpot-import -p test-pot-single -t 1.0 -U https://example.org\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"1\" FETCHPOT_CALLS\n\tassertEqualsMon \"_fetch_pot arg1\" \"test-pot-single\" FETCHPOT_CALL1_ARG1\n\tassertEqualsMon \"_fetch_pot arg2\" \"1.0\" FETCHPOT_CALL1_ARG2\n\tassertEqualsMon \"_fetch_pot arg3\" \"\" FETCHPOT_CALL1_ARG3\n\tassertEqualsMon \"_fetch_pot arg4\" \"https://example.org\" FETCHPOT_CALL1_ARG4\n\tassertEqualsMon \"_import calls\" \"1\" IMPORTS_CALLS\n\tassertEqualsMon \"_import arg1\" \"test-pot-single\" IMPORTS_CALL1_ARG1\n\tassertEqualsMon \"_import arg2\" \"1.0\" IMPORTS_CALL1_ARG2\n\tassertEqualsMon \"_import arg3\" \"test-pot-single_1_0\" IMPORTS_CALL1_ARG3\n}\n\ntest_pot_import_043()\n{\n\tpot-import -p test-pot-single -t 1.0 -U https://example.org -C import1.sh\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_fetch_pot calls\" \"1\" FETCHPOT_CALLS\n\tassertEqualsMon \"_fetch_pot arg1\" \"test-pot-single\" FETCHPOT_CALL1_ARG1\n\tassertEqualsMon \"_fetch_pot arg2\" \"1.0\" FETCHPOT_CALL1_ARG2\n\tassertEqualsMon \"_fetch_pot arg3\" \"import1.sh\" FETCHPOT_CALL1_ARG3\n\tassertEqualsMon \"_fetch_pot arg4\" \"https://example.org\" FETCHPOT_CALL1_ARG4\n\tassertEqualsMon \"_import calls\" \"1\" IMPORTS_CALLS\n\tassertEqualsMon \"_import arg1\" \"test-pot-single\" IMPORTS_CALL1_ARG1\n\tassertEqualsMon \"_import arg2\" \"1.0\" IMPORTS_CALL1_ARG2\n\tassertEqualsMon \"_import arg3\" \"test-pot-single_1_0\" IMPORTS_CALL1_ARG3\n}\n\ntest_pot_import_044()\n{\n\tpot-import -p test-pot-single -t 1.0 -U https://example.org -C nonexistent\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/info1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/info.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\ninfo-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_info_pot()\n{\n\t__monitor INFOPOT \"$@\"\n}\n\n_info_pot_env()\n{\n\t__monitor INFOPOTENV \"$@\"\n}\n\n_info_pot_snapshots()\n{\n\t__monitor INFOPOTSNAP \"$@\"\n}\n\ntest_pot_info_001()\n{\n\tpot-info\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\n\tsetUp\n\tpot-info -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\n\tsetUp\n\tpot-info -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\n\tsetUp\n\tpot-info -v\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n}\n\ntest_pot_info_002()\n{\n\tpot-info -p test-pot -v -q\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n\n\tsetUp\n\tpot-info -p test-pot -v -q -r\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_003()\n{\n\tpot-info -p test-pot -B test-bridge\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_020()\n{\n\tpot-info -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n\n\tsetUp\n\tpot-info -p not-a-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_021()\n{\n\tpot-info -p test-pot -q\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_022()\n{\n\tpot-info -p test-pot -qr\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_023()\n{\n\tpot-info -p test-pot-run -qr\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_040()\n{\n\tpot-info -p test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"1\" INFOPOT_CALLS\n\tassertEqualsMon \"Info arg\" \"test-pot\" INFOPOT_CALL1_ARG1\n}\n\ntest_pot_info_041()\n{\n\tpot-info -p test-pot -v\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"1\" INFOPOT_CALLS\n\tassertEqualsMon \"Info arg\" \"test-pot\" INFOPOT_CALL1_ARG1\n}\n\ntest_pot_info_042()\n{\n\tpot-info -p test-pot -r\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n}\n\ntest_pot_info_043()\n{\n\tpot-info -p test-pot -s\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFOPOT_CALLS\n\tassertEqualsMon \"InfoSnap calls\" \"1\" INFOPOTSNAP_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/info2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/info.sh\n\n. ../share/pot/common.sh\n# common stubs\n\n_get_pot_network_stack()\n{\n\n\techo \"${_TEST_STACK:-\"dual\"}\"\n}\n\n_get_pot_network_type()\n{\n\tcase \"$1\" in\n\t\ttest-pot-alias*)\n\t\t\techo \"alias\"\n\t\t\t;;\n\t\t*)\n\t\t\techo \"inherit\"\n\t\t\t;;\n\tesac\n}\n\n_get_ip_var()\n{\n\tcase \"$1\" in\n\t\ttest-pot-alias)\n\t\t\techo \"em0|192.168.0.1 em0|fe80::0\"\n\t\t\t;;\n\t\t*)\n\t\t\techo \"\"\n\t\t\t;;\n\tesac\n}\n\n_get_alias_ipv4()\n{\n\tif [ \"$_TEST_STACK\" = \"ipv6\" ]; then\n\t\treturn\n\tfi\n\tcase \"$1\" in\n\t\ttest-pot-alias)\n\t\t\techo \"em0|192.168.0.1\"\n\t\t\t;;\n\t\t*)\n\t\t\techo \"\"\n\t\t\t;;\n\tesac\n}\n\n_get_alias_ipv6()\n{\n\tif [ \"$_TEST_STACK\" = \"ipv4\" ]; then\n\t\treturn\n\tfi\n\tcase \"$1\" in\n\t\ttest-pot-alias)\n\t\t\techo \"em0|fe80::0\"\n\t\t\t;;\n\t\t*)\n\t\t\techo \"\"\n\t\t\t;;\n\tesac\n}\n\n# app specific stubs\n\ntest_info_pot_env_001()\n{\n\tassertEquals \"inherit has IP\" \"export _POT_IP=\" \"$(_info_pot_env test-pot-inherit | grep _POT_IP= )\"\n}\n\ntest_info_pot_env_020()\n{\n\tassertEquals \"alias has wrong IP\"        \"export _POT_IP=192.168.0.1\" \"$( _info_pot_env test-pot-alias | grep _POT_IP= )\"\n\tassertEquals \"alias has wrong IP LIST\"   \"$( _info_pot_env test-pot-alias | grep _POT_IP_LIST= )\" \"export _POT_IP_LIST=_POT_IP_0\\ _POT_IP_1\"\n\tassertEquals \"alias has wrong NIC LIST\"  \"$( _info_pot_env test-pot-alias | grep _POT_NIC_LIST= )\" \"export _POT_NIC_LIST=_POT_NIC_0\\ _POT_NIC_1\"\n\tassertEquals \"alias has wrong IP 0\"      \"$( _info_pot_env test-pot-alias | grep _POT_IP_0= )\" \"export _POT_IP_0=192.168.0.1\"\n\tassertEquals \"alias has wrong IP 1\"      \"$( _info_pot_env test-pot-alias | grep _POT_IP_1= )\" \"export _POT_IP_1=fe80::0\"\n\tassertEquals \"alias has wrong NIC 0\"     \"$( _info_pot_env test-pot-alias | grep _POT_NIC_0= )\" \"export _POT_NIC_0=em0\"\n\tassertEquals \"alias has wrong NIC 1\"     \"$( _info_pot_env test-pot-alias | grep _POT_NIC_1= )\" \"export _POT_NIC_1=em0\"\n}\n\ntest_info_pot_env_021()\n{\n\t_TEST_STACK=\"ipv4\"\n\tassertEquals \"alias has wrong IP\"        \"$( _info_pot_env test-pot-alias | grep _POT_IP= )\" \"export _POT_IP=192.168.0.1\"\n\tassertEquals \"alias has wrong IP LIST\"   \"$( _info_pot_env test-pot-alias | grep _POT_IP_LIST= )\" \"export _POT_IP_LIST=_POT_IP_0\"\n\tassertEquals \"alias has wrong NIC LIST\"  \"$( _info_pot_env test-pot-alias | grep _POT_NIC_LIST= )\" \"export _POT_NIC_LIST=_POT_NIC_0\"\n\tassertEquals \"alias has wrong IP 0\"      \"$( _info_pot_env test-pot-alias | grep _POT_IP_0= )\" \"export _POT_IP_0=192.168.0.1\"\n\tassertEquals \"alias has wrong NIC 0\"     \"$( _info_pot_env test-pot-alias | grep _POT_NIC_0= )\" \"export _POT_NIC_0=em0\"\n}\n\ntest_info_pot_env_022()\n{\n\t_TEST_STACK=\"ipv6\"\n\tassertEquals \"alias has wrong IP\"        \"$( _info_pot_env test-pot-alias | grep _POT_IP= )\" \"export _POT_IP=fe80::0\"\n\tassertEquals \"alias has wrong IP LIST\"   \"$( _info_pot_env test-pot-alias | grep _POT_IP_LIST= )\" \"export _POT_IP_LIST=_POT_IP_0\"\n\tassertEquals \"alias has wrong NIC LIST\"  \"$( _info_pot_env test-pot-alias | grep _POT_NIC_LIST= )\" \"export _POT_NIC_LIST=_POT_NIC_0\"\n\tassertEquals \"alias has wrong IP 0\"      \"$( _info_pot_env test-pot-alias | grep _POT_IP_0= )\" \"export _POT_IP_0=fe80::0\"\n\tassertEquals \"alias has wrong NIC 0\"     \"$( _info_pot_env test-pot-alias | grep _POT_NIC_0= )\" \"export _POT_NIC_0=em0\"\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/list1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/list.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nlist-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_ls_pots()\n{\n\t__monitor LSPOTS \"$@\"\n}\n\n_ls_bases()\n{\n\t__monitor LSBASES \"$@\"\n}\n\n_ls_fscomp()\n{\n\t__monitor LSFSCOMP \"$@\"\n}\n\n_ls_flavour()\n{\n\t__monitor LSFLAVOUR \"$@\"\n}\n\ntest_pot_list_001()\n{\n\tpot-list -k bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_002()\n{\n\tpot-list -pb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -bp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -ba\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -fpF\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_003()\n{\n\tpot-list -aq\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_020()\n{\n\tpot-list\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"1\" LSPOTS_CALLS\n\tassertEqualsMon \"list_pots args\" \"\" LSPOTS_CALL1_ARG1\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -q\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"1\" LSPOTS_CALLS\n\tassertEqualsMon \"list_pots args\" \"quiet\" LSPOTS_CALL1_ARG1\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_021()\n{\n\tpot-list -p\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"1\" LSPOTS_CALLS\n\tassertEqualsMon \"list_pots args\" \"\" LSPOTS_CALL1_ARG1\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -pq\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"1\" LSPOTS_CALLS\n\tassertEqualsMon \"list_pots args\" \"quiet\" LSPOTS_CALL1_ARG1\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_022()\n{\n\tpot-list -b\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"1\" LSBASES_CALLS\n\tassertEqualsMon \"list_bases args\" \"\" LSBASES_CALL1_ARG1\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -bq\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"1\" LSBASES_CALLS\n\tassertEqualsMon \"list_bases args\" \"quiet\" LSBASES_CALL1_ARG1\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_023()\n{\n\tpot-list -f\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"1\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_fscomp args\" \"\" LSFSCOMP_CALL1_ARG1\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n\n\tsetUp\n\tpot-list -fq\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"1\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_fscomp args\" \"quiet\" LSFSCOMP_CALL1_ARG1\n\tassertEqualsMon \"list_flavour calls\" \"0\" LSFLAVOUR_CALLS\n}\n\ntest_pot_list_024()\n{\n\tpot-list -F\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"1\" LSFLAVOUR_CALLS\n\tassertEqualsMon \"list_flavour args\" \"\" LSFLAVOUR_CALL1_ARG1\n\n\tsetUp\n\tpot-list -Fq\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"0\" LSPOTS_CALLS\n\tassertEqualsMon \"list_bases calls\" \"0\" LSBASES_CALLS\n\tassertEqualsMon \"list_fscomp calls\" \"0\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_flavour calls\" \"1\" LSFLAVOUR_CALLS\n\tassertEqualsMon \"list_flavour args\" \"quiet\" LSFLAVOUR_CALL1_ARG1\n}\n\ntest_pot_list_025()\n{\n\tpot-list -a\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"list_pots calls\" \"1\" LSPOTS_CALLS\n\tassertEqualsMon \"list_port args\" \"\" LSPOTS_CALL1_ARG1\n\tassertEqualsMon \"list_bases calls\" \"1\" LSBASES_CALLS\n\tassertEqualsMon \"list_bases args\" \"\" LSBASES_CALL1_ARG1\n\tassertEqualsMon \"list_fscomp calls\" \"1\" LSFSCOMP_CALLS\n\tassertEqualsMon \"list_fscomp args\" \"\" LSFSCOMP_CALL1_ARG1\n\tassertEqualsMon \"list_flavour calls\" \"1\" LSFLAVOUR_CALLS\n\tassertEqualsMon \"list_flavour args\" \"\" LSFLAVOUR_CALL1_ARG1\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/list2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/list.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nzfs()\n{\n\tif [ \"$1\" = \"list\" ]; then\n\t\tif [ \"$6\" = \"zroot/pot1/fscomp\" ]; then\n\t\t\techo \"zroot/pot1/fscomp\"\n\t\t\techo \"zroot/pot1/fscomp/fscomp1\"\n\t\telif [ \"$6\" = \"zroot/pot2/fscomp\" ]; then\n\t\t\techo \"zroot/pot1/fscomp\"\n\t\t\techo \"zroot/pot2/fscomp/fscomp1\"\n\t\t\techo \"zroot/pot2/fscomp/fscomp2\"\n\t\telif [ \"$6\" = \"zroot/pot3/fscomp\" ]; then\n\t\t\techo \"zroot/pot1/fscomp\"\n\t\t\techo \"zroot/pot3/fscomp/fscomp1\"\n\t\t\techo \"zroot/pot3/fscomp/fscomp2\"\n\t\t\techo \"zroot/pot3/fscomp/fscomp3\"\n\t\telse\n\t\t\techo \"error2\"\n\t\tfi\n\telse\n\t\techo \"error\"\n\tfi\n}\n\ntest_pot_list_fscomp001()\n{\n\tPOT_ZFS_ROOT=zroot/pot1\n\trc=$( _ls_fscomp )\n\tassertEquals \"rc\" \"fscomp: fscomp1\" \"$rc\"\n}\n\ntest_pot_list_fscomp002()\n{\n\tPOT_ZFS_ROOT=zroot/pot2\n\trc=$( _ls_fscomp | tr '\\n' ' ')\n\tassertEquals \"rc\" \"fscomp: fscomp1 fscomp: fscomp2 \" \"$rc\"\n}\n\ntest_pot_list_fscomp003()\n{\n\tPOT_ZFS_ROOT=zroot/pot3\n\trc=$( _ls_fscomp | tr '\\n' ' ')\n\tassertEquals \"rc\" \"fscomp: fscomp1 fscomp: fscomp2 fscomp: fscomp3 \" \"$rc\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/monitor.sh",
    "content": "#!/bin/sh\n# shellcheck disable=SC3043\n\nif [ -z \"$POT_MONITOR_TMP\" ]; then\n\tif [ \"$(command uname)\" = \"Linux\" ]; then\n\t\tPOT_MONITOR_TMP=/dev/shm\n\telse\n\t\tPOT_MONITOR_TMP=\"${TMPDIR:-/tmp}\"\n\tfi\n\tPOT_MONITOR_TMP=$(command mktemp -d \\\n\t  \"${POT_MONITOR_TMP}/pot-monitor.XXXXXX\") || exit 1\n\texport POT_MONITOR_TMP\nfi\n\n__mon_put()\n{\n\tlocal k v\n\tk=\"$1\"\n\tshift\n\tv=\"$*\"\n\tprintf %s \"$v\" >\"$POT_MONITOR_TMP/$k\"\n}\n\n__mon_get()\n{\n\tlocal k d r\n\tk=\"$1\"\n\td=\"$2\"\n\n\tif [ -e \"$POT_MONITOR_TMP/$k\" ]; then\n\t\tr=$(command cat \"$POT_MONITOR_TMP/$k\")\n\tfi\n\n\tif [ -n \"$r\" ]; then\n\t\techo \"$r\"\n\telif [ -n \"$d\" ]; then\n\t\techo \"$d\"\n\tfi\n}\n\n__mon_export()\n{\n\tlocal k v\n\n\tfor k in \"$POT_MONITOR_TMP\"/*; do\n\t\tv=$(command cat \"$k\")\n\t\texport \"$k\"=\"$v\"\n\tdone\n}\n\n__mon_init()\n{\n\tcommand mkdir -p \"$POT_MONITOR_TMP\" || exit 1\n\tcommand rm -f \"$POT_MONITOR_TMP\"/* || exit 1\n}\n\n__monitor_int()\n{\n\tlocal M i C\n\ti=0\n\tM=$1\n\tshift\n\tC=\"$(__mon_get \"${M}_CALLS\" 0)\"\n\tC=$(( C + 1 ))\n\t__mon_put \"${M}_CALLS\" \"$C\"\n\twhile [ -n \"$1\" ] || [ -n \"$2\" ] || [ -n \"$3\" ]; do\n\t\ti=$(( i + 1 ))\n\t\t__mon_put \"${M}_CALL${C}_ARG${i}\" \"$1\"\n\t\tshift\n\tdone\n}\n\n__monitor()\n{\n\t# requires \"pkg install flock\" on FreebSD\n\t(\n\t\tcommand flock -x -w 10 9\n\t\t__monitor_int \"$@\"\n\t) 9>\"$POT_MONITOR_TMP.lock\"\n}\n\n__mon_tearDown()\n{\n\tif [ -e \"$POT_MONITOR_TMP\" ]; then\n\t\tcommand rm -rf \"$POT_MONITOR_TMP\"\n\tfi\n\tif [ -e \"$POT_MONITOR_TMP.lock\" ]; then\n\t\tcommand rm \"$POT_MONITOR_TMP.lock\"\n\tfi\n}\n\n# $1 name\n# $2 left hand\n# $3 key of right hand mon var\n# $4 default value to compare to\n#    \"\" defaults to 0 in case key ends on \"_CALLS\"\nassertEqualsMon()\n{\n\tlocal n l k d\n\tn=\"$1\"\n\tl=\"$2\"\n\tk=\"$3\"\n\td=\"$4\"\n\tif [ -z \"$d\" ] && [ \"$k\" != \"${k%%_CALLS}\" ]; then\n\t\td=\"0\"\n\tfi\n\tassertEquals \"$n\" \"$l\" \"$(__mon_get \"$k\" \"$d\")\"\n}\n\n# $1 name\n# $2 left hand\n# $3 key of right hand mon var\n# $4 default value to compare to\n#    \"\" defaults to 0 in case key ends on \"_CALLS\"\nassertNotEqualsMon()\n{\n\tlocal n l k d\n\tn=\"$1\"\n\tl=\"$2\"\n\tk=\"$3\"\n\td=\"$4\"\n\tif [ -z \"$d\" ] && [ \"$k\" != \"${k%%_CALLS}\" ]; then\n\t\td=\"0\"\n\tfi\n\tassertNotEquals \"$n\" \"$l\" \"$(__mon_get \"$k\" \"$d\")\"\n}\n"
  },
  {
    "path": "tests/mount-in1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nif [ \"$(uname)\" = \"Linux\" ]; then\n\tTEST=/usr/bin/[\nelse\n\tTEST=/bin/[\nfi\n\n[()\n{\n\tif ${TEST} \"$1\" = \"!\" ]; then\n\t\tif ${TEST} \"$2\" = \"-d\" ]; then\n\t\t\tif ${TEST} \"$3\" = \"test-dir\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\tfi\n\tfi\n\t${TEST} \"$@\"\n\treturn $?\n}\n\nrealpath()\n{\n\t__monitor REALPATH \"$@\"\n\tif [ \"$2\" = \"test-dir\" ]; then\n\t\techo \"/home/test-dir\"\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\nlogger()\n{\n\t:\n}\n\n\n# UUT\n. ../share/pot/mount-in.sh\n\n# common stubs\n. common-stub.sh\n\n_zfs_dataset_valid()\n{\n\t__monitor ZDVALID \"$@\"\n\tif [ \"$1\" = \"zroot/test-dataset\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n# app specific stubs\nmount-in-help()\n{\n\t__monitor HELP \"$@\"\n\treturn 0 # true\n}\n\n\n_directory_validation()\n{\n\t__monitor DIRVALID \"$@\"\n}\n\n_mountpoint_validation()\n{\n\t__monitor MPVALID \"$@\"\n\techo \"$2\"\n}\n\n_mount_dir()\n{\n\t__monitor MOUNTDIR \"$@\"\n}\n\n_mount_dataset()\n{\n\t__monitor MOUNTDSET \"$@\"\n}\n\ntest_pot_mount_in_001()\n{\n\tpot-mount-in\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -b bb\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_002()\n{\n\tpot-mount-in -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -f test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -d /test-dir\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -z zroot/test-dataset\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_003()\n{\n\tpot-mount-in -p test-pot -f test-fscomp\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt -f test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_004()\n{\n\tpot-mount-in -p test-pot -d /test-dir\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt -d /test-dir\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_005()\n{\n\tpot-mount-in -p test-pot -z zroot/test-dataset\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt -z zroot/test-dataset\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -m /test-mnt -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_006()\n{\n\tpot-mount-in -p test-pot -m /test-mnt -z zroot/test-dataset -d /test-dir\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -m /test-mnt -z zroot/test-dataset -f test-fscomp\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -m /test-mnt -f test-fscomp -d /test-dir\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"0\" ZDVALID_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_007()\n{\n\tpot-mount-in -p test-no-pot -m /test-no-mnt -f zroot/test-no-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-no-pot -m /test-no-mnt -z test-no-dataset\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-no-pot -m /test-no-mnt -d test-no-dir\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_008()\n{\n\tpot-mount-in -p test-no-pot -m /test-no-mnt -f test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-no-pot -m /test-no-mnt -z zroot/test-dataset\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-no-pot -m /test-no-mnt -d test-dir\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_009()\n{\n\tpot-mount-in -p test-pot -f test-fscomp -m test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -d test-dir -m test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -z zroot/test-dataset -m test-no-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_010()\n{\n\tpot-mount-in -p test-pot -f test-fscomp -m /\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -d test-dir -m /\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -z zroot/test-dataset -m /\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_011()\n{\n\tpot-mount-in -p test-pot -f test-fscomp -m \"/mnt/with space\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -d test-dir -m \"/mnt/with space\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tsetUp\n\tpot-mount-in -p test-pot -z zroot/test-dataset -m \"/mnt/with space\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\n\tpot-mount-in -p test-pot -f test-fscomp -m \"/mnt/space  \"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n}\n\ntest_pot_mount_in_020()\n{\n\tpot-mount-in -p test-pot -f test-fscomp -m /test-mnt\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"1\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dataset arg\" \"zpot/fscomp/test-fscomp\" MOUNTDSET_CALL1_ARG1\n\tassertEqualsMon \"_mount_dataset arg\" \"test-pot\" MOUNTDSET_CALL1_ARG2\n\tassertEqualsMon \"_mount_dataset arg\" \"/test-mnt\" MOUNTDSET_CALL1_ARG3\n\tassertEqualsMon \"_mount_dataset arg\" \"\" MOUNTDSET_CALL1_ARG4\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\n\ntest_pot_mount_in_021()\n{\n\tpot-mount-in -p test-pot -f test-fscomp -m /test-mnt -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"1\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dataset arg\" \"zpot/fscomp/test-fscomp\" MOUNTDSET_CALL1_ARG1\n\tassertEqualsMon \"_mount_dataset arg\" \"test-pot\" MOUNTDSET_CALL1_ARG2\n\tassertEqualsMon \"_mount_dataset arg\" \"/test-mnt\" MOUNTDSET_CALL1_ARG3\n\tassertEqualsMon \"_mount_dataset arg\" \"ro\" MOUNTDSET_CALL1_ARG4\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\n\ntest_pot_mount_in_022()\n{\n\tpot-mount-in -p test-pot -f test-fscomp -m /test-mnt -w\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"1\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dataset arg\" \"zpot/fscomp/test-fscomp\" MOUNTDSET_CALL1_ARG1\n\tassertEqualsMon \"_mount_dataset arg\" \"test-pot\" MOUNTDSET_CALL1_ARG2\n\tassertEqualsMon \"_mount_dataset arg\" \"/test-mnt\" MOUNTDSET_CALL1_ARG3\n\tassertEqualsMon \"_mount_dataset arg\" \"zfs-remount\" MOUNTDSET_CALL1_ARG4\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\ntest_pot_mount_in_040()\n{\n\tpot-mount-in -p test-pot -z zroot/test-dataset -m /test-mnt\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"1\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dataset arg\" \"zroot/test-dataset\" MOUNTDSET_CALL1_ARG1\n\tassertEqualsMon \"_mount_dataset arg\" \"test-pot\" MOUNTDSET_CALL1_ARG2\n\tassertEqualsMon \"_mount_dataset arg\" \"/test-mnt\" MOUNTDSET_CALL1_ARG3\n\tassertEqualsMon \"_mount_dataset arg\" \"\" MOUNTDSET_CALL1_ARG4\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\n\ntest_pot_mount_in_041()\n{\n\tpot-mount-in -p test-pot -z zroot/test-dataset -m /test-mnt -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"1\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dataset arg\" \"zroot/test-dataset\" MOUNTDSET_CALL1_ARG1\n\tassertEqualsMon \"_mount_dataset arg\" \"test-pot\" MOUNTDSET_CALL1_ARG2\n\tassertEqualsMon \"_mount_dataset arg\" \"/test-mnt\" MOUNTDSET_CALL1_ARG3\n\tassertEqualsMon \"_mount_dataset arg\" \"ro\" MOUNTDSET_CALL1_ARG4\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\n\ntest_pot_mount_in_042()\n{\n\tpot-mount-in -p test-pot -z zroot/test-dataset -m /test-mnt -w\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"1\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dataset arg\" \"zroot/test-dataset\" MOUNTDSET_CALL1_ARG1\n\tassertEqualsMon \"_mount_dataset arg\" \"test-pot\" MOUNTDSET_CALL1_ARG2\n\tassertEqualsMon \"_mount_dataset arg\" \"/test-mnt\" MOUNTDSET_CALL1_ARG3\n\tassertEqualsMon \"_mount_dataset arg\" \"zfs-remount\" MOUNTDSET_CALL1_ARG4\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\n\ntest_pot_mount_in_060()\n{\n\tpot-mount-in -p test-pot -d test-dir -m /test-mnt\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"1\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dir arg\" \"/home/test-dir\" MOUNTDIR_CALL1_ARG1\n\tassertEqualsMon \"_mount_dir arg\" \"test-pot\" MOUNTDIR_CALL1_ARG2\n\tassertEqualsMon \"_mount_dir arg\" \"/test-mnt\" MOUNTDIR_CALL1_ARG3\n\tassertEqualsMon \"_mount_dir arg\" \"\" MOUNTDIR_CALL1_ARG4\n}\n\ntest_pot_mount_in_061()\n{\n\tpot-mount-in -p test-pot -d test-dir -m /test-mnt -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"1\" MOUNTDIR_CALLS\n\tassertEqualsMon \"_mount_dir arg\" \"/home/test-dir\" MOUNTDIR_CALL1_ARG1\n\tassertEqualsMon \"_mount_dir arg\" \"test-pot\" MOUNTDIR_CALL1_ARG2\n\tassertEqualsMon \"_mount_dir arg\" \"/test-mnt\" MOUNTDIR_CALL1_ARG3\n\tassertEqualsMon \"_mount_dir arg\" \"ro\" MOUNTDIR_CALL1_ARG4\n}\n\ntest_pot_mount_in_062()\n{\n\tpot-mount-in -p test-pot -d test-dir -m /test-mnt -w\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_mount_dataset calls\" \"0\" MOUNTDSET_CALLS\n\tassertEqualsMon \"_mount_dir calls\" \"0\" MOUNTDIR_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/mount-out1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nif [ \"$(uname)\" = \"Linux\" ]; then\n\tTEST=/usr/bin/[\nelse\n\tTEST=/bin/[\nfi\n\n[()\n{\n\tif ${TEST} \"$1\" = \"!\" ]; then\n\t\tif ${TEST} \"$2\" = \"-d\" ]; then\n\t\t\tif ${TEST} \"$3\" = \"test-dir\" ]; then\n\t\t\t\treturn 1 # false\n\t\t\tfi\n\t\tfi\n\tfi\n\t${TEST} \"$@\"\n\treturn $?\n}\n\nrealpath()\n{\n\t__monitor REALPATH \"$@\"\n\tif [ \"$2\" = \"test-dir\" ]; then\n\t\techo \"/home/test-dir\"\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\nlogger()\n{\n\t:\n}\n\n# UUT\n. ../share/pot/mount-out.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nmount-out-help()\n{\n\t__monitor HELP \"$@\"\n\treturn 0 # true\n}\n\n_mountpoint_validation()\n{\n\t__monitor MPVALID \"$@\"\n\techo \"$2\"\n}\n\n_umount_mnt_p()\n{\n\t__monitor UMNT_P \"$@\"\n}\n\ntest_pot_mount_in_001()\n{\n\tpot-mount-out\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"0\" UMNT_P_CALLS\n\n\tsetUp\n\tpot-mount-out -vb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"0\" UMNT_P_CALLS\n\n\tsetUp\n\tpot-mount-out -b bb\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"0\" UMNT_P_CALLS\n\n\tsetUp\n\tpot-mount-out -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"0\" UMNT_P_CALLS\n}\n\ntest_pot_mount_in_002()\n{\n\tpot-mount-out -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"0\" UMNT_P_CALLS\n\n\tsetUp\n\tpot-mount-out -m /test-mnt\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"0\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"0\" UMNT_P_CALLS\n}\n\ntest_pot_mount_in_020()\n{\n\tpot-mount-out -p test-pot -m /test-mnt\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_uid0 calls\" \"1\" ISUID0_CALLS\n\tassertEqualsMon \"_umount_mnt_p calls\" \"1\" UMNT_P_CALLS\n\tassertEqualsMon \"_umount_mnt_p arg\" \"test-pot\" UMNT_P_CALL1_ARG1\n\tassertEqualsMon \"_umount_mnt_p arg\" \"/test-mnt\" UMNT_P_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/network1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nifconfig() {\n\tif [ -z \"$1\" ]; then\n\t\tcat << EOF--\nem0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=200080<VLAN_HWCSUM,RXCSUM_IPV6>\n\tinet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.178.255\n\tether e4:b3:18:d8:4d:25\n\thwaddr c8:5b:76:3a:2f:96\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\n\tmedia: Ethernet autoselect\n\tstatus: no carrier\nem1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=200080<VLAN_HWCSUM,RXCSUM_IPV6>\n\tinet 10.192.168.2 netmask 0xffffff00 broadcast 10.192.168.255\n\tether e4:b3:18:d8:4d:45\n\thwaddr c8:5b:76:3a:2f:a6\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\n\tmedia: Ethernet autoselect\n\tstatus: no carrier\nbce0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=200080<VLAN_HWCSUM,RXCSUM_IPV6>\n\tinet 10.192.168.3 netmask 0xffffff00 broadcast 10.192.168.255\n\tether e4:b3:18:d8:4d:35\n\thwaddr c8:5b:76:3a:2f:b6\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\n\tmedia: Ethernet autoselect\n\tstatus: no carrier\nlo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384\n\toptions=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>\n\tinet6 ::1 prefixlen 128\n\tinet6 fe80::1%lo0 prefixlen 64 scopeid 0x2\n\tinet 127.0.0.1 netmask 0xff000000\n\tnd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>\n\tgroups: lo\nbridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\tether 02:87:a9:03:d7:00\n\tinet 10.192.0.111 netmask 0xffc00000 broadcast 10.255.255.255\n\tnd6 options=1<PERFORMNUD>\n\tgroups: bridge\n\tid 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15\n\tmaxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200\n\troot id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0\nbridge1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\tether 02:87:a9:03:d7:00\n\tinet 10.192.0.11 netmask 0xffc00000 broadcast 10.255.255.255\n\tnd6 options=1<PERFORMNUD>\n\tgroups: bridge\n\tid 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15\n\tmaxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200\n\troot id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0\nbridge2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\tether 02:87:a9:03:d7:00\n\tinet 10.192.0.1 netmask 0xffc00000 broadcast 10.255.255.255\n\tnd6 options=1<PERFORMNUD>\n\tgroups: bridge\n\tid 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15\n\tmaxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200\n\troot id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"-g\" ] && [ \"$2\" = \"bridge\" ]; then\n\t\tcat << EOF--\nbridge0\nbridge1\nbridge2\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"bridge0\" ]; then\n\t\tcat << EOF--\nbridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\tinet 10.192.0.111 netmask 0xffc00000 broadcast 10.255.255.255\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"bridge1\" ]; then\n\t\tcat << EOF--\nbridge1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\tinet 10.192.0.11 netmask 0xffc00000 broadcast 10.255.255.255\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"bridge2\" ]; then\n\t\tcat << EOF--\nbridge2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\tinet 10.192.0.1 netmask 0xffc00000 broadcast 10.255.255.255\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"em0\" ]; then\n\t\tcat << EOF--\nem0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=200080<VLAN_HWCSUM,RXCSUM_IPV6>\n\tinet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.178.255\n\tether e4:b3:18:d8:4d:25\n\thwaddr c8:5b:76:3a:2f:96\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\n\tmedia: Ethernet autoselect\n\tstatus: no carrier\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"em1\" ]; then\n\t\tcat << EOF--\nem1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=200080<VLAN_HWCSUM,RXCSUM_IPV6>\n\tinet 10.192.168.1 netmask 0xffffff00 broadcast 10.192.168.255\n\tether e4:b3:18:d8:4d:25\n\thwaddr c8:5b:76:3a:2f:96\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\n\tmedia: Ethernet autoselect\n\tstatus: no carrier\nEOF--\n\t\treturn 0 # true\n\telif [ \"$1\" = \"bce0\" ]; then\n\t\tcat << EOF--\nbce0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=200080<VLAN_HWCSUM,RXCSUM_IPV6>\n\tinet 10.192.168.3 netmask 0xffffff00 broadcast 10.192.168.255\n\tether e4:b3:18:d8:4d:35\n\thwaddr c8:5b:76:3a:2f:b6\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\n\tmedia: Ethernet autoselect\n\tstatus: no carrier\nEOF--\n\t\treturn 0 # true\n\telse\n\t\treturn 1 # false\n\tfi\n}\n\n# system utilities stubs\npotnet()\n{\n\tif [ \"$1\" = \"next\" ]; then\n\t\tif [ -n \"$3\" ]; then\n\t\t\techo \"10.192.123.234\"\n\t\telse\n\t\t\techo \"10.192.123.123\"\n\t\tfi\n\t\treturn 0 # true\n\tfi\n\tif [ \"$1\" = \"validate\" ] && [ \"$2\" = \"-H\" ] ; then\n\t\tif [ \"$3\" = \"10.192.123.123\" ] || [ \"$3\" = \"10.192.123.234\" ] ||\n\t\t\t[ \"$3\" = \"10.1.10.10\" ]; then\n\t\t\treturn 0 # true\n\t\tfi\n\tfi\n\tif [ \"$1\" = \"ipcheck\" ]; then\n\t\tcase \"$3\" in\n\t\t\t192.168.200.200|10.192.123.234|10.1.10.10)\n\t\t\t\t;;\n\t\t\t2a0a:fade:dead:01e::80|2a0a:fade:dead:01e::443)\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\treturn 1\n\t\t\t\t;;\n\t\tesac\n\t\treturn 0 # true\n\tfi\n\tif [ \"$1\" = \"ip4check\" ]; then\n\t\tcase \"$3\" in\n\t\t\t192.168.200.200|10.192.123.234|10.1.10.10)\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\treturn 1\n\t\t\t\t;;\n\t\tesac\n\t\treturn 0 # true\n\tfi\n\tif [ \"$1\" = \"ip6check\" ]; then\n\t\tcase \"$3\" in\n\t\t\t2a0a:fade:dead:01e::80|2a0a:fade:dead:01e::443)\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\treturn 1\n\t\t\t\t;;\n\t\tesac\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n# UUT\n. ../share/pot/network.sh\n\n. ../share/pot/common.sh\n\n# add common stub\n\n_is_vnet_available()\n{\n\treturn 0 # true\n}\n\n_is_potnet_available()\n{\n\treturn 0 # true\n}\n\n_get_network_stack()\n{\n\tif [ -z \"$STUB_STACK\" ]; then\n\t\techo dual\n\telse\n\t\techo \"$STUB_STACK\"\n\tfi\n}\n\n_get_pot_network_stack()\n{\n\t_get_network_stack\n}\n\n_is_bridge()\n{\n\tcase \"$1\" in\n\t\ttest-bridge)\n\t\t\treturn 0 # return true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n# app specific stubs\n\ntest_get_pot_rdr_anchor_name_001()\n{\n\t_rc=\"$(_get_pot_rdr_anchor_name \"test-pot\" )\"\n\tassertEquals \"test-pot\" \"$_rc\"\n}\n\ntest_get_pot_rdr_anchor_name_002()\n{\n\t_rc=\"$(_get_pot_rdr_anchor_name \"0123456789012345678901234567890123456789012345678901234\" )\"\n\tassertEquals \"0123456789012345678901234567890123456789012345678901234\" \"$_rc\"\n}\n\ntest_get_pot_rdr_anchor_name_003()\n{\n\t_rc=\"$(_get_pot_rdr_anchor_name \"01234567890123456789012345678901234567890123456789012345\" )\"\n\tassertEquals \"1234567890123456789012345678901234567890123456789012345\" \"$_rc\"\n}\n\ntest_get_pot_rdr_anchor_name_004()\n{\n\t_rc=\"$(_get_pot_rdr_anchor_name \"012345678901234567890123456789012345678901234567890123456789\" )\"\n\tassertEquals \"5678901234567890123456789012345678901234567890123456789\" \"$_rc\"\n}\n\ntest_get_pot_rdr_anchor_name_005()\n{\n\t_rc=\"$(_get_pot_rdr_anchor_name \"01234_678901234567890123456789012345678901234567890123456789\" )\"\n\tassertEquals \"678901234567890123456789012345678901234567890123456789\" \"$_rc\"\n}\n\ntest_get_pot_rdr_anchor_name_006()\n{\n\t_rc=\"$(_get_pot_rdr_anchor_name \"01234___8901234567890123456789012345678901234567890123456789\" )\"\n\tassertEquals \"8901234567890123456789012345678901234567890123456789\" \"$_rc\"\n}\n\ntest_pot_bridge_001()\n{\n\t# shellcheck disable=SC2039\n\tlocal _rc\n\tPOT_GATEWAY=10.192.0.111\n\t_rc=\"$(_pot_bridge )\"\n\tassertEquals \"bridge0\" \"$_rc\"\n\n\tPOT_GATEWAY=192.168.0.1\n\t_rc=\"$(_pot_bridge )\"\n\tassertEquals \"\" \"$_rc\"\n\n\tPOT_GATEWAY=10.192.0.1\n\t_rc=\"$(_pot_bridge )\"\n\tassertEquals \"bridge2\" \"$_rc\"\n}\n\ntest_pot_is_valid_netif_001()\n{\n\t_is_valid_netif bridge2\n\tassertTrue \"netif not recognized\" \"$?\"\n}\n\ntest_pot_is_valid_netif_002()\n{\n\t_is_valid_netif not-netif\n\tassertFalse \"netif wrongly recognized\" \"$?\"\n}\n\ntest_validate_alias_ipaddr_001()\n{\n\tassertTrue \"address not recognized\" '_validate_alias_ipaddr \"192.168.200.200\" \"dual\"'\n}\n\ntest_get_alias_ipv4_001()\n{\n\tipaddr=\"192.168.200.200\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"\" \"$output\"\n}\n\ntest_validate_alias_ipaddr_002()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|192.168.200.200\" \"dual\"'\n}\n\ntest_get_alias_ipv4_002()\n{\n\tipaddr=\"em0|192.168.200.200\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"\" \"$output\"\n}\n\ntest_validate_alias_ipaddr_003()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|192.168.200.200 10.1.10.10\" \"dual\"'\n}\n\ntest_get_alias_ipv4_003()\n{\n\tipaddr=\"em0|192.168.200.200 10.1.10.10\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200,bce0|10.1.10.10\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200,bce0|10.1.10.10\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200,bce0|10.1.10.10\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"\" \"$output\"\n}\n\ntest_validate_alias_ipaddr_004()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"10.1.10.10 em0|192.168.200.200\" \"dual\"'\n}\n\ntest_get_alias_ipv4_004()\n{\n\tipaddr=\"10.1.10.10 em0|192.168.200.200\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|10.1.10.10,em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|10.1.10.10,em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|10.1.10.10,em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"\" \"$output\"\n}\n\ntest_validate_alias_ipaddr_005()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|192.168.200.200 em1|10.1.10.10\" \"dual\"'\n}\n\ntest_get_alias_ipv4_005()\n{\n\tipaddr=\"em0|192.168.200.200 em1|10.1.10.10\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200,em1|10.1.10.10\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200,em1|10.1.10.10\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200,em1|10.1.10.10\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"\" \"$output\"\n}\n\ntest_validate_alias_ipaddr_006()\n{\n\tassertFalse \"NIC|address shouldn't be accepted\" '_validate_alias_ipaddr \"em0|192.168.200.200 em1|10.1.10.10\" \"ipv6\"'\n}\n\ntest_validate_alias_ipaddr_010()\n{\n\tassertTrue \"address not recognized\" '_validate_alias_ipaddr \"2a0a:fade:dead:01e::80\" \"dual\"'\n}\n\ntest_get_alias_ipv4_010()\n{\n\tipaddr=\"2a0a:fade:dead:01e::80\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_011()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|2a0a:fade:dead:01e::80\" \"dual\"'\n}\n\ntest_get_alias_ipv4_011()\n{\n\tipaddr=\"em0|2a0a:fade:dead:01e::80\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_012()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|2a0a:fade:dead:01e::80 2a0a:fade:dead:01e::443\" \"dual\"'\n}\n\ntest_get_alias_ipv4_012()\n{\n\tipaddr=\"em0|2a0a:fade:dead:01e::80 2a0a:fade:dead:01e::443\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_013()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"2a0a:fade:dead:01e::443 em0|2a0a:fade:dead:01e::80\" \"dual\"'\n}\n\ntest_get_alias_ipv4_013()\n{\n\tipaddr=\"2a0a:fade:dead:01e::443 em0|2a0a:fade:dead:01e::80\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_014()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|2a0a:fade:dead:01e::80 em1|2a0a:fade:dead:01e::443\" \"dual\"'\n}\n\ntest_get_alias_ipv4_014()\n{\n\tipaddr=\"em0|2a0a:fade:dead:01e::80 em1|2a0a:fade:dead:01e::443\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_015()\n{\n\tassertFalse \"NIC|address shouldn't be accepted\" '_validate_alias_ipaddr \"em0|2a0a:fade:dead:01e::80 em1|2a0a:fade:dead:01e::443\" \"ipv4\"'\n}\n\ntest_validate_alias_ipaddr_020()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|2a0a:fade:dead:01e::80 em1|192.168.200.200\" \"dual\"'\n}\n\ntest_get_alias_ipv4_020()\n{\n\tipaddr=\"em0|2a0a:fade:dead:01e::80 em1|192.168.200.200\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em1|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em1|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em1|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_021()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"em0|2a0a:fade:dead:01e::80 em0|192.168.200.200\" \"dual\"'\n}\n\ntest_get_alias_ipv4_021()\n{\n\tipaddr=\"em0|2a0a:fade:dead:01e::80 em0|192.168.200.200\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"em0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_022()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"2a0a:fade:dead:01e::80 192.168.200.200\" \"dual\"'\n}\n\ntest_get_alias_ipv4_022()\n{\n\tipaddr=\"2a0a:fade:dead:01e::80 192.168.200.200\"\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv4\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=dual\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertEquals \"alias_ipv4 is wrong\" \"bce0|192.168.200.200\" \"$output\"\n\n\tSTUB_STACK=ipv6\n\toutput=\"$( _get_alias_ipv4 test-pot \"$ipaddr\")\"\n\tassertTrue \"alias_ipv4 is wrong\" '[ -z \"$output\"]'\n}\n\ntest_validate_alias_ipaddr_023()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"2a0a:fade:dead:01e::80 192.168.200.200\" \"ipv4\"'\n}\n\ntest_validate_alias_ipaddr_024()\n{\n\tassertTrue \"NIC|address not recognized\" '_validate_alias_ipaddr \"2a0a:fade:dead:01e::80 192.168.200.200\" \"ipv6\"'\n}\n\ntest_validate_network_param_001()\n{\n\tif ipaddr=\"$(_validate_network_param \"no-network\")\" ; then\n\t\tfail \"Invalid network type not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" 'no-network'\n\tfi\n}\n\ntest_validate_network_param_002()\n{\n\tif ipaddr=\"$(_validate_network_param \"no-network\" \"ignored1\" \"ignored2\")\" ; then\n\t\tfail \"Invalid network type not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" 'no-network'\n\tfi\n}\n\ntest_validate_network_param_010()\n{\n\tif ipaddr=\"$(_validate_network_param \"inherit\" \"ignored1\" \"ignored2\")\" ; then\n\t\tassertTrue \"ip addr should be empty\" \"[ -z $ipaddr ]\"\n\telse\n\t\tfail \"Valid inherit config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_020()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"\" \"\")\" ; then\n\t\tfail \"Invalid alias config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" 'mandatory'\n\tfi\n}\n\ntest_validate_network_param_021()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"auto\" \"no-bridge\")\" ; then\n\t\tfail \"Invalid alias config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" 'auto'\n\tfi\n}\n\ntest_validate_network_param_022()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"500.0.0.1\" \"no-bridge\")\" ; then\n\t\tfail \"Invalid alias config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"500.0.0.1\"\n\tfi\n}\n\ntest_validate_network_param_023()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"192.168.200.200\" \"no-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"192.168.200.200\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid alias config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_024()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"em0|192.168.200.200\" \"no-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"em0|192.168.200.200\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid alias config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_025()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"em0|192.168.200.200 10.1.10.10\" \"no-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"em0|192.168.200.200 10.1.10.10\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid alias config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_026()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"em0|192.168.200.200 em1|10.1.10.10\" \"no-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"em0|192.168.200.200 em1|10.1.10.10\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid alias config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_027()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"em0|192.168.200.200 em1|10.1.10.10\" \"\" \"dual\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"em0|192.168.200.200 em1|10.1.10.10\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid alias config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_028()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"em0|192.168.200.200 em1|10.1.10.10\" \"\" \"ipv4\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"em0|192.168.200.200 em1|10.1.10.10\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid alias config not recognized\"\n\tfi\n}\n\ntest_validate_network_param_029()\n{\n\tif ipaddr=\"$(_validate_network_param \"alias\" \"em0|192.168.200.200 em1|10.1.10.10\" \"\" \"ipv6\")\" ; then\n\t\tfail \"Invalid alias config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"ipv6\"\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"em0|192.168.200.200 em1|10.1.10.10\"\n\tfi\n}\n\ntest_validate_network_param_040()\n{\n\tif ipaddr=\"$(_validate_network_param \"public-bridge\" \"500.0.0.1\" \"no-bridge\")\" ; then\n\t\tfail \"Invalid public-bridge config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"500.0.0.1\"\n\tfi\n}\n\ntest_validate_network_param_041()\n{\n\tif ipaddr=\"$(_validate_network_param \"public-bridge\" \"\" \"\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"10.192.123.123\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid public-bridge config not recognized - $ipaddr\"\n\tfi\n}\n\ntest_validate_network_param_042()\n{\n\tif ipaddr=\"$(_validate_network_param \"public-bridge\" \"10.192.123.123\" \"no-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"10.192.123.123\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid public-bridge config not recognized - $ipaddr\"\n\tfi\n}\n\ntest_validate_network_param_043()\n{\n\tif ipaddr=\"$(_validate_network_param \"public-bridge\" \"auto\" \"no-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"10.192.123.123\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid public-bridge config not recognized - $ipaddr\"\n\tfi\n}\n\ntest_validate_network_param_060()\n{\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"auto\" \"\")\" ; then\n\t\tfail \"Valid public-bridge config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"-B\"\n\tfi\n}\n\ntest_validate_network_param_061()\n{\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"auto\" \"no-bridge\")\" ; then\n\t\tfail \"Valid public-bridge config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"no-bridge\"\n\tfi\n}\n\ntest_validate_network_param_062()\n{\n\tSTUB_STACK=\"ipv6\"\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"auto\" \"test-bridge\")\" ; then\n\t\tfail \"Valid public-bridge config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"ipv6\"\n\tfi\n}\n\ntest_validate_network_param_063()\n{\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"500.0.0.1\" \"test-bridge\")\" ; then\n\t\tfail \"Valid public-bridge config not recognized\"\n\telse\n\t\tassertContains \"Wrong error message\" \"$ipaddr\" \"500.0.0.1\"\n\tfi\n}\n\ntest_validate_network_param_070()\n{\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"auto\" \"test-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"10.192.123.234\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid private-bridge config not recognized - $ipaddr\"\n\tfi\n}\n\ntest_validate_network_param_071()\n{\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"\" \"test-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"10.192.123.234\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid private-bridge config not recognized - $ipaddr\"\n\tfi\n}\n\ntest_validate_network_param_072()\n{\n\tif ipaddr=\"$(_validate_network_param \"private-bridge\" \"10.192.123.234\" \"test-bridge\")\" ; then\n\t\tassertEquals \"Wrong ip returned \" \"10.192.123.234\" \"$ipaddr\"\n\telse\n\t\tfail \"Valid private-bridge config not recognized - $ipaddr\"\n\tfi\n}\n\ntest_is_export_port_valid_001()\n{\n\t_is_export_port_valid\n\tassertFalse \"empty argument not recognized\" \"$?\"\n}\n\ntest_is_export_port_valid_002()\n{\n\t_is_export_port_valid ssh\n\tassertFalse \"port as a name should cause an error\" \"$?\"\n\n\t_is_export_port_valid ssh:8080\n\tassertFalse \"port as a name should cause an error\" \"$?\"\n\n\t_is_export_port_valid 8080:ssh\n\tassertFalse \"port as a name should cause an error\" \"$?\"\n}\n\ntest_is_export_port_valid_003()\n{\n\t_is_export_port_valid 80000\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid 80000:8080\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid 8080:80000\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid -22\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid -22:8080\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid 8080:-22\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n}\n\ntest_is_export_port_valid_004()\n{\n\t_is_export_port_valid udp:80000\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid udp:80000:8080\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid udp:8080:80000\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid udp:-22\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid udp:-22:8080\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid udp:8080:-22\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n}\n\ntest_is_export_port_valid_005()\n{\n\t_is_export_port_valid tcp:80000\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid tcp:80000:8080\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid tcp:8080:80000\n\tassertFalse \"invalid port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid tcp:-22\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid tcp:-22:8080\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n\n\t_is_export_port_valid tcp:8080:-22\n\tassertFalse \"negative port number should cause an error\" \"$?\"\n}\n\ntest_is_export_port_valid_010()\n{\n\t_is_export_port_valid 8080\n\tassertTrue \"valid port should be accepted\" \"$?\"\n\n\t_is_export_port_valid 8080:8080\n\tassertTrue \"valid port should be accepted\" \"$?\"\n}\n\ntest_is_export_port_valid_011()\n{\n\t_is_export_port_valid udp:8080\n\tassertTrue \"valid port should be accepted\" \"$?\"\n\n\t_is_export_port_valid udp:8080:8080\n\tassertTrue \"valid port should be accepted\" \"$?\"\n}\n\ntest_is_export_port_valid_012()\n{\n\t_is_export_port_valid tcp:8080\n\tassertTrue \"valid port should be accepted\" \"$?\"\n\n\t_is_export_port_valid tcp:8080:8080\n\tassertTrue \"valid port should be accepted\" \"$?\"\n}\n\nsetUp()\n{\n\t_POT_VERBOSITY=1\n\tPOT_EXTIF=\"bce0\"\n\tSTUB_STACK=\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/pipefail-stub.sh",
    "content": "#!/bin/sh\n\n_set_pipefail()\n{\n\tlocal _major _version\n\tif [ \"$(uname)\" = \"Linux\" ]; then\n\t\tset -o pipefail\n\t\treturn\n\tfi\n\t_major=\"$(sysctl -n kern.osrelease | cut -f 1 -d '.')\"\n\t_version=\"$(sysctl -n kern.osrelease | cut -f 1 -d '-')\"\n\tif [ \"$_major\" -ge \"13\" ]; then\n\t\tset -o pipefail\n\t\treturn\n\tfi\n\tcase \"$_version\" in\n\t\t\"12.1\")\n\t\t\tset -o pipefail\n\t\t\t;;\n\tesac\n}\n\n"
  },
  {
    "path": "tests/ps1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/ps.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nps-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_ps_pots()\n{\n\t__monitor PSPOTS \"$@\"\n}\n\n_is_vnet_up()\n{\n\treturn 0 # true\n}\n\ntest_pot_ps_001()\n{\n\tpot-ps -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"ps_pots calls\" \"0\" PSPOTS_CALLS\n\n\tsetUp\n\tpot-ps -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"ps_pots calls\" \"0\" PSPOTS_CALLS\n}\n\ntest_pot_ps_020()\n{\n\tpot-ps -q\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"ps_pots calls\" \"1\" PSPOTS_CALLS\n\tassertEqualsMon \"ps_pots arg1\" \"quiet\" PSPOTS_CALL1_ARG1\n}\n\ntest_pot_ps_021()\n{\n\tpot-ps\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"ps_pots calls\" \"1\" PSPOTS_CALLS\n\tassertEqualsMon \"ps_pots arg1\" \"\" PSPOTS_CALL1_ARG1\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/rename1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/rename.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nrename-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_rn_conf()\n{\n\t__monitor RNCONF \"$@\"\n}\n\n_rn_zfs()\n{\n\t__monitor RNZFS \"$@\"\n}\n\n_rn_recursive()\n{\n\t__monitor RNRECURSIVE \"$@\"\n}\n\ntest_pot_rename_001()\n{\n\tpot-rename\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n\n\tsetUp\n\tpot-rename -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n\n\tsetUp\n\tpot-rename -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n\n\tsetUp\n\tpot-rename -va\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n}\n\ntest_pot_rename_002()\n{\n\tpot-rename -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n\n\tsetUp\n\tpot-rename -n test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n}\n\ntest_pot_rename_003()\n{\n\tpot-rename -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n\n\tsetUp\n\tpot-rename -n test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n}\n\ntest_pot_rename_004()\n{\n\tpot-rename -p test-pot -n test-pot-2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n}\n\ntest_pot_rename_005()\n{\n\tpot-rename -p no-test-pot -n no-test-pot-2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n}\n\ntest_pot_rename_006()\n{\n\tpot-rename -p test-pot-run -n test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"0\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_zfs calls\" \"0\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_recursive calls\" \"0\" RNRECURSIVE_CALLS\n}\n\ntest_pot_rename_020()\n{\n\tpot-rename -p test-pot -n test-no-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_rn_conf calls\" \"1\" RNCONF_CALLS\n\tassertEqualsMon \"_rn_conf args\" \"test-pot\" RNCONF_CALL1_ARG1\n\tassertEqualsMon \"_rn_conf args\" \"test-no-pot\" RNCONF_CALL1_ARG2\n\tassertEqualsMon \"_rn_zfs calls\" \"1\" RNZFS_CALLS\n\tassertEqualsMon \"_rn_zfs args\" \"test-pot\" RNZFS_CALL1_ARG1\n\tassertEqualsMon \"_rn_zfs args\" \"test-no-pot\" RNZFS_CALL1_ARG2\n\tassertEqualsMon \"_rn_recursive calls\" \"1\" RNRECURSIVE_CALLS\n\tassertEqualsMon \"_rn_recursive args\" \"test-pot\" RNRECURSIVE_CALL1_ARG1\n\tassertEqualsMon \"_rn_recursive args\" \"test-no-pot\" RNRECURSIVE_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/rename2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nSED=sed_stub\nsed_stub()\n{\n\tif [ \"$(uname)\" = \"Linux\" ]; then\n\t\tsed -i'' \"$3\" \"$4\" \"$5\"\n\telse\n\t\tsed \"$@\"\n\tfi\n}\n\n# UUT\n. ../share/pot/rename.sh\n\n# common stubs\n. common-stub.sh\n. conf-stub.sh\n\n# app specific stubs\nhostname()\n{\n\techo \"test\"\n}\n\ntest_rn_conf_001()\n{\n\t_rn_conf test-pot new-pot\n\tassertEquals \"fscomp args1\" \"zpot/bases/11.1 /tmp/jails/new-pot/m ro\" \"$(sed '1!d' /tmp/jails/test-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args2\" \"zpot/jails/new-pot/usr.local /tmp/jails/new-pot/m/usr/local zfs-remount\" \"$(sed '2!d' /tmp/jails/test-pot/conf/fscomp.conf)\"\n\tassertEquals \"fscomp args3\" \"zpot/jails/new-pot/custom /tmp/jails/new-pot/m/opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/test-pot/conf/fscomp.conf)\"\n\tassertEquals \"host.hostname\" \"host.hostname=\\\"new-pot.test\\\"\" \"$(grep ^host.hostname /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tconf_setUp\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\tconf_tearDown\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/rename3.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nzfs()\n{\n\t__monitor ZFS \"$@\"\n}\n\n# UUT\n. ../share/pot/rename.sh\n\n# common stubs\n. common-stub.sh\n\n_zfs_dataset_valid()\n{\n\t__monitor ZDVALID \"$@\"\n\tcase \"$1\" in\n\t\t${POT_ZFS_ROOT}/jails/test-pot|\\\n\t\t${POT_ZFS_ROOT}/jails/test-pot/usr.local|\\\n\t\t${POT_ZFS_ROOT}/jails/test-pot/custom|\\\n\t\t${POT_ZFS_ROOT}/jails/test-pot-2|\\\n\t\t${POT_ZFS_ROOT}/jails/test-pot-2/custom|\\\n\t\t${POT_ZFS_ROOT}/jails/new-pot/usr.local|\\\n\t\t${POT_ZFS_ROOT}/jails/test-pot-single|\\\n\t\t${POT_ZFS_ROOT}/jails/test-pot-single/m|\\\n\t\t${POT_ZFS_ROOT}/jails/new-pot-single/m)\n\t\t\treturn 0 # true\n\t\t\t;;\n\tesac\n\treturn 1 # false\n}\n\n# app specific stubs\n\ntest_rn_zfs_001()\n{\n\t_rn_zfs test-pot new-pot\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"4\" ZDVALID_CALLS\n\tassertEqualsMon \"zfs calls\" \"9\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"umount\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"-f\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c1 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot/usr.local\" ZFS_CALL1_ARG3\n\tassertEqualsMon \"zfs c2 arg1\" \"set\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"mountpoint=/jails/new-pot/usr.local\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c2 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot/usr.local\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs c3 arg1\" \"umount\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-f\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot/custom\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c4 arg1\" \"set\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"mountpoint=/jails/new-pot/custom\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs c4 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot/custom\" ZFS_CALL4_ARG3\n\tassertEqualsMon \"zfs c5 arg1\" \"umount\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs c5 arg2\" \"-f\" ZFS_CALL5_ARG2\n\tassertEqualsMon \"zfs c5 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot\" ZFS_CALL5_ARG3\n\tassertEqualsMon \"zfs c6 arg1\" \"rename\" ZFS_CALL6_ARG1\n\tassertEqualsMon \"zfs c6 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot\" ZFS_CALL6_ARG2\n\tassertEqualsMon \"zfs c6 arg3\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL6_ARG3\n\tassertEqualsMon \"zfs c7 arg1\" \"mount\" ZFS_CALL7_ARG1\n\tassertEqualsMon \"zfs c7 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot\" ZFS_CALL7_ARG2\n\tassertEqualsMon \"zfs c8 arg1\" \"mount\" ZFS_CALL8_ARG1\n\tassertEqualsMon \"zfs c8 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/custom\" ZFS_CALL8_ARG2\n\tassertEqualsMon \"zfs c9 arg1\" \"mount\" ZFS_CALL9_ARG1\n\tassertEqualsMon \"zfs c9 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot/usr.local\" ZFS_CALL9_ARG2\n}\n\ntest_rn_zfs_002()\n{\n\t_rn_zfs test-pot-2 new-pot-2\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"4\" ZDVALID_CALLS\n\tassertEqualsMon \"zfs calls\" \"6\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"umount\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"-f\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c1 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot-2/custom\" ZFS_CALL1_ARG3\n\tassertEqualsMon \"zfs c2 arg1\" \"set\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"mountpoint=/jails/new-pot-2/custom\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c2 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot-2/custom\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs c3 arg1\" \"umount\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-f\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot-2\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c4 arg1\" \"rename\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot-2\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs c4 arg3\" \"${POT_ZFS_ROOT}/jails/new-pot-2\" ZFS_CALL4_ARG3\n\tassertEqualsMon \"zfs c5 arg1\" \"mount\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs c5 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot-2\" ZFS_CALL5_ARG2\n\tassertEqualsMon \"zfs c6 arg1\" \"mount\" ZFS_CALL6_ARG1\n\tassertEqualsMon \"zfs c6 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot-2/custom\" ZFS_CALL6_ARG2\n}\n\ntest_rn_zfs_003()\n{\n\t_rn_zfs test-pot-single new-pot-single\n\tassertEqualsMon \"_zfs_dataset_valid calls\" \"3\" ZDVALID_CALLS\n\tassertEqualsMon \"zfs calls\" \"6\" ZFS_CALLS\n\tassertEqualsMon \"zfs c1 arg1\" \"umount\" ZFS_CALL1_ARG1\n\tassertEqualsMon \"zfs c1 arg2\" \"-f\" ZFS_CALL1_ARG2\n\tassertEqualsMon \"zfs c1 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot-single/m\" ZFS_CALL1_ARG3\n\tassertEqualsMon \"zfs c2 arg1\" \"set\" ZFS_CALL2_ARG1\n\tassertEqualsMon \"zfs c2 arg2\" \"mountpoint=/jails/new-pot-single/m\" ZFS_CALL2_ARG2\n\tassertEqualsMon \"zfs c2 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot-single/m\" ZFS_CALL2_ARG3\n\tassertEqualsMon \"zfs c3 arg1\" \"umount\" ZFS_CALL3_ARG1\n\tassertEqualsMon \"zfs c3 arg2\" \"-f\" ZFS_CALL3_ARG2\n\tassertEqualsMon \"zfs c3 arg3\" \"${POT_ZFS_ROOT}/jails/test-pot-single\" ZFS_CALL3_ARG3\n\tassertEqualsMon \"zfs c4 arg1\" \"rename\" ZFS_CALL4_ARG1\n\tassertEqualsMon \"zfs c4 arg2\" \"${POT_ZFS_ROOT}/jails/test-pot-single\" ZFS_CALL4_ARG2\n\tassertEqualsMon \"zfs c4 arg3\" \"${POT_ZFS_ROOT}/jails/new-pot-single\" ZFS_CALL4_ARG3\n\tassertEqualsMon \"zfs c5 arg1\" \"mount\" ZFS_CALL5_ARG1\n\tassertEqualsMon \"zfs c5 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot-single\" ZFS_CALL5_ARG2\n\tassertEqualsMon \"zfs c6 arg1\" \"mount\" ZFS_CALL6_ARG1\n\tassertEqualsMon \"zfs c6 arg2\" \"${POT_ZFS_ROOT}/jails/new-pot-single/m\" ZFS_CALL6_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tPOT_ZFS_ROOT=zpot\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/rename4.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nls()\n{\n\tcat << LS_EOL\n/opt/pot/jails/test-pot/\n/opt/pot/jails/test-pot-2/\n/opt/pot/jails/test-pot-nosnap/\nLS_EOL\n}\n\nSED=sed_stub\nsed_stub()\n{\n\tif [ \"$(uname)\" = \"Linux\" ]; then\n\t\tsed -i'' \"$3\" \"$4\" \"$5\"\n\telse\n\t\tsed \"$@\"\n\tfi\n}\n\n# UUT\n. ../share/pot/rename.sh\n\n# common stubs\n. common-stub.sh\n. conf-stub.sh\n\n# app specific stubs\n\ntest_rn_recursive_001()\n{\n\t_rn_recursive test-pot new-pot\n\tassertEquals \"fscomp base\" \"zpot/bases/11.1 /tmp/jails/test-pot-2/m ro\" \"$(sed '1!d' /tmp/jails/test-pot-2/conf/fscomp.conf)\"\n\tassertEquals \"fscomp usr.local\" \"zpot/jails/new-pot/usr.local /tmp/jails/test-pot-2/m/usr/local ro\" \"$(sed '2!d' /tmp/jails/test-pot-2/conf/fscomp.conf)\"\n\tassertEquals \"fscomp custom\" \"zpot/jails/test-pot-2/custom /tmp/jails/test-pot-2/m/opt/custom zfs-remount\" \"$(sed '3!d' /tmp/jails/test-pot-2/conf/fscomp.conf)\"\n\tassertEquals \"pot.conf potbase\" \"pot.potbase=new-pot\" \"$(grep ^pot.potbase= /tmp/jails/test-pot-2/conf/pot.conf)\"\n\tassertEquals \"pot.conf depende\" \"pot.depend=new-pot\" \"$(grep ^pot.depend= /tmp/jails/test-pot-nosnap/conf/pot.conf)\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tconf_setUp\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\tconf_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/revert1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/revert.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nrevert-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_pot_zfs_rollback()\n{\n\t__monitor POTZFSROLL \"$@\"\n}\n\n_pot_zfs_rollback_full()\n{\n\t__monitor POTZFSROLLFULL \"$@\"\n}\n\n_fscomp_zfs_rollback()\n{\n\t__monitor FSCOMPZFSROLL \"$@\"\n}\n\ntest_pot_revert_001()\n{\n\tpot-revert\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\n\tsetUp\n\tpot-revert -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\n\tsetUp\n\tpot-revert -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\n\tsetUp\n\tpot-revert -va\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n}\n\ntest_pot_revert_002()\n{\n\tpot-revert -f test-fscomp -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\n\tsetUp\n\tpot-revert -p test-pot -f test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n}\n\ntest_pot_revert_020()\n{\n\tpot-revert -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\n\tsetUp\n\tpot-revert -p not-a-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\n\tsetUp\n\tpot-revert -p test-pot-run\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n}\n\ntest_pot_revert_021()\n{\n\tpot-revert -p test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"1\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback arg\" \"test-pot\" POTZFSROLL_CALL1_ARG1\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n}\n\ntest_pot_revert_022()\n{\n\tpot-revert -p test-pot -a\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full arg\" \"\" POTZFSROLLFULL_CALL1_ARG1\n}\n\ntest_pot_revert_040()\n{\n\tpot-revert -f\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\n\tsetUp\n\tpot-revert -f not-a-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"1\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n}\n\ntest_pot_revert_041()\n{\n\tpot-revert -f test-fscomp\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"1\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"1\" FSCOMPZFSROLL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback arg\" \"test-fscomp\" FSCOMPZFSROLL_CALL1_ARG1\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_revert_042()\n{\n\tpot-revert -f test-fscomp -a\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback calls\" \"0\" POTZFSROLL_CALLS\n\tassertEqualsMon \"_pot_zfs_rollback_full calls\" \"0\" POTZFSROLLFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback calls\" \"0\" FSCOMPZFSROLL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_rollback arg\" \"\" FSCOMPZFSROLL_CALL1_ARG1\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-attr1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/set-attribute.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-attribute-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_set_boolean_attribute()\n{\n\t__monitor SETATTR \"$@\"\n}\n\ntest_pot_set_attr_001()\n{\n\tpot-set-attribute\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -bv\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n}\n\ntest_pot_set_attr_002()\n{\n\tpot-set-attribute -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -A start-at-boot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -V ON\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n}\n\ntest_pot_set_attr_003()\n{\n\tpot-set-attribute -A start-at-boot -V ON\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -p test-pot -A start-at-boot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n\n\tsetUp\n\tpot-set-attribute -p test-pot -V ON\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n}\n\ntest_pot_set_attr_004()\n{\n\tpot-set-attribute -p test-no-pot -A start-at-boot -V ON\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n}\n\ntest_pot_set_attr_005()\n{\n\tpot-set-attribute -p test-pot -A not-an-attribute -V ON\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"0\" SETATTR_CALLS\n}\n\ntest_pot_set_attr_020()\n{\n\tpot-set-attribute -p test-pot -A start-at-boot -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr calls\" \"1\" SETATTR_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"start-at-boot\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_021()\n{\n\tpot-set-attribute -p test-pot -A persistent -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"persistent\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_022()\n{\n\tpot-set-attribute -p test-pot -A no-rc-script -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"no-rc-script\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_023()\n{\n\tpot-set-attribute -p test-pot -A fdescfs -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"fdescfs\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_024()\n{\n\tpot-set-attribute -p test-pot -A procfs -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"procfs\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_025()\n{\n\tpot-set-attribute -p test-pot -A prunable -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"prunable\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_026()\n{\n\tpot-set-attribute -p test-pot -A localhost-tunnel -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"localhost-tunnel\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\ntest_pot_set_attr_027()\n{\n\tpot-set-attribute -p test-pot -A early-start-at-boot -V ON\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_attr arg1\" \"test-pot\" SETATTR_CALL1_ARG1\n\tassertEqualsMon \"_set_attr arg2\" \"early-start-at-boot\" SETATTR_CALL1_ARG2\n\tassertEqualsMon \"_set_attr arg3\" \"ON\" SETATTR_CALL1_ARG3\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-attr2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/set-attribute.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-attribute-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_normalize_true_false_1()\n{\n\tlocal rc\n\tif rc=$(_normalize_true_false YES) ; then\n\t\tassertEquals \"YES\" \"$rc\"\n\telse\n\t\tfail \"it shouldn't be here\"\n\tfi\n}\n\ntest_normalize_true_false_2()\n{\n\tlocal rc\n\tif rc=$(_normalize_true_false NO) ; then\n\t\tassertEquals \"NO\" \"$rc\"\n\telse\n\t\tfail \"it shouldn't be here\"\n\tfi\n}\n\ntest_normalize_true_false_3()\n{\n\tlocal rc\n\tif rc=$(_normalize_true_false asdfasdf) ; then\n\t\tfail \"it shouldn't be here\"\n\telse\n\t\tassertEquals \"\" \"$rc\"\n\tfi\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-cmd1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/set-cmd.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-cmd-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_set_command()\n{\n\t__monitor SETCMD \"$@\"\n}\n\ntest_pot_set_cmd_001()\n{\n\tpot-set-cmd\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n\n\tsetUp\n\tpot-set-cmd -bv\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n\n\tsetUp\n\tpot-set-cmd -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n\n\tsetUp\n\tpot-set-cmd -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n}\n\ntest_pot_set_cmd_002()\n{\n\tpot-set-cmd -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n\n\tsetUp\n\tpot-set-cmd -c sh\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n}\n\ntest_pot_set_cmd_020()\n{\n\tpot-set-cmd -p test-no-pot -c \"sh /etc/rc\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"0\" SETCMD_CALLS\n}\n\ntest_pot_set_cmd_040()\n{\n\tpot-set-cmd -p test-pot -c \"/echo Hello World\"\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_command calls\" \"1\" SETCMD_CALLS\n\tassertEqualsMon \"_set_command arg1\" \"test-pot\" SETCMD_CALL1_ARG1\n\tassertEqualsMon \"_set_command arg2\" \"/echo Hello World\" SETCMD_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-env1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/set-env.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-env-help()\n{\n\t__monitor HELP \"$@\"\n}\n\nrm()\n{\n\t__monitor RM \"$@\"\n}\n\nmktemp()\n{\n\techo /tmp/pot-set-env\n}\n\n_set_environment()\n{\n\t__monitor SETENV \"$@\"\n}\n\ntest_pot_set_env_001()\n{\n\tpot-set-env\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-env -bv\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-env -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-env -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_002()\n{\n\tpot-set-env -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-env -E VAR=value\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_020()\n{\n\tpot-set-env -p test-no-pot -E VAR=value\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_021()\n{\n\tpot-set-env -p test-pot -E NOVAR\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"2\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"0\" SETENV_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_040()\n{\n\tpot-set-env -p test-pot -E VAR=value\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_041()\n{\n\tpot-set-env -p test-pot -E VAR=value -E VAR2=value2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEquals \"_tmpfile length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR2=value2\"' \"$(sed '2!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_042()\n{\n\tpot-set-env -p test-pot -E VAR=\"value1 value2\"\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 value2\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_043()\n{\n\tpot-set-env -p test-pot -E VAR=\"value1 value2\" -E VAR2=value3\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 value2\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR2=value3\"' \"$(sed '2!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_044()\n{\n\tpot-set-env -p test-pot -E EMPTYVAR=\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"EMPTYVAR=\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_045()\n{\n\tpot-set-env -p test-pot -E VAR=\"12*\"\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=12*\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_046()\n{\n\tpot-set-env -p test-pot -E VAR='12*' -E 'VAR2=?h* '\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=12*\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR2=?h* \"' \"$(sed '2!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_027()\n{\n\tpot-set-env -p test-pot -E VAR='value1 \"value2\"'\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 \\\"value2\\\"\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_060()\n{\n\tpot-set-env -p test-pot -E \"VAR=value1 value2\"\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 value2\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_061()\n{\n\tpot-set-env -p test-pot -E VAR=\"value1 value2\"\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 value2\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_062()\n{\n\tpot-set-env -p test-pot -E 'VAR=value1 value2'\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 value2\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_env_063()\n{\n\tpot-set-env -p test-pot -E VAR='value1 value2'\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_environment calls\" \"1\" SETENV_CALLS\n\tassertEqualsMon \"_set_environment arg1\" \"test-pot\" SETENV_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-env)\"\n\tassertEquals \"_tmpfile\" '\"VAR=value1 value2\"' \"$(sed '1!d' /tmp/pot-set-env)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\t/bin/rm -f /tmp/pot-set-env\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\t/bin/rm -f /tmp/pot-set-env\n}\n\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-env2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\nSED=sed_stub\nsed_stub()\n{\n\tif [ \"$(uname)\" = \"Linux\" ]; then\n\t\tsed -i'' \"$3\" \"$4\"\n\telse\n\t\tsed \"$@\"\n\tfi\n}\n\n# UUT\n. ../share/pot/set-env.sh\n. ../share/pot/common.sh\n\n# common stubs\n. conf-stub.sh\n\ntest_set_environment_000()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=value\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\n\tassertEquals \"pot.env lines\" \"1\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=value\"' \"$(grep ^pot.env /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_001()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=value\"\n\"VAR2=value2\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\n\tassertEquals \"pot.env lines\" \"2\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=value\"' \"$(grep \"^pot.env=\\\"VAR=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR2=value2\"' \"$(grep \"^pot.env=\\\"VAR2=\" /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_002()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=value1 value2\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\tassertEquals \"pot.env lines\" \"1\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=value1 value2\"' \"$(grep ^pot.env /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_003()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=value1 value2\"\n\"VAR2=value3\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\tassertEquals \"pot.env lines\" \"2\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=value1 value2\"' \"$(grep \"^pot.env=\\\"VAR=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR2=value3\"' \"$(grep \"^pot.env=\\\"VAR2=\" /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_004()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"EMPTYVAR=\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\tassertEquals \"pot.env lines\" \"1\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"EMPTYVAR=\"' \"$(grep ^pot.env /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_005()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=12*\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\tassertEquals \"pot.env lines\" \"1\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=12*\"' \"$(grep ^pot.env /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_006()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=12*\"\n\"VAR2=?h* \"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\tassertEquals \"pot.env lines\" \"2\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=12*\"' \"$(grep \"^pot.env=\\\"VAR=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR2=?h* \"' \"$(grep \"^pot.env=\\\"VAR2=\" /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\ntest_set_environment_007()\n{\n\tcat > /tmp/pot-set-env << EOF_SETENV\n\"VAR=value1 \\\"value2\\\"\"\nEOF_SETENV\n\t_set_environment test-pot /tmp/pot-set-env\n\tassertEquals \"pot.env lines\" \"1\" \"$(grep -c \"^pot.env=\" /tmp/jails/test-pot/conf/pot.conf)\"\n\tassertEquals \"pot.env args\" 'pot.env=\"VAR=value1 \\\"value2\\\"\"' \"$(grep \"^pot.env=\\\"VAR=\" /tmp/jails/test-pot/conf/pot.conf)\"\n}\n\nsetUp()\n{\n\tconf_setUp\n}\n\ntearDown()\n{\n\tconf_tearDown\n\t/bin/rm -f /tmp/pot-set-env\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-hook1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npotnet()\n{\n\tcase \"$4\" in\n\t\t\"10.1.2.3\"|\"10.1.2.4\"|\\\n\t\t\"fe00::2\"|\"::1\")\n\t\treturn 0 # true\n\tesac\n}\n\n# UUT\n. ../share/pot/set-hook.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-hook-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_set_hook()\n{\n\t__monitor SETHOOK \"$@\"\n}\n\n_is_valid_hook()\n{\n\t__monitor VALIDHOOK \"$@\"\n\tif [ \"$1\" != \"valid_script\" ]; then\n\t\treturn 1 # false\n\tfi\n\treturn 0 # true\n}\n\ntest_pot_set_hook_001()\n{\n\tpot-set-hook\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n\n\tsetUp\n\tpot-set-hook -bv\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n\n\tsetUp\n\tpot-set-hook -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n\n\tsetUp\n\tpot-set-hook -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_002()\n{\n\tpot-set-hook -s valid_script\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_003()\n{\n\tpot-set-hook -p test-pot -s\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_020()\n{\n\tpot-set-hook -p test-no-pot -s valid_script\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_021()\n{\n\tpot-set-hook -p test-pot -s not_valid_script\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_022()\n{\n\tpot-set-hook -p test-pot -S not_valid_script\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_023()\n{\n\tpot-set-hook -p test-pot -t not_valid_script\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_024()\n{\n\tpot-set-hook -p test-pot -T not_valid_script\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"0\" SETHOOK_CALLS\n}\n\ntest_pot_set_hook_040()\n{\n\tpot-set-hook -p test-pot -s valid_script\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"1\" SETHOOK_CALLS\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL1_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL1_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"prestart\" SETHOOK_CALL1_ARG3\n}\n\ntest_pot_set_hook_041()\n{\n\tpot-set-hook -p test-pot -s valid_script -S valid_script\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"2\" SETHOOK_CALLS\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL1_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL1_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"prestart\" SETHOOK_CALL1_ARG3\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL2_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL2_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"poststart\" SETHOOK_CALL2_ARG3\n}\n\ntest_pot_set_hook_042()\n{\n\tpot-set-hook -p test-pot -t valid_script -T valid_script\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"2\" SETHOOK_CALLS\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL1_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL1_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"prestop\" SETHOOK_CALL1_ARG3\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL2_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL2_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"poststop\" SETHOOK_CALL2_ARG3\n}\n\ntest_pot_set_hook_043()\n{\n\tpot-set-hook -p test-pot -t valid_script -T valid_script -s valid_script -S valid_script\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hook calls\" \"4\" SETHOOK_CALLS\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL1_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL1_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"prestart\" SETHOOK_CALL1_ARG3\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL2_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL2_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"poststart\" SETHOOK_CALL2_ARG3\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL3_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL3_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"prestop\" SETHOOK_CALL3_ARG3\n\tassertEqualsMon \"_set_hook arg1\" \"test-pot\" SETHOOK_CALL4_ARG1\n\tassertEqualsMon \"_set_hook arg2\" \"valid_script\" SETHOOK_CALL4_ARG2\n\tassertEqualsMon \"_set_hook arg3\" \"poststop\" SETHOOK_CALL4_ARG3\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-hosts1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npotnet()\n{\n\tcase \"$4\" in\n\t\t\"10.1.2.3\"|\"10.1.2.4\"|\\\n\t\t\"fe00::2\"|\"::1\")\n\t\treturn 0 # true\n\tesac\n}\n\n# UUT\n. ../share/pot/set-hosts.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-hosts-help()\n{\n\t__monitor HELP \"$@\"\n}\n\nrm()\n{\n\t__monitor RM \"$@\"\n}\n\nmktemp()\n{\n\techo \"/tmp/pot-set-hosts\"\n}\n\n_set_hosts()\n{\n\t__monitor SETHOSTS \"$@\"\n}\n\ntest_pot_set_hosts_001()\n{\n\tpot-set-hosts\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-hosts -bv\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-hosts -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n\n\tsetUp\n\tpot-set-hosts -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_002()\n{\n\tpot-set-hosts -H test-pot-2:10.1.2.3\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_003()\n{\n\tpot-set-hosts -p test-pot -H\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_020()\n{\n\tpot-set-hosts -p test-no-pot -H test-pot-2:10.1.2.3\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_021()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"2\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_022()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2:\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_023()\n{\n\tpot-set-hosts -p test-pot -H :10.1.2.3\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"0\" SETHOSTS_CALLS\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_040()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2:10.1.2.3\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"1\" SETHOSTS_CALLS\n\tassertEqualsMon \"_set_hosts arg1\" \"test-pot\" SETHOSTS_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '10.1.2.3 test-pot-2' \"$(sed '1!d' /tmp/pot-set-hosts)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_041()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2:10.1.2.3 -H test-pot-3:10.1.2.4\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"1\" SETHOSTS_CALLS\n\tassertEquals \"_tmpfile length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '10.1.2.3 test-pot-2' \"$(sed '1!d' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '10.1.2.4 test-pot-3' \"$(sed '2!d' /tmp/pot-set-hosts)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_042()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2:fe00::2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"1\" SETHOSTS_CALLS\n\tassertEqualsMon \"_set_hosts arg1\" \"test-pot\" SETHOSTS_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" 'fe00::2 test-pot-2' \"$(sed '1!d' /tmp/pot-set-hosts)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_043()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2:::1\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"1\" SETHOSTS_CALLS\n\tassertEqualsMon \"_set_hosts arg1\" \"test-pot\" SETHOSTS_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '::1 test-pot-2' \"$(sed '1!d' /tmp/pot-set-hosts)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\ntest_pot_set_hosts_044()\n{\n\tpot-set-hosts -p test-pot -H test-pot-2:10.1.2.3 -H test-pot-3:10.1.2.4 -H test-pot-4:::1 -H test-pot-5:fe00::2\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_hosts calls\" \"1\" SETHOSTS_CALLS\n\tassertEqualsMon \"_set_hosts arg1\" \"test-pot\" SETHOSTS_CALL1_ARG1\n\tassertEquals \"_tmpfile length\" \"4\" \"$( awk 'END {print NR}' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '10.1.2.3 test-pot-2' \"$(sed '1!d' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '10.1.2.4 test-pot-3' \"$(sed '2!d' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" '::1 test-pot-4' \"$(sed '3!d' /tmp/pot-set-hosts)\"\n\tassertEquals \"_tmpfile\" 'fe00::2 test-pot-5' \"$(sed '4!d' /tmp/pot-set-hosts)\"\n\tassertEqualsMon \"_rm calls\" \"1\" RM_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n\t/bin/rm -f /tmp/pot-set-hosts\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\t/bin/rm -f /tmp/pot-set-hosts\n}\n\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/set-rss1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/set-rss.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nset-rss-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_set_rss()\n{\n\t__monitor ADDRSS \"$@\"\n}\n\ntest_pot_set_rss_001()\n{\n\tpot-set-rss\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -bv\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n}\n\ntest_pot_set_rss_002()\n{\n\tpot-set-rss -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -C 1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -M 200M\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -M 200M -C 1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n}\n\ntest_pot_set_rss_003()\n{\n\tpot-set-rss -p test-pot -M 200Megabyte\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-pot -M 10000000T\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-pot -M 00M\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-pot -M 1.5G\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n}\n\ntest_pot_set_rss_020()\n{\n\tpot-set-rss -p test-no-pot -C 1\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-no-pot -M 200M\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-pot -M 200M -C 0\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"0\" ADDRSS_CALLS\n}\n\ntest_pot_set_rss_021()\n{\n\tpot-set-rss -p test-pot -M 200M\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"1\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-pot -C 1\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"1\" ADDRSS_CALLS\n\n\tsetUp\n\tpot-set-rss -p test-pot -C 2 -M 200M\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_set_rss calls\" \"2\" ADDRSS_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/show1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/show.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nshow-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_show_pot()\n{\n\t__monitor SHOWPOT \"$@\"\n}\n\n_show_all_pots()\n{\n\t__monitor SHOWALLPOTS \"$@\"\n}\n\n_show_running_pots()\n{\n\t__monitor SHOWRUNPOTS \"$@\"\n}\n\ntest_pot_show_001()\n{\n\tpot-show -k bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n\n\tsetUp\n\tpot-show -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_002()\n{\n\tpot-show -a -r\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_003()\n{\n\tpot-show -a -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_004()\n{\n\tpot-show -a -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_005()\n{\n\tpot-show -r -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_006()\n{\n\tpot-show -r -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_010()\n{\n\tpot-show -p test-no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_020()\n{\n\tpot-show\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"1\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_021()\n{\n\tpot-show -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"1\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_022()\n{\n\tpot-show -a\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"show_pot calls\" \"0\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_all_pots calls\" \"1\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\ntest_pot_show_023()\n{\n\tpot-show -p test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"show_pot calls\" \"1\" SHOWPOT_CALLS\n\tassertEqualsMon \"show_pot arg\" \"test-pot\" SHOWPOT_CALL1_ARG1\n\tassertEqualsMon \"show_all_pots calls\" \"0\" SHOWALLPOTS_CALLS\n\tassertEqualsMon \"show_running_pots calls\" \"0\" SHOWRUNPOTS_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/shunit/.gitignore",
    "content": "# Hidden files generated by macOS.\n.DS_Store\n._*\n"
  },
  {
    "path": "tests/shunit/.travis.yml",
    "content": "language: bash\n\nenv:\n  - SHUNIT_COLOR='always'\n\nscript:\n  # Execute the unit tests.\n  - ./test_runner\n\nos:\n  - linux\n  - osx\n\naddons:\n  apt:\n    packages:\n      - ksh\n      - zsh\n\nmatrix:\n  include:\n    - os: linux\n      script:\n        # Run the source through ShellCheck (http://www.shellcheck.net).\n        - shellcheck shunit2 *_test.sh\n        - shellcheck -s sh shunit2_test_helpers\n    - os: linux\n      # Support Ubuntu Trusty through Apr 2019.\n      dist: trusty\n"
  },
  {
    "path": "tests/shunit/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at kate.ward@forestent.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "tests/shunit/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "tests/shunit/README.md",
    "content": "# shUnit2\n\nshUnit2 is a [xUnit](http://en.wikipedia.org/wiki/XUnit) unit test framework for\nBourne based shell scripts, and it is designed to work in a similar manner to\n[JUnit](http://www.junit.org), [PyUnit](http://pyunit.sourceforge.net), etc.. If\nyou have ever had the desire to write a unit test for a shell script, shUnit2\ncan do the job.\n\n[![Travis CI](https://img.shields.io/travis/kward/shunit2.svg)](https://travis-ci.org/kward/shunit2)\n\n## Table of Contents\n\n* [Introduction](#introduction)\n  * [Credits / Contributors](#credits-contributors)\n  * [Feedback](#feedback)\n* [Quickstart](#quickstart)\n* [Function Reference](#function-reference)\n  * [General Info](#general-info)\n  * [Asserts](#asserts)\n  * [Failures](#failures)\n  * [Setup/Teardown](#setup-teardown)\n  * [Skipping](#skipping)\n  * [Suites](#suites)\n* [Advanced Usage](#advanced-usage)\n  * [Some constants you can use](#some-constants-you-can-use)\n  * [Error Handling](#error-handling)\n  * [Including Line Numbers in Asserts (Macros)](#including-line-numbers-in-asserts-macros)\n  * [Test Skipping](#test-skipping)\n  * [Running specific tests from the command line](#cmd-line-args)\n* [Appendix](#appendix)\n  * [Getting help](#getting-help)\n  * [Zsh](#zsh)\n\n---\n\n## <a name=\"introduction\"></a> Introduction\n\nshUnit2 was originally developed to provide a consistent testing solution for\n[log4sh][log4sh], a shell based logging framework similar to\n[log4j](http://logging.apache.org). During the development of that product, a\nrepeated problem of having things work just fine under one shell (`/bin/bash` on\nLinux to be specific), and then not working under another shell (`/bin/sh` on\nSolaris) kept coming up. Although several simple tests were run, they were not\nadequate and did not catch some corner cases. The decision was finally made to\nwrite a proper unit test framework after multiple brown-bag releases were made.\n_Research was done to look for an existing product that met the testing\nrequirements, but no adequate product was found._\n\n### Tested software\n\n**Tested Operating Systems** (varies over time)\n\nOS                                  | Support   | Verified\n----------------------------------- | --------- | --------\nUbuntu Linux (14.04.05 LTS)         | Travis CI | continuous\nmacOS High Sierra (10.13.3)         | Travis CI | continuous\nFreeBSD                             | user      | unknown\nSolaris 8, 9, 10 (inc. OpenSolaris) | user      | unknown\nCygwin                              | user      | unknown\n\n**Tested Shells**\n\n* Bourne Shell (__sh__)\n* BASH - GNU Bourne Again SHell (__bash__)\n* DASH (__dash__)\n* Korn Shell (__ksh__)\n* pdksh - Public Domain Korn Shell (__pdksh__)\n* zsh - Zsh (__zsh__) (since 2.1.2) _please see the Zsh shell errata for more information_\n\nSee the appropriate Release Notes for this release\n(`doc/RELEASE_NOTES-X.X.X.txt`) for the list of actual versions tested.\n\n### <a name=\"credits-contributors\"></a> Credits / Contributors\n\nA list of contributors to shUnit2 can be found in `doc/contributors.md`. Many\nthanks go out to all those who have contributed to make this a better tool.\n\nshUnit2 is the original product of many hours of work by Kate Ward, the primary\nauthor of the code. For related software, check out https://github.com/kward.\n\n### <a name=\"feedback\"></a> Feedback\n\nFeedback is most certainly welcome for this document. Send your questions,\ncomments, and criticisms via the\n[shunit2-users](https://groups.google.com/a/forestent.com/forum/#!forum/shunit2-users/new)\nforum (created 2018-12-09), or file an issue via\nhttps://github.com/kward/shunit2/issues.\n\n---\n\n## <a name=\"quickstart\"></a> Quickstart\n\nThis section will give a very quick start to running unit tests with shUnit2.\nMore information is located in later sections.\n\nHere is a quick sample script to show how easy it is to write a unit test in\nshell. _Note: the script as it stands expects that you are running it from the\n\"examples\" directory._\n\n```sh\n#! /bin/sh\n# file: examples/equality_test.sh\n\ntestEquality() {\n  assertEquals 1 1\n}\n\n# Load shUnit2.\n. ./shunit2\n```\n\nRunning the unit test should give results similar to the following.\n\n```console\n$ cd examples\n$ ./equality_test.sh\ntestEquality\n\nRan 1 test.\n\nOK\n```\n\nW00t! You've just run your first successful unit test. So, what just happened?\nQuite a bit really, and it all happened simply by sourcing the `shunit2`\nlibrary. The basic functionality for the script above goes like this:\n\n* When shUnit2 is sourced, it will walk through any functions defined whose name\n  starts with the string `test`, and add those to an internal list of tests to\n  execute. Once a list of test functions to be run has been determined, shunit2\n  will go to work.\n* Before any tests are executed, shUnit2 again looks for a function, this time\n  one named `oneTimeSetUp()`. If it exists, it will be run. This function is\n  normally used to setup the environment for all tests to be run. Things like\n  creating directories for output or setting environment variables are good to\n  place here. Just so you know, you can also declare a corresponding function\n  named `oneTimeTearDown()` function that does the same thing, but once all the\n  tests have been completed. It is good for removing temporary directories, etc.\n* shUnit2 is now ready to run tests. Before doing so though, it again looks for\n  another function that might be declared, one named `setUp()`. If the function\n  exists, it will be run before each test. It is good for resetting the\n  environment so that each test starts with a clean slate. **At this stage, the\n  first test is finally run.** The success of the test is recorded for a report\n  that will be generated later. After the test is run, shUnit2 looks for a final\n  function that might be declared, one named `tearDown()`. If it exists, it will\n  be run after each test. It is a good place for cleaning up after each test,\n  maybe doing things like removing files that were created, or removing\n  directories. This set of steps, `setUp() > test() > tearDown()`, is repeated\n  for all of the available tests.\n* Once all the work is done, shUnit2 will generate the nice report you saw\n  above. A summary of all the successes and failures will be given so that you\n  know how well your code is doing.\n\nWe should now try adding a test that fails. Change your unit test to look like\nthis.\n\n```sh\n#! /bin/sh\n# file: examples/party_test.sh\n\ntestEquality() {\n  assertEquals 1 1\n}\n\ntestPartyLikeItIs1999() {\n  year=`date '+%Y'`\n  assertEquals \"It's not 1999 :-(\" '1999' \"${year}\"\n}\n\n# Load shUnit2.\n. ./shunit2\n```\n\nSo, what did you get? I guess it told you that this isn't 1999. Bummer, eh?\nHopefully, you noticed a couple of things that were different about the second\ntest. First, we added an optional message that the user will see if the assert\nfails. Second, we did comparisons of strings instead of integers as in the first\ntest. It doesn't matter whether you are testing for equality of strings or\nintegers. Both work equally well with shUnit2.\n\nHopefully, this is enough to get you started with unit testing. If you want a\nton more examples, take a look at the tests provided with [log4sh][log4sh] or\n[shFlags][shflags]. Both provide excellent examples of more advanced usage.\nshUnit2 was after all written to meet the unit testing need that\n[log4sh][log4sh] had.\n\n---\n\n## <a name=\"function-reference\"></a> Function Reference\n\n### <a name=\"general-info\"></a> General Info\n\nAny string values passed should be properly quoted -- they should must be\nsurrounded by single-quote (`'`) or double-quote (`\"`) characters -- so that the\nshell will properly parse them.\n\n### <a name=\"asserts\"></a> Asserts\n\n`assertEquals [message] expected actual`\n\nAsserts that _expected_ and _actual_ are equal to one another. The _expected_\nand _actual_ values can be either strings or integer values as both will be\ntreated as strings. The _message_ is optional, and must be quoted.\n\n`assertNotEquals [message] unexpected actual`\n\nAsserts that _unexpected_ and _actual_ are not equal to one another. The\n_unexpected_ and _actual_ values can be either strings or integer values as both\nwill be treaded as strings. The _message_ is optional, and must be quoted.\n\n`assertSame [message] expected actual`\n\nThis function is functionally equivalent to `assertEquals`.\n\n`assertNotSame [message] unexpected actual`\n\nThis function is functionally equivalent to `assertNotEquals`.\n\n`assertContains [message] container content`\n\nAsserts that _container_ contains _content_. The _container_ and _content_\nvalues can be either strings or integer values as both will be treated as\nstrings. The _message_ is optional, and must be quoted.\n\n`assertNotContains [message] container content`\n\nAsserts that _container_ does not contain _content_. The _container_ and\n_content_ values can be either strings or integer values as both will be treaded\nas strings. The _message_ is optional, and must be quoted.\n\n`assertNull [message] value`\n\nAsserts that _value_ is _null_, or in shell terms, a zero-length string. The\n_value_ must be a string as an integer value does not translate into a zero-\nlength string. The _message_ is optional, and must be quoted.\n\n`assertNotNull [message] value`\n\nAsserts that _value_ is _not null_, or in shell terms, a non-empty string. The\n_value_ may be a string or an integer as the later will be parsed as a non-empty\nstring value. The _message_ is optional, and must be quoted.\n\n`assertTrue [message] condition`\n\nAsserts that a given shell test _condition_ is _true_. The condition can be as\nsimple as a shell _true_ value (the value `0` -- equivalent to\n`${SHUNIT_TRUE}`), or a more sophisticated shell conditional expression. The\n_message_ is optional, and must be quoted.\n\nA sophisticated shell conditional expression is equivalent to what the __if__ or\n__while__ shell built-ins would use (more specifically, what the __test__\ncommand would use). Testing for example whether some value is greater than\nanother value can be done this way.\n\n`assertTrue \"[ 34 -gt 23 ]\"`\n\nTesting for the ability to read a file can also be done. This particular test\nwill fail.\n\n`assertTrue 'test failed' \"[ -r /some/non-existant/file' ]\"`\n\nAs the expressions are standard shell __test__ expressions, it is possible to\nstring multiple expressions together with `-a` and `-o` in the standard fashion.\nThis test will succeed as the entire expression evaluates to _true_.\n\n`assertTrue 'test failed' '[ 1 -eq 1 -a 2 -eq 2 ]'`\n\n<i>One word of warning: be very careful with your quoting as shell is not the\nmost forgiving of bad quoting, and things will fail in strange ways.</i>\n\n`assertFalse [message] condition`\n\nAsserts that a given shell test _condition_ is _false_. The condition can be as\nsimple as a shell _false_ value (the value `1` -- equivalent to\n`${SHUNIT_FALSE}`), or a more sophisticated shell conditional expression. The\n_message_ is optional, and must be quoted.\n\n_For examples of more sophisticated expressions, see `assertTrue`._\n\n### <a name=\"failures\"></a> Failures\n\nJust to clarify, failures __do not__ test the various arguments against one\nanother. Failures simply fail, optionally with a message, and that is all they\ndo. If you need to test arguments against one another, use asserts.\n\nIf all failures do is fail, why might one use them? There are times when you may\nhave some very complicated logic that you need to test, and the simple asserts\nprovided are simply not adequate. You can do your own validation of the code,\nuse an `assertTrue ${SHUNIT_TRUE}` if your own tests succeeded, and use a\nfailure to record a failure.\n\n`fail [message]`\n\nFails the test immediately. The _message_ is optional, and must be quoted.\n\n`failNotEquals [message] unexpected actual`\n\nFails the test immediately, reporting that the _unexpected_ and _actual_ values\nare not equal to one another. The _message_ is optional, and must be quoted.\n\n_Note: no actual comparison of unexpected and actual is done._\n\n`failSame [message] expected actual`\n\nFails the test immediately, reporting that the _expected_ and _actual_ values\nare the same. The _message_ is optional, and must be quoted.\n\n_Note: no actual comparison of expected and actual is done._\n\n`failNotSame [message] expected actual`\n\nFails the test immediately, reporting that the _expected_ and _actual_ values\nare not the same. The _message_ is optional, and must be quoted.\n\n_Note: no actual comparison of expected and actual is done._\n\n`failFound [message] content`\n\nFails the test immediately, reporting that the _content_ was found. The\n_message_ is optional, and must be quoted.\n\n_Note: no actual search of content is done._\n\n`failNotFound [message] content`\n\nFails the test immediately, reporting that the _content_ was not found. The\n_message_ is optional, and must be quoted.\n\n_Note: no actual search of content is done._\n\n### <a name=\"setup-teardown\"></a> Setup/Teardown\n\n`oneTimeSetUp`\n\nThis function can be be optionally overridden by the user in their test suite.\n\nIf this function exists, it will be called once before any tests are run. It is\nuseful to prepare a common environment for all tests.\n\n`oneTimeTearDown`\n\nThis function can be be optionally overridden by the user in their test suite.\n\nIf this function exists, it will be called once after all tests are completed.\nIt is useful to clean up the environment after all tests.\n\n`setUp`\n\nThis function can be be optionally overridden by the user in their test suite.\n\nIf this function exists, it will be called before each test is run. It is useful\nto reset the environment before each test.\n\n`tearDown`\n\nThis function can be be optionally overridden by the user in their test suite.\n\nIf this function exists, it will be called after each test completes. It is\nuseful to clean up the environment after each test.\n\n### <a name=\"skipping\"></a> Skipping\n\n`startSkipping`\n\nThis function forces the remaining _assert_ and _fail_ functions to be\n\"skipped\", i.e. they will have no effect. Each function skipped will be recorded\nso that the total of asserts and fails will not be altered.\n\n`endSkipping`\n\nThis function returns calls to the _assert_ and _fail_ functions to their\ndefault behavior, i.e. they will be called.\n\n`isSkipping`\n\nThis function returns the current state of skipping. It can be compared against\n`${SHUNIT_TRUE}` or `${SHUNIT_FALSE}` if desired.\n\n### <a name=\"suites\"></a> Suites\n\nThe default behavior of shUnit2 is that all tests will be found dynamically. If\nyou have a specific set of tests you want to run, or you don't want to use the\nstandard naming scheme of prefixing your tests with `test`, these functions are\nfor you. Most users will never use them though.\n\n`suite`\n\nThis function can be optionally overridden by the user in their test suite.\n\nIf this function exists, it will be called when `shunit2` is sourced. If it does\nnot exist, shUnit2 will search the parent script for all functions beginning\nwith the word `test`, and they will be added dynamically to the test suite.\n\n`suite_addTest name`\n\nThis function adds a function named _name_ to the list of tests scheduled for\nexecution as part of this test suite. This function should only be called from\nwithin the `suite()` function.\n\n---\n\n## <a name=\"advanced-usage\"></a> Advanced Usage\n\n### <a name=\"some-constants-you-can-use\"></a> Some constants you can use\n\nThere are several constants provided by shUnit2 as variables that might be of\nuse to you.\n\n*Predefined*\n\n| Constant        | Value |\n| --------------- | ----- |\n| SHUNIT\\_TRUE    | Standard shell `true` value (the integer value 0). |\n| SHUNIT\\_FALSE   | Standard shell `false` value (the integer value 1). |\n| SHUNIT\\_ERROR   | The integer value 2. |\n| SHUNIT\\_TMPDIR  | Path to temporary directory that will be automatically cleaned up upon exit of shUnit2. |\n| SHUNIT\\_VERSION | The version of shUnit2 you are running. |\n\n*User defined*\n\n| Constant          | Value |\n| ----------------- | ----- |\n| SHUNIT\\_CMD\\_EXPR | Override which `expr` command is used. By default `expr` is used, except on BSD systems where `gexpr` is used. |\n| SHUNIT\\_COLOR     | Enable colorized output. Options are 'auto', 'always', or 'none', with 'auto' being the default. |\n| SHUNIT\\_PARENT    | The filename of the shell script containing the tests. This is needed specifically for Zsh support. |\n| SHUNIT\\_TEST\\_PREFIX | Define this variable to add a prefix in front of each test name that is output in the test report. |\n\n### <a name=\"error-handling\"></a> Error handling\n\nThe constants values `SHUNIT_TRUE`, `SHUNIT_FALSE`, and `SHUNIT_ERROR` are\nreturned from nearly every function to indicate the success or failure of the\nfunction. Additionally the variable `flags_error` is filled with a detailed\nerror message if any function returns with a `SHUNIT_ERROR` value.\n\n### <a name=\"including-line-numbers-in-asserts-macros\"></a> Including Line Numbers in Asserts (Macros)\n\nIf you include lots of assert statements in an individual test function, it can\nbecome difficult to determine exactly which assert was thrown unless your\nmessages are unique. To help somewhat, line numbers can be included in the\nassert messages. To enable this, a special shell \"macro\" must be used rather\nthan the standard assert calls. _Shell doesn't actually have macros; the name is\nused here as the operation is similar to a standard macro._\n\nFor example, to include line numbers for a `assertEquals()` function call,\nreplace the `assertEquals()` with `${_ASSERT_EQUALS_}`.\n\n_**Example** -- Asserts with and without line numbers_\n\n```sh\n#! /bin/sh\n# file: examples/lineno_test.sh\n\ntestLineNo() {\n  # This assert will have line numbers included (e.g. \"ASSERT:[123] ...\").\n  echo \"ae: ${_ASSERT_EQUALS_}\"\n  ${_ASSERT_EQUALS_} 'not equal' 1 2\n\n  # This assert will not have line numbers included (e.g. \"ASSERT: ...\").\n  assertEquals 'not equal' 1 2\n}\n\n# Load shUnit2.\n. ./shunit2\n```\n\nNotes:\n\n1. Due to how shell parses command-line arguments, all strings used with macros\n   should be quoted twice. Namely, single-quotes must be converted to single-\n   double-quotes, and vice-versa. If the string being passed is absolutely for\n   sure not empty, the extra quoting is not necessary.<br/>\n   <br/>\n   Normal `assertEquals` call.<br/>\n   `assertEquals 'some message' 'x' ''`<br/>\n   <br/>\n   Macro `_ASSERT_EQUALS_` call. Note the extra quoting around the _message_ and\n   the _null_ value.<br/>\n   `_ASSERT_EQUALS_ '\"some message\"' 'x' '\"\"'`\n\n1. Line numbers are not supported in all shells. If a shell does not support\n   them, no errors will be thrown. Supported shells include: __bash__ (>=3.0),\n   __ksh__, __pdksh__, and __zsh__.\n\n### <a name=\"test-skipping\"></a> Test Skipping\n\nThere are times where the test code you have written is just not applicable to\nthe system you are running on. This section describes how to skip these tests\nbut maintain the total test count.\n\nProbably the easiest example would be shell code that is meant to run under the\n__bash__ shell, but the unit test is running under the Bourne shell. There are\nthings that just won't work. The following test code demonstrates two sample\nfunctions, one that will be run under any shell, and the another that will run\nonly under the __bash__ shell.\n\n_**Example** -- math include_\n```sh\n# file: examples/math.inc.\n\nadd_generic() {\n  num_a=$1\n  num_b=$2\n\n  expr $1 + $2\n}\n\nadd_bash() {\n  num_a=$1\n  num_b=$2\n\n  echo $(($1 + $2))\n}\n```\n\nAnd here is a corresponding unit test that correctly skips the `add_bash()` function when the unit test is not running under the __bash__ shell.\n\n_**Example** -- math unit test_\n```sh\n#! /bin/sh\n# file: examples/math_test.sh\n\ntestAdding() {\n  result=`add_generic 1 2`\n  assertEquals \\\n      \"the result of '${result}' was wrong\" \\\n      3 \"${result}\"\n\n  # Disable non-generic tests.\n  [ -z \"${BASH_VERSION:-}\" ] && startSkipping\n\n  result=`add_bash 1 2`\n  assertEquals \\\n      \"the result of '${result}' was wrong\" \\\n      3 \"${result}\"\n}\n\noneTimeSetUp() {\n  # Load include to test.\n  . ./math.inc\n}\n\n# Load and run shUnit2.\n. ./shunit2\n```\n\nRunning the above test under the __bash__ shell will result in the following\noutput.\n\n```console\n$ /bin/bash math_test.sh\ntestAdding\n\nRan 1 test.\n\nOK\n```\n\nBut, running the test under any other Unix shell will result in the following\noutput.\n\n```console\n$ /bin/ksh math_test.sh\ntestAdding\n\nRan 1 test.\n\nOK (skipped=1)\n```\n\nAs you can see, the total number of tests has not changed, but the report\nindicates that some tests were skipped.\n\nSkipping can be controlled with the following functions: `startSkipping()`,\n`endSkipping()`, and `isSkipping()`. Once skipping is enabled, it will remain\nenabled until the end of the current test function call, after which skipping is\ndisabled.\n\n### <a name=\"cmd-line-args\"></a> Running specific tests from the command line.\n\nWhen running a test script, you may override the default set of tests, or the suite-specified set of tests, by providing additional arguments on the command line.  Each additional argument after the `--` marker is assumed to be the name of a test function to be run in the order specified.  e.g.\n\n```console\ntest-script.sh -- testOne testTwo otherFunction\n```\n\nor\n\n```console\nshunit2 test-script.sh testOne testTwo otherFunction\n```\n\nIn either case, three functions will be run as tests, `testOne`, `testTwo`, and `otherFunction`.  Note that the function `otherFunction` would not normally be run by `shunit2` as part of the implicit collection of tests as it's function name does not match the test function name pattern `test*`.\n\nIf a specified test function does not exist, `shunit2` will still attempt to run that function and thereby cause a failure which `shunit2` will catch and mark as a failed test.  All other tests will run normally.\n\nThe specification of tests does not affect how `shunit2` looks for and executes the setup and tear down functions, which will still run as expected.\n\n---\n\n## <a name=\"appendix\"></a> Appendix\n\n### <a name=\"getting-help\"></a> Getting Help\n\nFor help, please send requests to either the shunit2-users@forestent.com mailing\nlist (archives available on the web at\nhttps://groups.google.com/a/forestent.com/forum/#!forum/shunit2-users) or\ndirectly to Kate Ward <kate dot ward at forestent dot com>.\n\n### <a name=\"zsh\"></a> Zsh\n\nFor compatibility with Zsh, there is one requirement that must be met -- the\n`shwordsplit` option must be set. There are three ways to accomplish this.\n\n1. In the unit-test script, add the following shell code snippet before sourcing\n   the `shunit2` library.\n\n   ```sh\n   setopt shwordsplit\n   ```\n\n2. When invoking __zsh__ from either the command-line or as a script with `#!`,\n   add the `-y` parameter.\n\n    ```sh\n    #! /bin/zsh -y\n    ```\n\n3. When invoking __zsh__ from the command-line, add `-o shwordsplit --` as\n   parameters before the script name.\n\n   ```console\n   $ zsh -o shwordsplit -- some_script\n   ```\n\n[log4sh]: https://github.com/kward/log4sh\n[shflags]: https://github.com/kward/shflags\n"
  },
  {
    "path": "tests/shunit/doc/CHANGES-2.1.md",
    "content": "# shUnit2 2.1.x Changes\n\n## Changes with 2.1.8\n\n### New\n\nIssue #29. Add support for user defined prefix for test names. A prefix can be\nadded by defining the `SHUNIT_TEST_PREFIX` variable.\n\n### Improvements\n\nIssue #78. Added an example for using suite tests.\n\nRun continuous integration additionally against Ubuntu Trusty.\n\n### Fixed\n\nIssue #94. Removed the `gen_test_report.sh` script as the Travis CI output can\nbe used instead. Reports were used before Travis CI was used.\n\nIssue #84. Treat syntax errors in functions as test failures.\n\nIssue #77. Fail tests when the environment functions (e.g. `setup()` or\n`tearDown()`) fail.\n\n\n## Changes with 2.1.7\n\n### Bug fixes\n\nIssue #69. shUnit2 should not exit with 0 when it has (syntax) errors.\n\n### Enhancements\n\nIssue #54. Shell commands prefixed with '\\' so that they can be stubbed in\ntests.\n\nIssue #68. Ran all code through [ShellCheck](http://www.shellcheck.net/).\n\nIssue #60. Continuous integration tests now run with\n[Travis CI](https://travis-ci.org/kward/shunit2).\n\nIssue #56. Added color support. Color is enabled automatically when supported,\nbut can be disabled by defining the SHUNIT_COLOR environment variable before\nsourcing shunit2. Accepted values are `always`, `auto` (the default), and\n`none`.\n\nIssue #35. Add colored output.\n\n### Other\n\nMoved code to GitHub (https://github.com/kward/shunit2), and restructured to\nbe more GitHub like.\n\nChanged to the Apache 2.0 license.\n\n\n## Changes with 2.1.6\n\nRemoved all references to the DocBook documentation.\n\nSimplified the 'src' structure.\n\nFixed error message in fail() that stated wrong number of required arguments.\n\nUpdated lib/versions.\n\nFixed bug in `_shunit_mktempDir()` where a failure occurred when the 'od'\ncommand was not present in `/usr/bin`.\n\nRenamed `shunit_tmpDir` variable to `SHUNIT_TMPDIR` to closer match the standard\n`TMPDIR` variable.\n\nAdded support for calling shunit2 as an executable, in addition to the existing\nmethod of sourcing it in as a library. This allows users to keep tests working\ndespite the location of the shunit2 executable being different for each OS\ndistribution.\n\nIssue #14: Improved handling of some strange chars (e.g. single and double\nquotes) in messages.\n\nIssue# 27: Fixed error message for `assertSame()`.\n\nIssue# 25: Added check and error message to user when phantom functions are\nwritten to a partition mounted with `noexec`.\n\nIssue# 11: Added support for defining functions like `function someFunction()`.\n\n\n## Changes with 2.1.5\n\nIssue# 1: Fixed bug pointed out by R Bernstein in the trap code where certain\ntypes of exit conditions did not generate the ending report.\n\nIssue# 2: Added `assertNotEquals()` assert.\n\nIssue# 3: Moved check for unset variables out of shUnit2 into the unit tests.\nTesting poorly written software blows up if this check is in, but it is only\ninteresting for shUnit2 itself. Added `shunit_test_output.sh` unit test for\nthis. Some shells still do not catch such errors properly (e.g. Bourne shell and\nBASH 2.x).\n\nAdded new custom assert in test_helpers to check for output to STDOUT, and none\nto STDERR.\n\nReplaced fatal message in the temp directory creation with a `_shunit_fatal()`\nfunction call.\n\nFixed test_output unit test so it works now that the 'set -u' stuff was removed\nfor Issue# 3.\n\nFlushed out the coding standards in the `README.txt` a bit more, and brought the\nshunit2 code up to par with the documented standards.\n\nIssue# 4: Completely changed the reporting output to be a closer match for\nJUnit and PyUnit. As a result, tests are counted separately from assertions.\n\nProvide public `shunit_tmpDir` variable that can be used by unit test scripts\nthat need automated and guaranteed cleanup.\n\nIssue# 7: Fixed duplicated printing of messages passed to asserts.\n\nPer code review, fixed wording of `failSame()` and `failNotSame()` messages.\n\nReplaced `version_info.sh` with versions library and made appropriate changes in\nother scripts to use it.\n\nAdded `gen_test_results.sh` to make releases easier.\n\nFixed bugs in `shlib_relToAbsPath()` in shlib.\n\nConverted DocBook documentation to reStructuredText for easier maintenance. The\nDocBook documentation is now considered obsolete, and will be removed in a\nfuture release.\n\nIssue# 5: Fixed the documentation around the usage of failures.\n\nIssue# 9: Added unit tests and updated documentation to demonstrate the\nrequirement of quoting values twice when macros are used. This is due to how\nshell parses arguments.\n\nWhen an invalid number of arguments is passed to a function, the invalid number\nis returned to the user so they are more aware of what the cause might be.\n\n\n## Changes with 2.1.4\n\nRemoved the `_shunit_functionExists()` function as it was dead code.\n\nFixed zsh version number check in version_info.\n\nFixed bug in last resort temporary directory creation.\n\nFixed off-by-one in exit value for scripts caught by the trap handler.\n\nAdded argument count error checking to all functions.\n\nAdded mkdir_test.sh example.\n\nMoved src/test into src/shell to better match structure used with shFlags.\n\nFixed problem where null values were not handled properly under ksh.\n\nAdded support for outputting line numbers as part of assert messages.\n\nStarted documenting the coding standards, and changed some variable names as a\nresult.\n\nImproved zsh version and option checks.\n\nRenamed the `__SHUNIT_VERSION` variable to `SHUNIT_VERSION`.\n\n\n## Changes with 2.1.3\n\nAdded some explicit variable defaults, even though the variables are set, as\nthey sometimes behave strange when the script is canceled.\n\nAdditional workarounds for zsh compatibility.\n\nshUnit2 now exits with a non-zero exit code if any of the tests failed. This was\ndone for automated testing frameworks. Tests that were skipped are not\nconsidered failures, and do not affect the exit code.\n\nChanged detection of STDERR output in unit tests.\n\n\n## Changes with 2.1.2\n\nUnset additional variables that were missed.\n\nAdded checks and workarounds to improve zsh compatibility.\n\nAdded some argument count checks `assertEquals()`, `assertNull()`, and\n`assertSame()`.\n\n\n## Changes with 2.1.1\n\nFixed bug where `fail()` was not honoring skipping.\n\nFixed problem with `docs-docbook-prep` target that prevented it from working.\n(Thanks to Bryan Larsen for pointing this out.)\n\nChanged the test in `assertFalse()` so that any non-zero value registers as\nfalse. (Credits to Bryan Larsen)\n\nMajor fiddling to bring more in line with [JUnit](http://junit.org/). Asserts\ngive better output when no message is given, and failures now just fail.\n\nIt was pointed out that the simple 'failed' message for a failed assert was not\nonly insufficient, it was nonstandard (when compared to JUnit) and didn't\nprovide the user with an expected vs actual result. The code was revised\nsomewhat to bring closer into alignment with JUnit (v4.3.1 specifically) so\nthat it feels more \"normal\". (Credits to Richard Jensen)\n\nAs part of the JUnit realignment, it was noticed that `fail*()` functions in\nJUnit don't actually do any comparisons themselves. They only generate a\nfailure message. Updated the code to match.\n\nAdded self-testing unit tests. Kinda horkey, but they did find bugs during the\nJUnit realignment.\n\nFixed the code for returning from asserts as the return was being called before\nthe unsetting of variables occurred. (Credits to Mathias Goldau)\n\nThe assert(True|False)() functions now accept an integer value for a\nconditional test. A value of '0' is considered 'true', while any non-zero value\nis considered 'false'.\n\nAll public functions now fill use default values to work properly with the '-x'\nshell debugging flag.\n\nFixed the method of percent calculation for the report to get achieve better\naccuracy.\n\n\n## Changes with 2.1.0 (since 2.0.1)\n\nThis release is a branch of the 2.0.1 release.\n\nMoving to [reStructured Text](http://docutils.sourceforge.net/rst.html) for\nthe documentation.\n\nFixed problem with `fail()`. The failure message was not properly printed.\n\nFixed the `Makefile` so that the DocBook XML and XSLT files would be\ndownloaded before parsing can continue.\n\nRenamed the internal `__SHUNIT_TRUE` and `__SHUNIT_FALSE` variables to\n`SHUNIT_TRUE` and `SHUNIT_FALSE` so that unit tests can \"use\" them.\n\nAdded support for test \"skipping\". If skipping is turned on with the\n`startSkip()` function, `assert` and `fail` functions will return immediately,\nand the skip will be recorded.\n\nThe report output format was changed to include the percentage for each test\nresult, rather than just those successful.\n\n\n[travis_ci]: https://travis-ci.org/kward/shunit2\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.0.txt",
    "content": "Release Notes for shUnit2 2.1.0\n===============================\n\nThis release was branched from shUnit2 2.0.1. It mostly adds new functionality,\nbut there are couple of bugs fixed from the previous release.\n\nSee the ``CHANGES-2.1.rst`` file for a full list of changes.\n\n\nTested Platforms\n----------------\n\nThis list of platforms comes from the latest version of log4sh as shUnit2 is\nused in the testing of log4sh on each of these platforms.\n\nCygwin\n\n- bash 3.2.9(10)\n- pdksh 5.2.14\n\nLinux\n\n- bash 3.1.17(1), 3.2.10(1)\n- dash 0.5.3\n- ksh 1993-12-28\n- pdksh 5.2.14\n- zsh 4.3.2 (does not work)\n\nMac OS X 10.4.8 (Darwin 8.8)\n\n- bash 2.05b.0(1)\n- ksh 1993-12-28\n\nSolaris 8 U3 (x86)\n\n- /bin/sh\n- bash 2.03.0(1)\n- ksh M-11/16/88i\n\nSolaris 10 U2 (sparc)\n\n- /bin/sh\n- bash 3.00.16(1)\n- ksh M-11/16/88i\n\nSolaris 10 U2 (x86)\n\n- /bin/sh\n- bash 3.00.16(1)\n- ksh M-11/16/88i\n\n\nNew Features\n------------\n\nTest skipping\n\n  Support added for test \"skipping\". A skip mode can be enabled so that\n  subsequent ``assert`` and ``fail`` functions that are called will be recorded\n  as \"skipped\" rather than as \"passed\" or \"failed\". This functionality can be\n  used such that when a set of tests makes sense on one platform but not on\n  another, they can be effectively disabled without altering the total number\n  of tests.\n\n  One example might be when something is supported under ``bash``, but not\n  under a standard Bourne shell.\n\n  New functions: ``startSkipping()``, ``endSkipping``, ``isSkipping``\n\n\nChanges and Enhancements\n------------------------\n\nMoving to the use of `reStructured Text\n<http://docutils.sourceforge.net/rst.html>`_ for documentation. It is easy to\nread and edit in textual form, but converts nicely to HTML.\n\nThe report format has changed. Rather than including a simple \"success\"\npercentage at the end, a percentage is given for each type of test.\n\n\nBug Fixes\n---------\n\nThe ``fail()`` function did not output the optional failure message.\n\nFixed the ``Makefile`` so that the DocBook XML and XSLT files would be\ndownloaded before documentation parsing will continue.\n\n\nDeprecated Features\n-------------------\n\nNone.\n\n\nKnown Bugs and Issues\n---------------------\n\nNone.\n\n\n.. $Revision$\n.. vim:fileencoding=latin1:spell:syntax=rst:textwidth=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.1.txt",
    "content": "Release Notes for shUnit2 2.1.1\n===============================\n\nThis is mainly a bug fix release, but it also incorporates a realignment with\nthe JUnit 4 code. Asserts now provide better failure messages, and the failure\nfunctions no longer perform tests.\n\nSee the ``CHANGES-2.1.txt`` file for a full list of changes.\n\n\nTested Platforms\n----------------\n\nThis list of platforms comes from the latest version of log4sh as shUnit2 is\nused in the testing of log4sh on each of these platforms.\n\nCygwin\n\n- bash 3.2.15(13)\n- pdksh 5.2.14\n\nLinux\n\n- bash 3.1.17(1), 3.2.10(1)\n- dash 0.5.3\n- ksh 1993-12-28\n- pdksh 5.2.14\n- zsh 4.3.2 (does not work)\n\nMac OS X 10.4.9 (Darwin 8.9.1)\n\n- bash 2.05b.0(1)\n- ksh 1993-12-28\n\nSolaris 8 U3 (x86)\n\n- /bin/sh\n- bash 2.03.0(1)\n- ksh M-11/16/88i\n\nSolaris 10 U2 (sparc, x86)\n\n- /bin/sh\n- bash 3.00.16(1)\n- ksh M-11/16/88i\n\n\nNew Features\n------------\n\nNone.\n\n\nChanges and Enhancements\n------------------------\n\nThe internal test in ``assertFalse()`` now accepts any non-zero value as false.\n\nThe ``assertTrue()`` and ``assertFalse()`` functions now accept an integer value\nfor a conditional test. A value of '0' is considered 'true', while any non-zero\nvalue is considered 'false'.\n\nSelf-testing unit tests were added.\n\n\nBug Fixes\n---------\n\nThe ``fail()`` assert now honors skipping.\n\nThe ``docs-docbook-prep`` target now works properly.\n\nAll asserts now properly unset their variables.\n\n\nDeprecated Features\n-------------------\n\nNone.\n\n\nKnown Bugs and Issues\n---------------------\n\nFunctions do not properly test for an invalid number of arguments.\n\n\n.. vim:fileencoding=latin1:ft=rst:spell:textwidth=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.2.txt",
    "content": "Release Notes for shUnit2 2.1.2\n===============================\n\nThis release adds initial support for the zsh shell. Due to some differences\nwith this shell as compared with others, some special checks have been added,\nand there are some extra requirements necessary when this shell is to be used.\n\nTo use zsh with shUnit2, the following two requirements must be met:\n* The ``shwordsplit`` option must be set.\n* The ``function_argzero`` option must be unset.\n\nPlease read the Shell Errata section of the documentation for guidance on how\nto meet these requirements.\n\n\nSee the ``CHANGES-2.1.txt`` file for a full list of changes.\n\n\nTested Platforms\n----------------\n\nThis list of platforms comes from the latest version of log4sh as shUnit2 is\nused in the testing of log4sh on each of these platforms.\n\nLinux\n\n- bash 3.1.17(1), 3.2.25(1)\n- dash 0.5.4\n- ksh 1993-12-28\n- pdksh 5.2.14\n- zsh 4.2.5, 4.3.4\n\nMac OS X 10.4.11 (Darwin 8.11.1)\n\n- bash 2.05b.0(1)\n- ksh 1993-12-28\n- zsh 4.2.3\n\nSolaris 10 U3 (x86)\n\n- /bin/sh\n- bash 3.00.16(1)\n- ksh M-11/16/88i\n- zsh 4.2.1\n\n\nNew Features\n------------\n\nSupport for the zsh shell.\n\n\nChanges and Enhancements\n------------------------\n\nAdded some argument count checks.\n\n\nBug Fixes\n---------\n\nNone.\n\n\nDeprecated Features\n-------------------\n\nNone.\n\n\nKnown Bugs and Issues\n---------------------\n\nFunctions do not properly test for an invalid number of arguments.\n\nksh and pdksh do not pass null arguments (i.e. empty strings as '') properly,\nand as such checks do not work properly.\n\nzsh requires the ``shwordsplit`` option to be set, and the ``function_argzero``\noption to be unset for proper operation.\n\n\n.. vim:fileencoding=latin1:ft=rst:spell:textwidth=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.3.txt",
    "content": "Release Notes for shUnit2 2.1.3\n===============================\n\nThis release is minor feature release. It improves support for zsh (although it\nstill isn't what it could be) and adds automated testing framework support by\nreturning a non-zero exit when tests fail.\n\nTo use zsh with shUnit2, the following two requirements must be met:\n* The ``shwordsplit`` option must be set.\n* The ``function_argzero`` option must be unset.\n\nPlease read the Shell Errata section of the documentation for guidance on how\nto meet these requirements.\n\nSee the ``CHANGES-2.1.txt`` file for a full list of changes.\n\n\nTested Platforms\n----------------\n\nCygwin\n\n- bash 3.2.33(18)\n- pdksh 5.2.14\n\nLinux\n\n- bash 3.2.33(1)\n- dash 0.5.4\n- ksh 1993-12-28\n- pdksh 5.2.14\n- zsh 4.3.4\n\nMac OS X 10.5.2 (Darwin 9.2.2)\n\n- bash 3.2.17(1)\n- ksh 1993-12-28\n- zsh 4.3.4\n\nSolaris 11 x86 (Nevada 77)\n\n- /bin/sh\n- bash 3.2.25(1)\n- ksh M-11/16/88i\n- zsh 4.3.4\n\n\nNew Features\n------------\n\nNone.\n\n\nChanges and Enhancements\n------------------------\n\nSupport for automated testing frameworks.\n\n\nBug Fixes\n---------\n\nFixed some issues with zsh support.\n\n\nDeprecated Features\n-------------------\n\nNone.\n\n\nKnown Bugs and Issues\n---------------------\n\nFunctions do not properly test for an invalid number of arguments.\n\nksh and pdksh do not pass null arguments (i.e. empty strings as '') properly,\nand as such checks do not work properly.\n\nzsh requires the ``shwordsplit`` option to be set, and the ``function_argzero``\noption to be unset for proper operation.\n\n\n.. vim:fileencoding=latin1:ft=rst:spell:textwidth=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.4.txt",
    "content": "Release Notes for shUnit2 2.1.4\n===============================\n\nThis release contains lots of bug fixes and changes. Mostly, it fixes zsh\nsupport in zsh 3.0, and the handling of null values in ksh.\n\nTo use zsh with shUnit2, the following requirement must be met:\n\n- The ``shwordsplit`` option must be set.\n\nPlease read the Shell Errata section of the documentation for guidance on how\nto meet these requirements.\n\nSee the ``CHANGES-2.1.txt`` file for a full list of changes.\n\n\nTested Platforms\n----------------\n\nCygwin\n\n- bash 3.2.39(19)\n- pdksh 5.2.14\n- zsh 4.3.4\n\nLinux (Ubuntu Dapper 6.06)\n\n- bash 3.1.17(1)\n- pdksh 5.2.14\n- zsh 4.2.5\n\nLinux (Ubuntu Hardy 8.04)\n\n- bash 3.2.39(1)\n- dash 0.5.4\n- ksh 1993-12-28\n- pdksh 5.2.14\n- zsh 4.3.4\n\nMac OS X 10.5.4 (Darwin 9.4.0)\n\n- bash 3.2.17(1)\n- ksh 1993-12-28\n- zsh 4.3.4\n\nSolaris 9 U6 x86\n\n- /bin/sh\n- bash 2.05.0(1)\n- ksh M-11/16/88i\n- zsh 3.0.8\n\nSolaris 11 x86 (Nevada 77)\n\n- /bin/sh\n- bash 3.2.25(1)\n- ksh M-11/16/88i\n- zsh 4.3.4\n\n\nNew Features\n------------\n\nSupport added to output assert source line number as part of assert messages.\n\n\nChanges and Enhancements\n------------------------\n\nSupport for automated testing frameworks.\n\nAdded argument count error checking to all functions.\n\n\nBug Fixes\n---------\n\nFixed some issues with ksh and zsh support.\n\nFixed off-by-one of exit value in trap handler.\n\nFixed handling of null values under ksh.\n\nFixed bug in last resort temporary directory creation.\n\n\nDeprecated Features\n-------------------\n\nNone.\n\n\nKnown Bugs and Issues\n---------------------\n\nzsh requires the ``shwordsplit`` option to be set.\n\nLine numbers in assert messages do not work properly with Bash 2.x.\n\n.. vim:fileencoding=latin1:ft=rst:spell:tw=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.5.txt",
    "content": "Release Notes for shUnit2 2.1.5\n===============================\n\nThis release contains several bug fixes and changes. Additionally, it includes\na rewrite of the test output to better match JUnit and PyUnit.\n\nThis version also includes a slightly expanded set of coding standards by which\nshUnit2 is coded. It should help anyone reading the code to better understand\nit.\n\n\n\nPlease read the Shell Errata section of the documentation for guidance on how\nto meet these requirements.\n\nSee the ``CHANGES-2.1.txt`` file for a full list of changes.\n\n\nTested Platforms\n----------------\n\nCygwin\n\n- bash 3.2.39(20)\n- ksh (sym-link to pdksh)\n- pdksh 5.2.14\n- zsh 4.3.4\n\nLinux (Ubuntu Dapper 6.06)\n\n- bash 3.1.17(1)\n- ksh M-1993-12-28\n- pdksh 5.2.14-99/07/13.2\n- zsh 4.2.5\n\nLinux (Ubuntu Hardy 8.04)\n\n- bash 3.2.39(1)\n- dash 0.5.4\n- ksh M-1993-12-28\n- pdksh 5.2.14-99/07/13.2\n- zsh 4.3.4\n\nMac OS X 10.5.4 (Darwin 9.4.0)\n\n- bash 3.2.17(1)\n- ksh M-1993-12-28\n- zsh 4.3.4\n\nSolaris 9 U6 x86\n\n- /bin/sh\n- bash 2.05.0(1)\n- ksh M-11/16/88i\n- zsh 3.0.8\n\nSolaris 11 x86 (Nevada 77)\n\n- /bin/sh\n- bash 3.2.25(1)\n- ksh M-11/16/88i\n- zsh 4.3.4\n\n\nNew Features\n------------\n\nSupport added for output assert source line number as part of assert messages.\n\nIssue #2: Added assertNotEquals() assert.\n\nProvided a public ``shunit_tmpDir`` variable that can be used by unit test\nscripts that need automated and guaranteed cleanup.\n\n\nChanges and Enhancements\n------------------------\n\nIssue #3: Removed the check for unset variables as shUnit2 should not expect\nscripts being tested to be clean.\n\nIssue #4: Rewrote the test summary. It is now greatly simplified and much more\nscript friendly.\n\nIssue #5: Fixed the documentation around the usage of failures.\n\nIssue #9: Added unit tests and improved documentation around the use of macros.\n\nCode updated to meet documented coding standards.\n\nImproved code reuse of ``_shunit_exit()`` and ``_shunit_fatal()`` functions.\n\nAll output except shUnit2 error messages now goes to STDOUT.\n\nConverted DocBook documentation to reStructuredText for easier maintenance.\n\n\nBug Fixes\n---------\n\nIssue #1: Fixed bug in rap code where certain types of exit conditions did not\ngenerate the ending report.\n\nIssue #7: Fixed duplicated printing of messages passed to asserts.\n\nFixed bugs in ``shlib_relToAbsPath()`` in ``shlib``.\n\n\nDeprecated Features\n-------------------\n\nNone.\n\n\nKnown Bugs and Issues\n---------------------\n\nZsh requires the ``shwordsplit`` option to be set. See the documentation for\nexamples of how to do this.\n\nLine numbers in assert messages do not work properly with BASH 2.x.\n\nThe Bourne shell of Solaris, BASH 2.x, and Zsh 3.0.x do not properly catch the\nSIGTERM signal. As such, shell interpreter failures due to such things as\nunbound variables cannot be caught. (See ``shunit_test_misc.sh``)\n\n\n.. vim:fileencoding=latin1:ft=rst:spell:tw=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.6.txt",
    "content": "Release Notes for shUnit2 2.1.6\n===============================\n\nThis release contains bug fixes and changes. It is also the first release to\nsupport running shunit2 as a standalone program.\n\nPlease read the Shell Errata section of the documentation for guidance on how\nto meet these requirements.\n\nSee the ``CHANGES-2.1.txt`` file for a full list of changes.\n\nNew Features\n------------\n\nSupport for running shUnit2 as a standalone program. This makes it possible for\nusers to execute their unit tests in a manner that is not dependent on the\nlocation an OS distribution maintainer chose to place shUnit2 in the file\nsystem.\n\nAdded support for functions defined like 'function someFunction()'.\n\nChanges and Enhancements\n------------------------\n\nRenamed the public ``shunit_tmpDir`` variable to ``SHUNIT_TMPDIR`` to be more\nconsistent with the ``TMPDIR`` variable.\n\nBug Fixes\n---------\n\nFixed issue where shunit2 would fail on some distributions when creating a\ntemporary directory because the **od** command was not present.\n\nDeprecated Features\n-------------------\n\nNone.\n\nKnown Bugs and Issues\n---------------------\n\nZsh requires the ``shwordsplit`` option to be set. See the documentation for\nexamples of how to do this.\n\nLine numbers in assert messages do not work properly with BASH 2.x.\n\nThe Bourne shell of Solaris, BASH 2.x, and Zsh 3.0.x do not properly catch the\nSIGTERM signal. As such, shell interpreter failures due to such things as\nunbound variables cannot be caught. (See ``shunit_test_misc.sh``)\n\nTested Platforms\n----------------\n\nCygwin 1.7.9 (Windows XP SP2)\n\n- bash 4.1.10(4)\n- dash 0.5.6.1\n- ksh (sym-link to pdksh)\n- pdksh 5.2.14\n- zsh 4.3.11\n\nLinux (Ubuntu Dapper 6.06.2 LTS)\n\n- bash 3.1.17(1)\n- dash 0.5.3\n- ksh (sym-link to pdksh)\n- pdksh 5.2.14-99/07/13.2\n- zsh 4.2.5\n\nLinux (Ubuntu Hardy 8.04.4 LTS)\n\n- bash 3.2.39(1)\n- dash 0.5.4\n- ksh M-1993-12-28\n- pdksh 5.2.14-99/07/13.2\n- zsh 4.3.4\n\nLinux (Ubuntu Lucid 10.04.2 LTS)\n\n- bash 4.1.5(1)\n- dash 0.5.5.1\n- ksh JM-93t+-2009-05-01\n- pdksh 5.2.14-99/07/13.2\n- zsh 4.3.10\n\nMac OS X 10.6.7\n\n- bash 3.2.48(1)\n- ksh M-1993-12-28\n- zsh 4.3.9\n\nSolaris 8 U7 x86\n\n- /bin/sh\n- bash 2.03.0(1)\n- ksh M-11/16/88i\n- zsh 3.0.6\n\nSolaris 9 U6 x86\n\n- /bin/sh\n- bash 2.05.0(1)\n- ksh M-11/16/88i\n- zsh 3.0.8\n\nOpenSolaris 2009.06(snv_111b) x86\n\n- /bin/sh\n- bash 3.2.25(1)\n- ksh 2008-11-04\n\n.. vim:fileencoding=latin1:ft=rst:spell:tw=80\n"
  },
  {
    "path": "tests/shunit/doc/RELEASE_NOTES-2.1.7.md",
    "content": "# shUnit2 2.1.7 Release Notes\n\nhttps://github.com/kward/shunit2\n\nThis release contains bug fixes and enhancements. It is the first release since moving to GitHub. Users can now clone the latest version at any time.\n\nSee the `CHANGES-2.1.md` file for a full list of changes.\n\n\n## New Features\n\nColorized output, based on popular demand. shUnit2 output is now colorized based on the result of the asserts.\n\n\n## Changes and Enhancements\n\nWith the move to GitHub, the shUnit2 unit tests are run on every commit using the [Travis CI][TravisCI] continuous integration framework. Additionally, all code is run through [ShellCheck](http:/www.shellcheck.net/) on every commit.\n\n[TravisCI]: https://travis-ci.org/kward/shunit2\n\nShell commands in shUnit2 are prefixed with '\\' so that they can be stubbed in tests.\n\n\n## Bug Fixes\n\nshUnit2 no longer exits with an 'OK' result if there were syntax errors due to incorrect usage of the assert commands.\n\n\n## Deprecated Features\n\nNone.\n\n\n## Known Bugs and Issues\n\nZsh requires the `shwordsplit` option to be set. See the documentation for examples of how to do this.\n\nLine numbers in assert messages do not work properly with BASH 2.x.\n\nThe Bourne shell of Solaris, BASH 2.x, and Zsh 3.0.x do not properly catch the\nSIGTERM signal. As such, shell interpreter failures due to such things as\nunbound variables cannot be caught. (See `shunit_test_misc.sh`)\n\n\n## Tested Platforms\n\nContinuous integration testing is provided by [Travis CI][TravisCI].\n\nTested OSes:\n\n- Linux\n- macOS\n\nTested shells:\n\n- /bin/sh\n- ash\n- bash\n- dash\n- ksh\n- pdksh\n- zsh\n"
  },
  {
    "path": "tests/shunit/doc/TODO.txt",
    "content": "Make it possible to execute a single test by passing the name of the test on\nthe command line\n\nAdd support for '--randomize-order' so that the test order is randomized to\ncheck for dependencies (which shouldn't be there) between tests.\n\n--debug option to display point in source code (line number and such) where the\nproblem showed up.\n\nassertTrue() just gives 'ASSERT:', nothing else :-(. others too?\nupd: assertNull() will give message passed, but nothing else useful :-(\n\n$Revision$\n"
  },
  {
    "path": "tests/shunit/doc/contributors.md",
    "content": "The original author of shunit2 is Kate Ward. The following people have\ncontributed in some way or another to shunit2.\n\n- [Alex Harvey](https://github.com/alexharv074)\n- Bryan Larsen\n- [David Acacio](https://github.com/dacacioa)\n- Kevin Van Horn\n- [Maciej Bliziński](https://github.com/automatthias)\n- Mario Sparada\n- Mathias Goldau\n- Richard Jensen\n- Rob Holland\n- Rocky Bernstein\n- [rugk](https://github.com/rugk)\n- wood4321 (of code.google.com)\n"
  },
  {
    "path": "tests/shunit/doc/design_doc.txt",
    "content": "Design Doc for shUnit\n\nshUnit is based upon JUnit. The initial ideas for the script came from the book\n\"Pragmatic Unit Testing - In Java with JUnit\" by Andrew Hunt and David Thomas.\n\nThe script was written to perform unit testing for log4sh. log4sh had grown\nenough that it was becoming difficult to easily test and and verify that the\ntests passed for the many different operating systems on which it was being\nused.\n\nThe functions in shUnit are meant to match those in JUnit as much as possible\nwhere shell allows. In the initial version, there will be no concept of\nexceptions (as normal POSIX shell has no concept of them) but attempts to trap\nproblems will be done.\n\nProgramatic Standards:\n\n* SHUNIT_TRUE - public global constant\n* __SHUNIT_SHELL_FLAGS - private global constant\n* __shunit_oldShellFlags - private global variable\n\n* assertEquals - public unit test function\n* shunit_publicFunc - public shUnit function; can be called from parent unit\n  test script\n* _shunit_privateFunc - private shUnit function; should not be called from\n  parent script. meant for internal use by shUnit\n\n* _su_myVar - variable inside a public function. prefixing with '_su_' to\n  reduce the chances that a variable outside of shUnit will be overridden.\n* _su__myVar - variable inside a private function. prefixing with '_su__' to\n  reduce the chances that a variable in a shUnit public function, or a variable\n  outside of shUnit will be overridden.\n\n$Revision$\n"
  },
  {
    "path": "tests/shunit/examples/equality_test.sh",
    "content": "#! /bin/sh\n# file: examples/equality_test.sh\n\ntestEquality() {\n  assertEquals 1 1\n}\n\n# Load and run shUnit2.\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/examples/lineno_test.sh",
    "content": "#! /bin/sh\n# file: examples/lineno_test.sh\n\ntestLineNo() {\n  # This assert will have line numbers included (e.g. \"ASSERT:[123] ...\") if\n  # they are supported.\n  echo \"_ASSERT_EQUALS_ macro value: ${_ASSERT_EQUALS_}\"\n  ${_ASSERT_EQUALS_} '\"not equal\"' 1 2\n\n  # This assert will not have line numbers included (e.g. \"ASSERT: ...\").\n  assertEquals 'not equal' 1 2\n}\n\n# Load and run shUnit2.\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/examples/math.inc",
    "content": "# available as examples/math.inc\n\nadd_generic()\n{\n  num_a=$1\n  num_b=$2\n\n  expr $1 + $2\n}\n\nadd_bash()\n{\n  num_a=$1\n  num_b=$2\n\n  echo $(($1 + $2))\n}\n"
  },
  {
    "path": "tests/shunit/examples/math_test.sh",
    "content": "#! /bin/sh\n# file: examples/math_test.sh\n\ntestAdding() {\n  result=`add_generic 1 2`\n  assertEquals \\\n      \"the result of '${result}' was wrong\" \\\n      3 \"${result}\"\n\n  # Disable non-generic tests.\n  [ -z \"${BASH_VERSION:-}\" ] && startSkipping\n\n  result=`add_bash 1 2`\n  assertEquals \\\n      \"the result of '${result}' was wrong\" \\\n      3 \"${result}\"\n}\n\noneTimeSetUp() {\n  # Load include to test.\n  . ./math.inc\n}\n\n# Load and run shUnit2.\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/examples/mkdir_test.sh",
    "content": "#!/bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# Copyright 2008-2019 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# shUnit2 -- Unit testing framework for Unix shell scripts.\n# https://github.com/kward/shunit2\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n#\n# Example unit test for the mkdir command.\n#\n# There are times when an existing shell script needs to be tested. In this\n# example, we will test several aspects of the the mkdir command, but the\n# techniques could be used for any existing shell script.\n\ntestMissingDirectoryCreation() {\n  ${mkdirCmd} \"${testDir}\" >${stdoutF} 2>${stderrF}\n  rtrn=$?\n  th_assertTrueWithNoOutput ${rtrn} \"${stdoutF}\" \"${stderrF}\"\n\n  assertTrue 'directory missing' \"[ -d '${testDir}' ]\"\n}\n\ntestExistingDirectoryCreationFails() {\n  # Create a directory to test against.\n  ${mkdirCmd} \"${testDir}\"\n\n  # Test for expected failure while trying to create directory that exists.\n  ${mkdirCmd} \"${testDir}\" >${stdoutF} 2>${stderrF}\n  rtrn=$?\n  assertFalse 'expecting return code of 1 (false)' ${rtrn}\n  assertNull 'unexpected output to stdout' \"`cat ${stdoutF}`\"\n  assertNotNull 'expected error message to stderr' \"`cat ${stderrF}`\"\n\n  assertTrue 'directory missing' \"[ -d '${testDir}' ]\"\n}\n\ntestRecursiveDirectoryCreation() {\n  testDir2=\"${testDir}/test2\"\n\n  ${mkdirCmd} -p \"${testDir2}\" >${stdoutF} 2>${stderrF}\n  rtrn=$?\n  th_assertTrueWithNoOutput ${rtrn} \"${stdoutF}\" \"${stderrF}\"\n\n  assertTrue 'first directory missing' \"[ -d '${testDir}' ]\"\n  assertTrue 'second directory missing' \"[ -d '${testDir2}' ]\"\n}\n\nth_assertTrueWithNoOutput() {\n  th_return_=$1\n  th_stdout_=$2\n  th_stderr_=$3\n\n  assertFalse 'unexpected output to STDOUT' \"[ -s '${th_stdout_}' ]\"\n  assertFalse 'unexpected output to STDERR' \"[ -s '${th_stderr_}' ]\"\n\n  unset th_return_ th_stdout_ th_stderr_\n}\n\noneTimeSetUp() {\n  outputDir=\"${SHUNIT_TMPDIR}/output\"\n  mkdir \"${outputDir}\"\n  stdoutF=\"${outputDir}/stdout\"\n  stderrF=\"${outputDir}/stderr\"\n\n  mkdirCmd='mkdir'  # save command name in variable to make future changes easy\n  testDir=\"${SHUNIT_TMPDIR}/some_test_dir\"\n}\n\ntearDown() {\n  rm -fr \"${testDir}\"\n}\n\n# Load and run shUnit2.\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=$0\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/examples/mock_file.sh",
    "content": "#!/bin/sh\n#\n# shUnit2 example for mocking files.\n#\n# This example demonstrates two different mechanisms for mocking files on the\n# system. The first method is preferred for testing specific aspects of a file,\n# and the second method is preferred when multiple tests need access to the\n# same mock data.\n#\n# When mocking files, the key thing of importance is providing the code under\n# test with the correct file to read. The best practice for writing code where\n# files need to be mocked is either:\n# - Pass the filename to be tested into a function and test that function, or\n# - Provide a function that returns the name of the filename to be read.\n#\n# The first case is preferred whenever possible as it allows the unit test to\n# be explicit about what is being tested. The second case is useful when the\n# first case is not achievable.\n#\n# For the second case, there are two common methods to mock the filename\n# returned by the function:\n# - Provide a special value (e.g. a mock variable) that is only available\n#   during testing, or\n# - Override something (e.g. the constant) in the test script.\n#\n# The first case is preferred as it doesn't require the unit test to alter code\n# in any way. Yes, it means that the code itself knows that it is under test,\n# and it behaves slightly differently than under normal conditions, but a\n# visual inspection of the code by the developer should be sufficient to\n# validate proper functionality of such a simple function.\n\n# Treat unset variables as an error.\nset -u\n\nPASSWD='/etc/passwd'\n\n# Read the root UID from the passwd filename provided as the first argument.\nroot_uid_from_passed_filename() {\n  filename=$1\n  root_uid \"${filename}\"\n  unset filename\n}\n\n\n# Read the root UID from the passwd filename derived by call to the\n# passwd_filename() function.\nroot_uid_from_derived_filename() {\n  root_uid \"$(passwd_filename)\"\n}\n\npasswd_filename() {\n  if [ -n \"${MOCK_PASSWD:-}\" ]; then\n    echo \"${MOCK_PASSWD}\"  # Mock file for testing.\n    return\n  fi\n  echo \"${PASSWD}\"\n}\n\n\n# Extract the root UID.\nroot_uid() { awk -F: 'u==$1{print $3}' u=root \"$1\"; }\n\n\nmain() {\n  echo \"root_uid_from_passed_filename:\"\n  root_uid_from_passed_filename \"${PASSWD}\"\n\n  echo\n\n  echo \"root_uid_from_derived_filename:\"\n  root_uid_from_derived_filename\n}\n\n\n# Execute main() if this is run in standalone mode (i.e. not in a unit test).\nARGV0=\"$(basename \"$0\")\"\nargv0=\"$(echo \"${ARGV0}\" |sed 's/_test$//;s/_test\\.sh$//')\"\nif [ \"${ARGV0}\" = \"${argv0}\" ]; then\n  main \"$@\"\nfi\n"
  },
  {
    "path": "tests/shunit/examples/mock_file_test.sh",
    "content": "#!/bin/sh\n#\n# shUnit2 example for mocking files.\n\nMOCK_PASSWD=''  # This will be overridden in oneTimeSetUp().\n\ntest_root_uid_from_passed_filename() {\n  result=\"$(root_uid_from_passed_filename \"${MOCK_PASSWD}\")\"\n  assertEquals 'unexpected root uid' '0' \"${result}\"\n}\n\ntest_root_uid_from_derived_filename() {\n  result=\"$(root_uid_from_derived_filename)\"\n  assertEquals 'unexpected root uid' '0' \"${result}\"\n}\n\noneTimeSetUp() {\n  # Provide a mock passwd file for testing. This will be cleaned up\n  # automatically by shUnit2.\n  MOCK_PASSWD=\"${SHUNIT_TMPDIR}/passwd\"\n  cat <<EOF >\"${MOCK_PASSWD}\"\nnobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false\nroot:*:0:0:System Administrator:/var/root:/bin/sh\ndaemon:*:1:1:System Services:/var/root:/usr/bin/false\nEOF\n\n  # Load script under test.\n  . './mock_file.sh'\n}\n\n# Load and run shUnit2.\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=$0\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/examples/party_test.sh",
    "content": "#! /bin/sh\n# file: examples/party_test.sh\n#\n# This test is mostly for fun. Technically, it is a bad example of a unit test\n# because of the temporal requirement, namely that the year be 1999. A better\n# test would have been to pass in both a known-bad and known-good year into a\n# function, and test for the expected result.\n\ntestPartyLikeItIs1999() {\n  year=`date '+%Y'`\n  assertEquals \"It's not 1999 :-(\" \\\n      '1999' \"${year}\"\n}\n\n# Load and run shUnit2.\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/examples/suite_test.sh",
    "content": "#!/bin/sh\n# file: examples/suite_test.sh\n#\n# This test demonstrates the use of suites. Note: the suite functionality is\n# deprecated as of v2.1.0, and will be removed in a future major release.\n\n# suite is a special function called by shUnit2 to setup a suite of tests. It\n# enables a developer to call a set of functions that contain tests without\n# needing to rename the functions to start with \"test\".\n#\n# Tests that are to be called from within `suite()` are added to the list of\n# executable tests by means of the `suite_addTest()` function.\nsuite() {\n  # Add the suite_test_one() function to the list of executable tests.\n  suite_addTest suite_test_one\n\n  # Call the suite_test_two() function, but note that the test results will not\n  # be added to the global stats, and therefore not reported at the end of the\n  # unit test execution.\n  suite_test_two\n}\n\nsuite_test_one() {\n  assertEquals 1 1\n}\n\nsuite_test_two() {\n  assertNotEquals 1 2\n}\n\n# Load and run shUnit2.\n. ../shunit2\n"
  },
  {
    "path": "tests/shunit/lib/shflags",
    "content": "# vim:et:ft=sh:sts=2:sw=2\n#\n# Copyright 2008-2017 Kate Ward. All Rights Reserved.\n# Released under the Apache License 2.0 license.\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# shFlags -- Advanced command-line flag library for Unix shell scripts.\n# https://github.com/kward/shflags\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n#\n# This module implements something like the gflags library available\n# from https://github.com/gflags/gflags.\n#\n# FLAG TYPES: This is a list of the DEFINE_*'s that you can do.  All flags take\n# a name, default value, help-string, and optional 'short' name (one-letter\n# name). Some flags have other arguments, which are described with the flag.\n#\n# DEFINE_string: takes any input, and interprets it as a string.\n#\n# DEFINE_boolean: does not take any arguments. Say --myflag to set\n#   FLAGS_myflag to true, or --nomyflag to set FLAGS_myflag to false. For short\n#   flags, passing the flag on the command-line negates the default value, i.e.\n#   if the default is true, passing the flag sets the value to false.\n#\n# DEFINE_float: takes an input and interprets it as a floating point number. As\n#   shell does not support floats per-se, the input is merely validated as\n#   being a valid floating point value.\n#\n# DEFINE_integer: takes an input and interprets it as an integer.\n#\n# SPECIAL FLAGS: There are a few flags that have special meaning:\n#   --help (or -?)  prints a list of all the flags in a human-readable fashion\n#   --flagfile=foo  read flags from foo.  (not implemented yet)\n#   --              as in getopt(), terminates flag-processing\n#\n# EXAMPLE USAGE:\n#\n#   -- begin hello.sh --\n#   #! /bin/sh\n#   . ./shflags\n#   DEFINE_string name 'world' \"somebody's name\" n\n#   FLAGS \"$@\" || exit $?\n#   eval set -- \"${FLAGS_ARGV}\"\n#   echo \"Hello, ${FLAGS_name}.\"\n#   -- end hello.sh --\n#\n#   $ ./hello.sh -n Kate\n#   Hello, Kate.\n#\n# CUSTOMIZABLE BEHAVIOR:\n#\n# A script can override the default 'getopt' command by providing the path to\n# an alternate implementation by defining the FLAGS_GETOPT_CMD variable.\n#\n# NOTES:\n#\n# * Not all systems include a getopt version that supports long flags. On these\n#   systems, only short flags are recognized.\n\n#==============================================================================\n# shFlags\n#\n# Shared attributes:\n#   flags_error:  last error message\n#   flags_output: last function output (rarely valid)\n#   flags_return: last return value\n#\n#   __flags_longNames: list of long names for all flags\n#   __flags_shortNames: list of short names for all flags\n#   __flags_boolNames: list of boolean flag names\n#\n#   __flags_opts: options parsed by getopt\n#\n# Per-flag attributes:\n#   FLAGS_<flag_name>: contains value of flag named 'flag_name'\n#   __flags_<flag_name>_default: the default flag value\n#   __flags_<flag_name>_help: the flag help string\n#   __flags_<flag_name>_short: the flag short name\n#   __flags_<flag_name>_type: the flag type\n#\n# Notes:\n# - lists of strings are space separated, and a null value is the '~' char.\n#\n### ShellCheck (http://www.shellcheck.net/)\n# $() are not fully portable (POSIX != portable).\n#   shellcheck disable=SC2006\n# [ p -a q ] are well defined enough (vs [ p ] && [ q ]).\n#   shellcheck disable=SC2166\n\n# Return if FLAGS already loaded.\n[ -n \"${FLAGS_VERSION:-}\" ] && return 0\nFLAGS_VERSION='1.2.3pre'\n\n# Return values that scripts can use.\nFLAGS_TRUE=0\nFLAGS_FALSE=1\nFLAGS_ERROR=2\n\n# Logging levels.\nFLAGS_LEVEL_DEBUG=0\nFLAGS_LEVEL_INFO=1\nFLAGS_LEVEL_WARN=2\nFLAGS_LEVEL_ERROR=3\nFLAGS_LEVEL_FATAL=4\n__FLAGS_LEVEL_DEFAULT=${FLAGS_LEVEL_WARN}\n\n# Determine some reasonable command defaults.\n__FLAGS_EXPR_CMD='expr --'\n__FLAGS_UNAME_S=`uname -s`\nif [ \"${__FLAGS_UNAME_S}\" = 'BSD' ]; then\n  __FLAGS_EXPR_CMD='gexpr --'\nelse\n  _flags_output_=`${__FLAGS_EXPR_CMD} 2>&1`\n  if [ $? -eq ${FLAGS_TRUE} -a \"${_flags_output_}\" = '--' ]; then\n    # We are likely running inside BusyBox.\n    __FLAGS_EXPR_CMD='expr'\n  fi\n  unset _flags_output_\nfi\n\n# Commands a user can override if desired.\nFLAGS_EXPR_CMD=${FLAGS_EXPR_CMD:-${__FLAGS_EXPR_CMD}}\nFLAGS_GETOPT_CMD=${FLAGS_GETOPT_CMD:-getopt}\n\n# Specific shell checks.\nif [ -n \"${ZSH_VERSION:-}\" ]; then\n  setopt |grep \"^shwordsplit$\" >/dev/null\n  if [ $? -ne ${FLAGS_TRUE} ]; then\n    _flags_fatal 'zsh shwordsplit option is required for proper zsh operation'\n  fi\n  if [ -z \"${FLAGS_PARENT:-}\" ]; then\n    _flags_fatal \"zsh does not pass \\$0 through properly. please declare' \\\n\\\"FLAGS_PARENT=\\$0\\\" before calling shFlags\"\n  fi\nfi\n\n# Can we use built-ins?\n( echo \"${FLAGS_TRUE#0}\"; ) >/dev/null 2>&1\nif [ $? -eq ${FLAGS_TRUE} ]; then\n  __FLAGS_USE_BUILTIN=${FLAGS_TRUE}\nelse\n  __FLAGS_USE_BUILTIN=${FLAGS_FALSE}\nfi\n\n\n#\n# Constants.\n#\n\n# Reserved flag names.\n__FLAGS_RESERVED_LIST=' ARGC ARGV ERROR FALSE GETOPT_CMD HELP PARENT TRUE '\n__FLAGS_RESERVED_LIST=\"${__FLAGS_RESERVED_LIST} VERSION \"\n\n# Determined getopt version (standard or enhanced).\n__FLAGS_GETOPT_VERS_STD=0\n__FLAGS_GETOPT_VERS_ENH=1\n\n# shellcheck disable=SC2120\n_flags_getopt_vers() {\n  _flags_getopt_cmd_=${1:-${FLAGS_GETOPT_CMD}}\n  case \"`${_flags_getopt_cmd_} -lfoo '' --foo 2>&1`\" in\n    ' -- --foo') echo ${__FLAGS_GETOPT_VERS_STD} ;;\n    ' --foo --') echo ${__FLAGS_GETOPT_VERS_ENH} ;;\n    # Unrecognized output. Assuming standard getopt version.\n    *) echo ${__FLAGS_GETOPT_VERS_STD} ;;\n  esac\n  unset _flags_getopt_cmd_\n}\n# shellcheck disable=SC2119\n__FLAGS_GETOPT_VERS=`_flags_getopt_vers`\n\n# getopt optstring lengths\n__FLAGS_OPTSTR_SHORT=0\n__FLAGS_OPTSTR_LONG=1\n\n__FLAGS_NULL='~'\n\n# Flag info strings.\n__FLAGS_INFO_DEFAULT='default'\n__FLAGS_INFO_HELP='help'\n__FLAGS_INFO_SHORT='short'\n__FLAGS_INFO_TYPE='type'\n\n# Flag lengths.\n__FLAGS_LEN_SHORT=0\n__FLAGS_LEN_LONG=1\n\n# Flag types.\n__FLAGS_TYPE_NONE=0\n__FLAGS_TYPE_BOOLEAN=1\n__FLAGS_TYPE_FLOAT=2\n__FLAGS_TYPE_INTEGER=3\n__FLAGS_TYPE_STRING=4\n\n# Set the constants readonly.\n__flags_constants=`set |awk -F= '/^FLAGS_/ || /^__FLAGS_/ {print $1}'`\nfor __flags_const in ${__flags_constants}; do\n  # Skip certain flags.\n  case ${__flags_const} in\n    FLAGS_HELP) continue ;;\n    FLAGS_PARENT) continue ;;\n  esac\n  # Set flag readonly.\n  if [ -z \"${ZSH_VERSION:-}\" ]; then\n    readonly \"${__flags_const}\"\n    continue\n  fi\n  case ${ZSH_VERSION} in\n    [123].*) readonly \"${__flags_const}\" ;;\n    *) readonly -g \"${__flags_const}\" ;;  # Declare readonly constants globally.\n  esac\ndone\nunset __flags_const __flags_constants\n\n#\n# Internal variables.\n#\n\n# Space separated lists.\n__flags_boolNames=' '     # Boolean flag names.\n__flags_longNames=' '     # Long flag names.\n__flags_shortNames=' '    # Short flag names.\n__flags_definedNames=' '  # Defined flag names (used for validation).\n\n__flags_columns=''  # Screen width in columns.\n__flags_level=0     # Default logging level.\n__flags_opts=''     # Temporary storage for parsed getopt flags.\n\n#------------------------------------------------------------------------------\n# Private functions.\n#\n\n# Logging functions.\n_flags_debug() {\n  [ ${__flags_level} -le ${FLAGS_LEVEL_DEBUG} ] || return\n  echo \"flags:DEBUG $*\" >&2\n}\n_flags_info() {\n  [ ${__flags_level} -le ${FLAGS_LEVEL_INFO} ] || return\n  echo \"flags:INFO $*\" >&2\n}\n_flags_warn() {\n  [ ${__flags_level} -le ${FLAGS_LEVEL_WARN} ] || return\n  echo \"flags:WARN $*\" >&2\n}\n_flags_error() {\n  [ ${__flags_level} -le ${FLAGS_LEVEL_ERROR} ] || return\n  echo \"flags:ERROR $*\" >&2\n}\n_flags_fatal() {\n  [ ${__flags_level} -le ${FLAGS_LEVEL_FATAL} ] || return\n  echo \"flags:FATAL $*\" >&2\n  exit ${FLAGS_ERROR}\n}\n\n# Get the logging level.\nflags_loggingLevel() { echo ${__flags_level}; }\n\n# Set the logging level.\n#\n# Args:\n#   _flags_level_: integer: new logging level\n# Returns:\n#   nothing\nflags_setLoggingLevel() {\n  [ $# -ne 1 ] && _flags_fatal \"flags_setLevel(): logging level missing\"\n  _flags_level_=$1\n  [ \"${_flags_level_}\" -ge \"${FLAGS_LEVEL_DEBUG}\" \\\n    -a \"${_flags_level_}\" -le \"${FLAGS_LEVEL_FATAL}\" ] \\\n      || _flags_fatal \"Invalid logging level '${_flags_level_}' specified.\"\n  __flags_level=$1\n  unset _flags_level_\n}\n\n# Define a flag.\n#\n# Calling this function will define the following info variables for the\n# specified flag:\n#   FLAGS_flagname - the name for this flag (based upon the long flag name)\n#   __flags_<flag_name>_default - the default value\n#   __flags_flagname_help - the help string\n#   __flags_flagname_short - the single letter alias\n#   __flags_flagname_type - the type of flag (one of __FLAGS_TYPE_*)\n#\n# Args:\n#   _flags_type_: integer: internal type of flag (__FLAGS_TYPE_*)\n#   _flags_name_: string: long flag name\n#   _flags_default_: default flag value\n#   _flags_help_: string: help string\n#   _flags_short_: string: (optional) short flag name\n# Returns:\n#   integer: success of operation, or error\n_flags_define() {\n  if [ $# -lt 4 ]; then\n    flags_error='DEFINE error: too few arguments'\n    flags_return=${FLAGS_ERROR}\n    _flags_error \"${flags_error}\"\n    return ${flags_return}\n  fi\n\n  _flags_type_=$1\n  _flags_name_=$2\n  _flags_default_=$3\n  _flags_help_=${4:-§}  # Special value '§' indicates no help string provided.\n  _flags_short_=${5:-${__FLAGS_NULL}}\n\n  _flags_debug \"type:${_flags_type_} name:${_flags_name_}\" \\\n      \"default:'${_flags_default_}' help:'${_flags_help_}'\" \\\n      \"short:${_flags_short_}\"\n\n  _flags_return_=${FLAGS_TRUE}\n  _flags_usName_=\"`_flags_underscoreName \"${_flags_name_}\"`\"\n\n  # Check whether the flag name is reserved.\n  _flags_itemInList \"${_flags_usName_}\" \"${__FLAGS_RESERVED_LIST}\"\n  if [ $? -eq ${FLAGS_TRUE} ]; then\n    flags_error=\"flag name (${_flags_name_}) is reserved\"\n    _flags_return_=${FLAGS_ERROR}\n  fi\n\n  # Require short option for getopt that don't support long options.\n  if [ ${_flags_return_} -eq ${FLAGS_TRUE} \\\n      -a \"${__FLAGS_GETOPT_VERS}\" -ne \"${__FLAGS_GETOPT_VERS_ENH}\" \\\n      -a \"${_flags_short_}\" = \"${__FLAGS_NULL}\" ]\n  then\n    flags_error=\"short flag required for (${_flags_name_}) on this platform\"\n    _flags_return_=${FLAGS_ERROR}\n  fi\n\n  # Check for existing long name definition.\n  if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then\n    if _flags_itemInList \"${_flags_usName_}\" \"${__flags_definedNames}\"; then\n      flags_error=\"definition for ([no]${_flags_name_}) already exists\"\n      _flags_warn \"${flags_error}\"\n      _flags_return_=${FLAGS_FALSE}\n    fi\n  fi\n\n  # Check for existing short name definition.\n  if [ ${_flags_return_} -eq ${FLAGS_TRUE} \\\n      -a \"${_flags_short_}\" != \"${__FLAGS_NULL}\" ]\n  then\n    if _flags_itemInList \"${_flags_short_}\" \"${__flags_shortNames}\"; then\n      flags_error=\"flag short name (${_flags_short_}) already defined\"\n      _flags_warn \"${flags_error}\"\n      _flags_return_=${FLAGS_FALSE}\n    fi\n  fi\n\n  # Handle default value. Note, on several occasions the 'if' portion of an\n  # if/then/else contains just a ':' which does nothing. A binary reversal via\n  # '!' is not done because it does not work on all shells.\n  if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then\n    case ${_flags_type_} in\n      ${__FLAGS_TYPE_BOOLEAN})\n        if _flags_validBool \"${_flags_default_}\"; then\n          case ${_flags_default_} in\n            true|t|0) _flags_default_=${FLAGS_TRUE} ;;\n            false|f|1) _flags_default_=${FLAGS_FALSE} ;;\n          esac\n        else\n          flags_error=\"invalid default flag value '${_flags_default_}'\"\n          _flags_return_=${FLAGS_ERROR}\n        fi\n        ;;\n\n      ${__FLAGS_TYPE_FLOAT})\n        if _flags_validFloat \"${_flags_default_}\"; then\n          :\n        else\n          flags_error=\"invalid default flag value '${_flags_default_}'\"\n          _flags_return_=${FLAGS_ERROR}\n        fi\n        ;;\n\n      ${__FLAGS_TYPE_INTEGER})\n        if _flags_validInt \"${_flags_default_}\"; then\n          :\n        else\n          flags_error=\"invalid default flag value '${_flags_default_}'\"\n          _flags_return_=${FLAGS_ERROR}\n        fi\n        ;;\n\n      ${__FLAGS_TYPE_STRING}) ;;  # Everything in shell is a valid string.\n\n      *)\n        flags_error=\"unrecognized flag type '${_flags_type_}'\"\n        _flags_return_=${FLAGS_ERROR}\n        ;;\n    esac\n  fi\n\n  if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then\n    # Store flag information.\n    eval \"FLAGS_${_flags_usName_}='${_flags_default_}'\"\n    eval \"__flags_${_flags_usName_}_${__FLAGS_INFO_TYPE}=${_flags_type_}\"\n    eval \"__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}=\\\n\\\"${_flags_default_}\\\"\"\n    eval \"__flags_${_flags_usName_}_${__FLAGS_INFO_HELP}=\\\"${_flags_help_}\\\"\"\n    eval \"__flags_${_flags_usName_}_${__FLAGS_INFO_SHORT}='${_flags_short_}'\"\n\n    # append flag names to name lists\n    __flags_shortNames=\"${__flags_shortNames}${_flags_short_} \"\n    __flags_longNames=\"${__flags_longNames}${_flags_name_} \"\n    [ \"${_flags_type_}\" -eq \"${__FLAGS_TYPE_BOOLEAN}\" ] && \\\n        __flags_boolNames=\"${__flags_boolNames}no${_flags_name_} \"\n\n    # Append flag names to defined names for later validation checks.\n    __flags_definedNames=\"${__flags_definedNames}${_flags_usName_} \"\n    [ \"${_flags_type_}\" -eq \"${__FLAGS_TYPE_BOOLEAN}\" ] && \\\n        __flags_definedNames=\"${__flags_definedNames}no${_flags_usName_} \"\n  fi\n\n  flags_return=${_flags_return_}\n  unset _flags_default_ _flags_help_ _flags_name_ _flags_return_ \\\n      _flags_short_ _flags_type_ _flags_usName_\n  [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error \"${flags_error}\"\n  return ${flags_return}\n}\n\n# Underscore a flag name by replacing dashes with underscores.\n#\n# Args:\n#   unnamed: string: log flag name\n# Output:\n#   string: underscored name\n_flags_underscoreName() {\n  echo \"$1\" |tr '-' '_'\n}\n\n# Return valid getopt options using currently defined list of long options.\n#\n# This function builds a proper getopt option string for short (and long)\n# options, using the current list of long options for reference.\n#\n# Args:\n#   _flags_optStr: integer: option string type (__FLAGS_OPTSTR_*)\n# Output:\n#   string: generated option string for getopt\n# Returns:\n#   boolean: success of operation (always returns True)\n_flags_genOptStr() {\n  _flags_optStrType_=$1\n\n  _flags_opts_=''\n\n  for _flags_name_ in ${__flags_longNames}; do\n    _flags_usName_=\"`_flags_underscoreName \"${_flags_name_}\"`\"\n    _flags_type_=\"`_flags_getFlagInfo \"${_flags_usName_}\" \"${__FLAGS_INFO_TYPE}\"`\"\n    [ $? -eq ${FLAGS_TRUE} ] || _flags_fatal 'call to _flags_type_ failed'\n    case ${_flags_optStrType_} in\n      ${__FLAGS_OPTSTR_SHORT})\n        _flags_shortName_=\"`_flags_getFlagInfo \\\n            \"${_flags_usName_}\" \"${__FLAGS_INFO_SHORT}\"`\"\n        if [ \"${_flags_shortName_}\" != \"${__FLAGS_NULL}\" ]; then\n          _flags_opts_=\"${_flags_opts_}${_flags_shortName_}\"\n          # getopt needs a trailing ':' to indicate a required argument.\n          [ \"${_flags_type_}\" -ne \"${__FLAGS_TYPE_BOOLEAN}\" ] && \\\n              _flags_opts_=\"${_flags_opts_}:\"\n        fi\n        ;;\n\n      ${__FLAGS_OPTSTR_LONG})\n        _flags_opts_=\"${_flags_opts_:+${_flags_opts_},}${_flags_name_}\"\n        # getopt needs a trailing ':' to indicate a required argument\n        [ \"${_flags_type_}\" -ne \"${__FLAGS_TYPE_BOOLEAN}\" ] && \\\n            _flags_opts_=\"${_flags_opts_}:\"\n        ;;\n    esac\n  done\n\n  echo \"${_flags_opts_}\"\n  unset _flags_name_ _flags_opts_ _flags_optStrType_ _flags_shortName_ \\\n      _flags_type_ _flags_usName_\n  return ${FLAGS_TRUE}\n}\n\n# Returns flag details based on a flag name and flag info.\n#\n# Args:\n#   string: underscored flag name\n#   string: flag info (see the _flags_define function for valid info types)\n# Output:\n#   string: value of dereferenced flag variable\n# Returns:\n#   integer: one of FLAGS_{TRUE|FALSE|ERROR}\n_flags_getFlagInfo() {\n  # Note: adding gFI to variable names to prevent naming conflicts with calling\n  # functions\n  _flags_gFI_usName_=$1\n  _flags_gFI_info_=$2\n\n  # Example: given argument usName (underscored flag name) of 'my_flag', and\n  # argument info of 'help', set the _flags_infoValue_ variable to the value of\n  # ${__flags_my_flag_help}, and see if it is non-empty.\n  _flags_infoVar_=\"__flags_${_flags_gFI_usName_}_${_flags_gFI_info_}\"\n  _flags_strToEval_=\"_flags_infoValue_=\\\"\\${${_flags_infoVar_}:-}\\\"\"\n  eval \"${_flags_strToEval_}\"\n  if [ -n \"${_flags_infoValue_}\" ]; then\n    # Special value '§' indicates no help string provided.\n    [ \"${_flags_gFI_info_}\" = ${__FLAGS_INFO_HELP} \\\n        -a \"${_flags_infoValue_}\" = '§' ] && _flags_infoValue_=''\n    flags_return=${FLAGS_TRUE}\n  else\n    # See if the _flags_gFI_usName_ variable is a string as strings can be\n    # empty...\n    # Note: the DRY principle would say to have this function call itself for\n    # the next three lines, but doing so results in an infinite loop as an\n    # invalid _flags_name_ will also not have the associated _type variable.\n    # Because it doesn't (it will evaluate to an empty string) the logic will\n    # try to find the _type variable of the _type variable, and so on. Not so\n    # good ;-)\n    #\n    # Example cont.: set the _flags_typeValue_ variable to the value of\n    # ${__flags_my_flag_type}, and see if it equals '4'.\n    _flags_typeVar_=\"__flags_${_flags_gFI_usName_}_${__FLAGS_INFO_TYPE}\"\n    _flags_strToEval_=\"_flags_typeValue_=\\\"\\${${_flags_typeVar_}:-}\\\"\"\n    eval \"${_flags_strToEval_}\"\n    # shellcheck disable=SC2154\n    if [ \"${_flags_typeValue_}\" = \"${__FLAGS_TYPE_STRING}\" ]; then\n      flags_return=${FLAGS_TRUE}\n    else\n      flags_return=${FLAGS_ERROR}\n      flags_error=\"missing flag info variable (${_flags_infoVar_})\"\n    fi\n  fi\n\n  echo \"${_flags_infoValue_}\"\n  unset _flags_gFI_usName_ _flags_gfI_info_ _flags_infoValue_ _flags_infoVar_ \\\n      _flags_strToEval_ _flags_typeValue_ _flags_typeVar_\n  [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error \"${flags_error}\"\n  return ${flags_return}\n}\n\n# Check for presence of item in a list.\n#\n# Passed a string (e.g. 'abc'), this function will determine if the string is\n# present in the list of strings (e.g.  ' foo bar abc ').\n#\n# Args:\n#   _flags_str_: string: string to search for in a list of strings\n#   unnamed: list: list of strings\n# Returns:\n#   boolean: true if item is in the list\n_flags_itemInList() {\n  _flags_str_=$1\n  shift\n\n  case \" ${*:-} \" in\n    *\\ ${_flags_str_}\\ *) flags_return=${FLAGS_TRUE} ;;\n    *) flags_return=${FLAGS_FALSE} ;;\n  esac\n\n  unset _flags_str_\n  return ${flags_return}\n}\n\n# Returns the width of the current screen.\n#\n# Output:\n#   integer: width in columns of the current screen.\n_flags_columns() {\n  if [ -z \"${__flags_columns}\" ]; then\n    if eval stty size >/dev/null 2>&1; then\n      # stty size worked :-)\n      # shellcheck disable=SC2046\n      set -- `stty size`\n      __flags_columns=\"${2:-}\"\n    fi\n  fi\n  if [ -z \"${__flags_columns}\" ]; then\n   if eval tput cols >/dev/null 2>&1; then\n      # shellcheck disable=SC2046\n      set -- `tput cols`\n      __flags_columns=\"${1:-}\"\n    fi\n  fi\n  echo \"${__flags_columns:-80}\"\n}\n\n# Validate a boolean.\n#\n# Args:\n#   _flags__bool: boolean: value to validate\n# Returns:\n#   bool: true if the value is a valid boolean\n_flags_validBool() {\n  _flags_bool_=$1\n\n  flags_return=${FLAGS_TRUE}\n  case \"${_flags_bool_}\" in\n    true|t|0) ;;\n    false|f|1) ;;\n    *) flags_return=${FLAGS_FALSE} ;;\n  esac\n\n  unset _flags_bool_\n  return ${flags_return}\n}\n\n# Validate a float.\n#\n# Args:\n#   _flags_float_: float: value to validate\n# Returns:\n#   bool: true if the value is a valid integer\n_flags_validFloat() {\n  flags_return=${FLAGS_FALSE}\n  [ -n \"$1\" ] || return ${flags_return}\n  _flags_float_=$1\n\n  if _flags_validInt \"${_flags_float_}\"; then\n    flags_return=${FLAGS_TRUE}\n  elif _flags_useBuiltin; then\n    _flags_float_whole_=${_flags_float_%.*}\n    _flags_float_fraction_=${_flags_float_#*.}\n    if _flags_validInt \"${_flags_float_whole_:-0}\" -a \\\n      _flags_validInt \"${_flags_float_fraction_}\"; then\n      flags_return=${FLAGS_TRUE}\n    fi\n    unset _flags_float_whole_ _flags_float_fraction_\n  else\n    flags_return=${FLAGS_TRUE}\n    case ${_flags_float_} in\n      -*)  # Negative floats.\n        _flags_test_=`${FLAGS_EXPR_CMD} \"${_flags_float_}\" :\\\n            '\\(-[0-9]*\\.[0-9]*\\)'`\n        ;;\n      *)  # Positive floats.\n        _flags_test_=`${FLAGS_EXPR_CMD} \"${_flags_float_}\" :\\\n            '\\([0-9]*\\.[0-9]*\\)'`\n        ;;\n    esac\n    [ \"${_flags_test_}\" != \"${_flags_float_}\" ] && flags_return=${FLAGS_FALSE}\n    unset _flags_test_\n  fi\n\n  unset _flags_float_ _flags_float_whole_ _flags_float_fraction_\n  return ${flags_return}\n}\n\n# Validate an integer.\n#\n# Args:\n#   _flags_int_: integer: value to validate\n# Returns:\n#   bool: true if the value is a valid integer\n_flags_validInt() {\n  flags_return=${FLAGS_FALSE}\n  [ -n \"$1\" ] || return ${flags_return}\n  _flags_int_=$1\n\n  case ${_flags_int_} in\n    -*.*) ;;  # Ignore negative floats (we'll invalidate them later).\n    -*)  # Strip possible leading negative sign.\n      if _flags_useBuiltin; then\n        _flags_int_=${_flags_int_#-}\n      else\n        _flags_int_=`${FLAGS_EXPR_CMD} \"${_flags_int_}\" : '-\\([0-9][0-9]*\\)'`\n      fi\n      ;;\n  esac\n\n  case ${_flags_int_} in\n    *[!0-9]*) flags_return=${FLAGS_FALSE} ;;\n    *) flags_return=${FLAGS_TRUE} ;;\n  esac\n\n  unset _flags_int_\n  return ${flags_return}\n}\n\n# Parse command-line options using the standard getopt.\n#\n# Note: the flag options are passed around in the global __flags_opts so that\n# the formatting is not lost due to shell parsing and such.\n#\n# Args:\n#   @: varies: command-line options to parse\n# Returns:\n#   integer: a FLAGS success condition\n_flags_getoptStandard() {\n  flags_return=${FLAGS_TRUE}\n  _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`\n\n  # Check for spaces in passed options.\n  for _flags_opt_ in \"$@\"; do\n    # Note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06.\n    _flags_match_=`echo \"x${_flags_opt_}x\" |sed 's/ //g'`\n    if [ \"${_flags_match_}\" != \"x${_flags_opt_}x\" ]; then\n      flags_error='the available getopt does not support spaces in options'\n      flags_return=${FLAGS_ERROR}\n      break\n    fi\n  done\n\n  if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then\n    __flags_opts=`getopt \"${_flags_shortOpts_}\" \"$@\" 2>&1`\n    _flags_rtrn_=$?\n    if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then\n      _flags_warn \"${__flags_opts}\"\n      flags_error='unable to parse provided options with getopt.'\n      flags_return=${FLAGS_ERROR}\n    fi\n  fi\n\n  unset _flags_match_ _flags_opt_ _flags_rtrn_ _flags_shortOpts_\n  return ${flags_return}\n}\n\n# Parse command-line options using the enhanced getopt.\n#\n# Note: the flag options are passed around in the global __flags_opts so that\n# the formatting is not lost due to shell parsing and such.\n#\n# Args:\n#   @: varies: command-line options to parse\n# Returns:\n#   integer: a FLAGS success condition\n_flags_getoptEnhanced() {\n  flags_return=${FLAGS_TRUE}\n  _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`\n  _flags_boolOpts_=`echo \"${__flags_boolNames}\" \\\n      |sed 's/^ *//;s/ *$//;s/ /,/g'`\n  _flags_longOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}`\n\n  __flags_opts=`${FLAGS_GETOPT_CMD} \\\n      -o \"${_flags_shortOpts_}\" \\\n      -l \"${_flags_longOpts_},${_flags_boolOpts_}\" \\\n      -- \"$@\" 2>&1`\n  _flags_rtrn_=$?\n  if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then\n    _flags_warn \"${__flags_opts}\"\n    flags_error='unable to parse provided options with getopt.'\n    flags_return=${FLAGS_ERROR}\n  fi\n\n  unset _flags_boolOpts_ _flags_longOpts_ _flags_rtrn_ _flags_shortOpts_\n  return ${flags_return}\n}\n\n# Dynamically parse a getopt result and set appropriate variables.\n#\n# This function does the actual conversion of getopt output and runs it through\n# the standard case structure for parsing. The case structure is actually quite\n# dynamic to support any number of flags.\n#\n# Args:\n#   argc: int: original command-line argument count\n#   @: varies: output from getopt parsing\n# Returns:\n#   integer: a FLAGS success condition\n_flags_parseGetopt() {\n  _flags_argc_=$1\n  shift\n\n  flags_return=${FLAGS_TRUE}\n\n  if [ \"${__FLAGS_GETOPT_VERS}\" -ne \"${__FLAGS_GETOPT_VERS_ENH}\" ]; then\n    # The @$ must be unquoted as it needs to be re-split.\n    #   shellcheck disable=SC2068\n    set -- $@\n  else\n    # Note the quotes around the `$@' -- they are essential!\n    eval set -- \"$@\"\n  fi\n\n  # Provide user with the number of arguments to shift by later.\n  # NOTE: the FLAGS_ARGC variable is obsolete as of 1.0.3 because it does not\n  # properly give user access to non-flag arguments mixed in between flag\n  # arguments. Its usage was replaced by FLAGS_ARGV, and it is being kept only\n  # for backwards compatibility reasons.\n  FLAGS_ARGC=`_flags_math \"$# - 1 - ${_flags_argc_}\"`\n  export FLAGS_ARGC\n\n  # Handle options. note options with values must do an additional shift.\n  while true; do\n    _flags_opt_=$1\n    _flags_arg_=${2:-}\n    _flags_type_=${__FLAGS_TYPE_NONE}\n    _flags_name_=''\n\n    # Determine long flag name.\n    case \"${_flags_opt_}\" in\n      --) shift; break ;;  # Discontinue option parsing.\n\n      --*)  # Long option.\n        if _flags_useBuiltin; then\n          _flags_opt_=${_flags_opt_#*--}\n        else\n          _flags_opt_=`${FLAGS_EXPR_CMD} \"${_flags_opt_}\" : '--\\(.*\\)'`\n        fi\n        _flags_len_=${__FLAGS_LEN_LONG}\n        if _flags_itemInList \"${_flags_opt_}\" \"${__flags_longNames}\"; then\n          _flags_name_=${_flags_opt_}\n        else\n          # Check for negated long boolean version.\n          if _flags_itemInList \"${_flags_opt_}\" \"${__flags_boolNames}\"; then\n            if _flags_useBuiltin; then\n              _flags_name_=${_flags_opt_#*no}\n            else\n              _flags_name_=`${FLAGS_EXPR_CMD} \"${_flags_opt_}\" : 'no\\(.*\\)'`\n            fi\n            _flags_type_=${__FLAGS_TYPE_BOOLEAN}\n            _flags_arg_=${__FLAGS_NULL}\n          fi\n        fi\n        ;;\n\n      -*)  # Short option.\n        if _flags_useBuiltin; then\n          _flags_opt_=${_flags_opt_#*-}\n        else\n          _flags_opt_=`${FLAGS_EXPR_CMD} \"${_flags_opt_}\" : '-\\(.*\\)'`\n        fi\n        _flags_len_=${__FLAGS_LEN_SHORT}\n        if _flags_itemInList \"${_flags_opt_}\" \"${__flags_shortNames}\"; then\n          # Yes. Match short name to long name. Note purposeful off-by-one\n          # (too high) with awk calculations.\n          _flags_pos_=`echo \"${__flags_shortNames}\" \\\n              |awk 'BEGIN{RS=\" \";rn=0}$0==e{rn=NR}END{print rn}' \\\n                  e=\"${_flags_opt_}\"`\n          _flags_name_=`echo \"${__flags_longNames}\" \\\n              |awk 'BEGIN{RS=\" \"}rn==NR{print $0}' rn=\"${_flags_pos_}\"`\n        fi\n        ;;\n    esac\n\n    # Die if the flag was unrecognized.\n    if [ -z \"${_flags_name_}\" ]; then\n      flags_error=\"unrecognized option (${_flags_opt_})\"\n      flags_return=${FLAGS_ERROR}\n      break\n    fi\n\n    # Set new flag value.\n    _flags_usName_=`_flags_underscoreName \"${_flags_name_}\"`\n    [ ${_flags_type_} -eq ${__FLAGS_TYPE_NONE} ] && \\\n        _flags_type_=`_flags_getFlagInfo \\\n            \"${_flags_usName_}\" ${__FLAGS_INFO_TYPE}`\n    case ${_flags_type_} in\n      ${__FLAGS_TYPE_BOOLEAN})\n        if [ ${_flags_len_} -eq ${__FLAGS_LEN_LONG} ]; then\n          if [ \"${_flags_arg_}\" != \"${__FLAGS_NULL}\" ]; then\n            eval \"FLAGS_${_flags_usName_}=${FLAGS_TRUE}\"\n          else\n            eval \"FLAGS_${_flags_usName_}=${FLAGS_FALSE}\"\n          fi\n        else\n          _flags_strToEval_=\"_flags_val_=\\\n\\${__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}}\"\n          eval \"${_flags_strToEval_}\"\n          # shellcheck disable=SC2154\n          if [ \"${_flags_val_}\" -eq ${FLAGS_FALSE} ]; then\n            eval \"FLAGS_${_flags_usName_}=${FLAGS_TRUE}\"\n          else\n            eval \"FLAGS_${_flags_usName_}=${FLAGS_FALSE}\"\n          fi\n        fi\n        ;;\n\n      ${__FLAGS_TYPE_FLOAT})\n        if _flags_validFloat \"${_flags_arg_}\"; then\n          eval \"FLAGS_${_flags_usName_}='${_flags_arg_}'\"\n        else\n          flags_error=\"invalid float value (${_flags_arg_})\"\n          flags_return=${FLAGS_ERROR}\n          break\n        fi\n        ;;\n\n      ${__FLAGS_TYPE_INTEGER})\n        if _flags_validInt \"${_flags_arg_}\"; then\n          eval \"FLAGS_${_flags_usName_}='${_flags_arg_}'\"\n        else\n          flags_error=\"invalid integer value (${_flags_arg_})\"\n          flags_return=${FLAGS_ERROR}\n          break\n        fi\n        ;;\n\n      ${__FLAGS_TYPE_STRING})\n        eval \"FLAGS_${_flags_usName_}='${_flags_arg_}'\"\n        ;;\n    esac\n\n    # Handle special case help flag.\n    if [ \"${_flags_usName_}\" = 'help' ]; then\n      # shellcheck disable=SC2154\n      if [ \"${FLAGS_help}\" -eq ${FLAGS_TRUE} ]; then\n        flags_help\n        flags_error='help requested'\n        flags_return=${FLAGS_FALSE}\n        break\n      fi\n    fi\n\n    # Shift the option and non-boolean arguments out.\n    shift\n    [ \"${_flags_type_}\" != ${__FLAGS_TYPE_BOOLEAN} ] && shift\n  done\n\n  # Give user back non-flag arguments.\n  FLAGS_ARGV=''\n  while [ $# -gt 0 ]; do\n    FLAGS_ARGV=\"${FLAGS_ARGV:+${FLAGS_ARGV} }'$1'\"\n    shift\n  done\n\n  unset _flags_arg_ _flags_len_ _flags_name_ _flags_opt_ _flags_pos_ \\\n      _flags_strToEval_ _flags_type_ _flags_usName_ _flags_val_\n  return ${flags_return}\n}\n\n# Perform some path using built-ins.\n#\n# Args:\n#   $@: string: math expression to evaluate\n# Output:\n#   integer: the result\n# Returns:\n#   bool: success of math evaluation\n_flags_math() {\n  if [ $# -eq 0 ]; then\n    flags_return=${FLAGS_FALSE}\n  elif _flags_useBuiltin; then\n    # Variable assignment is needed as workaround for Solaris Bourne shell,\n    # which cannot parse a bare $((expression)).\n    # shellcheck disable=SC2016\n    _flags_expr_='$(($@))'\n    eval echo ${_flags_expr_}\n    flags_return=$?\n    unset _flags_expr_\n  else\n    eval expr \"$@\"\n    flags_return=$?\n  fi\n\n  return ${flags_return}\n}\n\n# Cross-platform strlen() implementation.\n#\n# Args:\n#   _flags_str: string: to determine length of\n# Output:\n#   integer: length of string\n# Returns:\n#   bool: success of strlen evaluation\n_flags_strlen() {\n  _flags_str_=${1:-}\n\n  if [ -z \"${_flags_str_}\" ]; then\n    flags_output=0\n  elif _flags_useBuiltin; then\n    flags_output=${#_flags_str_}\n  else\n    flags_output=`${FLAGS_EXPR_CMD} \"${_flags_str_}\" : '.*'`\n  fi\n  flags_return=$?\n\n  unset _flags_str_\n  echo \"${flags_output}\"\n  return ${flags_return}\n}\n\n# Use built-in helper function to enable unit testing.\n#\n# Args:\n#   None\n# Returns:\n#   bool: true if built-ins should be used\n_flags_useBuiltin() { return ${__FLAGS_USE_BUILTIN}; }\n\n#------------------------------------------------------------------------------\n# public functions\n#\n# A basic boolean flag. Boolean flags do not take any arguments, and their\n# value is either 1 (false) or 0 (true). For long flags, the false value is\n# specified on the command line by prepending the word 'no'. With short flags,\n# the presence of the flag toggles the current value between true and false.\n# Specifying a short boolean flag twice on the command results in returning the\n# value back to the default value.\n#\n# A default value is required for boolean flags.\n#\n# For example, lets say a Boolean flag was created whose long name was 'update'\n# and whose short name was 'x', and the default value was 'false'. This flag\n# could be explicitly set to 'true' with '--update' or by '-x', and it could be\n# explicitly set to 'false' with '--noupdate'.\nDEFINE_boolean() { _flags_define ${__FLAGS_TYPE_BOOLEAN} \"$@\"; }\n\n# Other basic flags.\nDEFINE_float()   { _flags_define ${__FLAGS_TYPE_FLOAT} \"$@\"; }\nDEFINE_integer() { _flags_define ${__FLAGS_TYPE_INTEGER} \"$@\"; }\nDEFINE_string()  { _flags_define ${__FLAGS_TYPE_STRING} \"$@\"; }\n\n# Parse the flags.\n#\n# Args:\n#   unnamed: list: command-line flags to parse\n# Returns:\n#   integer: success of operation, or error\nFLAGS() {\n  # Define a standard 'help' flag if one isn't already defined.\n  [ -z \"${__flags_help_type:-}\" ] && \\\n      DEFINE_boolean 'help' false 'show this help' 'h'\n\n  # Parse options.\n  if [ $# -gt 0 ]; then\n    if [ \"${__FLAGS_GETOPT_VERS}\" -ne \"${__FLAGS_GETOPT_VERS_ENH}\" ]; then\n      _flags_getoptStandard \"$@\"\n    else\n      _flags_getoptEnhanced \"$@\"\n    fi\n    flags_return=$?\n  else\n    # Nothing passed; won't bother running getopt.\n    __flags_opts='--'\n    flags_return=${FLAGS_TRUE}\n  fi\n\n  if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then\n    _flags_parseGetopt $# \"${__flags_opts}\"\n    flags_return=$?\n  fi\n\n  [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_fatal \"${flags_error}\"\n  return ${flags_return}\n}\n\n# This is a helper function for determining the 'getopt' version for platforms\n# where the detection isn't working. It simply outputs debug information that\n# can be included in a bug report.\n#\n# Args:\n#   none\n# Output:\n#   debug info that can be included in a bug report\n# Returns:\n#   nothing\nflags_getoptInfo() {\n  # Platform info.\n  _flags_debug \"uname -a: `uname -a`\"\n  _flags_debug \"PATH: ${PATH}\"\n\n  # Shell info.\n  if [ -n \"${BASH_VERSION:-}\" ]; then\n    _flags_debug 'shell: bash'\n    _flags_debug \"BASH_VERSION: ${BASH_VERSION}\"\n  elif [ -n \"${ZSH_VERSION:-}\" ]; then\n    _flags_debug 'shell: zsh'\n    _flags_debug \"ZSH_VERSION: ${ZSH_VERSION}\"\n  fi\n\n  # getopt info.\n  ${FLAGS_GETOPT_CMD} >/dev/null\n  _flags_getoptReturn=$?\n  _flags_debug \"getopt return: ${_flags_getoptReturn}\"\n  _flags_debug \"getopt --version: `${FLAGS_GETOPT_CMD} --version 2>&1`\"\n\n  unset _flags_getoptReturn\n}\n\n# Returns whether the detected getopt version is the enhanced version.\n#\n# Args:\n#   none\n# Output:\n#   none\n# Returns:\n#   bool: true if getopt is the enhanced version\nflags_getoptIsEnh() {\n  test \"${__FLAGS_GETOPT_VERS}\" -eq \"${__FLAGS_GETOPT_VERS_ENH}\"\n}\n\n# Returns whether the detected getopt version is the standard version.\n#\n# Args:\n#   none\n# Returns:\n#   bool: true if getopt is the standard version\nflags_getoptIsStd() {\n  test \"${__FLAGS_GETOPT_VERS}\" -eq \"${__FLAGS_GETOPT_VERS_STD}\"\n}\n\n# This is effectively a 'usage()' function. It prints usage information and\n# exits the program with ${FLAGS_FALSE} if it is ever found in the command line\n# arguments. Note this function can be overridden so other apps can define\n# their own --help flag, replacing this one, if they want.\n#\n# Args:\n#   none\n# Returns:\n#   integer: success of operation (always returns true)\nflags_help() {\n  if [ -n \"${FLAGS_HELP:-}\" ]; then\n    echo \"${FLAGS_HELP}\" >&2\n  else\n    echo \"USAGE: ${FLAGS_PARENT:-$0} [flags] args\" >&2\n  fi\n  if [ -n \"${__flags_longNames}\" ]; then\n    echo 'flags:' >&2\n    for flags_name_ in ${__flags_longNames}; do\n      flags_flagStr_=''\n      flags_boolStr_=''\n      flags_usName_=`_flags_underscoreName \"${flags_name_}\"`\n\n      flags_default_=`_flags_getFlagInfo \\\n          \"${flags_usName_}\" ${__FLAGS_INFO_DEFAULT}`\n      flags_help_=`_flags_getFlagInfo \\\n          \"${flags_usName_}\" ${__FLAGS_INFO_HELP}`\n      flags_short_=`_flags_getFlagInfo \\\n          \"${flags_usName_}\" ${__FLAGS_INFO_SHORT}`\n      flags_type_=`_flags_getFlagInfo \\\n          \"${flags_usName_}\" ${__FLAGS_INFO_TYPE}`\n\n      [ \"${flags_short_}\" != \"${__FLAGS_NULL}\" ] && \\\n          flags_flagStr_=\"-${flags_short_}\"\n\n      if [ \"${__FLAGS_GETOPT_VERS}\" -eq \"${__FLAGS_GETOPT_VERS_ENH}\" ]; then\n        [ \"${flags_short_}\" != \"${__FLAGS_NULL}\" ] && \\\n            flags_flagStr_=\"${flags_flagStr_},\"\n        # Add [no] to long boolean flag names, except the 'help' flag.\n        [ \"${flags_type_}\" -eq ${__FLAGS_TYPE_BOOLEAN} \\\n          -a \"${flags_usName_}\" != 'help' ] && \\\n            flags_boolStr_='[no]'\n        flags_flagStr_=\"${flags_flagStr_}--${flags_boolStr_}${flags_name_}:\"\n      fi\n\n      case ${flags_type_} in\n        ${__FLAGS_TYPE_BOOLEAN})\n          if [ \"${flags_default_}\" -eq ${FLAGS_TRUE} ]; then\n            flags_defaultStr_='true'\n          else\n            flags_defaultStr_='false'\n          fi\n          ;;\n        ${__FLAGS_TYPE_FLOAT}|${__FLAGS_TYPE_INTEGER})\n          flags_defaultStr_=${flags_default_} ;;\n        ${__FLAGS_TYPE_STRING}) flags_defaultStr_=\"'${flags_default_}'\" ;;\n      esac\n      flags_defaultStr_=\"(default: ${flags_defaultStr_})\"\n\n      flags_helpStr_=\"  ${flags_flagStr_}  ${flags_help_:+${flags_help_} }${flags_defaultStr_}\"\n      _flags_strlen \"${flags_helpStr_}\" >/dev/null\n      flags_helpStrLen_=${flags_output}\n      flags_columns_=`_flags_columns`\n\n      if [ \"${flags_helpStrLen_}\" -lt \"${flags_columns_}\" ]; then\n        echo \"${flags_helpStr_}\" >&2\n      else\n        echo \"  ${flags_flagStr_}  ${flags_help_}\" >&2\n        # Note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06\n        # because it doesn't like empty strings when used in this manner.\n        flags_emptyStr_=\"`echo \\\"x${flags_flagStr_}x\\\" \\\n            |awk '{printf \"%\"length($0)-2\"s\", \"\"}'`\"\n        flags_helpStr_=\"  ${flags_emptyStr_}  ${flags_defaultStr_}\"\n        _flags_strlen \"${flags_helpStr_}\" >/dev/null\n        flags_helpStrLen_=${flags_output}\n\n        if [ \"${__FLAGS_GETOPT_VERS}\" -eq \"${__FLAGS_GETOPT_VERS_STD}\" \\\n            -o \"${flags_helpStrLen_}\" -lt \"${flags_columns_}\" ]; then\n          # Indented to match help string.\n          echo \"${flags_helpStr_}\" >&2\n        else\n          # Indented four from left to allow for longer defaults as long flag\n          # names might be used too, making things too long.\n          echo \"    ${flags_defaultStr_}\" >&2\n        fi\n      fi\n    done\n  fi\n\n  unset flags_boolStr_ flags_default_ flags_defaultStr_ flags_emptyStr_ \\\n      flags_flagStr_ flags_help_ flags_helpStr flags_helpStrLen flags_name_ \\\n      flags_columns_ flags_short_ flags_type_ flags_usName_\n  return ${FLAGS_TRUE}\n}\n\n# Reset shflags back to an uninitialized state.\n#\n# Args:\n#   none\n# Returns:\n#   nothing\nflags_reset() {\n  for flags_name_ in ${__flags_longNames}; do\n    flags_usName_=`_flags_underscoreName \"${flags_name_}\"`\n    flags_strToEval_=\"unset FLAGS_${flags_usName_}\"\n    for flags_type_ in \\\n        ${__FLAGS_INFO_DEFAULT} \\\n        ${__FLAGS_INFO_HELP} \\\n        ${__FLAGS_INFO_SHORT} \\\n        ${__FLAGS_INFO_TYPE}\n    do\n      flags_strToEval_=\\\n\"${flags_strToEval_} __flags_${flags_usName_}_${flags_type_}\"\n    done\n    eval \"${flags_strToEval_}\"\n  done\n\n  # Reset internal variables.\n  __flags_boolNames=' '\n  __flags_longNames=' '\n  __flags_shortNames=' '\n  __flags_definedNames=' '\n\n  # Reset logging level back to default.\n  flags_setLoggingLevel ${__FLAGS_LEVEL_DEFAULT}\n\n  unset flags_name_ flags_type_ flags_strToEval_ flags_usName_\n}\n\n#\n# Initialization\n#\n\n# Set the default logging level.\nflags_setLoggingLevel ${__FLAGS_LEVEL_DEFAULT}\n"
  },
  {
    "path": "tests/shunit/lib/versions",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# Versions determines the versions of all installed shells.\n#\n# Copyright 2008-2018 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 License.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shlib\n#\n# This library provides reusable functions that determine actual names and\n# versions of installed shells and the OS. The library can also be run as a\n# script if set executable.\n#\n# Disable checks that aren't fully portable (POSIX != portable).\n# shellcheck disable=SC2006\n\nARGV0=`basename \"$0\"`\nLSB_RELEASE='/etc/lsb-release'\nVERSIONS_SHELLS='ash /bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/zsh /bin/sh /usr/xpg4/bin/sh /sbin/sh'\n\ntrue; TRUE=$?\nfalse; FALSE=$?\nERROR=2\n\nUNAME_R=`uname -r`\nUNAME_S=`uname -s`\n\n__versions_haveStrings=${ERROR}\n\nversions_osName() {\n  os_name_='unrecognized'\n  os_system_=${UNAME_S}\n  os_release_=${UNAME_R}\n  case ${os_system_} in\n    CYGWIN_NT-*) os_name_='Cygwin' ;;\n    Darwin)\n      os_name_=`/usr/bin/sw_vers -productName`\n      os_version_=`versions_osVersion`\n      case ${os_version_} in\n        10.4|10.4.[0-9]*) os_name_='Mac OS X Tiger' ;;\n        10.5|10.5.[0-9]*) os_name_='Mac OS X Leopard' ;;\n        10.6|10.6.[0-9]*) os_name_='Mac OS X Snow Leopard' ;;\n        10.7|10.7.[0-9]*) os_name_='Mac OS X Lion' ;;\n        10.8|10.8.[0-9]*) os_name_='Mac OS X Mountain Lion' ;;\n        10.9|10.9.[0-9]*) os_name_='Mac OS X Mavericks' ;;\n        10.10|10.10.[0-9]*) os_name_='Mac OS X Yosemite' ;;\n        10.11|10.11.[0-9]*) os_name_='Mac OS X El Capitan' ;;\n        10.12|10.12.[0-9]*) os_name_='macOS Sierra' ;;\n        10.13|10.13.[0-9]*) os_name_='macOS High Sierra' ;;\n        10.14|10.14.[0-9]*) os_name_='macOS Mojave' ;;\n        *) os_name_='macOS' ;;\n      esac\n      ;;\n    FreeBSD) os_name_='FreeBSD' ;;\n    Linux) os_name_='Linux' ;;\n    SunOS)\n      os_name_='SunOS'\n      if [ -r '/etc/release' ]; then\n        if grep 'OpenSolaris' /etc/release >/dev/null; then\n          os_name_='OpenSolaris'\n        else\n          os_name_='Solaris'\n        fi\n      fi\n      ;;\n  esac\n\n  echo ${os_name_}\n  unset os_name_ os_system_ os_release_ os_version_\n}\n\nversions_osVersion() {\n  os_version_='unrecognized'\n  os_system_=${UNAME_S}\n  os_release_=${UNAME_R}\n  case ${os_system_} in\n    CYGWIN_NT-*)\n      os_version_=`expr \"${os_release_}\" : '\\([0-9]*\\.[0-9]\\.[0-9]*\\).*'`\n      ;;\n    Darwin)\n      os_version_=`/usr/bin/sw_vers -productVersion`\n      ;;\n    FreeBSD)\n      os_version_=`expr \"${os_release_}\" : '\\([0-9]*\\.[0-9]*\\)-.*'`\n      ;;\n    Linux)\n      if [ -r '/etc/os-release' ]; then\n          os_version_=`awk -F= '$1~/PRETTY_NAME/{print $2}' /etc/os-release \\\n            |sed 's/\"//g'`\n      elif [ -r '/etc/redhat-release' ]; then\n        os_version_=`cat /etc/redhat-release`\n      elif [ -r '/etc/SuSE-release' ]; then\n        os_version_=`head -n 1 /etc/SuSE-release`\n      elif [ -r \"${LSB_RELEASE}\" ]; then\n        if grep -q 'DISTRIB_ID=Ubuntu' \"${LSB_RELEASE}\"; then\n          # shellcheck disable=SC2002\n          os_version_=`cat \"${LSB_RELEASE}\" \\\n            |awk -F= '$1~/DISTRIB_DESCRIPTION/{print $2}' \\\n            |sed 's/\"//g;s/ /-/g'`\n        fi\n      fi\n      ;;\n    SunOS)\n      if [ -r '/etc/release' ]; then\n        if grep 'OpenSolaris' /etc/release >/dev/null; then  # OpenSolaris\n          os_version_=`grep 'OpenSolaris' /etc/release |awk '{print $2\"(\"$3\")\"}'`\n        else  # Solaris\n          major_=`echo \"${os_release_}\" |sed 's/[0-9]*\\.\\([0-9]*\\)/\\1/'`\n          minor_=`grep Solaris /etc/release |sed 's/[^u]*\\(u[0-9]*\\).*/\\1/'`\n          os_version_=\"${major_}${minor_}\"\n        fi\n      fi\n      ;;\n  esac\n\n  echo \"${os_version_}\"\n  unset os_release_ os_system_ os_version_ major_ minor_\n}\n\nversions_shellVersion() {\n  shell_=$1\n\n  shell_present_=${FALSE}\n  case \"${shell_}\" in\n    ash) [ -x '/bin/busybox' ] && shell_present_=${TRUE} ;;\n    *) [ -x \"${shell_}\" ] && shell_present_=${TRUE} ;;\n  esac\n  if [ ${shell_present_} -eq ${FALSE} ]; then\n    echo 'not installed'\n    return ${FALSE}\n  fi\n\n  version_=''\n  case ${shell_} in\n    /sbin/sh) ;; # SunOS\n    /usr/xpg4/bin/sh)\n      version_=`versions_shell_xpg4 \"${shell_}\"`\n      ;; # SunOS\n    */sh)\n      # This could be one of any number of shells. Try until one fits.\n      version_=''\n      [ -z \"${version_}\" ] && version_=`versions_shell_bash \"${shell_}\"`\n      # dash cannot be self determined yet\n      [ -z \"${version_}\" ] && version_=`versions_shell_ksh \"${shell_}\"`\n      # pdksh is covered in versions_shell_ksh()\n      [ -z \"${version_}\" ] && version_=`versions_shell_xpg4 \"${shell_}\"`\n      [ -z \"${version_}\" ] && version_=`versions_shell_zsh \"${shell_}\"`\n      ;;\n    ash) version_=`versions_shell_ash \"${shell_}\"` ;;\n    */bash) version_=`versions_shell_bash \"${shell_}\"` ;;\n    */dash)\n      # Assuming Ubuntu Linux until somebody comes up with a better test. The\n      # following test will return an empty string if dash is not installed.\n      version_=`versions_shell_dash`\n      ;;\n    */ksh) version_=`versions_shell_ksh \"${shell_}\"` ;;\n    */pdksh) version_=`versions_shell_pdksh \"${shell_}\"` ;;\n    */zsh) version_=`versions_shell_zsh \"${shell_}\"` ;;\n    *) version_='invalid'\n  esac\n\n  echo \"${version_:-unknown}\"\n  unset shell_ version_\n}\n\n# The ash shell is included in BusyBox.\nversions_shell_ash() {\n  busybox --help |head -1 |sed 's/BusyBox v\\([0-9.]*\\) .*/\\1/'\n}\n\nversions_shell_bash() {\n  $1 --version : 2>&1 |grep 'GNU bash' |sed 's/.*version \\([^ ]*\\).*/\\1/'\n}\n\nversions_shell_dash() {\n  eval dpkg >/dev/null 2>&1\n  [ $? -eq 127 ] && return  # Return if dpkg not found.\n\n  dpkg -l |grep ' dash ' |awk '{print $3}'\n}\n\nversions_shell_ksh() {\n  versions_shell_=$1\n  versions_version_=''\n\n  # Try a few different ways to figure out the version.\n  versions_version_=`${versions_shell_} --version : 2>&1`\n  # shellcheck disable=SC2181\n  if [ $? -eq 0 ]; then\n    versions_version_=`echo \"${versions_version_}\" \\\n      |sed 's/.*\\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\\).*/\\1/'`\n  else\n    versions_version_=''\n  fi\n  if [ -z \"${versions_version_}\" ]; then\n    _versions_have_strings\n    versions_version_=`strings \"${versions_shell_}\" 2>&1 \\\n      |grep Version \\\n      |sed 's/^.*Version \\(.*\\)$/\\1/;s/ s+ \\$$//;s/ /-/g'`\n  fi\n  if [ -z \"${versions_version_}\" ]; then\n    versions_version_=`versions_shell_pdksh \"${versions_shell_}\"`\n  fi\n\n  echo \"${versions_version_}\"\n  unset versions_shell_ versions_version_\n}\n\nversions_shell_pdksh() {\n  _versions_have_strings\n  strings \"$1\" 2>&1 \\\n  |grep 'PD KSH' \\\n  |sed -e 's/.*PD KSH \\(.*\\)/\\1/;s/ /-/g'\n}\n\nversions_shell_xpg4() {\n  _versions_have_strings\n  strings \"$1\" 2>&1 \\\n  |grep 'Version' \\\n  |sed -e 's/^@(#)Version //'\n}\n\nversions_shell_zsh() {\n  versions_shell_=$1\n\n  # Try a few different ways to figure out the version.\n  # shellcheck disable=SC2016\n  versions_version_=`echo 'echo ${ZSH_VERSION}' |${versions_shell_}`\n  if [ -z \"${versions_version_}\" ]; then\n    versions_version_=`${versions_shell_} --version : 2>&1`\n    # shellcheck disable=SC2181\n    if [ $? -eq 0 ]; then\n      versions_version_=`echo \"${versions_version_}\" |awk '{print $2}'`\n    else\n      versions_version_=''\n    fi\n  fi\n\n  echo \"${versions_version_}\"\n  unset versions_shell_ versions_version_\n}\n\n# Determine if the 'strings' binary installed.\n_versions_have_strings() {\n  [ ${__versions_haveStrings} -ne ${ERROR} ] && return\n  if eval strings /dev/null >/dev/null 2>&1; then\n    __versions_haveStrings=${TRUE}\n    return\n  fi\n\n  echo 'WARN: strings not installed. try installing binutils?' >&2\n  __versions_haveStrings=${FALSE}\n}\n\nversions_main() {\n  # Treat unset variables as an error.\n  set -u\n\n  os_name=`versions_osName`\n  os_version=`versions_osVersion`\n  echo \"os: ${os_name} version: ${os_version}\"\n\n  for shell in ${VERSIONS_SHELLS}; do\n    shell_version=`versions_shellVersion \"${shell}\"`\n    echo \"shell: ${shell} version: ${shell_version}\"\n  done\n}\n\nif [ \"${ARGV0}\" = 'versions' ]; then\n  versions_main \"$@\"\nfi\n"
  },
  {
    "path": "tests/shunit/shunit2",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# Copyright 2008-2019 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# shUnit2 -- Unit testing framework for Unix shell scripts.\n# https://github.com/kward/shunit2\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n#\n# shUnit2 is a xUnit based unit test framework for Bourne shell scripts. It is\n# based on the popular JUnit unit testing framework for Java.\n#\n# $() are not fully portable (POSIX != portable).\n#   shellcheck disable=SC2006\n# expr may be antiquated, but it is the only solution in some cases.\n#   shellcheck disable=SC2003\n\n# Return if shunit2 already loaded.\ncommand [ -n \"${SHUNIT_VERSION:-}\" ] && exit 0\nSHUNIT_VERSION='2.1.8pre'\n\n# Return values that scripts can use.\nSHUNIT_TRUE=0\nSHUNIT_FALSE=1\nSHUNIT_ERROR=2\n\n# Logging functions.\n_shunit_warn() {\n  ${__SHUNIT_CMD_ECHO_ESC} \\\n      \"${__shunit_ansi_yellow}shunit2:WARN${__shunit_ansi_none} $*\" >&2\n}\n_shunit_error() {\n  ${__SHUNIT_CMD_ECHO_ESC} \\\n      \"${__shunit_ansi_red}shunit2:ERROR${__shunit_ansi_none} $*\" >&2\n}\n_shunit_fatal() {\n  ${__SHUNIT_CMD_ECHO_ESC} \\\n      \"${__shunit_ansi_red}shunit2:FATAL${__shunit_ansi_none} $*\" >&2\n  exit ${SHUNIT_ERROR}\n}\n\n# Determine some reasonable command defaults.\n__SHUNIT_CMD_ECHO_ESC='echo -e'\n# shellcheck disable=SC2039\ncommand [ \"`echo -e test`\" = '-e test' ] && __SHUNIT_CMD_ECHO_ESC='echo'\n\n__SHUNIT_UNAME_S=`uname -s`\ncase \"${__SHUNIT_UNAME_S}\" in\n  BSD) __SHUNIT_CMD_EXPR='gexpr' ;;\n  *) __SHUNIT_CMD_EXPR='expr' ;;\nesac\n__SHUNIT_CMD_TPUT='tput'\n\n# Commands a user can override if needed.\nSHUNIT_CMD_EXPR=${SHUNIT_CMD_EXPR:-${__SHUNIT_CMD_EXPR}}\nSHUNIT_CMD_TPUT=${SHUNIT_CMD_TPUT:-${__SHUNIT_CMD_TPUT}}\n\n# Enable color output. Options are 'never', 'always', or 'auto'.\nSHUNIT_COLOR=${SHUNIT_COLOR:-auto}\n\n# Specific shell checks.\nif command [ -n \"${ZSH_VERSION:-}\" ]; then\n  setopt |grep \"^shwordsplit$\" >/dev/null\n  if command [ $? -ne ${SHUNIT_TRUE} ]; then\n    _shunit_fatal 'zsh shwordsplit option is required for proper operation'\n  fi\n  if command [ -z \"${SHUNIT_PARENT:-}\" ]; then\n    _shunit_fatal \"zsh does not pass \\$0 through properly. please declare \\\n\\\"SHUNIT_PARENT=\\$0\\\" before calling shUnit2\"\n  fi\nfi\n\n#\n# Constants\n#\n\n__SHUNIT_MODE_SOURCED='sourced'\n__SHUNIT_MODE_STANDALONE='standalone'\n__SHUNIT_PARENT=${SHUNIT_PARENT:-$0}\n\n# User provided test prefix to display in front of the name of the test being\n# executed. Define by setting the SHUNIT_TEST_PREFIX variable.\n__SHUNIT_TEST_PREFIX=${SHUNIT_TEST_PREFIX:-}\n\n# ANSI colors.\n__SHUNIT_ANSI_NONE='\\033[0m'\n__SHUNIT_ANSI_RED='\\033[1;31m'\n__SHUNIT_ANSI_GREEN='\\033[1;32m'\n__SHUNIT_ANSI_YELLOW='\\033[1;33m'\n__SHUNIT_ANSI_CYAN='\\033[1;36m'\n\n# Set the constants readonly.\n__shunit_constants=`set |grep '^__SHUNIT_' |cut -d= -f1`\necho \"${__shunit_constants}\" |grep '^Binary file' >/dev/null && \\\n    __shunit_constants=`set |grep -a '^__SHUNIT_' |cut -d= -f1`\nfor __shunit_const in ${__shunit_constants}; do\n  if command [ -z \"${ZSH_VERSION:-}\" ]; then\n    readonly \"${__shunit_const}\"\n  else\n    case ${ZSH_VERSION} in\n      [123].*) readonly \"${__shunit_const}\" ;;\n      *) readonly -g \"${__shunit_const}\"  # Declare readonly constants globally.\n    esac\n  fi\ndone\nunset __shunit_const __shunit_constants\n\n#\n# Internal variables.\n#\n\n# Variables.\n__shunit_lineno=''  # Line number of executed test.\n__shunit_mode=${__SHUNIT_MODE_SOURCED}  # Operating mode.\n__shunit_reportGenerated=${SHUNIT_FALSE}  # Is report generated.\n__shunit_script=''  # Filename of unittest script (standalone mode).\n__shunit_skip=${SHUNIT_FALSE}  # Is skipping enabled.\n__shunit_suite=''  # Suite of tests to execute.\n__shunit_clean=${SHUNIT_FALSE}  # _shunit_cleanup() was already called.\n\n# ANSI colors (populated by _shunit_configureColor()).\n__shunit_ansi_none=''\n__shunit_ansi_red=''\n__shunit_ansi_green=''\n__shunit_ansi_yellow=''\n__shunit_ansi_cyan=''\n\n# Counts of tests.\n__shunit_testSuccess=${SHUNIT_TRUE}\n__shunit_testsTotal=0\n__shunit_testsPassed=0\n__shunit_testsFailed=0\n\n# Counts of asserts.\n__shunit_assertsTotal=0\n__shunit_assertsPassed=0\n__shunit_assertsFailed=0\n__shunit_assertsSkipped=0\n\n#\n# Macros.\n#\n\n# shellcheck disable=SC2016,SC2089\n_SHUNIT_LINENO_='eval __shunit_lineno=\"\"; if command [ \"${1:-}\" = \"--lineno\" ]; then command [ -n \"$2\" ] && __shunit_lineno=\"[$2] \"; shift 2; fi'\n\n#-----------------------------------------------------------------------------\n# Assertion functions.\n#\n\n# Assert that two values are equal to one another.\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertEquals() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"assertEquals() requires two or three arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_expected_=$1\n  shunit_actual_=$2\n\n  shunit_return=${SHUNIT_TRUE}\n  if command [ \"${shunit_expected_}\" = \"${shunit_actual_}\" ]; then\n    _shunit_assertPass\n  else\n    failNotEquals \"${shunit_message_}\" \"${shunit_expected_}\" \"${shunit_actual_}\"\n    shunit_return=${SHUNIT_FALSE}\n  fi\n\n  unset shunit_message_ shunit_expected_ shunit_actual_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_EQUALS_='eval assertEquals --lineno \"${LINENO:-}\"'\n\n# Assert that two values are not equal to one another.\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertNotEquals() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"assertNotEquals() requires two or three arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_expected_=$1\n  shunit_actual_=$2\n\n  shunit_return=${SHUNIT_TRUE}\n  if command [ \"${shunit_expected_}\" != \"${shunit_actual_}\" ]; then\n    _shunit_assertPass\n  else\n    failSame \"${shunit_message_}\" \"${shunit_expected_}\" \"${shunit_actual_}\"\n    shunit_return=${SHUNIT_FALSE}\n  fi\n\n  unset shunit_message_ shunit_expected_ shunit_actual_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_NOT_EQUALS_='eval assertNotEquals --lineno \"${LINENO:-}\"'\n\n# Assert that a container contains a content.\n#\n# Args:\n#   message: string: failure message [optional]\n#   container: string: container to analyze\n#   content: string: content to find\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertContains() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"assertContains() requires two or three arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_container_=$1\n  shunit_content_=$2\n\n  shunit_return=${SHUNIT_TRUE}\n  if echo \"$shunit_container_\" | grep -F -- \"$shunit_content_\" > /dev/null; then\n    _shunit_assertPass\n  else\n    failNotFound \"${shunit_message_}\" \"${shunit_content_}\"\n    shunit_return=${SHUNIT_FALSE}\n  fi\n\n  unset shunit_message_ shunit_container_ shunit_content_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_CONTAINS_='eval assertContains --lineno \"${LINENO:-}\"'\n\n# Assert that a container does not contain a content.\n#\n# Args:\n#   message: string: failure message [optional]\n#   container: string: container to analyze\n#   content: string: content to look for\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertNotContains() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"assertNotContains() requires two or three arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_container_=$1\n  shunit_content_=$2\n\n  shunit_return=${SHUNIT_TRUE}\n  if echo \"$shunit_container_\" | grep -F -- \"$shunit_content_\" > /dev/null; then\n    failFound \"${shunit_message_}\" \"${shunit_content_}\"\n    shunit_return=${SHUNIT_FALSE}\n  else\n    _shunit_assertPass\n  fi\n\n  unset shunit_message_ shunit_container_ shunit_content_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_NOT_CONTAINS_='eval assertNotContains --lineno \"${LINENO:-}\"'\n\n# Assert that a value is null (i.e. an empty string)\n#\n# Args:\n#   message: string: failure message [optional]\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertNull() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 1 -o $# -gt 2 ]; then\n    _shunit_error \"assertNull() requires one or two arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 2 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  assertTrue \"${shunit_message_}\" \"[ -z '$1' ]\"\n  shunit_return=$?\n\n  unset shunit_message_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_NULL_='eval assertNull --lineno \"${LINENO:-}\"'\n\n# Assert that a value is not null (i.e. a non-empty string)\n#\n# Args:\n#   message: string: failure message [optional]\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertNotNull() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -gt 2 ]; then  # allowing 0 arguments as $1 might actually be null\n    _shunit_error \"assertNotNull() requires one or two arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 2 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_actual_=`_shunit_escapeCharactersInString \"${1:-}\"`\n  test -n \"${shunit_actual_}\"\n  assertTrue \"${shunit_message_}\" $?\n  shunit_return=$?\n\n  unset shunit_actual_ shunit_message_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_NOT_NULL_='eval assertNotNull --lineno \"${LINENO:-}\"'\n\n# Assert that two values are the same (i.e. equal to one another).\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertSame() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"assertSame() requires two or three arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  assertEquals \"${shunit_message_}\" \"$1\" \"$2\"\n  shunit_return=$?\n\n  unset shunit_message_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_SAME_='eval assertSame --lineno \"${LINENO:-}\"'\n\n# Assert that two values are not the same (i.e. not equal to one another).\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertNotSame() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"assertNotSame() requires two or three arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_:-}$1\"\n    shift\n  fi\n  assertNotEquals \"${shunit_message_}\" \"$1\" \"$2\"\n  shunit_return=$?\n\n  unset shunit_message_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_NOT_SAME_='eval assertNotSame --lineno \"${LINENO:-}\"'\n\n# Assert that a value or shell test condition is true.\n#\n# In shell, a value of 0 is true and a non-zero value is false. Any integer\n# value passed can thereby be tested.\n#\n# Shell supports much more complicated tests though, and a means to support\n# them was needed. As such, this function tests that conditions are true or\n# false through evaluation rather than just looking for a true or false.\n#\n# The following test will succeed:\n#   assertTrue 0\n#   assertTrue \"[ 34 -gt 23 ]\"\n# The following test will fail with a message:\n#   assertTrue 123\n#   assertTrue \"test failed\" \"[ -r '/non/existent/file' ]\"\n#\n# Args:\n#   message: string: failure message [optional]\n#   condition: string: integer value or shell conditional statement\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertTrue() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 1 -o $# -gt 2 ]; then\n    _shunit_error \"assertTrue() takes one or two arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 2 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_condition_=$1\n\n  # See if condition is an integer, i.e. a return value.\n  shunit_match_=`expr \"${shunit_condition_}\" : '\\([0-9]*\\)'`\n  shunit_return=${SHUNIT_TRUE}\n  if command [ -z \"${shunit_condition_}\" ]; then\n    # Null condition.\n    shunit_return=${SHUNIT_FALSE}\n  elif command [ -n \"${shunit_match_}\" -a \"${shunit_condition_}\" = \"${shunit_match_}\" ]\n  then\n    # Possible return value. Treating 0 as true, and non-zero as false.\n    command [ \"${shunit_condition_}\" -ne 0 ] && shunit_return=${SHUNIT_FALSE}\n  else\n    # Hopefully... a condition.\n    ( eval \"${shunit_condition_}\" ) >/dev/null 2>&1\n    command [ $? -ne 0 ] && shunit_return=${SHUNIT_FALSE}\n  fi\n\n  # Record the test.\n  if command [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then\n    _shunit_assertPass\n  else\n    _shunit_assertFail \"${shunit_message_}\"\n  fi\n\n  unset shunit_message_ shunit_condition_ shunit_match_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_TRUE_='eval assertTrue --lineno \"${LINENO:-}\"'\n\n# Assert that a value or shell test condition is false.\n#\n# In shell, a value of 0 is true and a non-zero value is false. Any integer\n# value passed can thereby be tested.\n#\n# Shell supports much more complicated tests though, and a means to support\n# them was needed. As such, this function tests that conditions are true or\n# false through evaluation rather than just looking for a true or false.\n#\n# The following test will succeed:\n#   assertFalse 1\n#   assertFalse \"[ 'apples' = 'oranges' ]\"\n# The following test will fail with a message:\n#   assertFalse 0\n#   assertFalse \"test failed\" \"[ 1 -eq 1 -a 2 -eq 2 ]\"\n#\n# Args:\n#   message: string: failure message [optional]\n#   condition: string: integer value or shell conditional statement\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nassertFalse() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 1 -o $# -gt 2 ]; then\n    _shunit_error \"assertFalse() requires one or two arguments; $# given\"\n    _shunit_assertFail\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 2 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_condition_=$1\n\n  # See if condition is an integer, i.e. a return value.\n  shunit_match_=`expr \"${shunit_condition_}\" : '\\([0-9]*\\)'`\n  shunit_return=${SHUNIT_TRUE}\n  if command [ -z \"${shunit_condition_}\" ]; then\n    # Null condition.\n    shunit_return=${SHUNIT_FALSE}\n  elif command [ -n \"${shunit_match_}\" -a \"${shunit_condition_}\" = \"${shunit_match_}\" ]\n  then\n    # Possible return value. Treating 0 as true, and non-zero as false.\n    command [ \"${shunit_condition_}\" -eq 0 ] && shunit_return=${SHUNIT_FALSE}\n  else\n    # Hopefully... a condition.\n    ( eval \"${shunit_condition_}\" ) >/dev/null 2>&1\n    command [ $? -eq 0 ] && shunit_return=${SHUNIT_FALSE}\n  fi\n\n  # Record the test.\n  if command [ \"${shunit_return}\" -eq \"${SHUNIT_TRUE}\" ]; then\n    _shunit_assertPass\n  else\n    _shunit_assertFail \"${shunit_message_}\"\n  fi\n\n  unset shunit_message_ shunit_condition_ shunit_match_\n  return \"${shunit_return}\"\n}\n# shellcheck disable=SC2016,SC2034\n_ASSERT_FALSE_='eval assertFalse --lineno \"${LINENO:-}\"'\n\n#-----------------------------------------------------------------------------\n# Failure functions.\n#\n\n# Records a test failure.\n#\n# Args:\n#   message: string: failure message [optional]\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nfail() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -gt 1 ]; then\n    _shunit_error \"fail() requires zero or one arguments; $# given\"\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 1 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n\n  _shunit_assertFail \"${shunit_message_}\"\n\n  unset shunit_message_\n  return ${SHUNIT_FALSE}\n}\n# shellcheck disable=SC2016,SC2034\n_FAIL_='eval fail --lineno \"${LINENO:-}\"'\n\n# Records a test failure, stating two values were not equal.\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nfailNotEquals() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"failNotEquals() requires one or two arguments; $# given\"\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_expected_=$1\n  shunit_actual_=$2\n\n  shunit_message_=${shunit_message_%% }\n  _shunit_assertFail \"${shunit_message_:+${shunit_message_} }expected:<${shunit_expected_}> but was:<${shunit_actual_}>\"\n\n  unset shunit_message_ shunit_expected_ shunit_actual_\n  return ${SHUNIT_FALSE}\n}\n# shellcheck disable=SC2016,SC2034\n_FAIL_NOT_EQUALS_='eval failNotEquals --lineno \"${LINENO:-}\"'\n\n# Records a test failure, stating a value was found.\n#\n# Args:\n#   message: string: failure message [optional]\n#   content: string: found value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nfailFound() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 1 -o $# -gt 2 ]; then\n    _shunit_error \"failFound() requires one or two arguments; $# given\"\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 2 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n\n  shunit_message_=${shunit_message_%% }\n  _shunit_assertFail \"${shunit_message_:+${shunit_message_} }Found\"\n\n  unset shunit_message_\n  return ${SHUNIT_FALSE}\n}\n# shellcheck disable=SC2016,SC2034\n_FAIL_FOUND_='eval failFound --lineno \"${LINENO:-}\"'\n\n# Records a test failure, stating a content was not found.\n#\n# Args:\n#   message: string: failure message [optional]\n#   content: string: content not found\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nfailNotFound() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 1 -o $# -gt 2 ]; then\n    _shunit_error \"failNotFound() requires one or two arguments; $# given\"\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 2 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  shunit_content_=$1\n\n  shunit_message_=${shunit_message_%% }\n  _shunit_assertFail \"${shunit_message_:+${shunit_message_} }Not found:<${shunit_content_}>\"\n\n  unset shunit_message_ shunit_content_\n  return ${SHUNIT_FALSE}\n}\n# shellcheck disable=SC2016,SC2034\n_FAIL_NOT_FOUND_='eval failNotFound --lineno \"${LINENO:-}\"'\n\n# Records a test failure, stating two values should have been the same.\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nfailSame()\n{\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"failSame() requires two or three arguments; $# given\"\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n\n  shunit_message_=${shunit_message_%% }\n  _shunit_assertFail \"${shunit_message_:+${shunit_message_} }expected not same\"\n\n  unset shunit_message_\n  return ${SHUNIT_FALSE}\n}\n# shellcheck disable=SC2016,SC2034\n_FAIL_SAME_='eval failSame --lineno \"${LINENO:-}\"'\n\n# Records a test failure, stating two values were not equal.\n#\n# This is functionally equivalent to calling failNotEquals().\n#\n# Args:\n#   message: string: failure message [optional]\n#   expected: string: expected value\n#   actual: string: actual value\n# Returns:\n#   integer: success (TRUE/FALSE/ERROR constant)\nfailNotSame() {\n  # shellcheck disable=SC2090\n  ${_SHUNIT_LINENO_}\n  if command [ $# -lt 2 -o $# -gt 3 ]; then\n    _shunit_error \"failNotSame() requires one or two arguments; $# given\"\n    return ${SHUNIT_ERROR}\n  fi\n  _shunit_shouldSkip && return ${SHUNIT_TRUE}\n\n  shunit_message_=${__shunit_lineno}\n  if command [ $# -eq 3 ]; then\n    shunit_message_=\"${shunit_message_}$1\"\n    shift\n  fi\n  failNotEquals \"${shunit_message_}\" \"$1\" \"$2\"\n  shunit_return=$?\n\n  unset shunit_message_\n  return ${shunit_return}\n}\n# shellcheck disable=SC2016,SC2034\n_FAIL_NOT_SAME_='eval failNotSame --lineno \"${LINENO:-}\"'\n\n#-----------------------------------------------------------------------------\n# Skipping functions.\n#\n\n# Force remaining assert and fail functions to be \"skipped\".\n#\n# This function forces the remaining assert and fail functions to be \"skipped\",\n# i.e. they will have no effect. Each function skipped will be recorded so that\n# the total of asserts and fails will not be altered.\n#\n# Args:\n#   None\nstartSkipping() { __shunit_skip=${SHUNIT_TRUE}; }\n\n# Resume the normal recording behavior of assert and fail calls.\n#\n# Args:\n#   None\nendSkipping() { __shunit_skip=${SHUNIT_FALSE}; }\n\n# Returns the state of assert and fail call skipping.\n#\n# Args:\n#   None\n# Returns:\n#   boolean: (TRUE/FALSE constant)\nisSkipping() { return ${__shunit_skip}; }\n\n#-----------------------------------------------------------------------------\n# Suite functions.\n#\n\n# Stub. This function should contains all unit test calls to be made.\n#\n# DEPRECATED (as of 2.1.0)\n#\n# This function can be optionally overridden by the user in their test suite.\n#\n# If this function exists, it will be called when shunit2 is sourced. If it\n# does not exist, shunit2 will search the parent script for all functions\n# beginning with the word 'test', and they will be added dynamically to the\n# test suite.\n#\n# This function should be overridden by the user in their unit test suite.\n# Note: see _shunit_mktempFunc() for actual implementation\n#\n# Args:\n#   None\n#suite() { :; }  # DO NOT UNCOMMENT THIS FUNCTION\n\n# Adds a function name to the list of tests schedule for execution.\n#\n# This function should only be called from within the suite() function.\n#\n# Args:\n#   function: string: name of a function to add to current unit test suite\nsuite_addTest() {\n  shunit_func_=${1:-}\n\n  __shunit_suite=\"${__shunit_suite:+${__shunit_suite} }${shunit_func_}\"\n  __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`\n\n  unset shunit_func_\n}\n\n# Stub. This function will be called once before any tests are run.\n#\n# Common one-time environment preparation tasks shared by all tests can be\n# defined here.\n#\n# This function should be overridden by the user in their unit test suite.\n# Note: see _shunit_mktempFunc() for actual implementation\n#\n# Args:\n#   None\n#oneTimeSetUp() { :; }  # DO NOT UNCOMMENT THIS FUNCTION\n\n# Stub. This function will be called once after all tests are finished.\n#\n# Common one-time environment cleanup tasks shared by all tests can be defined\n# here.\n#\n# This function should be overridden by the user in their unit test suite.\n# Note: see _shunit_mktempFunc() for actual implementation\n#\n# Args:\n#   None\n#oneTimeTearDown() { :; }  # DO NOT UNCOMMENT THIS FUNCTION\n\n# Stub. This function will be called before each test is run.\n#\n# Common environment preparation tasks shared by all tests can be defined here.\n#\n# This function should be overridden by the user in their unit test suite.\n# Note: see _shunit_mktempFunc() for actual implementation\n#\n# Args:\n#   None\n#setUp() { :; }  # DO NOT UNCOMMENT THIS FUNCTION\n\n# Note: see _shunit_mktempFunc() for actual implementation\n# Stub. This function will be called after each test is run.\n#\n# Common environment cleanup tasks shared by all tests can be defined here.\n#\n# This function should be overridden by the user in their unit test suite.\n# Note: see _shunit_mktempFunc() for actual implementation\n#\n# Args:\n#   None\n#tearDown() { :; }  # DO NOT UNCOMMENT THIS FUNCTION\n\n#------------------------------------------------------------------------------\n# Internal shUnit2 functions.\n#\n\n# Create a temporary directory to store various run-time files in.\n#\n# This function is a cross-platform temporary directory creation tool. Not all\n# OSes have the `mktemp` function, so one is included here.\n#\n# Args:\n#   None\n# Outputs:\n#   string: the temporary directory that was created\n_shunit_mktempDir() {\n  # Try the standard `mktemp` function.\n  ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return\n\n  # The standard `mktemp` didn't work. Use our own.\n  # shellcheck disable=SC2039\n  if command [ -r '/dev/urandom' -a -x '/usr/bin/od' ]; then\n    _shunit_random_=`/usr/bin/od -vAn -N4 -tx4 </dev/urandom \\\n        |command sed 's/^[^0-9a-f]*//'`\n  elif command [ -n \"${RANDOM:-}\" ]; then\n    # $RANDOM works\n    _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$\n  else\n    # `$RANDOM` doesn't work.\n    _shunit_date_=`date '+%Y%m%d%H%M%S'`\n    _shunit_random_=`expr \"${_shunit_date_}\" / $$`\n  fi\n\n  _shunit_tmpDir_=\"${TMPDIR:-/tmp}/shunit.${_shunit_random_}\"\n  ( umask 077 && command mkdir \"${_shunit_tmpDir_}\" ) || \\\n      _shunit_fatal 'could not create temporary directory! exiting'\n\n  echo \"${_shunit_tmpDir_}\"\n  unset _shunit_date_ _shunit_random_ _shunit_tmpDir_\n}\n\n# This function is here to work around issues in Cygwin.\n#\n# Args:\n#   None\n_shunit_mktempFunc() {\n  for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite noexec\n  do\n    _shunit_file_=\"${__shunit_tmpDir}/${_shunit_func_}\"\n    command cat <<EOF >\"${_shunit_file_}\"\n#! /bin/sh\nexit ${SHUNIT_TRUE}\nEOF\n    command chmod +x \"${_shunit_file_}\"\n  done\n\n  unset _shunit_file_\n}\n\n# Final cleanup function to leave things as we found them.\n#\n# Besides removing the temporary directory, this function is in charge of the\n# final exit code of the unit test. The exit code is based on how the script\n# was ended (e.g. normal exit, or via Ctrl-C).\n#\n# Args:\n#   name: string: name of the trap called (specified when trap defined)\n_shunit_cleanup() {\n  _shunit_name_=$1\n\n  case \"${_shunit_name_}\" in\n    EXIT) ;;\n    INT) _shunit_signal_=130 ;;  # 2+128\n    TERM) _shunit_signal_=143 ;;  # 15+128\n    *)\n      _shunit_error \"unrecognized trap value (${_shunit_name_})\"\n      _shunit_signal_=0\n      ;;\n  esac\n  if command [ \"${_shunit_name_}\" != 'EXIT' ]; then\n    _shunit_warn \"trapped and now handling the (${_shunit_name_}) signal\"\n  fi\n\n  # Do our work.\n  if command [ ${__shunit_clean} -eq ${SHUNIT_FALSE} ]; then\n    # Ensure tear downs are only called once.\n    __shunit_clean=${SHUNIT_TRUE}\n\n    tearDown\n    command [ $? -eq ${SHUNIT_TRUE} ] \\\n        || _shunit_warn \"tearDown() returned non-zero return code.\"\n    oneTimeTearDown\n    command [ $? -eq ${SHUNIT_TRUE} ] \\\n        || _shunit_warn \"oneTimeTearDown() returned non-zero return code.\"\n\n    command rm -fr \"${__shunit_tmpDir}\"\n  fi\n\n  if command [ \"${_shunit_name_}\" != 'EXIT' ]; then\n    # Handle all non-EXIT signals.\n    trap - 0  # Disable EXIT trap.\n    exit ${_shunit_signal_}\n  elif command [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ]; then\n    _shunit_assertFail 'unknown failure encountered running a test'\n    _shunit_generateReport\n    exit ${SHUNIT_ERROR}\n  fi\n\n  unset _shunit_name_ _shunit_signal_\n}\n\n# configureColor based on user color preference.\n#\n# Args:\n#   color: string: color mode (one of `always`, `auto`, or `none`).\n_shunit_configureColor() {\n  _shunit_color_=${SHUNIT_FALSE}  # By default, no color.\n  case $1 in\n    'always') _shunit_color_=${SHUNIT_TRUE} ;;\n    'auto')\n      command [ \"`_shunit_colors`\" -ge 8 ] && _shunit_color_=${SHUNIT_TRUE}\n      ;;\n    'none') ;;\n    *) _shunit_fatal \"unrecognized color option '$1'\" ;;\n  esac\n\n  case ${_shunit_color_} in\n    ${SHUNIT_TRUE})\n      __shunit_ansi_none=${__SHUNIT_ANSI_NONE}\n      __shunit_ansi_red=${__SHUNIT_ANSI_RED}\n      __shunit_ansi_green=${__SHUNIT_ANSI_GREEN}\n      __shunit_ansi_yellow=${__SHUNIT_ANSI_YELLOW}\n      __shunit_ansi_cyan=${__SHUNIT_ANSI_CYAN}\n      ;;\n    ${SHUNIT_FALSE})\n      __shunit_ansi_none=''\n      __shunit_ansi_red=''\n      __shunit_ansi_green=''\n      __shunit_ansi_yellow=''\n      __shunit_ansi_cyan=''\n      ;;\n  esac\n\n  unset _shunit_color_ _shunit_tput_\n}\n\n# colors returns the number of supported colors for the TERM.\n_shunit_colors() {\n  _shunit_tput_=`${SHUNIT_CMD_TPUT} colors 2>/dev/null`\n  if command [ $? -eq 0 ]; then\n    echo \"${_shunit_tput_}\"\n  else\n    echo 16\n  fi\n  unset _shunit_tput_\n}\n\n# The actual running of the tests happens here.\n#\n# Args:\n#   None\n_shunit_execSuite() {\n  for _shunit_test_ in ${__shunit_suite}; do\n    __shunit_testSuccess=${SHUNIT_TRUE}\n\n    # Disable skipping.\n    endSkipping\n\n    # Execute the per-test setup function.\n    setUp\n    command [ $? -eq ${SHUNIT_TRUE} ] \\\n        || _shunit_fatal \"setup() returned non-zero return code.\"\n\n    # Execute the test.\n    echo \"${__SHUNIT_TEST_PREFIX}${_shunit_test_}\"\n    eval \"${_shunit_test_}\"\n    if command [ $? -ne ${SHUNIT_TRUE} ]; then\n      _shunit_error \"${_shunit_test_}() returned non-zero return code.\"\n      __shunit_testSuccess=${SHUNIT_ERROR}\n      _shunit_incFailedCount\n    fi\n\n    # Execute the per-test tear-down function.\n    tearDown\n    command [ $? -eq ${SHUNIT_TRUE} ] \\\n        || _shunit_fatal \"tearDown() returned non-zero return code.\"\n\n    # Update stats.\n    if command [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then\n      __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`\n    else\n      __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`\n    fi\n  done\n\n  unset _shunit_test_\n}\n\n# Generates the user friendly report with appropriate OK/FAILED message.\n#\n# Args:\n#   None\n# Output:\n#   string: the report of successful and failed tests, as well as totals.\n_shunit_generateReport() {\n  command [ \"${__shunit_reportGenerated}\" -eq ${SHUNIT_TRUE} ] && return\n\n  _shunit_ok_=${SHUNIT_TRUE}\n\n  # If no exit code was provided, determine an appropriate one.\n  command [ \"${__shunit_testsFailed}\" -gt 0 \\\n      -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ] \\\n          && _shunit_ok_=${SHUNIT_FALSE}\n\n  echo\n  _shunit_msg_=\"Ran ${__shunit_ansi_cyan}${__shunit_testsTotal}${__shunit_ansi_none}\"\n  if command [ \"${__shunit_testsTotal}\" -eq 1 ]; then\n    ${__SHUNIT_CMD_ECHO_ESC} \"${_shunit_msg_} test.\"\n  else\n    ${__SHUNIT_CMD_ECHO_ESC} \"${_shunit_msg_} tests.\"\n  fi\n\n  if command [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then\n    _shunit_msg_=\"${__shunit_ansi_green}OK${__shunit_ansi_none}\"\n    command [ \"${__shunit_assertsSkipped}\" -gt 0 ] \\\n        && _shunit_msg_=\"${_shunit_msg_} (${__shunit_ansi_yellow}skipped=${__shunit_assertsSkipped}${__shunit_ansi_none})\"\n  else\n    _shunit_msg_=\"${__shunit_ansi_red}FAILED${__shunit_ansi_none}\"\n    _shunit_msg_=\"${_shunit_msg_} (${__shunit_ansi_red}failures=${__shunit_assertsFailed}${__shunit_ansi_none}\"\n    command [ \"${__shunit_assertsSkipped}\" -gt 0 ] \\\n        && _shunit_msg_=\"${_shunit_msg_},${__shunit_ansi_yellow}skipped=${__shunit_assertsSkipped}${__shunit_ansi_none}\"\n    _shunit_msg_=\"${_shunit_msg_})\"\n  fi\n\n  echo\n  ${__SHUNIT_CMD_ECHO_ESC} \"${_shunit_msg_}\"\n  __shunit_reportGenerated=${SHUNIT_TRUE}\n\n  unset _shunit_msg_ _shunit_ok_\n}\n\n# Test for whether a function should be skipped.\n#\n# Args:\n#   None\n# Returns:\n#   boolean: whether the test should be skipped (TRUE/FALSE constant)\n_shunit_shouldSkip() {\n  command [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}\n  _shunit_assertSkip\n}\n\n# Records a successful test.\n#\n# Args:\n#   None\n_shunit_assertPass() {\n  __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1`\n  __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`\n}\n\n# Records a test failure.\n#\n# Args:\n#   message: string: failure message to provide user\n_shunit_assertFail() {\n  __shunit_testSuccess=${SHUNIT_FALSE}\n  _shunit_incFailedCount\n\n  \\[ $# -gt 0 ] && ${__SHUNIT_CMD_ECHO_ESC} \\\n      \"${__shunit_ansi_red}ASSERT:${__shunit_ansi_none}$*\"\n}\n\n# Increment the count of failed asserts.\n#\n# Args:\n#   none\n_shunit_incFailedCount() {\n  __shunit_assertsFailed=`expr \"${__shunit_assertsFailed}\" + 1`\n  __shunit_assertsTotal=`expr \"${__shunit_assertsTotal}\" + 1`\n}\n\n\n# Records a skipped test.\n#\n# Args:\n#   None\n_shunit_assertSkip() {\n  __shunit_assertsSkipped=`expr \"${__shunit_assertsSkipped}\" + 1`\n  __shunit_assertsTotal=`expr \"${__shunit_assertsTotal}\" + 1`\n}\n\n# Prepare a script filename for sourcing.\n#\n# Args:\n#   script: string: path to a script to source\n# Returns:\n#   string: filename prefixed with ./ (if necessary)\n_shunit_prepForSourcing() {\n  _shunit_script_=$1\n  case \"${_shunit_script_}\" in\n    /*|./*) echo \"${_shunit_script_}\" ;;\n    *) echo \"./${_shunit_script_}\" ;;\n  esac\n  unset _shunit_script_\n}\n\n# Escape a character in a string.\n#\n# Args:\n#   c: string: unescaped character\n#   s: string: to escape character in\n# Returns:\n#   string: with escaped character(s)\n_shunit_escapeCharInStr() {\n  command [ -n \"$2\" ] || return  # No point in doing work on an empty string.\n\n  # Note: using shorter variable names to prevent conflicts with\n  # _shunit_escapeCharactersInString().\n  _shunit_c_=$1\n  _shunit_s_=$2\n\n  # Escape the character.\n  # shellcheck disable=SC1003,SC2086\n  echo ''${_shunit_s_}'' |command sed 's/\\'${_shunit_c_}'/\\\\\\'${_shunit_c_}'/g'\n\n  unset _shunit_c_ _shunit_s_\n}\n\n# Escape a character in a string.\n#\n# Args:\n#   str: string: to escape characters in\n# Returns:\n#   string: with escaped character(s)\n_shunit_escapeCharactersInString() {\n  command [ -n \"$1\" ] || return  # No point in doing work on an empty string.\n\n  _shunit_str_=$1\n\n  # Note: using longer variable names to prevent conflicts with\n  # _shunit_escapeCharInStr().\n  for _shunit_char_ in '\"' '$' \"'\" '`'; do\n    _shunit_str_=`_shunit_escapeCharInStr \"${_shunit_char_}\" \"${_shunit_str_}\"`\n  done\n\n  echo \"${_shunit_str_}\"\n  unset _shunit_char_ _shunit_str_\n}\n\n# Extract list of functions to run tests against.\n#\n# Args:\n#   script: string: name of script to extract functions from\n# Returns:\n#   string: of function names\n_shunit_extractTestFunctions() {\n  _shunit_script_=$1\n\n  # Extract the lines with test function names, strip of anything besides the\n  # function name, and output everything on a single line.\n  _shunit_regex_='^\\s*((function test[A-Za-z0-9_-]*)|(test[A-Za-z0-9_-]* *\\(\\)))'\n  # shellcheck disable=SC2196\n  egrep \"${_shunit_regex_}\" \"${_shunit_script_}\" \\\n  |command sed 's/^[^A-Za-z0-9_-]*//;s/^function //;s/\\([A-Za-z0-9_-]*\\).*/\\1/g' \\\n  |xargs\n\n  unset _shunit_regex_ _shunit_script_\n}\n\n#------------------------------------------------------------------------------\n# Main.\n#\n\n# Determine the operating mode.\nif command [ $# -eq 0 -o \"${1:-}\" = '--' ]; then\n  __shunit_script=${__SHUNIT_PARENT}\n  __shunit_mode=${__SHUNIT_MODE_SOURCED}\nelse\n  __shunit_script=$1\n  command [ -r \"${__shunit_script}\" ] || \\\n      _shunit_fatal \"unable to read from ${__shunit_script}\"\n  __shunit_mode=${__SHUNIT_MODE_STANDALONE}\nfi\n\n# Create a temporary storage location.\n__shunit_tmpDir=`_shunit_mktempDir`\n\n# Provide a public temporary directory for unit test scripts.\n# TODO(kward): document this.\nSHUNIT_TMPDIR=\"${__shunit_tmpDir}/tmp\"\ncommand mkdir \"${SHUNIT_TMPDIR}\"\n\n# Setup traps to clean up after ourselves.\ntrap '_shunit_cleanup EXIT' 0\ntrap '_shunit_cleanup INT' 2\ntrap '_shunit_cleanup TERM' 15\n\n# Create phantom functions to work around issues with Cygwin.\n_shunit_mktempFunc\nPATH=\"${__shunit_tmpDir}:${PATH}\"\n\n# Make sure phantom functions are executable. This will bite if `/tmp` (or the\n# current `$TMPDIR`) points to a path on a partition that was mounted with the\n# 'noexec' option. The noexec command was created with `_shunit_mktempFunc()`.\nnoexec 2>/dev/null || _shunit_fatal \\\n    'Please declare TMPDIR with path on partition with exec permission.'\n\n# We must manually source the tests in standalone mode.\nif command [ \"${__shunit_mode}\" = \"${__SHUNIT_MODE_STANDALONE}\" ]; then\n  # shellcheck disable=SC1090\n  command . \"`_shunit_prepForSourcing \\\"${__shunit_script}\\\"`\"\nfi\n\n# Configure default output coloring behavior.\n_shunit_configureColor \"${SHUNIT_COLOR}\"\n\n# Execute the oneTimeSetUp function (if it exists).\noneTimeSetUp\ncommand [ $? -eq ${SHUNIT_TRUE} ] \\\n    || _shunit_fatal \"oneTimeSetUp() returned non-zero return code.\"\n\n# Command line selected tests or suite selected tests\nif command [ \"$#\" -ge 2 ]; then\n  # Argument $1 is either the filename of tests or '--'; either way, skip it.\n  shift\n  # Remaining arguments ($2 .. $#) are assumed to be test function names.\n  # Interate through all remaining args in \"$@\" in a POSIX (likely portable) way.\n  # Helpful tip: https://unix.stackexchange.com/questions/314032/how-to-use-arguments-like-1-2-in-a-for-loop\n  for _shunit_arg_ do\n    suite_addTest \"${_shunit_arg_}\"\n  done\n  unset _shunit_arg_\nelse\n  # Execute the suite function defined in the parent test script.\n  # DEPRECATED as of 2.1.0.\n  suite\nfi\n\n# If no tests or suite specified, dynamically build a list of functions.\nif command [ -z \"${__shunit_suite}\" ]; then\n  shunit_funcs_=`_shunit_extractTestFunctions \"${__shunit_script}\"`\n  for shunit_func_ in ${shunit_funcs_}; do\n    suite_addTest \"${shunit_func_}\"\n  done\nfi\nunset shunit_func_ shunit_funcs_\n\n# Execute the suite of unit tests.\n_shunit_execSuite\n\n# Execute the oneTimeTearDown function (if it exists).\noneTimeTearDown\ncommand [ $? -eq ${SHUNIT_TRUE} ] \\\n    || _shunit_fatal \"oneTimeTearDown() returned non-zero return code.\"\n\n# Generate a report summary.\n_shunit_generateReport\n\n# That's it folks.\ncommand [ \"${__shunit_testsFailed}\" -eq 0 ]\nexit $?\n"
  },
  {
    "path": "tests/shunit/shunit2_args_test.sh",
    "content": "#!/bin/sh\n#\n# shunit2 unit test for running subset(s) of tests based upon command line arguments.\n# Also shows how non-default tests or a arbitrary subset of tests can be run.\n#\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n\n# Load test helpers.\n. ./shunit2_test_helpers\n\n# This test does not nomrally run because it does not begin \"test*\"\n# Will be run by settting the arguments to the script to include the name of this test.\nnon_default_test() {\n  # arbitrary assert\n  assertTrue 0\n  # true intent is to set this variable, which will be tested below\n  NON_DEFAULT_TEST_RAN=\"yup, we ran\"\n}\n\n# Test that the \"non_default_test\" ran, otherwise fail\ntest_non_default_ran() {\n  assertNotNull \"'non_default_test' did not run\" \"$NON_DEFAULT_TEST_RAN\"\n}\n\n# fail if this test runs, which is shouldn't if args are set correctly.\ntest_will_fail() {\n  fail \"test_will_fail should not be run if arg-parsing works\"\n}\n\noneTimeSetUp() {\n  th_oneTimeSetUp\n  # prime with \"null\" value\n  NON_DEFAULT_TEST_RAN=\"\"\n}\n\n# Load and run shunit2.\n# shellcheck disable=SC2034\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=$0\n\n# If zero/one argument(s) are provided, this test is being run in it's\n# entirety, and therefore we want to set the arguments to the script\n# to (simulate and) test the processing of command-line specified\n# tests.  If we don't, then the \"test_will_fail\" test will run (by\n# default) and the overall test will fail.\n#\n# However, if two or more arguments are provided, then assume this\n# test script is being run by hand to experiment with command-line\n# test specification, and then don't override the user provided\n# arguments.\nif command [ \"$#\" -le 1 ]; then\n  # We set the arguments in a POSIX way, inasmuch as we can;\n  # helpful tip:\n  #   https://unix.stackexchange.com/questions/258512/how-to-remove-a-positional-parameter-from\n  set -- \"--\" \"non_default_test\" \"test_non_default_ran\"\nfi\n\n# Load and run tests, but only if running as a script, not if being sourced by shunit2\ncommand [ -z \"${SHUNIT_VERSION:-}\" ] && . \"${TH_SHUNIT}\"\n"
  },
  {
    "path": "tests/shunit/shunit2_asserts_test.sh",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# shunit2 unit test for assert functions.\n#\n# Copyright 2008-2017 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shunit2\n#\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n\n# These variables will be overridden by the test helpers.\nstdoutF=\"${TMPDIR:-/tmp}/STDOUT\"\nstderrF=\"${TMPDIR:-/tmp}/STDERR\"\n\n# Load test helpers.\n. ./shunit2_test_helpers\n\ncommonEqualsSame() {\n  fn=$1\n\n  ( ${fn} 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'equal' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} \"${MSG}\" 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'equal; with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} 'abc def' 'abc def' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'equal with spaces' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not equal' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} '' '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'null values' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} arg1 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} arg1 arg2 arg3 arg4 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ncommonNotEqualsSame() {\n  fn=$1\n\n  ( ${fn} 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not same' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} \"${MSG}\" 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not same, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'same' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} '' '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'null values' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} arg1 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( ${fn} arg1 arg2 arg3 arg4 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestAssertEquals() {\n  commonEqualsSame 'assertEquals'\n}\n\ntestAssertNotEquals() {\n  commonNotEqualsSame 'assertNotEquals'\n}\n\ntestAssertSame() {\n  commonEqualsSame 'assertSame'\n}\n\ntestAssertNotSame() {\n  commonNotEqualsSame 'assertNotSame'\n}\n\ntestAssertContains() {\n  ( assertContains 'abcdef' 'abc' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' 'bcd' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' 'def' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abc -Xabc def' '-Xabc' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'content starts with \"-\"' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains \"${MSG}\" 'abcdef' 'abc' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'found, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' 'xyz' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' 'zab' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' 'efg' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' 'acf' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains 'abcdef' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertContains arg1 arg2 arg3 arg4 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestAssertNotContains() {\n  ( assertNotContains 'abcdef' 'xyz' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains 'abcdef' 'zab' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains 'abcdef' 'efg' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains 'abcdef' 'acf' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains \"${MSG}\" 'abcdef' 'xyz' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not found, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains 'abcdef' 'abc' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'found' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains 'abcdef' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotContains arg1 arg2 arg3 arg4 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestAssertNull() {\n  ( assertNull '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'null' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNull \"${MSG}\" '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'null, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNull 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not null' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNull >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNull arg1 arg2 arg3 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestAssertNotNull()\n{\n  ( assertNotNull 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not null' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotNull \"${MSG}\" 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not null, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotNull 'x\"b' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not null, with double-quote' $? \\\n      \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotNull \"x'b\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not null, with single-quote' $? \\\n      \"${stdoutF}\" \"${stderrF}\"\n\n  # shellcheck disable=SC2016\n  ( assertNotNull 'x$b' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not null, with dollar' $? \\\n      \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotNull 'x`b' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'not null, with backtick' $? \\\n      \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertNotNull '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'null' $? \"${stdoutF}\" \"${stderrF}\"\n\n  # There is no test for too few arguments as $1 might actually be null.\n\n  ( assertNotNull arg1 arg2 arg3 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestAssertTrue() {\n  ( assertTrue 0 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'true' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue \"${MSG}\" 0 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'true, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue '[ 0 -eq 0 ]' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'true condition' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue 1 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'false' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue '[ 0 -eq 1 ]' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'false condition' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'null' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertTrue arg1 arg2 arg3 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestAssertFalse() {\n  ( assertFalse 1 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'false' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse \"${MSG}\" 1 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'false, with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse '[ 0 -eq 1 ]' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertTrueWithNoOutput 'false condition' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse 0 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'true' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse '[ 0 -eq 0 ]' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'true condition' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'true condition' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( assertFalse arg1 arg2 arg3 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\noneTimeSetUp() {\n  th_oneTimeSetUp\n\n  MSG='This is a test message'\n}\n\n# Load and run shunit2.\n# shellcheck disable=SC2034\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=$0\n. \"${TH_SHUNIT}\"\n"
  },
  {
    "path": "tests/shunit/shunit2_failures_test.sh",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# Copyright 2008-2019 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# shUnit2 -- Unit testing framework for Unix shell scripts.\n# https://github.com/kward/shunit2\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n#\n# shUnit2 unit test for failure functions\n#\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n\n# These variables will be overridden by the test helpers.\nstdoutF=\"${TMPDIR:-/tmp}/STDOUT\"\nstderrF=\"${TMPDIR:-/tmp}/STDERR\"\n\n# Load test helpers.\n. ./shunit2_test_helpers\n\ntestFail() {\n  ( fail >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'fail' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( fail \"${MSG}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'fail with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( fail arg1 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestFailNotEquals() {\n  ( failNotEquals 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'same' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failNotEquals \"${MSG}\" 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'same with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failNotEquals 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not same' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failNotEquals '' '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'null values' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failNotEquals >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failNotEquals arg1 arg2 arg3 arg4 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\ntestFailSame() {\n  ( failSame 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'same' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failSame \"${MSG}\" 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'same with msg' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failSame 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'not same' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failSame '' '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithOutput 'null values' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failSame >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too few arguments' $? \"${stdoutF}\" \"${stderrF}\"\n\n  ( failSame arg1 arg2 arg3 arg4 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  th_assertFalseWithError 'too many arguments' $? \"${stdoutF}\" \"${stderrF}\"\n}\n\noneTimeSetUp() {\n  th_oneTimeSetUp\n\n  MSG='This is a test message'\n}\n\n# Load and run shUnit2.\n# shellcheck disable=SC2034\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=$0\n. \"${TH_SHUNIT}\"\n"
  },
  {
    "path": "tests/shunit/shunit2_macros_test.sh",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# shunit2 unit test for macros.\n#\n# Copyright 2008-2017 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shunit2\n#\n### ShellCheck http://www.shellcheck.net/\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n# Presence of LINENO variable is checked.\n#   shellcheck disable=SC2039\n\n# These variables will be overridden by the test helpers.\nstdoutF=\"${TMPDIR:-/tmp}/STDOUT\"\nstderrF=\"${TMPDIR:-/tmp}/STDERR\"\n\n# Load test helpers.\n. ./shunit2_test_helpers\n\ntestAssertEquals() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_EQUALS_} 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_EQUALS_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_EQUALS_} '\"some msg\"' 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_EQUALS_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestAssertNotEquals() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_NOT_EQUALS_} 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NOT_EQUALS_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_NOT_EQUALS_} '\"some msg\"' 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NOT_EQUALS_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestSame() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_SAME_} 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_SAME_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_SAME_} '\"some msg\"' 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_SAME_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestNotSame() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_NOT_SAME_} 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NOT_SAME_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_NOT_SAME_} '\"some msg\"' 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NOT_SAME_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestNull() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_NULL_} 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NULL_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_NULL_} '\"some msg\"' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NULL_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestNotNull()\n{\n  # start skipping if LINENO not available\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_NOT_NULL_} '' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NOT_NULL_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_NOT_NULL_} '\"some msg\"' '\"\"' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_NOT_NULL_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stdoutF}\" \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestAssertTrue() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_TRUE_} \"${SHUNIT_FALSE}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_TRUE_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_TRUE_} '\"some msg\"' \"${SHUNIT_FALSE}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_TRUE_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestAssertFalse() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_ASSERT_FALSE_} \"${SHUNIT_TRUE}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_FALSE_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_ASSERT_FALSE_} '\"some msg\"' \"${SHUNIT_TRUE}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_ASSERT_FALSE_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestFail() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_FAIL_} >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_FAIL_} '\"some msg\"' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestFailNotEquals()\n{\n  # start skipping if LINENO not available\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_FAIL_NOT_EQUALS_} 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_NOT_EQUALS_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_FAIL_NOT_EQUALS_} '\"some msg\"' 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_NOT_EQUALS_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestFailSame() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_FAIL_SAME_} 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_SAME_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_FAIL_SAME_} '\"some msg\"' 'x' 'x' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_SAME_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\ntestFailNotSame() {\n  # Start skipping if LINENO not available.\n  [ -z \"${LINENO:-}\" ] && startSkipping\n\n  ( ${_FAIL_NOT_SAME_} 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_NOT_SAME_ failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  ( ${_FAIL_NOT_SAME_} '\"some msg\"' 'x' 'y' >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^ASSERT:\\[[0-9]*\\] *' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertTrue '_FAIL_NOT_SAME_ w/ msg failure' ${rtrn}\n  [ \"${rtrn}\" -ne \"${SHUNIT_TRUE}\" ] && cat \"${stderrF}\" >&2\n\n  return 0\n}\n\noneTimeSetUp() {\n  th_oneTimeSetUp\n}\n\n# Disable output coloring as it breaks the tests.\nSHUNIT_COLOR='none'; export SHUNIT_COLOR\n\n# Load and run shUnit2.\n# shellcheck disable=SC2034\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=\"$0\"\n. \"${TH_SHUNIT}\"\n"
  },
  {
    "path": "tests/shunit/shunit2_misc_test.sh",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# shUnit2 unit tests of miscellaneous things\n#\n# Copyright 2008-2018 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shunit2\n#\n### ShellCheck http://www.shellcheck.net/\n# $() are not fully portable (POSIX != portable).\n#   shellcheck disable=SC2006\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n# Not wanting to escape single quotes.\n#   shellcheck disable=SC1003\n\n# These variables will be overridden by the test helpers.\nstdoutF=\"${TMPDIR:-/tmp}/STDOUT\"\nstderrF=\"${TMPDIR:-/tmp}/STDERR\"\n\n# Load test helpers.\n. ./shunit2_test_helpers\n\n# Note: the test script is prefixed with '#' chars so that shUnit2 does not\n# incorrectly interpret the embedded functions as real functions.\ntestUnboundVariable() {\n  unittestF=\"${SHUNIT_TMPDIR}/unittest\"\n  sed 's/^#//' >\"${unittestF}\" <<EOF\n## Treat unset variables as an error when performing parameter expansion.\n#set -u\n#\n#boom() { x=\\$1; }  # This function goes boom if no parameters are passed!\n#test_boom() {\n#  assertEquals 1 1\n#  boom  # No parameter given\n#  assertEquals 0 \\$?\n#}\n#SHUNIT_COLOR='none'\n#. ${TH_SHUNIT}\nEOF\n  ( exec \"${SHELL:-sh}\" \"${unittestF}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  assertFalse 'expected a non-zero exit value' $?\n  grep '^ASSERT:unknown failure' \"${stdoutF}\" >/dev/null\n  assertTrue 'assert message was not generated' $?\n  grep '^Ran [0-9]* test' \"${stdoutF}\" >/dev/null\n  assertTrue 'test count message was not generated' $?\n  grep '^FAILED' \"${stdoutF}\" >/dev/null\n  assertTrue 'failure message was not generated' $?\n}\n\n# assertEquals repeats message argument.\n# https://github.com/kward/shunit2/issues/7\ntestIssue7() {\n  # Disable coloring so 'ASSERT:' lines can be matched correctly.\n  _shunit_configureColor 'none'\n\n  ( assertEquals 'Some message.' 1 2 >\"${stdoutF}\" 2>\"${stderrF}\" )\n  diff \"${stdoutF}\" - >/dev/null <<EOF\nASSERT:Some message. expected:<1> but was:<2>\nEOF\n  rtrn=$?\n  assertEquals \"${SHUNIT_TRUE}\" \"${rtrn}\"\n  [ \"${rtrn}\" -eq \"${SHUNIT_TRUE}\" ] || cat \"${stderrF}\" >&2\n}\n\n# Support prefixes on test output.\n# https://github.com/kward/shunit2/issues/29\ntestIssue29() {\n  unittestF=\"${SHUNIT_TMPDIR}/unittest\"\n  sed 's/^#//' >\"${unittestF}\" <<EOF\n## Support test prefixes.\n#test_assert() { assertTrue ${SHUNIT_TRUE}; }\n#SHUNIT_COLOR='none'\n#SHUNIT_TEST_PREFIX='--- '\n#. ${TH_SHUNIT}\nEOF\n  ( exec \"${SHELL:-sh}\" \"${unittestF}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^--- test_assert' \"${stdoutF}\" >/dev/null\n  rtrn=$?\n  assertEquals \"${SHUNIT_TRUE}\" \"${rtrn}\"\n  [ \"${rtrn}\" -eq \"${SHUNIT_TRUE}\" ] || cat \"${stdoutF}\" >&2\n}\n\n# shUnit2 should not exit with 0 when it has syntax errors.\n# https://github.com/kward/shunit2/issues/69\ntestIssue69() {\n  unittestF=\"${SHUNIT_TMPDIR}/unittest\"\n\n  for t in Equals NotEquals Null NotNull Same NotSame True False; do\n    assert=\"assert${t}\"\n    sed 's/^#//' >\"${unittestF}\" <<EOF\n## Asserts with invalid argument counts should be counted as failures.\n#test_assert() { ${assert}; }\n#SHUNIT_COLOR='none'\n#. ${TH_SHUNIT}\nEOF\n    ( exec \"${SHELL:-sh}\" \"${unittestF}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n    grep '^FAILED' \"${stdoutF}\" >/dev/null\n    assertTrue \"failure message for ${assert} was not generated\" $?\n  done\n}\n\n# Ensure that test fails if setup/teardown functions fail.\ntestIssue77() {\n  unittestF=\"${SHUNIT_TMPDIR}/unittest\"\n  for func in oneTimeSetUp setUp tearDown oneTimeTearDown; do\n    sed 's/^#//' >\"${unittestF}\" <<EOF\n## Environment failure should end test.\n#${func}() { return ${SHUNIT_FALSE}; }\n#test_true() { assertTrue ${SHUNIT_TRUE}; }\n#SHUNIT_COLOR='none'\n#. ${TH_SHUNIT}\nEOF\n    ( exec \"${SHELL:-sh}\" \"${unittestF}\" ) >\"${stdoutF}\" 2>\"${stderrF}\"\n    grep '^FAILED' \"${stdoutF}\" >/dev/null\n    assertTrue \"failure of ${func}() did not end test\" $?\n  done\n}\n\n# Ensure a test failure is recorded for code containing syntax errors.\n# https://github.com/kward/shunit2/issues/84\ntestIssue84() {\n  unittestF=\"${SHUNIT_TMPDIR}/unittest\"\n  sed 's/^#//' >\"${unittestF}\" <<\\EOF\n## Function with syntax error.\n#syntax_error() { ${!#3442} -334 a$@2[1]; }\n#test_syntax_error() {\n#  syntax_error\n#  assertTrue ${SHUNIT_TRUE}\n#}\n#SHUNIT_COLOR='none'\n#SHUNIT_TEST_PREFIX='--- '\n#. ${TH_SHUNIT}\nEOF\n  ( exec \"${SHELL:-sh}\" \"${unittestF}\" >\"${stdoutF}\" 2>\"${stderrF}\" )\n  grep '^FAILED' \"${stdoutF}\" >/dev/null\n  assertTrue \"failure message for ${assert} was not generated\" $?\n}\n\ntestPrepForSourcing() {\n  assertEquals '/abc' \"`_shunit_prepForSourcing '/abc'`\"\n  assertEquals './abc' \"`_shunit_prepForSourcing './abc'`\"\n  assertEquals './abc' \"`_shunit_prepForSourcing 'abc'`\"\n}\n\ntestEscapeCharInStr() {\n  while read -r desc char str want; do\n    got=`_shunit_escapeCharInStr \"${char}\" \"${str}\"`\n    assertEquals \"${desc}\" \"${want}\" \"${got}\"\n  done <<'EOF'\nbackslash      \\ ''       ''\nbackslash_pre  \\ \\def     \\\\def\nbackslash_mid  \\ abc\\def  abc\\\\def\nbackslash_post \\ abc\\     abc\\\\\nquote          \" ''       ''\nquote_pre      \" \"def     \\\"def\nquote_mid      \" abc\"def  abc\\\"def\nquote_post     \" abc\"     abc\\\"\nstring         $ ''       ''\nstring_pre     $ $def     \\$def\nstring_mid     $ abc$def  abc\\$def\nstring_post    $ abc$     abc\\$\nEOF\n\n  # TODO(20170924:kward) fix or remove.\n#  actual=`_shunit_escapeCharInStr \"'\" ''`\n#  assertEquals '' \"${actual}\"\n#  assertEquals \"abc\\\\'\" `_shunit_escapeCharInStr \"'\" \"abc'\"`\n#  assertEquals \"abc\\\\'def\" `_shunit_escapeCharInStr \"'\" \"abc'def\"`\n#  assertEquals \"\\\\'def\" `_shunit_escapeCharInStr \"'\" \"'def\"`\n\n#  # Must put the backtick in a variable so the shell doesn't misinterpret it\n#  # while inside a backticked sequence (e.g. `echo '`'` would fail).\n#  backtick='`'\n#  actual=`_shunit_escapeCharInStr ${backtick} ''`\n#  assertEquals '' \"${actual}\"\n#  assertEquals '\\`abc' \\\n#      `_shunit_escapeCharInStr \"${backtick}\" ${backtick}'abc'`\n#  assertEquals 'abc\\`' \\\n#      `_shunit_escapeCharInStr \"${backtick}\" 'abc'${backtick}`\n#  assertEquals 'abc\\`def' \\\n#      `_shunit_escapeCharInStr \"${backtick}\" 'abc'${backtick}'def'`\n}\n\ntestEscapeCharInStr_specialChars() {\n  # Make sure our forward slash doesn't upset sed.\n  assertEquals '/' \"`_shunit_escapeCharInStr '\\' '/'`\"\n\n  # Some shells escape these differently.\n  # TODO(20170924:kward) fix or remove.\n  #assertEquals '\\\\a' `_shunit_escapeCharInStr '\\' '\\a'`\n  #assertEquals '\\\\b' `_shunit_escapeCharInStr '\\' '\\b'`\n}\n\n# Test the various ways of declaring functions.\n#\n# Prefixing (then stripping) with comment symbol so these functions aren't\n# treated as real functions by shUnit2.\ntestExtractTestFunctions() {\n  f=\"${SHUNIT_TMPDIR}/extract_test_functions\"\n  sed 's/^#//' <<EOF >\"${f}\"\n## Function on a single line.\n#testABC() { echo 'ABC'; }\n## Multi-line function with '{' on next line.\n#test_def()\n# {\n#  echo 'def'\n#}\n## Multi-line function with '{' on first line.\n#testG3 () {\n#  echo 'G3'\n#}\n## Function with numerical values in name.\n#function test4() { echo '4'; }\n## Leading space in front of function.\n#\ttest5() { echo '5'; }\n## Function with '_' chars in name.\n#some_test_function() { echo 'some func'; }\n## Function that sets variables.\n#func_with_test_vars() {\n#  testVariable=1234\n#}\n## Function with keyword but no parenthesis\n#function test6 { echo '6'; }\n## Function with keyword but no parenthesis, multi-line\n#function test7 {\n#  echo '7';\n#}\n## Function with no parenthesis, '{' on next line\n#function test8\n#{\n#  echo '8'\n#}\n## Function with hyphenated name\n#test-9() {\n#  echo '9';\n#}\n## Function without parenthesis or keyword\n#test_foobar { echo 'hello world'; }\n## Function with multiple function keywords\n#function function test_test_test() { echo 'lorem'; }\nEOF\n\n  actual=`_shunit_extractTestFunctions \"${f}\"`\n  assertEquals 'testABC test_def testG3 test4 test5 test6 test7 test8 test-9' \"${actual}\"\n}\n\n# Test that certain external commands sometimes \"stubbed\" by users are escaped.\ntestIssue54() {\n  for c in mkdir rm cat chmod sed; do\n    grep \"^[^#]*${c} \" \"${TH_SHUNIT}\" | grep -qv \"command ${c}\"\n    assertFalse \"external call to ${c} not protected somewhere\" $?\n  done\n  grep '^[^#]*[^ ]  *\\[' \"${TH_SHUNIT}\" | grep -qv 'command \\['\n  assertFalse \"call to [ ... ] not protected somewhere\" $?\n  grep '^[^#]*  *\\.' \"${TH_SHUNIT}\" | grep -qv 'command \\.'\n  assertFalse \"call to . not protected somewhere\" $?\n}\n\nmock_tput() {\n  if [ -z \"${TERM}\" ]; then\n    # shellcheck disable=SC2016\n    echo 'tput: No value for $TERM and no -T specified'\n    return 2\n  fi\n  if [ \"$1\" = 'colors' ]; then\n    echo 256\n    return 0\n  fi\n  return 1\n}\n\ntestColors() {\n  while read -r desc cmd colors; do\n    SHUNIT_CMD_TPUT=${cmd}\n    got=`_shunit_colors`\n    want=${colors}\n    assertEquals \"${got}\" \"${want}\"\n  done <<'EOF'\nmissing missing_tput 16\nmock mock_tput 256\nEOF\n}\n\ntestColorsWitoutTERM() {\n  SHUNIT_CMD_TPUT='mock_tput'\n  got=`TERM='' _shunit_colors`\n  want=16\n  assertEquals \"${got}\" \"${want}\"\n}\n\nsetUp() {\n  for f in \"${stdoutF}\" \"${stderrF}\"; do\n    cp /dev/null \"${f}\"\n  done\n\n  # Reconfigure coloring as some tests override default behavior.\n  _shunit_configureColor \"${SHUNIT_COLOR_DEFAULT}\"\n\n  # shellcheck disable=SC2034,SC2153\n  SHUNIT_CMD_TPUT=${__SHUNIT_CMD_TPUT}\n}\n\noneTimeSetUp() {\n  SHUNIT_COLOR_DEFAULT=\"${SHUNIT_COLOR}\"\n  th_oneTimeSetUp\n}\n\n# Load and run shUnit2.\n# shellcheck disable=SC2034\n[ -n \"${ZSH_VERSION:-}\" ] && SHUNIT_PARENT=$0\n. \"${TH_SHUNIT}\"\n"
  },
  {
    "path": "tests/shunit/shunit2_standalone_test.sh",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# shUnit2 unit test for standalone operation.\n#\n# Copyright 2010-2017 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shunit2\n#\n# This unit test is purely to test that calling shunit2 directly, while passing\n# the name of a unit test script, works. When run, this script determines if it\n# is running as a standalone program, and calls main() if it is.\n#\n### ShellCheck http://www.shellcheck.net/\n# $() are not fully portable (POSIX != portable).\n#   shellcheck disable=SC2006\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n\nARGV0=\"`basename \"$0\"`\"\n\n# Load test helpers.\n. ./shunit2_test_helpers\n\ntestStandalone() {\n  assertTrue \"${SHUNIT_TRUE}\"\n}\n\nmain() {\n  ${TH_SHUNIT} \"${ARGV0}\"\n}\n\n# Are we running as a standalone?\nif [ \"${ARGV0}\" = 'shunit2_test_standalone.sh' ]; then\n  if [ $# -gt 0 ]; then main \"$@\"; else main; fi\nfi\n"
  },
  {
    "path": "tests/shunit/shunit2_test_helpers",
    "content": "# vim:et:ft=sh:sts=2:sw=2\n#\n# shUnit2 unit test common functions\n#\n# Copyright 2008 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shunit2\n#\n### ShellCheck (http://www.shellcheck.net/)\n# Commands are purposely escaped so they can be mocked outside shUnit2.\n#   shellcheck disable=SC1001,SC1012\n# expr may be antiquated, but it is the only solution in some cases.\n#   shellcheck disable=SC2003\n# $() are not fully portable (POSIX != portable).\n#   shellcheck disable=SC2006\n\n# Treat unset variables as an error when performing parameter expansion.\nset -u\n\n# Set shwordsplit for zsh.\n\\[ -n \"${ZSH_VERSION:-}\" ] && setopt shwordsplit\n\n#\n# Constants.\n#\n\n# Path to shUnit2 library. Can be overridden by setting SHUNIT_INC.\nTH_SHUNIT=${SHUNIT_INC:-./shunit2}; export TH_SHUNIT\n\n# Configure debugging. Set the DEBUG environment variable to any\n# non-empty value to enable debug output, or TRACE to enable trace\n# output.\nTRACE=${TRACE:+'th_trace '}\n\\[ -n \"${TRACE}\" ] && DEBUG=1\n\\[ -z \"${TRACE}\" ] && TRACE=':'\n\nDEBUG=${DEBUG:+'th_debug '}\n\\[ -z \"${DEBUG}\" ] && DEBUG=':'\n\n#\n# Variables.\n#\n\nth_RANDOM=0\n\n#\n# Functions.\n#\n\n# Logging functions.\nth_trace() { echo \"${MY_NAME}:TRACE $*\" >&2; }\nth_debug() { echo \"${MY_NAME}:DEBUG $*\" >&2; }\nth_info() { echo \"${MY_NAME}:INFO $*\" >&2; }\nth_warn() { echo \"${MY_NAME}:WARN $*\" >&2; }\nth_error() { echo \"${MY_NAME}:ERROR $*\" >&2; }\nth_fatal() { echo \"${MY_NAME}:FATAL $*\" >&2; }\n\n# Output subtest name.\nth_subtest() { echo \" $*\" >&2; }\n\nth_oneTimeSetUp() {\n  # These files will be cleaned up automatically by shUnit2.\n  stdoutF=\"${SHUNIT_TMPDIR}/stdout\"\n  stderrF=\"${SHUNIT_TMPDIR}/stderr\"\n  returnF=\"${SHUNIT_TMPDIR}/return\"\n  expectedF=\"${SHUNIT_TMPDIR}/expected\"\n  export stdoutF stderrF returnF expectedF\n}\n\n# Generate a random number.\nth_generateRandom() {\n  tfgr_random=${th_RANDOM}\n\n  while \\[ \"${tfgr_random}\" = \"${th_RANDOM}\" ]; do\n    # shellcheck disable=SC2039\n    if \\[ -n \"${RANDOM:-}\" ]; then\n      # $RANDOM works\n      # shellcheck disable=SC2039\n      tfgr_random=${RANDOM}${RANDOM}${RANDOM}$$\n    elif \\[ -r '/dev/urandom' ]; then\n      tfgr_random=`od -vAn -N4 -tu4 </dev/urandom |sed 's/^[^0-9]*//'`\n    else\n      tfgr_date=`date '+%H%M%S'`\n      tfgr_random=`expr \"${tfgr_date}\" \\* $$`\n      unset tfgr_date\n    fi\n    \\[ \"${tfgr_random}\" = \"${th_RANDOM}\" ] && sleep 1\n  done\n\n  th_RANDOM=${tfgr_random}\n  unset tfgr_random\n}\n\n# This section returns the data section from the specified section of a file. A\n# data section is defined by a [header], one or more lines of data, and then a\n# blank line.\nth_getDataSect() {\n  th_sgrep \"\\\\[$1\\\\]\" \"$2\" |sed '1d'\n}\n\n# This function greps a section from a file. a section is defined as a group of\n# lines preceded and followed by blank lines..\nth_sgrep() {\n  th_pattern_=$1\n  shift\n\n  # shellcheck disable=SC2068\n  sed -e '/./{H;$!d;}' -e \"x;/${th_pattern_}/\"'!d;' $@ |sed '1d'\n\n  unset th_pattern_\n}\n\n# Custom assert that checks for true return value (0), and no output to STDOUT\n# or STDERR. If a non-zero return value is encountered, the output of STDERR\n# will be output.\n#\n# Args:\n#  th_test_: string: name of the subtest\n#  th_rtrn_: integer: the return value of the subtest performed\n#  th_stdout_: string: filename where stdout was redirected to\n#  th_stderr_: string: filename where stderr was redirected to\nth_assertTrueWithNoOutput() {\n  th_test_=$1\n  th_rtrn_=$2\n  th_stdout_=$3\n  th_stderr_=$4\n\n  assertTrue \"${th_test_}; expected return value of zero\" \"${th_rtrn_}\"\n  \\[ \"${th_rtrn_}\" -ne \"${SHUNIT_TRUE}\" ] && \\cat \"${th_stderr_}\"\n  assertFalse \"${th_test_}; expected no output to STDOUT\" \\\n      \"[ -s '${th_stdout_}' ]\"\n  assertFalse \"${th_test_}; expected no output to STDERR\" \\\n      \"[ -s '${th_stderr_}' ]\"\n\n  unset th_test_ th_rtrn_ th_stdout_ th_stderr_\n}\n\n# Custom assert that checks for non-zero return value, output to STDOUT, but no\n# output to STDERR.\n#\n# Args:\n#  th_test_: string: name of the subtest\n#  th_rtrn_: integer: the return value of the subtest performed\n#  th_stdout_: string: filename where stdout was redirected to\n#  th_stderr_: string: filename where stderr was redirected to\nth_assertFalseWithOutput()\n{\n  th_test_=$1\n  th_rtrn_=$2\n  th_stdout_=$3\n  th_stderr_=$4\n\n  assertFalse \"${th_test_}; expected non-zero return value\" \"${th_rtrn_}\"\n  assertTrue \"${th_test_}; expected output to STDOUT\" \\\n      \"[ -s '${th_stdout_}' ]\"\n  assertFalse \"${th_test_}; expected no output to STDERR\" \\\n      \"[ -s '${th_stderr_}' ]\"\n  \\[ -s \"${th_stdout_}\" -a ! -s \"${th_stderr_}\" ] || \\\n      _th_showOutput \"${SHUNIT_FALSE}\" \"${th_stdout_}\" \"${th_stderr_}\"\n\n  unset th_test_ th_rtrn_ th_stdout_ th_stderr_\n}\n\n# Custom assert that checks for non-zero return value, no output to STDOUT, but\n# output to STDERR.\n#\n# Args:\n#  th_test_: string: name of the subtest\n#  th_rtrn_: integer: the return value of the subtest performed\n#  th_stdout_: string: filename where stdout was redirected to\n#  th_stderr_: string: filename where stderr was redirected to\nth_assertFalseWithError() {\n  th_test_=$1\n  th_rtrn_=$2\n  th_stdout_=$3\n  th_stderr_=$4\n\n  assertFalse \"${th_test_}; expected non-zero return value\" \"${th_rtrn_}\"\n  assertFalse \"${th_test_}; expected no output to STDOUT\" \\\n      \"[ -s '${th_stdout_}' ]\"\n  assertTrue \"${th_test_}; expected output to STDERR\" \\\n      \"[ -s '${th_stderr_}' ]\"\n  \\[ ! -s \"${th_stdout_}\" -a -s \"${th_stderr_}\" ] || \\\n      _th_showOutput \"${SHUNIT_FALSE}\" \"${th_stdout_}\" \"${th_stderr_}\"\n\n  unset th_test_ th_rtrn_ th_stdout_ th_stderr_\n}\n\n# Some shells, zsh on Solaris in particular, return immediately from a sub-shell\n# when a non-zero return value is encountered. To properly catch these values,\n# they are either written to disk, or recognized as an error the file is empty.\nth_clearReturn() { cp /dev/null \"${returnF}\"; }\nth_queryReturn() {\n  if \\[ -s \"${returnF}\" ]; then\n    th_return=`\\cat \"${returnF}\"`\n  else\n    th_return=${SHUNIT_ERROR}\n  fi\n  export th_return\n}\n\n# Providing external and internal calls to the showOutput helper function.\nth_showOutput() { _th_showOutput \"$@\"; }\n_th_showOutput() {\n  _th_return_=$1\n  _th_stdout_=$2\n  _th_stderr_=$3\n\n  isSkipping\n  if \\[ $? -eq \"${SHUNIT_FALSE}\" -a \"${_th_return_}\" != \"${SHUNIT_TRUE}\" ]; then\n    if \\[ -n \"${_th_stdout_}\" -a -s \"${_th_stdout_}\" ]; then\n      echo '>>> STDOUT' >&2\n      \\cat \"${_th_stdout_}\" >&2\n    fi\n    if \\[ -n \"${_th_stderr_}\" -a -s \"${_th_stderr_}\" ]; then\n      echo '>>> STDERR' >&2\n      \\cat \"${_th_stderr_}\" >&2\n    fi\n    if \\[ -n \"${_th_stdout_}\" -o -n \"${_th_stderr_}\" ]; then\n      echo '<<< end output' >&2\n    fi\n  fi\n\n  unset _th_return_ _th_stdout_ _th_stderr_\n}\n\n#\n# Main.\n#\n\n${TRACE} 'trace output enabled'\n${DEBUG} 'debug output enabled'\n"
  },
  {
    "path": "tests/shunit/test_runner",
    "content": "#! /bin/sh\n# vim:et:ft=sh:sts=2:sw=2\n#\n# Unit test suite runner.\n#\n# Copyright 2008-2018 Kate Ward. All Rights Reserved.\n# Released under the Apache 2.0 license.\n#\n# Author: kate.ward@forestent.com (Kate Ward)\n# https://github.com/kward/shlib\n#\n# This script runs all the unit tests that can be found, and generates a nice\n# report of the tests.\n#\n### ShellCheck (http://www.shellcheck.net/)\n# Disable source following.\n#   shellcheck disable=SC1090,SC1091\n# expr may be antiquated, but it is the only solution in some cases.\n#   shellcheck disable=SC2003\n# $() are not fully portable (POSIX != portable).\n#   shellcheck disable=SC2006\n\n# Return if test_runner already loaded.\n[ -z \"${RUNNER_LOADED:-}\" ] || return 0\nRUNNER_LOADED=0\n\nRUNNER_ARGV0=`basename \"$0\"`\nRUNNER_SHELLS='/bin/sh ash /bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/zsh'\nRUNNER_TEST_SUFFIX='_test.sh'\ntrue; RUNNER_TRUE=$?\nfalse; RUNNER_FALSE=$?\n\nrunner_warn() { echo \"runner:WARN $*\" >&2; }\nrunner_error() { echo \"runner:ERROR $*\" >&2; }\nrunner_fatal() { echo \"runner:FATAL $*\" >&2; exit 1; }\n\nrunner_usage() {\n  echo \"usage: ${RUNNER_ARGV0} [-e key=val ...] [-s shell(s)] [-t test(s)]\"\n}\n\n_runner_tests() { echo ./*${RUNNER_TEST_SUFFIX} |sed 's#./##g'; }\n_runner_testName() {\n  # shellcheck disable=SC1117\n  _runner_testName_=`expr \"${1:-}\" : \"\\(.*\\)${RUNNER_TEST_SUFFIX}\"`\n  if [ -n \"${_runner_testName_}\" ]; then\n    echo \"${_runner_testName_}\"\n  else\n    echo 'unknown'\n  fi\n  unset _runner_testName_\n}\n\nmain() {\n  # Find and load versions library.\n  for _runner_dir_ in . ${LIB_DIR:-lib}; do\n    if [ -r \"${_runner_dir_}/versions\" ]; then\n      _runner_lib_dir_=\"${_runner_dir_}\"\n      break\n    fi\n  done\n  [ -n \"${_runner_lib_dir_}\" ] || runner_fatal 'Unable to find versions library.'\n  . \"${_runner_lib_dir_}/versions\" || runner_fatal 'Unable to load versions library.'\n  unset _runner_dir_ _runner_lib_dir_\n\n  # Process command line flags.\n  env=''\n  while getopts 'e:hs:t:' opt; do\n    case ${opt} in\n      e)  # set an environment variable\n        key=`expr \"${OPTARG}\" : '\\([^=]*\\)='`\n        val=`expr \"${OPTARG}\" : '[^=]*=\\(.*\\)'`\n        # shellcheck disable=SC2166\n        if [ -z \"${key}\" -o -z \"${val}\" ]; then\n          runner_usage\n          exit 1\n        fi\n        eval \"${key}='${val}'\"\n        eval \"export ${key}\"\n        env=\"${env:+${env} }${key}\"\n        ;;\n      h) runner_usage; exit 0 ;;  # help output\n      s) shells=${OPTARG} ;;  # list of shells to run\n      t) tests=${OPTARG} ;;  # list of tests to run\n      *) runner_usage; exit 1 ;;\n    esac\n  done\n  shift \"`expr ${OPTIND} - 1`\"\n\n  # Fill shells and/or tests.\n  shells=${shells:-${RUNNER_SHELLS}}\n  [ -z \"${tests}\" ] && tests=`_runner_tests`\n\n  # Error checking.\n  if [ -z \"${tests}\" ]; then\n    runner_error 'no tests found to run; exiting'\n    exit 1\n  fi\n\n  cat <<EOF\n#------------------------------------------------------------------------------\n# System data.\n#\n\n$ uname -mprsv\n`uname -mprsv`\n\nOS Name: `versions_osName`\nOS Version: `versions_osVersion`\n\n### Test run info.\nshells: ${shells}\ntests: ${tests}\nEOF\nfor key in ${env}; do\n  eval \"echo \\\"${key}=\\$${key}\\\"\"\ndone\n\n# Run tests.\nrunner_passing_=${RUNNER_TRUE}\nfor shell in ${shells}; do\n  echo\n\n  cat <<EOF\n\n#------------------------------------------------------------------------------\n# Running the test suite with ${shell}.\n#\nEOF\n\n    # Check for existence of shell.\n    shell_bin=${shell}\n    shell_name=''\n    shell_present=${RUNNER_FALSE}\n    case ${shell} in\n      ash)\n        shell_bin=`command -v busybox`\n        [ $? -eq \"${RUNNER_TRUE}\" ] && shell_present=\"${RUNNER_TRUE}\"\n        shell_bin=\"${shell_bin:+${shell_bin} }ash\"\n        shell_name=${shell}\n        ;;\n      *)\n        [ -x \"${shell_bin}\" ] && shell_present=\"${RUNNER_TRUE}\"\n        shell_name=`basename \"${shell}\"`\n        ;;\n    esac\n    if [ \"${shell_present}\" -eq \"${RUNNER_FALSE}\" ]; then\n      runner_warn \"unable to run tests with the ${shell_name} shell\"\n      continue\n    fi\n\n    shell_version=`versions_shellVersion \"${shell}\"`\n\n    echo \"shell name: ${shell_name}\"\n    echo \"shell version: ${shell_version}\"\n\n    # Execute the tests.\n    for t in ${tests}; do\n      echo\n      echo \"--- Executing the '`_runner_testName \"${t}\"`' test suite. ---\"\n      # ${shell_bin} needs word splitting.\n      #   shellcheck disable=SC2086\n      ( exec ${shell_bin} \"./${t}\" 2>&1; )\n      test \"${runner_passing_}\" -eq ${RUNNER_TRUE} -a $? -eq ${RUNNER_TRUE}\n      runner_passing_=$?\n    done\n  done\n  return ${runner_passing_}\n}\n\n# Execute main() if this is run in standalone mode (i.e. not from a unit test).\n[ -z \"${SHUNIT_VERSION}\" ] && main \"$@\"\n"
  },
  {
    "path": "tests/signal1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/signal.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nsignal-help()\n{\n\t__monitor HELP \"$@\"\n}\n\n_get_signal_names()\n{\n\t__monitor GETSIGNALNAMES \"$@\"\n}\n\n_validate_signal_name()\n{\n\t__monitor VALIDATESIGNALNAME \"$@\"\n\tif [ \"$1\" = \"SIGINFO\" ] || [ \"$1\" = \"SIGHUP\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_validate_pid()\n{\n\t__monitor VALIDATEPID \"$@\"\n\tif [ \"$1\" = \"1234\" ]; then\n\t\treturn 0 # true\n\tfi\n\treturn 1 # false\n}\n\n_send_signal()\n{\n\t__monitor SENDSIGNAL \"$@\"\n}\n\ntest_pot_signal_001()\n{\n\tpot-signal\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n\n\tsetUp\n\tpot-signal -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n\n\tsetUp\n\tpot-signal -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n\n\tsetUp\n\tpot-signal -v\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n}\n\ntest_pot_signal_002()\n{\n\tpot-signal -p test-pot -s SIGBAD\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Validate signal calls\" \"1\" VALIDATESIGNALNAME_CALLS\n\tassertEqualsMon \"Validate signal arg\" \"SIGBAD\" VALIDATESIGNALNAME_CALL1_ARG1\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n\n\tsetUp\n\tpot-signal -p test-pot -P 1234 -m cmd\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Validate pid calls\" \"0\" VALIDATEPID_CALLS\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n\n\tsetUp\n\tpot-signal -p test-pot -P cmd\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Validate pid calls\" \"1\" VALIDATEPID_CALLS\n\tassertEqualsMon \"Validate pid calls\" \"cmd\" VALIDATEPID_CALL1_ARG1\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n}\n\ntest_pot_signal_003()\n{\n\tpot-signal -p test-pot -P 1234\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Validate pid calls\" \"1\" VALIDATEPID_CALLS\n\tassertEqualsMon \"Validate pid calls\" \"1234\" VALIDATEPID_CALL1_ARG1\n\tassertEqualsMon \"Validate signal calls\" \"1\" VALIDATESIGNALNAME_CALLS\n\tassertEqualsMon \"Validate signal arg\" \"SIGINFO\" VALIDATESIGNALNAME_CALL1_ARG1\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"Send signal calls\" \"0\" SENDSIGNAL_CALLS\n}\n\ntest_pot_signal_020()\n{\n\tpot-signal -p test-pot-run\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"1\" SENDSIGNAL_CALLS\n\tassertEqualsMon \"Send signal arg1\" \"test-pot-run\" SENDSIGNAL_CALL1_ARG1\n\tassertEqualsMon \"Send signal arg2\" \"SIGINFO\" SENDSIGNAL_CALL1_ARG2\n\tassertEqualsMon \"Send signal arg3\" \"\" SENDSIGNAL_CALL1_ARG3\n\tassertEqualsMon \"Send signal arg4\" \"\" SENDSIGNAL_CALL1_ARG4\n\tassertEqualsMon \"Send signal arg5\" \"NO\" SENDSIGNAL_CALL1_ARG5\n\tassertEqualsMon \"Send signal arg6\" \"NO\" SENDSIGNAL_CALL1_ARG6\n\n\tsetUp\n\tpot-signal -p test-pot-run -s SIGHUP\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"1\" SENDSIGNAL_CALLS\n\tassertEqualsMon \"Send signal arg1\" \"test-pot-run\" SENDSIGNAL_CALL1_ARG1\n\tassertEqualsMon \"Send signal arg2\" \"SIGHUP\" SENDSIGNAL_CALL1_ARG2\n\tassertEqualsMon \"Send signal arg3\" \"\" SENDSIGNAL_CALL1_ARG3\n\tassertEqualsMon \"Send signal arg4\" \"\" SENDSIGNAL_CALL1_ARG4\n\tassertEqualsMon \"Send signal arg5\" \"NO\" SENDSIGNAL_CALL1_ARG5\n\tassertEqualsMon \"Send signal arg6\" \"NO\" SENDSIGNAL_CALL1_ARG6\n}\n\ntest_pot_signal_021()\n{\n\tpot-signal -p test-pot-run -s SIGHUP -P 1234 -f -C\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"1\" SENDSIGNAL_CALLS\n\tassertEqualsMon \"Send signal arg1\" \"test-pot-run\" SENDSIGNAL_CALL1_ARG1\n\tassertEqualsMon \"Send signal arg2\" \"SIGHUP\" SENDSIGNAL_CALL1_ARG2\n\tassertEqualsMon \"Send signal arg3\" \"1234\" SENDSIGNAL_CALL1_ARG3\n\tassertEqualsMon \"Send signal arg4\" \"\" SENDSIGNAL_CALL1_ARG4\n\tassertEqualsMon \"Send signal arg5\" \"YES\" SENDSIGNAL_CALL1_ARG5\n\tassertEqualsMon \"Send signal arg6\" \"YES\" SENDSIGNAL_CALL1_ARG6\n}\n\ntest_pot_signal_022()\n{\n\tpot-signal -p test-pot-run -s SIGINFO -m grep -f -C\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Send signal calls\" \"1\" SENDSIGNAL_CALLS\n\tassertEqualsMon \"Send signal arg1\" \"test-pot-run\" SENDSIGNAL_CALL1_ARG1\n\tassertEqualsMon \"Send signal arg2\" \"SIGINFO\" SENDSIGNAL_CALL1_ARG2\n\tassertEqualsMon \"Send signal arg3\" \"\" SENDSIGNAL_CALL1_ARG3\n\tassertEqualsMon \"Send signal arg4\" \"grep\" SENDSIGNAL_CALL1_ARG4\n\tassertEqualsMon \"Send signal arg5\" \"YES\" SENDSIGNAL_CALL1_ARG5\n\tassertEqualsMon \"Send signal arg6\" \"YES\" SENDSIGNAL_CALL1_ARG6\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/signal2.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npkill()\n{\n\t__monitor PKILL \"$@\"\n}\n\npgrep()\n{\n\t__monitor PGREP \"$@\"\n}\n\nmktemp()\n{\n\t__monitor MKTEMP \"$@\"\n\techo /dev/null\n}\n\nrm()\n{\n\t__monitor RM \"$@\"\n}\n\n# UUT\n. ../share/pot/signal.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n_get_conf_var()\n{\n\t__monitor GETCONFVAR \"$@\"\n\tif [ \"$1\" = \"test-pot-presist\" ]; then\n\t\techo \"YES\"\n\t\treturn\n\tfi\n\techo \"NO\"\n}\n\n# app specific stubs\n\ntest_send_signal_001()\n{\n\t_send_signal test-pot SIGINFO \"\" \"\" \"NO\" \"NO\"\n\tassertEqualsMon \"pgrep calls\" \"0\" PGREP_CALLS\n\tassertEqualsMon \"pkill calls\" \"1\" PKILL_CALLS\n\tassertEqualsMon \"pkill arg1\" \"-SIGINFO\" PKILL_CALL1_ARG1\n\tassertEqualsMon \"pkill arg2\" \"-j\" PKILL_CALL1_ARG2\n\tassertEqualsMon \"pkill arg3\" \"test-pot\" PKILL_CALL1_ARG3\n\tassertEqualsMon \"pkill arg4\" \"-F\" PKILL_CALL1_ARG4\n\tassertEqualsMon \"pkill arg5\" \"/tmp/pot_main_pid_test-pot\" PKILL_CALL1_ARG5\n\tassertEqualsMon \"rm calls\" \"0\" RM_CALLS\n}\n\ntest_send_signal_002()\n{\n\t_send_signal test-pot-presist SIGINFO \"\" \"\" \"NO\" \"NO\"\n\trc=$?\n\tassertEquals \"return code\" \"1\" \"$rc\"\n\tassertEqualsMon \"pgrep calls\" \"0\" PGREP_CALLS\n\tassertEqualsMon \"pkill calls\" \"0\" PKILL_CALLS\n}\n\ntest_send_signal_003()\n{\n\t_send_signal test-pot-presist SIGINFO \"\" \"\" \"YES\" \"NO\"\n\trc=$?\n\tassertEquals \"return code\" \"0\" \"$rc\"\n\tassertEqualsMon \"pgrep calls\" \"0\" PGREP_CALLS\n\tassertEqualsMon \"pkill calls\" \"0\" PKILL_CALLS\n}\n\ntest_send_signal_010()\n{\n\t_send_signal test-pot SIGINFO \"\" \"command\" \"NO\" \"NO\"\n\tassertEqualsMon \"pgrep calls\" \"0\" PGREP_CALLS\n\tassertEqualsMon \"pkill calls\" \"1\" PKILL_CALLS\n\tassertEqualsMon \"pkill arg1\" \"-SIGINFO\" PKILL_CALL1_ARG1\n\tassertEqualsMon \"pkill arg2\" \"-j\" PKILL_CALL1_ARG2\n\tassertEqualsMon \"pkill arg3\" \"test-pot\" PKILL_CALL1_ARG3\n\tassertEqualsMon \"pkill arg4\" \"command\" PKILL_CALL1_ARG4\n\tassertEqualsMon \"rm calls\" \"0\" RM_CALLS\n}\n\ntest_send_signal_011()\n{\n\t_send_signal test-pot SIGINFO \"1234\" \"\" \"NO\" \"NO\"\n\tassertEqualsMon \"pgrep calls\" \"0\" PGREP_CALLS\n\tassertEqualsMon \"pkill calls\" \"1\" PKILL_CALLS\n\tassertEqualsMon \"pkill arg1\" \"-SIGINFO\" PKILL_CALL1_ARG1\n\tassertEqualsMon \"pkill arg2\" \"-j\" PKILL_CALL1_ARG2\n\tassertEqualsMon \"pkill arg3\" \"test-pot\" PKILL_CALL1_ARG3\n\tassertEqualsMon \"pkill arg4\" \"-F\" PKILL_CALL1_ARG4\n\tassertEqualsMon \"pkill arg5\" \"/dev/null\" PKILL_CALL1_ARG5\n\tassertEqualsMon \"rm calls\" \"1\" RM_CALLS\n}\n\ntest_send_signal_020()\n{\n\t_send_signal test-pot SIGINFO \"\" \"\" \"NO\" \"YES\"\n\tassertEqualsMon \"pgrep calls\" \"1\" PGREP_CALLS\n\tassertEqualsMon \"pkill arg1\" \"-j\" PGREP_CALL1_ARG1\n\tassertEqualsMon \"pkill arg2\" \"test-pot\" PGREP_CALL1_ARG2\n\tassertEqualsMon \"pkill arg4\" \"/tmp/pot_main_pid_test-pot\" PGREP_CALL1_ARG4\n\tassertEqualsMon \"pkill calls\" \"0\" PKILL_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/snapshot1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/snapshot.sh\n\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nsnapshot-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_snapshot_001()\n{\n\tpot-snapshot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\n\tsetUp\n\tpot-snapshot -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\n\tsetUp\n\tpot-snapshot -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\n\tsetUp\n\tpot-snapshot -va\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n}\n\ntest_pot_snapshot_002()\n{\n\tpot-snapshot -f test-fscomp -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_003()\n{\n\tpot-snapshot -p test-pot -f test-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_004()\n{\n\tpot-snapshot -p test-pot -n backup\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_020()\n{\n\tpot-snapshot -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\n\tsetUp\n\tpot-snapshot -p not-a-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\n\tsetUp\n\tpot-snapshot -p test-pot-run\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n}\n\ntest_pot_snapshot_021()\n{\n\tpot-snapshot -p test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"1\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap arg\" \"test-pot\" POTZFSSNAP_CALL1_ARG1\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n}\n\ntest_pot_snapshot_022()\n{\n\tpot-snapshot -p test-pot -a\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_023()\n{\n\tpot-snapshot -p test-pot -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"1\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"1\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap arg\" \"test-pot\" RMVPOTSNAP_CALL1_ARG1\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"1\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap arg\" \"test-pot\" POTZFSSNAP_CALL1_ARG1\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n}\n\ntest_pot_snapshot_040()\n{\n\tpot-snapshot -f\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\n\tsetUp\n\tpot-snapshot -f not-a-fscomp\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"1\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n}\n\ntest_pot_snapshot_041()\n{\n\tpot-snapshot -f test-fscomp\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"1\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"1\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap arg\" \"test-fscomp\" FSCOMPZFSSNAP_CALL1_ARG1\n\tassertEqualsMon \"_fscomp_zfs_snap arg\" \"\" FSCOMPZFSSNAP_CALL1_ARG2\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_042()\n{\n\tpot-snapshot -f test-fscomp -a\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_043()\n{\n\tpot-snapshot -f test-fscomp -n backup\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"0\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"0\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"0\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\ntest_pot_snapshot_044()\n{\n\tpot-snapshot -f test-fscomp -r\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot calls\" \"0\" ISPOT_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_pot_zfs_snap calls\" \"0\" POTZFSSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_pot_snap calls\" \"0\" RMVPOTSNAP_CALLS\n\tassertEqualsMon \"_pot_zfs_snap_full calls\" \"0\" POTZFSSNAPFULL_CALLS\n\tassertEqualsMon \"_zfs_exist calls\" \"1\" ZFSEXIST_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap calls\" \"1\" RMVFSCOMPSNAP_CALLS\n\tassertEqualsMon \"_remove_oldest_fscomp_snap arg\" \"test-fscomp\" RMVFSCOMPSNAP_CALL1_ARG1\n\tassertEqualsMon \"_fscomp_zfs_snap calls\" \"1\" FSCOMPZFSSNAP_CALLS\n\tassertEqualsMon \"_fscomp_zfs_snap arg\" \"test-fscomp\" FSCOMPZFSSNAP_CALL1_ARG1\n\tassertEqualsMon \"_fscomp_zfs_snap arg\" \"\" FSCOMPZFSSNAP_CALL1_ARG2\n\tassertEqualsMon \"Info calls\" \"0\" INFO_CALLS\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/start2.sh",
    "content": "#!/bin/sh\n\n: ${MKTEMP_FILE:=/tmp/pot_pfrules_test}\n# system utilities stubs\npfctl()\n{\n\t__monitor PFCTL \"$@\"\n}\n\nmktemp()\n{\n\ttouch $MKTEMP_FILE\n\techo $MKTEMP_FILE\n}\n\nrm()\n{\n\t:\n}\n\n# UUT\n. ../share/pot/start.sh\n\nPOT_MKTEMP_SUFFIX=XXX\n\n# common stubs\n. common-stub.sh\n\n_get_pot_export_ports()\n{\n\t__monitor GETEXPORTPORTS \"$@\"\n}\n\n_js_get_free_rnd_port()\n{\n\t__monitor RNDPORT \"$@\"\n\techo 3333\n}\n\n_get_ip_var()\n{\n\techo 1.2.3.4\n}\n\n_get_pot_export_ports()\n{\n\tcase $1 in\n\t\"test-pot80\")\n\t\techo 80\n\t\t;;\n\t\"test-pot80s3000\")\n\t\techo 80:3000\n\t\t;;\n\t\"test-pot80433\")\n\t\techo 80 433:3000\n\t\t;;\n\t\"test-pot53udp80433tcp\")\n\t\techo udp:53:53 tcp:80 tcp:433:3000\n\t\t;;\n\t*)\n\t\t;;\n\tesac\n}\n\ntest_js_export_ports_001()\n{\n\t_js_export_ports test-pot80\n\tassertEqualsMon \"pfctl calls\" \"1\" PFCTL_CALLS\n\tassertEquals \"pfrules lines\" \"1\" \"$( wc -l $MKTEMP_FILE | awk '{print $1}')\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto tcp from any to (em2) port 3333 -> 1.2.3.4 port 80\" \"$(sed '1!d' $MKTEMP_FILE)\"\n}\n\n\ntest_js_export_ports_002()\n{\n\t_js_export_ports test-pot80s3000\n\tassertEqualsMon \"pfctl calls\" \"1\" PFCTL_CALLS\n\tassertEquals \"pfrules lines\" \"1\" \"$( wc -l $MKTEMP_FILE | awk '{print $1}')\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto tcp from any to (em2) port 3000 -> 1.2.3.4 port 80\" \"$(sed '1!d' $MKTEMP_FILE)\"\n}\n\ntest_js_export_ports_003()\n{\n\t_js_export_ports test-pot80433\n\tassertEqualsMon \"pfctl calls\" \"1\" PFCTL_CALLS\n\tassertEquals \"pfrules lines\" \"2\" \"$( wc -l $MKTEMP_FILE | awk '{print $1}')\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto tcp from any to (em2) port 3333 -> 1.2.3.4 port 80\" \"$(sed '1!d' $MKTEMP_FILE)\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto tcp from any to (em2) port 3000 -> 1.2.3.4 port 433\" \"$(sed '2!d' $MKTEMP_FILE)\"\n}\n\ntest_js_export_ports_004()\n{\n\t_js_export_ports test-pot53udp80433tcp\n\tassertEqualsMon \"pfctl calls\" \"1\" PFCTL_CALLS\n\tassertEquals \"pfrules lines\" \"3\" \"$( wc -l $MKTEMP_FILE | awk '{print $1}')\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto udp from any to (em2) port 53 -> 1.2.3.4 port 53\" \"$(sed '1!d' $MKTEMP_FILE)\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto tcp from any to (em2) port 3333 -> 1.2.3.4 port 80\" \"$(sed '2!d' $MKTEMP_FILE)\"\n\tassertEquals \"rdr rule\" \"rdr pass on em2 proto tcp from any to (em2) port 3000 -> 1.2.3.4 port 433\" \"$(sed '3!d' $MKTEMP_FILE)\"\n}\nsetUp()\n{\n\tcommon_setUp\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n\tPOT_EXTIF=\"em2\"\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\t/bin/rm -f $MKTEMP_FILE\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/start3.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npfctl()\n{\n\t__monitor PFCTL \"$@\"\n}\n\nSED=sed_stub\nsed_stub()\n{\n\tif [ \"$(uname)\" = \"Linux\" ]; then\n\t\tshift 2\n\t\tsed -i'' \"$@\"\n\telse\n\t\tsed \"$@\"\n\tfi\n}\n\nPOT_MKTEMP_SUFFIX=XXX\n\n# UUT\n. ../share/pot/start.sh\n\n# common stubs\n. ../share/pot/common.sh\n. ../share/pot/set-env.sh\n. common-stub.sh\n. conf-stub.sh\n\ncp()\n{\n\t:\n}\n\npot-cmd()\n{\n\techo _POT_NAME=test-pot\n}\n\ntest_js_env_001()\n{\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"1\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n}\n\ntest_js_env_020()\n{\n\tpot-set-env -p test-pot -E VAR=value\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=value\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line2\" \"0\" \"$( grep -F -c 'export \"VAR2=' /tmp/pot_environment_test-pot.sh)\"\n\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$VAR\" \"value\"\n#\tassertEquals \"export validation\" \"$_POT_NAME\" \"test-pot\"\n}\n\ntest_js_env_021()\n{\n\tpot-set-env -p test-pot -E VAR=value -E VAR2=value2\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"3\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=value\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR2=value2\"' /tmp/pot_environment_test-pot.sh)\"\n\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$VAR\" \"value\"\n#\tassertEquals \"export validation\" \"$VAR2\" \"value2\"\n}\n\ntest_js_env_022()\n{\n\tpot-set-env -p test-pot -E VAR=\"value1 value2\"\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=value1 value2\"' /tmp/pot_environment_test-pot.sh)\"\n\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$VAR\" \"value1 value2\"\n}\n\ntest_js_env_023()\n{\n\tpot-set-env -p test-pot -E \"VAR=value1 value2\" -E VAR2=value3\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"3\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=value1 value2\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR2=value3\"' /tmp/pot_environment_test-pot.sh)\"\n\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$VAR\" \"value1 value2\"\n#\tassertEquals \"export validation\" \"$VAR2\" \"value3\"\n}\n\ntest_js_env_024()\n{\n\tpot-set-env -p test-pot -E \"EMPTYVAR=\"\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"EMPTYVAR=\"' /tmp/pot_environment_test-pot.sh)\"\n#\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$EMPTYVAR\" \"\"\n}\n\ntest_js_env_025()\n{\n\tpot-set-env -p test-pot -E \"VAR=12*\"\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=12*\"' /tmp/pot_environment_test-pot.sh)\"\n#\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$VAR\" \"12*\"\n}\n\ntest_js_env_026()\n{\n\tpot-set-env -p test-pot -E \"VAR=12*\" -E \"VAR2=?h* \"\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"3\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=12*\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR2=?h* \"' /tmp/pot_environment_test-pot.sh)\"\n\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" \"$VAR\" \"12*\"\n#\tassertEquals \"export validation\" \"$VAR2\" \"?h* \"\n}\n\ntest_js_env_027()\n{\n\tpot-set-env -p test-pot -E 'VAR=value1 \"value2\"'\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"2\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR=value1 \\\"value2\\\"\"' /tmp/pot_environment_test-pot.sh)\"\n#\n#\t. /tmp/pot_environment_test-pot.sh\n#\tassertEquals \"export validation\" 'value1 \"value2\"' \"$VAR\"\n}\n\ntest_js_env_040()\n{\n\tpot-set-env -p test-pot -E VAR1=value1 -E \"VAR2=value1 value2\" -E 'VAR3=value1 value2 value3' -E VAR4=value4\n\t_js_env test-pot\n#\tassertTrue \"env script exists\" \"[ -e /tmp/pot_environment_test-pot.sh ]\"\n#\tassertEquals \"env script length\" \"5\" \"$( awk 'END {print NR}' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR1=value1\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR2=value1 value2\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR3=value1 value2 value3\"' /tmp/pot_environment_test-pot.sh)\"\n#\tassertEquals \"export line\" \"1\" \"$( grep -F -c 'export \"VAR4=value4\"' /tmp/pot_environment_test-pot.sh)\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n\tconf_setUp\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\tconf_tearDown\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/start4.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\npotnet()\n{\n\tif [ -z \"$3\" ]; then\n\t\t# public bridge\n\t\techo \"10.1.2.3 test-pot-2\"\n\t\techo \"10.1.2.4 test-single\"\n\tfi\n\tif [ \"$3\" = \"test-bridge\" ]; then\n\t\t# private-bridge\n\t\techo \"10.1.3.3 test-pot-multi-private\"\n\tfi\n}\n\n# UUT\n. ../share/pot/start.sh\n\n# common stubs\n. common-stub.sh\n\ntest_js_etc_hosts_000()\n{\n\t_js_etc_hosts test-pot-2\n\tassertTrue \"/etc/hosts\" \"[ -r /tmp/jails/test-pot-2/m/etc ]\"\n\tassertEquals \"/etc/hosts length\" \"4\" \"$( awk 'END {print NR}' /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"127.0.0.1\" \"127.0.0.1 localhost test-pot-2.test-domain\" \"$( grep \"^127.0.0.1\" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"::1\" \"::1 localhost test-pot-2.test-domain\" \"$( grep \"^::1\" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"test-pot-2\" \"10.1.2.3 test-pot-2\" \"$( grep \"^10.1.2.3 \" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"test-single\" \"10.1.2.4 test-single\" \"$( grep \"^10.1.2.4 \" /tmp/jails/test-pot-2/m/etc/hosts)\"\n}\n\ntest_js_etc_hosts_001()\n{\n\t_js_etc_hosts test-pot-multi-private\n\tassertTrue \"/etc/hosts\" \"[ -r /tmp/jails/test-pot-multi-private/m/etc ]\"\n\tassertEquals \"/etc/hosts length\" \"3\" \"$( awk 'END {print NR}' /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"127.0.0.1\" \"127.0.0.1 localhost test-pot-multi-private.test-domain\" \"$( grep \"^127.0.0.1\" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"::1\" \"::1 localhost test-pot-multi-private.test-domain\" \"$( grep \"^::1\" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"test-pot-multi-private\" \"10.1.3.3 test-pot-multi-private\" \"$( grep \"^10.1.3.3 \" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n}\n\ntest_js_etc_hosts_020()\n{\n\techo \"pot.hosts=10.10.10.1 test-pot-custom\" > /tmp/jails/test-pot-2/conf/pot.conf\n\techo \"pot.hosts=10.10.10.2 test-pot-custom-2\" >> /tmp/jails/test-pot-2/conf/pot.conf\n\t_js_etc_hosts test-pot-2\n\tassertTrue \"/etc/hosts\" \"[ -r /tmp/jails/test-pot-2/m/etc ]\"\n\tassertEquals \"/etc/hosts length\" \"6\" \"$( awk 'END {print NR}' /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"127.0.0.1\" \"127.0.0.1 localhost test-pot-2.test-domain\" \"$( grep \"^127.0.0.1\" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"::1\" \"::1 localhost test-pot-2.test-domain\" \"$( grep \"^::1\" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"test-pot-2\" \"10.1.2.3 test-pot-2\" \"$( grep \"^10.1.2.3 \" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"test-single\" \"10.1.2.4 test-single\" \"$( grep \"^10.1.2.4 \" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"test-pot-custom\" \"10.10.10.1 test-pot-custom\" \"$( grep \"^10.10.10.1 \" /tmp/jails/test-pot-2/m/etc/hosts)\"\n\tassertEquals \"test-pot-custom-2\" \"10.10.10.2 test-pot-custom-2\" \"$( grep \"^10.10.10.2 \" /tmp/jails/test-pot-2/m/etc/hosts)\"\n}\n\ntest_js_etc_hosts_021()\n{\n\techo \"pot.hosts=10.10.10.1 test-pot-custom\" > /tmp/jails/test-pot-multi-private/conf/pot.conf\n\techo \"pot.hosts=10.10.10.2 test-pot-custom-2\" >> /tmp/jails/test-pot-multi-private/conf/pot.conf\n\t_js_etc_hosts test-pot-multi-private\n\tassertTrue \"/etc/hosts\" \"[ -r /tmp/jails/test-pot-multi-private/m/etc/hosts ]\"\n\tassertEquals \"/etc/hosts length\" \"5\" \"$( awk 'END {print NR}' /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"127.0.0.1\" \"127.0.0.1 localhost test-pot-multi-private.test-domain\" \"$( grep \"^127.0.0.1\" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"::1\" \"::1 localhost test-pot-multi-private.test-domain\" \"$( grep \"^::1\" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"test-pot-multi-private\" \"10.1.3.3 test-pot-multi-private\" \"$( grep \"^10.1.3.3 \" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"test-pot-custom\" \"10.10.10.1 test-pot-custom\" \"$( grep \"^10.10.10.1 \" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n\tassertEquals \"test-pot-custom-2\" \"10.10.10.2 test-pot-custom-2\" \"$( grep \"^10.10.10.2 \" /tmp/jails/test-pot-multi-private/m/etc/hosts)\"\n}\n\ntest_js_resolv_001()\n{\n\t_js_resolv test-pot-dns-off\n\tassertFalse \"off created a resolv.conf\" \"[ -r /tmp/jails/test-pot-dns-off/m/etc/resolv.conf ]\"\n}\n\ntest_js_resolv_002()\n{\n\t_js_resolv test-pot-dns-inherit\n\tassertTrue \"not created a resolv.conf\" \"[ -r /tmp/jails/test-pot-dns-inherit/m/etc/resolv.conf ]\"\n\tassertTrue \"wrong resolv.conf\" \"diff /tmp/jails/test-pot-dns-inherit/m/etc/resolv.conf /etc/resolv.conf\"\n}\n\ntest_js_resolv_003()\n{\n\t_js_resolv test-pot-dns-custom\n\tassertTrue \"off created a resolv.conf\" \"[ -r /tmp/jails/test-pot-dns-custom/m/etc/resolv.conf ]\"\n\tassertTrue \"wrong resolv.conf\" \"diff /tmp/jails/test-pot-dns-custom/m/etc/resolv.conf /tmp/jails/test-pot-dns-custom/conf/resolv.conf\"\n}\n\ntest_js_resolv_004()\n{\n\t_js_resolv test-pot-dns-pot\n\tassertTrue \"off created a resolv.conf\" \"[ -r /tmp/jails/test-pot-dns-pot/m/etc/resolv.conf ]\"\n\tassertEquals \"test-js-resolv-search\" \"search test-domain\" \"$( grep \"^search \" /tmp/jails/test-pot-dns-pot/m/etc/resolv.conf)\"\n\tassertEquals \"test-js-resolv-server\" \"nameserver 10.2.3.4\" \"$( grep \"^nameserver \" /tmp/jails/test-pot-dns-pot/m/etc/resolv.conf)\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n\n\tPOT_FS_ROOT=/tmp\n\tPOT_ZFS_ROOT=zpot\n\tPOT_EXTIF=\"em2\"\n\tPOT_DNS_IP=\"10.2.3.4\"\n\n\tmkdir -p /tmp/jails/test-pot-2/m/etc\n\tmkdir -p /tmp/jails/test-pot-2/conf\n\ttouch /tmp/jails/test-pot-2/conf/pot.conf\n\tmkdir -p /tmp/jails/test-pot-multi-private/m/etc\n\tmkdir -p /tmp/jails/test-pot-multi-private/conf\n\ttouch /tmp/jails/test-pot-multi-private/conf/pot.conf\n\n\tmkdir -p /tmp/jails/test-pot-dns-inherit/m/etc\n\tmkdir -p /tmp/jails/test-pot-dns-pot/m/etc\n\tmkdir -p /tmp/jails/test-pot-dns-custom/m/etc\n\tmkdir -p /tmp/jails/test-pot-dns-custom/conf\n\ttouch /tmp/jails/test-pot-dns-custom/conf/resolv.conf\n}\n\ntearDown()\n{\n\tcommon_tearDown\n\trm -rf /tmp/jails\n}\n. shunit/shunit2\n"
  },
  {
    "path": "tests/stop1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\nlockf()\n{\n\treturn 0\n}\n# UUT\n. ../share/pot/stop.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\n\n_js_rm_resolv()\n{\n\treturn 0 # true\n}\n\n_pot_umount()\n{\n\treturn 0 # true\n}\n\n_epair_cleanup()\n{\n\treturn 0 # true\n}\n\n_js_stop()\n{\n\t__monitor STOPPED \"$@\"\n}\n\nstop-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_stop_001()\n{\n\tpot-stop\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"0\" STOPPED_CALLS\n\n\tsetUp\n\tpot-stop -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"0\" STOPPED_CALLS\n\n\tsetUp\n\tpot-stop -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"0\" STOPPED_CALLS\n}\n\ntest_pot_stop_002()\n{\n\tpot-stop non-existent-test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"0\" STOPPED_CALLS\n}\n\ntest_pot_stop_020()\n{\n\tpot-stop test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"1\" STOPPED_CALLS\n\tassertEqualsMon \"stop args\" \"test-pot\" STOPPED_CALL1_ARG1\n\tassertEqualsMon \"stop args\" \"NO\" STOPPED_CALL1_ARG2\n\tassertEqualsMon \"stop args\" \"\" STOPPED_CALL1_ARG3\n}\n\ntest_pot_stop_021()\n{\n\tpot-stop -p test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"1\" STOPPED_CALLS\n\tassertEqualsMon \"stop args\" \"test-pot\" STOPPED_CALL1_ARG1\n\tassertEqualsMon \"stop args\" \"NO\" STOPPED_CALL1_ARG2\n\tassertEqualsMon \"stop args\" \"\" STOPPED_CALL1_ARG3\n}\n\ntest_pot_stop_022()\n{\n\tpot-stop -p test-pot -s\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"1\" STOPPED_CALLS\n\tassertEqualsMon \"stop args\" \"test-pot\" STOPPED_CALL1_ARG1\n\tassertEqualsMon \"stop args\" \"YES\" STOPPED_CALL1_ARG2\n\tassertEqualsMon \"stop args\" \"\" STOPPED_CALL1_ARG3\n}\n\ntest_pot_stop_023()\n{\n\tpot-stop -p test-pot -s -i epair4a\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"Stop calls\" \"1\" STOPPED_CALLS\n\tassertEqualsMon \"stop args\" \"test-pot\" STOPPED_CALL1_ARG1\n\tassertEqualsMon \"stop args\" \"YES\" STOPPED_CALL1_ARG2\n\tassertEqualsMon \"stop args\" \"epair4a\" STOPPED_CALL1_ARG3\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/term1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/term.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\n\npot-cmd()\n{\n\t__monitor POTCMD \"$@\"\n\tif [ \"$POTCMD_SHOULD_START_POT\" = \"yes\" ]; then\n\t\t_pname=\"test-pot-run\"\n\tfi\n}\n\n\n_term()\n{\n\t__monitor TERM \"$@\"\n}\n\nterm-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_term_001()\n{\n\tpot-term\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"0\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"0\" POTCMD_CALLS\n\n\tsetUp\n\tpot-term -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"0\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"0\" POTCMD_CALLS\n\n\tsetUp\n\tpot-term -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"0\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"0\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"0\" POTCMD_CALLS\n}\n\ntest_pot_term_020()\n{\n\tpot-term test-pot-run\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"1\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"0\" POTCMD_CALLS\n}\n\ntest_pot_term_030()\n{\n\tpot-term test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"1\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"0\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"0\" POTCMD_CALLS\n}\n\ntest_pot_term_031()\n{\n\tpot-term -f test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"2\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"0\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"1\" POTCMD_CALLS\n}\n\ntest_pot_term_032() {\n\t# In this test \"pot-cmd start\" is changing pot name from\n\t# test-pot to test-pot-run.\n\tPOTCMD_SHOULD_START_POT=yes\n\tpot-term -f test-pot\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"_is_pot_running calls\" \"2\" ISPOTRUN_CALLS\n\tassertEqualsMon \"_term calls\" \"1\" TERM_CALLS\n\tassertEqualsMon \"pot-cmd calls\" \"1\" POTCMD_CALLS\n}\n\n\nsetUp()\n{\n\tcommon_setUp\n\tPOTCMD_SHOULD_START_POT=no\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/test-suite.sh",
    "content": "#!/bin/sh\n\nDOIT=\nSHL=\"sh\"\nif [ \"$(uname)\" = \"Linux\" ]; then\n\t# using bash explicitely because of travis unkowns about /bin/sh\n\tDOIT=bash\n\tSHL=bash\nfi\n\nif ! $SHL -n ../bin/pot ../share/pot/*.sh ; then\n\texit 1\nelse\n\techo \"Syntax check passed\"\n\techo\nfi\n\nif ! command -v flock >/dev/null; then\n\techo \"flock not found.\" 1>&2\n\tif [ \"$(uname)\" = \"FreeBSD\" ]; then\n\t\techo \"Consider installing sysutils/flock\" 1>&2\n\t\techo \"(pkg install flock)\" 1>&2\n\tfi\n\texit 1\nfi\n\nsuites=$(ls ./*.sh)\nrc=0\nfor s in $suites ; do\n\tif [ \"$s\" = \"./test-suite.sh\" ]; then\n\t\tcontinue\n\telif [ \"$s\" = \"./common-stub.sh\" ]; then\n\t\tcontinue\n\telif [ \"$s\" = \"./conf-stub.sh\" ]; then\n\t\tcontinue\n\telif [ \"$s\" = \"./pipefail-stub.sh\" ]; then\n\t\tcontinue\n\telif [ \"$s\" = \"./monitor.sh\" ]; then\n\t\tcontinue\n\telse\n\t\techo \"Running $( basename $s ) ...\"\n\t\t$DOIT \"./$s\" || rc=1\n\tfi\ndone\nexit $rc\n"
  },
  {
    "path": "tests/top1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\ntop()\n{\n\t__monitor TOP \"$@\"\n}\n\n# UUT\n. ../share/pot/top.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\ntop-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_top_001()\n{\n\tpot-top -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"0\" TOP_CALLS\n\n\tsetUp\n\tpot-top -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"0\" TOP_CALLS\n}\n\ntest_pot_top_020()\n{\n\tpot-top -p\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"0\" TOP_CALLS\n\tassertEqualsMon \"top arg1\" \"\" TOP_CALL1_ARG1\n}\n\ntest_pot_top_021()\n{\n\tpot-top -p \"\"\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"0\" TOP_CALLS\n\tassertEqualsMon \"top arg1\" \"\" TOP_CALL1_ARG1\n}\n\ntest_pot_top_022()\n{\n\tpot-top -p no-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"0\" TOP_CALLS\n\tassertEqualsMon \"top arg1\" \"\" TOP_CALL1_ARG1\n}\n\ntest_pot_top_023()\n{\n\tpot-top -p test-pot\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"1\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"0\" TOP_CALLS\n\tassertEqualsMon \"top arg1\" \"\" TOP_CALL1_ARG1\n}\n\ntest_pot_top_040()\n{\n\tpot-top -p test-pot-run\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"0\" HELP_CALLS\n\tassertEqualsMon \"Error calls\" \"0\" ERROR_CALLS\n\tassertEqualsMon \"top calls\" \"1\" TOP_CALLS\n\tassertEqualsMon \"top arg1\" \"-J\" TOP_CALL1_ARG1\n\tassertEqualsMon \"top arg2\" \"test-pot-run\" TOP_CALL1_ARG2\n}\n\nsetUp()\n{\n\tcommon_setUp\n}\n\n. shunit/shunit2\n"
  },
  {
    "path": "tests/version1.sh",
    "content": "#!/bin/sh\n\n# system utilities stubs\n\n# UUT\n. ../share/pot/version.sh\n\n. ../share/pot/common.sh\n# common stubs\n. common-stub.sh\n\n# app specific stubs\nversion-help()\n{\n\t__monitor HELP \"$@\"\n}\n\ntest_pot_version_001()\n{\n\tpot-version -b bb\n\tassertEquals \"Exit rc\" \"1\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n\n\tsetUp\n\tpot-version -h\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEqualsMon \"Help calls\" \"1\" HELP_CALLS\n}\n\ntest_pot_version_020()\n{\n\tresult=$(pot-version)\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEquals \"Incorrect version\" \"pot version: $_POT_VERSION\" \"$result\"\n}\n\ntest_pot_version_021()\n{\n\tresult=$(pot-version -v)\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEquals \"Incorrect version\" \"pot version: $_POT_VERSION\" \"$result\"\n}\n\ntest_pot_version_022()\n{\n\tresult=$(pot-version -q)\n\tassertEquals \"Exit rc\" \"0\" \"$?\"\n\tassertEquals \"Incorrect version\" \"$_POT_VERSION\" \"$result\"\n}\n\nsetUp()\n{\n\tcommon_setUp\n\t_POT_VERSION=\"5.4.3\"\n\t_POT_VERBOSITY=\"1\"\n\n}\n\n. shunit/shunit2\n"
  }
]