pax_global_header00006660000000000000000000000064136262462050014520gustar00rootroot0000000000000052 comment=c5bfea7486beb649091d9248310252ae2c0ab416 ohai-16.0.7/000077500000000000000000000000001362624620500125335ustar00rootroot00000000000000ohai-16.0.7/.expeditor/000077500000000000000000000000001362624620500146145ustar00rootroot00000000000000ohai-16.0.7/.expeditor/config.yml000066400000000000000000000034151362624620500166070ustar00rootroot00000000000000# Documentation available at https://expeditor.chef.io/docs/getting-started/ --- # Slack channel in Chef Software slack to send notifications about build failures, etc slack: notify_channel: chef-infra-notify # This publish is triggered by the `built_in:publish_rubygems` artifact_action. rubygems: - ohai github: # This deletes the GitHub PR branch after successfully merged into the release branch delete_branch_on_merge: true # The tag format to use (e.g. v1.0.0) version_tag_format: "v{{version}}" # allow bumping the minor release via label minor_bump_labels: - "Expeditor: Bump Version Minor" # allow bumping the major release via label major_bump_labels: - "Expeditor: Bump Version Major" # Which Github branches to build Omnibus releases from, and what versions # (as determined by the value in the VERSION file) those branches are responsible # for building. release_branch: - master: version_constraint: 16.* - 15-stable: version_constraint: 15.* - 14-stable: version_constraint: 14.* changelog: rollup_header: Changes not yet released to rubygems.org # These actions are taken, in order they are specified, anytime a Pull Request is merged. merge_actions: - built_in:bump_version: ignore_labels: - "Expeditor: Skip Version Bump" - "Expeditor: Skip All" - bash:.expeditor/update_version.sh: only_if: built_in:bump_version - built_in:update_changelog: ignore_labels: - "Expeditor: Skip Changelog" - "Expeditor: Skip All" - built_in:build_gem: only_if: built_in:bump_version promote: actions: - built_in:rollover_changelog - built_in:publish_rubygems pipelines: - verify: description: Pull Request validation tests public: true ohai-16.0.7/.expeditor/run_linux_tests.sh000077500000000000000000000023451362624620500204240ustar00rootroot00000000000000#!/bin/bash # # This script runs a passed in command, but first setups up the bundler caching on the repo set -ue export USER="root" echo "--- dependencies" export LANG=C.UTF-8 LANGUAGE=C.UTF-8 S3_URL="s3://public-cd-buildkite-cache/${BUILDKITE_PIPELINE_SLUG}/${BUILDKITE_LABEL}" pull_s3_file() { aws s3 cp "${S3_URL}/$1" "$1" || echo "Could not pull $1 from S3" } push_s3_file() { if [ -f "$1" ]; then aws s3 cp "$1" "${S3_URL}/$1" || echo "Could not push $1 to S3 for caching." fi } apt-get update -y apt-get install awscli -y echo "--- bundle install" pull_s3_file "bundle.tar.gz" pull_s3_file "bundle.sha256" if [ -f bundle.tar.gz ]; then tar -xzf bundle.tar.gz fi if [ -n "${RESET_BUNDLE_CACHE:-}" ]; then rm bundle.sha256 fi bundle config --local path vendor/bundle bundle install --jobs=7 --retry=3 echo "--- bundle cache" if test -f bundle.sha256 && shasum --check bundle.sha256 --status; then echo "Bundled gems have not changed. Skipping upload to s3" else echo "Bundled gems have changed. Uploading to s3" shasum -a 256 Gemfile.lock > bundle.sha256 tar -czf bundle.tar.gz vendor/ push_s3_file bundle.tar.gz push_s3_file bundle.sha256 fi echo "+++ bundle exec task" bundle exec $@ ohai-16.0.7/.expeditor/update_version.sh000077500000000000000000000006761362624620500202130ustar00rootroot00000000000000#!/bin/sh # # After a PR merge, Chef Expeditor will bump the PATCH version in the VERSION file. # It then executes this file to update any other files/components with that new version. # set -evx sed -i -r "s/^(\s*)VERSION = \".+\"/\1VERSION = \"$(cat VERSION)\"/" lib/ohai/version.rb # Once Expeditor finshes executing this script, it will commit the changes and push # the commit as a new tag corresponding to the value in the VERSION file. ohai-16.0.7/.expeditor/verify.pipeline.yml000066400000000000000000000021131362624620500204440ustar00rootroot00000000000000--- expeditor: defaults: buildkite: retry: automatic: limit: 1 timeout_in_minutes: 30 steps: - label: lint-chefstyle command: - .expeditor/run_linux_tests.sh "rake style" expeditor: executor: docker: image: ruby:2.6-buster - label: run-ohai command: - .expeditor/run_linux_tests.sh "bundle exec ohai" expeditor: executor: docker: image: ruby:2.6-buster - label: run-specs-ruby-2.5 command: - .expeditor/run_linux_tests.sh rspec expeditor: executor: docker: image: ruby:2.5-buster - label: run-specs-ruby-2.6 command: - .expeditor/run_linux_tests.sh rspec expeditor: executor: docker: image: ruby:2.6-buster - label: run-specs-ruby-2.7 command: - .expeditor/run_linux_tests.sh rspec expeditor: executor: docker: image: ruby:2.7-buster - label: run-specs-windows command: - bundle install --jobs=7 --retry=3 --without docs debug - bundle exec rake spec expeditor: executor: docker: host_os: windows ohai-16.0.7/.github/000077500000000000000000000000001362624620500140735ustar00rootroot00000000000000ohai-16.0.7/.github/CODEOWNERS000066400000000000000000000002721362624620500154670ustar00rootroot00000000000000# Order is important. The last matching pattern has the most precedence. * @chef/chef-infra-reviewers .expeditor/** @chef/jex-team *.md @chef/docs-team ohai-16.0.7/.github/ISSUE_TEMPLATE/000077500000000000000000000000001362624620500162565ustar00rootroot00000000000000ohai-16.0.7/.github/ISSUE_TEMPLATE/BUG_TEMPLATE.md000066400000000000000000000010611362624620500205060ustar00rootroot00000000000000--- name: πŸ› Bug Report about: If something isn't working as expected πŸ€”. labels: "Status: Untriaged, Type: Bug" --- ## Description Briefly describe the issue ## Ohai Version Tell us which version of Ohai you are using. ## Platform Version Tell us which Operating System distribution and version Ohai is running on. ## Ohai Output If relevant please include your complete Ohai output or link to a gist. Make sure to change any values that may be sensitive. The debug output (ohai -l debug) may be useful, but please link to a gist, or truncate it. ohai-16.0.7/.github/ISSUE_TEMPLATE/DESIGN_PROPOSAL.md000066400000000000000000000023721362624620500210740ustar00rootroot00000000000000--- name: Design Proposal about: I have a significant change I would like to propose and discuss before starting labels: "Status: Untriaged, Type: Design Proposal" --- ### When a Change Needs a Design Proposal A design proposal should be opened any time a change meets one of the following qualifications: - Significantly changes the user experience of a project in a way that impacts users. - Significantly changes the underlying architecture of the project in a way that impacts other developers. - Changes the development or testing process of the project such as a change of CI systems or test frameworks. ### Why We Use This Process - Allows all interested parties (including any community member) to discuss large impact changes to a project. - Serves as a durable paper trail for discussions regarding project architecture. - Forces design discussions to occur before PRs are created. - Reduces PR refactoring and rejected PRs. --- ## Motivation ## Specification ## Downstream Impact ohai-16.0.7/.github/ISSUE_TEMPLATE/ENHANCEMENT_REQUEST_TEMPLATE.md000066400000000000000000000014041362624620500230270ustar00rootroot00000000000000--- name: πŸš€ Enhancement Request about: I have a suggestion (and may want to implement it πŸ™‚)! labels: "Status: Untriaged" --- ### Describe the Enhancement ### Describe the Need ### Current Alternative ### Can We Help You Implement This? ohai-16.0.7/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md000066400000000000000000000006621362624620500213070ustar00rootroot00000000000000--- name: πŸ€— Support Question about: If you have a question πŸ’¬, please check out our Slack! --- We use GitHub issues to track bugs and feature requests. If you need help please post to our Mailing List or join the Chef Community Slack. * Chef Community Slack at * Chef Mailing List Support issues opened here will be closed and redirected to Slack or Discourse. ohai-16.0.7/.gitignore000066400000000000000000000001561362624620500145250ustar00rootroot00000000000000*.sw? Gemfile.lock Gemfile.local pkg/ tmp/ coverage/ .DS_Store .bundle *~ vendor .idea/* # yard .yardoc doc/*ohai-16.0.7/.rspec000066400000000000000000000000311362624620500136420ustar00rootroot00000000000000-f documentation --color ohai-16.0.7/.rubocop.yml000066400000000000000000000004431362624620500150060ustar00rootroot00000000000000AllCops: TargetRubyVersion: 2.5 Exclude: - "spec/data/**/*" - "vendor/**/*" - "pkg/**/*" # these have shellout examples that need to have the tabs that come with the shellout Layout/Tab: Exclude: - "lib/ohai/plugins/mono.rb" - "lib/ohai/plugins/darwin/hardware.rb"ohai-16.0.7/CHANGELOG.md000066400000000000000000001727701362624620500143620ustar00rootroot00000000000000# Change Log ## [v16.0.7](https://github.com/chef/ohai/tree/v16.0.7) (2020-02-28) #### Merged Pull Requests - use bool instead of raise/rescue to detect linux user is exists [#1434](https://github.com/chef/ohai/pull/1434) ([sawanoboly](https://github.com/sawanoboly)) ### Changes not yet released to rubygems.org #### Merged Pull Requests - use bool instead of raise/rescue to detect linux user is exists [#1434](https://github.com/chef/ohai/pull/1434) ([sawanoboly](https://github.com/sawanoboly)) - Minor testing updates [#1432](https://github.com/chef/ohai/pull/1432) ([tas50](https://github.com/tas50)) - Chefstyle fixes from Rubocop 0.80 [#1431](https://github.com/chef/ohai/pull/1431) ([tas50](https://github.com/tas50)) - Replace filesystem with filesystem2 on aix/solaris/bsd [#1426](https://github.com/chef/ohai/pull/1426) ([tas50](https://github.com/tas50)) - fix [#1406]: ensure optional_plugins to be array of symbols [#1408](https://github.com/chef/ohai/pull/1408) ([salzig](https://github.com/salzig)) - Use is_a? to check the class in the DMI plugin [#1423](https://github.com/chef/ohai/pull/1423) ([tas50](https://github.com/tas50)) - Allow chef-config 16 [#1422](https://github.com/chef/ohai/pull/1422) ([tas50](https://github.com/tas50)) - Bump to version 16.0.0 [#1420](https://github.com/chef/ohai/pull/1420) ([tas50](https://github.com/tas50)) ## [v15.7.3](https://github.com/chef/ohai/tree/v15.7.3) (2020-01-17) #### Merged Pull Requests - Substitute require for require_relative [#1415](https://github.com/chef/ohai/pull/1415) ([tas50](https://github.com/tas50)) - Test on Ruby 2.7 final docker container and remove old Jenkins files [#1416](https://github.com/chef/ohai/pull/1416) ([tas50](https://github.com/tas50)) - Minor spec cleanup from rubocop-rspec project [#1417](https://github.com/chef/ohai/pull/1417) ([tas50](https://github.com/tas50)) - Fix missing volume name and re-implement adding drivetype to filesystem plugin [#1419](https://github.com/chef/ohai/pull/1419) ([sshock](https://github.com/sshock)) ## [v15.6.3](https://github.com/chef/ohai/tree/v15.6.3) (2019-12-10) #### Merged Pull Requests - Use s3 caching / smaller conntainers in BK & add Ruby 2.7 testing [#1410](https://github.com/chef/ohai/pull/1410) ([tas50](https://github.com/tas50)) - Strip the Rakefile and specs from our gem artifact [#1409](https://github.com/chef/ohai/pull/1409) ([tas50](https://github.com/tas50)) - Rename Ohai::Mixin::DmiDecode spec file to end in `_spec.rb` [#1413](https://github.com/chef/ohai/pull/1413) ([KrisShannon](https://github.com/KrisShannon)) - Fix failures under Ruby 2.7 [#1412](https://github.com/chef/ohai/pull/1412) ([KrisShannon](https://github.com/KrisShannon)) - [filesystem] Convert windows to filesystem2 [#1267](https://github.com/chef/ohai/pull/1267) ([jaymzh](https://github.com/jaymzh)) ## [v15.3.1](https://github.com/chef/ohai/tree/v15.3.1) (2019-09-05) #### Merged Pull Requests - Use Benchmark.realtime for the main application time as well [#1397](https://github.com/chef/ohai/pull/1397) ([tas50](https://github.com/tas50)) - rspec updates from rubocop-rspec [#1399](https://github.com/chef/ohai/pull/1399) ([tas50](https://github.com/tas50)) - Add sysctl ohai plugin [#1401](https://github.com/chef/ohai/pull/1401) ([joshuamiller01](https://github.com/joshuamiller01)) - Make the new sysctl plugin optional [#1402](https://github.com/chef/ohai/pull/1402) ([tas50](https://github.com/tas50)) - Simplify and fix Openstack detection on Linux [#1395](https://github.com/chef/ohai/pull/1395) ([tas50](https://github.com/tas50)) ## [v15.2.5](https://github.com/chef/ohai/tree/v15.2.5) (2019-08-08) #### Merged Pull Requests - new chefstyle rules for 0.13.2 [#1384](https://github.com/chef/ohai/pull/1384) ([lamont-granquist](https://github.com/lamont-granquist)) - Feature - Change regex for detecting interface's state [#1382](https://github.com/chef/ohai/pull/1382) ([josephmilla](https://github.com/josephmilla)) - Switch from Appveyor to Buildkite for Windows PR testing [#1383](https://github.com/chef/ohai/pull/1383) ([tas50](https://github.com/tas50)) - Add other_versions subfield for RPM packages. [#1369](https://github.com/chef/ohai/pull/1369) ([jjustice6](https://github.com/jjustice6)) - Translating platform "archarm" to "arch" [#1388](https://github.com/chef/ohai/pull/1388) ([BackSlasher](https://github.com/BackSlasher)) - Display elapsed real time instead of total cpu time [#1392](https://github.com/chef/ohai/pull/1392) ([teknofire](https://github.com/teknofire)) - Use virtualization plugin to detect if we're on openstack on Windows. [#1391](https://github.com/chef/ohai/pull/1391) ([jjustice6](https://github.com/jjustice6)) - Simplify the Openstack plugin by not polling DMI data [#1394](https://github.com/chef/ohai/pull/1394) ([tas50](https://github.com/tas50)) - Fix platform_version detection on Fedora rawhide [#1396](https://github.com/chef/ohai/pull/1396) ([ritzk](https://github.com/ritzk)) ## [15.1.5](https://github.com/chef/ohai/tree/15.1.5) (2019-06-22) #### Merged Pull Requests - [shard_seed] fix default_sources for linux, darwin and windows [#1379](https://github.com/chef/ohai/pull/1379) ([michel-slm](https://github.com/michel-slm)) - [shard_seed] fix default_digest_algorithm on darwin [#1381](https://github.com/chef/ohai/pull/1381) ([michel-slm](https://github.com/michel-slm)) ## [15.1.3](https://github.com/chef/ohai/tree/15.1.3) (2019-06-14) #### Merged Pull Requests - Apply require speedups to ohai [#1363](https://github.com/chef/ohai/pull/1363) ([lamont-granquist](https://github.com/lamont-granquist)) - fix shellout require idempotency [#1365](https://github.com/chef/ohai/pull/1365) ([lamont-granquist](https://github.com/lamont-granquist)) - Solaris network plugin fix for issue https://github.com/chef/ohai/iss… [#1367](https://github.com/chef/ohai/pull/1367) ([devoptimist](https://github.com/devoptimist)) - Avoid constant warnings in windows/filesystem plugin [#1360](https://github.com/chef/ohai/pull/1360) ([tas50](https://github.com/tas50)) - Add VboxHost plugin to support VirtualBox as a virtualization host [#1339](https://github.com/chef/ohai/pull/1339) ([freakinhippie](https://github.com/freakinhippie)) - Test on ruby 2.6 in Appveyor and remove the travis config [#1372](https://github.com/chef/ohai/pull/1372) ([tas50](https://github.com/tas50)) - Use virtualization attributes to run or skip the virtualbox plugin [#1373](https://github.com/chef/ohai/pull/1373) ([tas50](https://github.com/tas50)) - Simplify how we create empty mashes in the plugins [#1374](https://github.com/chef/ohai/pull/1374) ([tas50](https://github.com/tas50)) - Merge the new vbox plugin into the existing virtualbox plugin [#1376](https://github.com/chef/ohai/pull/1376) ([tas50](https://github.com/tas50)) ## [v15.0.35](https://github.com/chef/ohai/tree/v15.0.35) (2019-05-10) #### Merged Pull Requests - Update master branch for Ohai 15 development [#1277](https://github.com/chef/ohai/pull/1277) ([tas50](https://github.com/tas50)) - Remove the chdir to / when running ohai [#1250](https://github.com/chef/ohai/pull/1250) ([tas50](https://github.com/tas50)) - Remove the deprecated system_profiler plugin [#1278](https://github.com/chef/ohai/pull/1278) ([tas50](https://github.com/tas50)) - Remove the deprecated Ohai::Util::Win32::GroupHelper class [#1279](https://github.com/chef/ohai/pull/1279) ([tas50](https://github.com/tas50)) - Removed unused refresh_plugins method in System class [#1280](https://github.com/chef/ohai/pull/1280) ([tas50](https://github.com/tas50)) - Ignore empty metadata openstack [#1290](https://github.com/chef/ohai/pull/1290) ([sawanoboly](https://github.com/sawanoboly)) - Set User-Agent in HTTP header for GCE plugin [#1291](https://github.com/chef/ohai/pull/1291) ([nathenharvey](https://github.com/nathenharvey)) - Adds more resilient GCE checking [#1292](https://github.com/chef/ohai/pull/1292) ([nathenharvey](https://github.com/nathenharvey)) - Plugin to load hyper_v hostname from guest [#1303](https://github.com/chef/ohai/pull/1303) ([safematix](https://github.com/safematix)) - Remove old spec files [#1301](https://github.com/chef/ohai/pull/1301) ([tas50](https://github.com/tas50)) - Remove circa ~2005 virtualization hypervisor detection [#1305](https://github.com/chef/ohai/pull/1305) ([tas50](https://github.com/tas50)) - Correctly detect openSUSE leap 15+ [#1297](https://github.com/chef/ohai/pull/1297) ([tas50](https://github.com/tas50)) - /etc/os-release based OS detection [#1299](https://github.com/chef/ohai/pull/1299) ([tas50](https://github.com/tas50)) - Windows: Fix for fqdn is being set as the machine name instead of fqdn [#1310](https://github.com/chef/ohai/pull/1310) ([vijaymmali1990](https://github.com/vijaymmali1990)) - Linux Virtualization: Use the new nests `systems` format for lxd / lxc [#1309](https://github.com/chef/ohai/pull/1309) ([tas50](https://github.com/tas50)) - Add mangeia platform with madriva platform_family [#1316](https://github.com/chef/ohai/pull/1316) ([tas50](https://github.com/tas50)) - Add support for SUSE Linux Enterprise Desktop [#1314](https://github.com/chef/ohai/pull/1314) ([tas50](https://github.com/tas50)) - Fix arista platform detection [#1312](https://github.com/chef/ohai/pull/1312) ([tas50](https://github.com/tas50)) - bsd virtualization: Detect amazonec2 hypervisor + kvm without dmidecode [#1319](https://github.com/chef/ohai/pull/1319) ([tas50](https://github.com/tas50)) - platform: Identify sles_sap as the suse platform [#1313](https://github.com/chef/ohai/pull/1313) ([tas50](https://github.com/tas50)) - Add support for antergos linux and fix opensuseleap platform_family [#1320](https://github.com/chef/ohai/pull/1320) ([tas50](https://github.com/tas50)) - Don't ship the readme with ohai [#1321](https://github.com/chef/ohai/pull/1321) ([tas50](https://github.com/tas50)) - Back out SLES -> SUSE remapping and instead fix the platform_family [#1322](https://github.com/chef/ohai/pull/1322) ([tas50](https://github.com/tas50)) - Require Ruby 2.5 or later [#1300](https://github.com/chef/ohai/pull/1300) ([tas50](https://github.com/tas50)) - Unify virtualization detection on a single helper [#1317](https://github.com/chef/ohai/pull/1317) ([tas50](https://github.com/tas50)) - Add support for XCP-ng platform [#1283](https://github.com/chef/ohai/pull/1283) ([heyjodom](https://github.com/heyjodom)) - Remove V6 plugin Struct to reduce memory consumption [#1333](https://github.com/chef/ohai/pull/1333) ([tas50](https://github.com/tas50)) - Fully remove support for HP-UX [#1336](https://github.com/chef/ohai/pull/1336) ([tas50](https://github.com/tas50)) - Chefstyle fixes for Chefstyle 0.12 [#1337](https://github.com/chef/ohai/pull/1337) ([tas50](https://github.com/tas50)) - Parse new /proc/meminfo fields [#1340](https://github.com/chef/ohai/pull/1340) ([davide125](https://github.com/davide125)) - Loosen the mixlib pins to allow for new major releases [#1341](https://github.com/chef/ohai/pull/1341) ([tas50](https://github.com/tas50)) - Ohai::Util::FileHelper does not need to be loaded in this systemd_paths plugin [#1347](https://github.com/chef/ohai/pull/1347) ([burtlo](https://github.com/burtlo)) - Adds mention of the style task [#1351](https://github.com/chef/ohai/pull/1351) ([burtlo](https://github.com/burtlo)) - Replaces require_relative with require [#1349](https://github.com/chef/ohai/pull/1349) ([burtlo](https://github.com/burtlo)) - Update the repo for the new governance [#1348](https://github.com/chef/ohai/pull/1348) ([tas50](https://github.com/tas50)) - Run ohai in Buildkite [#1355](https://github.com/chef/ohai/pull/1355) ([tas50](https://github.com/tas50)) - Require ohai/version where we use it [#1361](https://github.com/chef/ohai/pull/1361) ([tas50](https://github.com/tas50)) ## [v14.6.2](https://github.com/chef/ohai/tree/v14.6.2) (2018-10-11) #### Merged Pull Requests - Review and copyediting of RELEASE_NOTES [#1255](https://github.com/chef/ohai/pull/1255) ([mjingle](https://github.com/mjingle)) - Avoid gathering all data with sysctl which seems to hang [#1259](https://github.com/chef/ohai/pull/1259) ([tas50](https://github.com/tas50)) - Add more yard comments [#1256](https://github.com/chef/ohai/pull/1256) ([tas50](https://github.com/tas50)) - Unify the OS plugins [#1261](https://github.com/chef/ohai/pull/1261) ([jaymzh](https://github.com/jaymzh)) - Unify the cpu plugin [#1262](https://github.com/chef/ohai/pull/1262) ([jaymzh](https://github.com/jaymzh)) - Trim out bogus data in system_profile plugin [#1263](https://github.com/chef/ohai/pull/1263) ([tas50](https://github.com/tas50)) - [filesystem] Convert rest of unix to fs2 [#1266](https://github.com/chef/ohai/pull/1266) ([jaymzh](https://github.com/jaymzh)) - Correctly detect SLES 15 systems as "suse" platform [#1272](https://github.com/chef/ohai/pull/1272) ([tas50](https://github.com/tas50)) - Deprecate the system_profile plugin [#1264](https://github.com/chef/ohai/pull/1264) ([tas50](https://github.com/tas50)) ## [v14.5.4](https://github.com/chef/ohai/tree/v14.5.4) (2018-09-17) #### Merged Pull Requests - Remove redundant platform from the gemspec [#1248](https://github.com/chef/ohai/pull/1248) ([tas50](https://github.com/tas50)) - Add additional yard comments [#1249](https://github.com/chef/ohai/pull/1249) ([tas50](https://github.com/tas50)) - Connect to GCE metadata by IP not name [#1252](https://github.com/chef/ohai/pull/1252) ([tas50](https://github.com/tas50)) - Revert "Connect to GCE metadata by IP not name" [#1253](https://github.com/chef/ohai/pull/1253) ([tas50](https://github.com/tas50)) ## [v14.5.0](https://github.com/chef/ohai/tree/v14.5.0) (2018-09-14) #### Merged Pull Requests - Add "EncryptionStatus" to each volume on Windows [#1238](https://github.com/chef/ohai/pull/1238) ([Nimesh-Msys](https://github.com/Nimesh-Msys)) - override timout by Ohai::Config.ohai[:openstack_metadata_timeout] [#1244](https://github.com/chef/ohai/pull/1244) ([sawanoboly](https://github.com/sawanoboly)) - Fix providing relative paths to the config file [#1241](https://github.com/chef/ohai/pull/1241) ([tas50](https://github.com/tas50)) - Fix root_group plugin invalid byte sequence on non-English version of Windows [#1240](https://github.com/chef/ohai/pull/1240) ([jugatsu](https://github.com/jugatsu)) - Release Ohai 14.5 [#1247](https://github.com/chef/ohai/pull/1247) ([tas50](https://github.com/tas50)) ## [v14.4.2](https://github.com/chef/ohai/tree/v14.4.2) (2018-08-22) #### Merged Pull Requests - Uniquely name our network plugin helper methods [#1236](https://github.com/chef/ohai/pull/1236) ([tas50](https://github.com/tas50)) ## [v14.4.1](https://github.com/chef/ohai/tree/v14.4.1) (2018-08-21) #### Merged Pull Requests - Prefer ipv4 for default_gateway over ipv6 on windows [#1231](https://github.com/chef/ohai/pull/1231) ([Nimesh-Msys](https://github.com/Nimesh-Msys)) ## [v14.4.0](https://github.com/chef/ohai/tree/v14.4.0) (2018-08-08) #### Merged Pull Requests - Add system_enclosure plugin for Windows [#1210](https://github.com/chef/ohai/pull/1210) ([stuartpreston](https://github.com/stuartpreston)) - Load collect_data() even if we've already seen it [#1224](https://github.com/chef/ohai/pull/1224) ([btm](https://github.com/btm)) - Remove the changelog generator task [#1225](https://github.com/chef/ohai/pull/1225) ([tas50](https://github.com/tas50)) - Update Expeditor to clean branches / bump minors [#1223](https://github.com/chef/ohai/pull/1223) ([tas50](https://github.com/tas50)) - Add support for passing multiple plugin directories on CLI/client.rb [#1221](https://github.com/chef/ohai/pull/1221) ([tas50](https://github.com/tas50)) - Make the default shell_out timeout of 30 seconds configurable [#1227](https://github.com/chef/ohai/pull/1227) ([WheresAlice](https://github.com/WheresAlice)) - Resolve Expeditor config warnings [#1229](https://github.com/chef/ohai/pull/1229) ([tas50](https://github.com/tas50)) - Add release notes for 14.4 [#1230](https://github.com/chef/ohai/pull/1230) ([tas50](https://github.com/tas50)) ## [v14.3.0](https://github.com/chef/ohai/tree/v14.3.0) (2018-07-09) #### Merged Pull Requests - Fixes for new chefstyle rules [#1211](https://github.com/chef/ohai/pull/1211) ([lamont-granquist](https://github.com/lamont-granquist)) - Resolve several performance issues identified by Rubocop [#1208](https://github.com/chef/ohai/pull/1208) ([tas50](https://github.com/tas50)) - Properly detect Amazon Linux 2 final release platform version [#1214](https://github.com/chef/ohai/pull/1214) ([tas50](https://github.com/tas50)) - Remove the outdated manpage [#1217](https://github.com/chef/ohai/pull/1217) ([tas50](https://github.com/tas50)) - Bump version to 14.3 + add release notes [#1219](https://github.com/chef/ohai/pull/1219) ([tas50](https://github.com/tas50)) ## [v14.2.0](https://github.com/chef/ohai/tree/v14.2.0) (2018-06-04) #### Merged Pull Requests - Fix yard parsing issues & add more commments [#1187](https://github.com/chef/ohai/pull/1187) ([tas50](https://github.com/tas50)) - Misc minor cleanup [#1189](https://github.com/chef/ohai/pull/1189) ([tas50](https://github.com/tas50)) - Fix an issue caused by using the wrong field in the AIX filesystem plugin. [#1191](https://github.com/chef/ohai/pull/1191) ([jjustice6](https://github.com/jjustice6)) - Detect virtualization on newer AWS instance types. (m5) [#1193](https://github.com/chef/ohai/pull/1193) ([cbajumpaa](https://github.com/cbajumpaa)) - Bump version to 14.2.0 [#1195](https://github.com/chef/ohai/pull/1195) ([tas50](https://github.com/tas50)) ## [v14.1.3](https://github.com/chef/ohai/tree/v14.1.3) (2018-05-15) #### Merged Pull Requests - Rework FIPS detection to only use the positive of OpenSSL.fips_mode [#1186](https://github.com/chef/ohai/pull/1186) ([coderanger](https://github.com/coderanger)) ## [v14.1.2](https://github.com/chef/ohai/tree/v14.1.2) (2018-05-14) #### Merged Pull Requests - [filesystem] Unify plugins, bring BSD into the modern age [#1181](https://github.com/chef/ohai/pull/1181) ([jaymzh](https://github.com/jaymzh)) - Fix shard plugin under FIPS mode because my testing was not sufficient [#1184](https://github.com/chef/ohai/pull/1184) ([coderanger](https://github.com/coderanger)) ## [v14.1.0](https://github.com/chef/ohai/tree/v14.1.0) (2018-05-04) #### Merged Pull Requests - Don't stacktrace if we can't shell_out to zpool [#1141](https://github.com/chef/ohai/pull/1141) ([tas50](https://github.com/tas50)) - Exclude example output from rubocop rules & remove changelog generator gem [#1169](https://github.com/chef/ohai/pull/1169) ([tas50](https://github.com/tas50)) - Add Ohai 14 release notes [#1166](https://github.com/chef/ohai/pull/1166) ([tas50](https://github.com/tas50)) - SCSI plugin [#1170](https://github.com/chef/ohai/pull/1170) ([jaymzh](https://github.com/jaymzh)) - Make the FIPS plugins use the new Ruby 2.5 accessor if present [#1178](https://github.com/chef/ohai/pull/1178) ([coderanger](https://github.com/coderanger)) - Make the shard plugin work under FIPS by using SHA2 instead of MD5 [#1175](https://github.com/chef/ohai/pull/1175) ([coderanger](https://github.com/coderanger)) - Make the DMI IDs we whitelist configurable [#970](https://github.com/chef/ohai/pull/970) ([tas50](https://github.com/tas50)) - Update Release Notes for 14.1 [#1179](https://github.com/chef/ohai/pull/1179) ([thommay](https://github.com/thommay)) ## [v14.0.28](https://github.com/chef/ohai/tree/v14.0.28) (2018-03-19) #### Merged Pull Requests - adds whitespace stripping for the shellout stdout [#1132](https://github.com/chef/ohai/pull/1132) ([rmcleod8](https://github.com/rmcleod8)) - Simplify path logic by requiring chef-config 12.8+ [#1128](https://github.com/chef/ohai/pull/1128) ([tas50](https://github.com/tas50)) - account for snap based installations of LXD [#1131](https://github.com/chef/ohai/pull/1131) ([thewyzard44](https://github.com/thewyzard44)) - Fix vmware specs to actually run the plugin [#1133](https://github.com/chef/ohai/pull/1133) ([tas50](https://github.com/tas50)) - Initial removal of support for Ohai V6 plugins [#1127](https://github.com/chef/ohai/pull/1127) ([tas50](https://github.com/tas50)) - fix failing tests on non linux platforms [#1134](https://github.com/chef/ohai/pull/1134) ([thommay](https://github.com/thommay)) - Docker host detection and information [#1125](https://github.com/chef/ohai/pull/1125) ([tas50](https://github.com/tas50)) - fix critical plugin tests [#1135](https://github.com/chef/ohai/pull/1135) ([thommay](https://github.com/thommay)) - Support optional plugins [#1136](https://github.com/chef/ohai/pull/1136) ([thommay](https://github.com/thommay)) - Simplify & optimize the kernel plugin [#1139](https://github.com/chef/ohai/pull/1139) ([tas50](https://github.com/tas50)) - Add scaleway plugin [#1124](https://github.com/chef/ohai/pull/1124) ([josqu4red](https://github.com/josqu4red)) - Update root_group plugin to use the collect_data helper [#1144](https://github.com/chef/ohai/pull/1144) ([tas50](https://github.com/tas50)) - Add additional information to the kernel plugin on Windows [#1142](https://github.com/chef/ohai/pull/1142) ([tas50](https://github.com/tas50)) - Mark the shard plugin as optional [#1146](https://github.com/chef/ohai/pull/1146) ([thommay](https://github.com/thommay)) - Expand what we blacklist from the kernel/network plugins on Windows [#1147](https://github.com/chef/ohai/pull/1147) ([tas50](https://github.com/tas50)) - Softlayer is forcing tlsv1_2 for all API calls [#1149](https://github.com/chef/ohai/pull/1149) ([smcavallo](https://github.com/smcavallo)) - Remove support for Windows 2003 from uptime/cpu plugins [#1148](https://github.com/chef/ohai/pull/1148) ([tas50](https://github.com/tas50)) - SUSE: Use /etc/os-release if present for all platform attributes [#1140](https://github.com/chef/ohai/pull/1140) ([yeoldegrove](https://github.com/yeoldegrove)) - Fix chefstyle issues in ohai [#1153](https://github.com/chef/ohai/pull/1153) ([tas50](https://github.com/tas50)) - add ohai support for softlayer cloud [#1155](https://github.com/chef/ohai/pull/1155) ([smcavallo](https://github.com/smcavallo)) - Fix bug in azure plugin/update to recent metadata version. [#1154](https://github.com/chef/ohai/pull/1154) ([kriszentner](https://github.com/kriszentner)) - Minor updates to the Ohai/Chef plugins [#1160](https://github.com/chef/ohai/pull/1160) ([tas50](https://github.com/tas50)) - Detect virtualbox and vmware guests on Macs [#1164](https://github.com/chef/ohai/pull/1164) ([tas50](https://github.com/tas50)) - Move ohai to structured logging [#1161](https://github.com/chef/ohai/pull/1161) ([thommay](https://github.com/thommay)) ## [v13.7.1](https://github.com/chef/ohai/tree/v13.7.1) (2018-01-10) [Full Changelog](https://github.com/chef/ohai/compare/v13.7.0...v13.7.1) - Fix docker detection when running on new Docker for mac releases - [linux/network] Tunnel information - Add a plugin to provide PCI bus information using `lspci` ## [v13.7.0](https://github.com/chef/ohai/tree/v13.7.0) (2017-12-04) [Full Changelog](https://github.com/chef/ohai/compare/v13.6.0...v13.7.0) - Detect new Amazon hypervisor used by the C5 instances - [mdadm] Support arrays more than 10 disks - [mdadm] Handle journal and spare devices properly - Add support for Linux MemAvailable value - Added systemd-nspawn virtualization detection - Remove Ruby 1.8 era rubygems error handling code - Fix several typos and add a missing debug message ## [v13.6.0](https://github.com/chef/ohai/tree/v13.6.0) (2017-10-24) [Full Changelog](https://github.com/chef/ohai/compare/v13.5.0...v13.6.0) - Add support for Critical Plugins [#1064](https://github.com/chef/ohai/pull/1064) - Fix LXC detection on lxc 1+ by also checking for lxc-start [#1070](https://github.com/chef/ohai/pull/1070) - Gather packages on Amazon Linux [#1071](https://github.com/chef/ohai/pull/1071) - Updating AIX uptime_seconds to reflect elapsed seconds from boot rather than epoch [#1075](https://github.com/chef/ohai/pull/1075) - Detect Rackspace on Windows [#1060](https://github.com/chef/ohai/pull/1060) ## [v13.5.0](https://github.com/chef/ohai/tree/v13.5.0) (2017-09-28) [Full Changelog](https://github.com/chef/ohai/compare/v13.4.0...v13.5.0) - Fix the route support for IPV6 routes ending in :: [#1058](https://github.com/chef/ohai/pull/1058) - Add plugin timing information in debug mode [#1056](https://github.com/chef/ohai/pull/1056) - Make sure we require wmi/lite in the ec2 plugin [#1059](https://github.com/chef/ohai/pull/1059) ## [v13.4.0](https://github.com/chef/ohai/tree/v13.4.0) (2017-09-11) [Full Changelog](https://github.com/chef/ohai/compare/v13.3.0...v13.4.0) - Add Arch Linux support to package plugin [#1042](https://github.com/chef/ohai/pull/1042) - Detect LXC if LXC and Docker are on the same host [#1055](https://github.com/chef/ohai/pull/1055) - Add Azure metadata endpoint support [#1033](https://github.com/chef/ohai/pull/1033) - Move all requires into the plugin definitions [#1045](https://github.com/chef/ohai/pull/1045) - Improve detection of Windows EC2 nodes by using UUID information [#1052](https://github.com/chef/ohai/pull/1052) - Add error handling in Linux filesystem plugin [#1047](https://github.com/chef/ohai/pull/1047) - Properly handle uptimes over a year on AIX [#1049](https://github.com/chef/ohai/pull/1049) - Handle situations where /proc/cpuinfo lacks core data [#1038](https://github.com/chef/ohai/pull/1038) ## [v13.3.0](https://github.com/chef/ohai/tree/v13.3.0) (2017-8-10) [Full Changelog](https://github.com/chef/ohai/compare/v13.2.0...v13.3.0) - Bump timeout for lsblk and blkid to 60s [#1042](https://github.com/chef/ohai/pull/1043) - Detect F5 Big-IPs as platform bigip [#1035](https://github.com/chef/ohai/pull/1035) - Properly parse Solaris network interface data [#1030](https://github.com/chef/ohai/pull/1030) ## [v13.2.0](https://github.com/chef/ohai/tree/v13.2.0) (2017-06-29) [Full Changelog](https://github.com/chef/ohai/compare/v13.1.0...v13.2.0) - Deprecate the IPScopes Plugin [#1023](https://github.com/chef/ohai/pull/1023) - Fix the AIX package data [#1020](https://github.com/chef/ohai/pull/1020) - Add support for ClearLinux [#1021](https://github.com/chef/ohai/pull/1021) - [mdadm] Handle inactive arrays correctly [#1017](https://github.com/chef/ohai/pull/1017) - Make Linux filesystem plugin more resilient [#1014](https://github.com/chef/ohai/pull/1014) - Add clearos platform to RHEL platform_family [#1004](https://github.com/chef/ohai/pull/1004) - Add systemd_paths plugin for system and user paths [#1013](https://github.com/chef/ohai/pull/1013) - Find network binaries with the which helper [#1009](https://github.com/chef/ohai/pull/1009) - Fix mdadm plugin when arrays are in interesting states [#1012](https://github.com/chef/ohai/pull/1012) - cpu: add support for arm64 cpuinfo fields [#1010](https://github.com/chef/ohai/pull/1010) - Only shellout to sw_vers in darwin hardware once [#1008](https://github.com/chef/ohai/pull/1008) - Run sysctl only once on Darwin to determine CPU data [#1007](https://github.com/chef/ohai/pull/1007) - Update zpools plugin to work on Linux/BSD [#1001](https://github.com/chef/ohai/pull/1001) - Cleanup and prune the dev gems [#1003](https://github.com/chef/ohai/pull/1003) ## [v13.1.0](https://github.com/chef/ohai/tree/v13.1.0) (2017-05-12) [Full Changelog](https://github.com/chef/ohai/compare/v13.0.1...v13.1.0) - Improvements to EC2 metadata handling to reuse connections [#995](https://github.com/chef/ohai/pull/995) ([tas50](https://github.com/tas50)) - EC2: Poll EC2 metadata from the new 2016 metadata API versions [#992](https://github.com/chef/ohai/pull/992) ([tas50](https://github.com/tas50)) - Inject sane paths into shell_out [#991](https://github.com/chef/ohai/pull/991) ([akitada](https://github.com/akitada)) - mdadm: Add members devices array [#989](https://github.com/chef/ohai/pull/989) ([jaymzh](https://github.com/jaymzh)) ## [v13.0.1](https://github.com/chef/ohai/tree/v13.0.1) (2017-04-12) [Full Changelog](https://github.com/chef/ohai/compare/v13.0.0...v13.0.1) **Fixed bugs:** - Fix Eucalyptus plugin to use the HttpHelper mixin [#987](https://github.com/chef/ohai/pull/987) ([akitada](https://github.com/akitada)) - Fix OpenStack plugin to use the HttpHelper mixin [#986](https://github.com/chef/ohai/pull/986) ([akitada](https://github.com/akitada)) ## [v13.0.0](https://github.com/chef/ohai/tree/v13.0.0) (2017-04-06) [Full Changelog](https://github.com/chef/ohai/compare/v8.23.0...v13.0.0) **Implemented enhancements:** - Load all the plugin paths for ohai plugin dependency resolution [#984](https://github.com/chef/ohai/pull/984) ([thommay](https://github.com/thommay)) - Require Ruby 2.3+ to match Chef itself [#981](https://github.com/chef/ohai/pull/981) ([tas50](https://github.com/tas50)) - Allow ohai to load a plugin path [#980](https://github.com/chef/ohai/pull/980) ([thommay](https://github.com/thommay)) - Fully rename the cloud_v2 plugin to cloud [#978](https://github.com/chef/ohai/pull/978) ([tas50](https://github.com/tas50)) - Replace the existing filesystem plugin on Linux and Darwin with filesystem_v2 [#974](https://github.com/chef/ohai/pull/974) ([tas50](https://github.com/tas50)) - Replace the cloud plugin with the cloud_v2 plugin [#973](https://github.com/chef/ohai/pull/973) ([tas50](https://github.com/tas50)) - Freeze all string values coming out of Ohai. [#972](https://github.com/chef/ohai/pull/972) ([coderanger](https://github.com/coderanger)) - Update amazon to use the platform_family of amazon not RHEL [#971](https://github.com/chef/ohai/pull/971) ([lamont-granquist](https://github.com/lamont-granquist)) - Add DMI type 40,41, and 42 from the latest man page [#969](https://github.com/chef/ohai/pull/969) ([tas50](https://github.com/tas50)) - [ec2] Add additional data from identity document [#964](https://github.com/chef/ohai/pull/964) ([webframp](https://github.com/webframp)) - Move duplicate http logic into a helper [#951](https://github.com/chef/ohai/pull/951) ([tas50](https://github.com/tas50)) - Remove deprecated config logic [#939](https://github.com/chef/ohai/pull/939) ([tas50](https://github.com/tas50)) - Require Ruby 2.2+ [#938](https://github.com/chef/ohai/pull/938) ([tas50](https://github.com/tas50)) - Remove the deprecated run_command and popen4 methods [#933](https://github.com/chef/ohai/pull/933) ([tas50](https://github.com/tas50)) - Remove usage of the Sigar gem [#930](https://github.com/chef/ohai/pull/930) ([tas50](https://github.com/tas50)) **Fixed bugs:** - Remove sbt version detect as it's not possible in the current sbt [#982](https://github.com/chef/ohai/pull/982) ([tas50](https://github.com/tas50)) - Fix scala detection when version output contains a warning [#959](https://github.com/chef/ohai/pull/959) ([tas50](https://github.com/tas50)) - Fix lua detection on new versions of lua [#958](https://github.com/chef/ohai/pull/958) ([tas50](https://github.com/tas50)) - Fix logger issues [#955](https://github.com/chef/ohai/pull/955) ([lamont-granquist](https://github.com/lamont-granquist)) - Rescue exception in DMI plugin [#952](https://github.com/chef/ohai/pull/952) ([tas50](https://github.com/tas50)) - Use name for Windows CPU model_name [#918](https://github.com/chef/ohai/pull/918) ([tduffield](https://github.com/tduffield)) ## [8.24.0](https://github.com/chef/ohai/tree/v8.24.0) (2017-05-08) [Full Changelog](https://github.com/chef/ohai/compare/v8.23.0...v8.24.0) - base: Load additional ohai plugins from /etc/chef/ohai/plugins or C:\chef\ohai\plugins\ - ec2: Poll EC2 metadata from the new 2016 metadata API versions [#992](https://github.com/chef/ohai/pull/992) ([tas50](https://github.com/tas50)) - mdadm: Add a new 'members' attribute for member devices in the array [#989](https://github.com/chef/ohai/pull/989) ([jaymzh](https://github.com/jaymzh)) - dmi: Add DMI type 40,41, and 42 from the latest man page [#969](https://github.com/chef/ohai/pull/969) ([tas50](https://github.com/tas50)) - ec2: Gather availability_zone and region data [#964](https://github.com/chef/ohai/pull/964) ([webframp](https://github.com/webframp)) - scala: Fix scala detection when version output contains a warning [#959](https://github.com/chef/ohai/pull/959) ([tas50](https://github.com/tas50)) - lua: Fix lua detection on new versions of lua [#958](https://github.com/chef/ohai/pull/958) ([tas50](https://github.com/tas50)) - dmi: Rescue exception in DMI plugin to improve debug logs [#952](https://github.com/chef/ohai/pull/952) ([tas50](https://github.com/tas50)) ## [v8.23.0](https://github.com/chef/ohai/tree/v8.23.0) (2017-01-24) [Full Changelog](https://github.com/chef/ohai/compare/v8.22.1...v8.23.0) **Implemented enhancements:** - C Plugin: Expand GCC data & only shellout to gcc if Xcode is installed on macOS [#944](https://github.com/chef/ohai/pull/944) ([tas50](https://github.com/tas50)) - Improve debug logging in multiple plugins [#935](https://github.com/chef/ohai/pull/935) ([tas50](https://github.com/tas50)) - Detect guests running on Veertu hypervisor [#925](https://github.com/chef/ohai/pull/925) ([tas50](https://github.com/tas50)) - Detect Windows guests running on Hyper-v and Xen [#922](https://github.com/chef/ohai/pull/922) ([rdean716](https://github.com/rdean716)) - Properly detect Cumulus Linux platform / version [#921](https://github.com/chef/ohai/pull/921) ([tas50](https://github.com/tas50)) - Fetch AWS Account ID from metadata [#907](https://github.com/chef/ohai/pull/907) ([Fodoj](https://github.com/Fodoj)) **Fixed bugs:** - Fix log level selection when running the ohai command [#942](https://github.com/chef/ohai/pull/942) ([thommay](https://github.com/thommay)) - updating cloud plugin to populate azure private_ip as it's currently nil [#937](https://github.com/chef/ohai/pull/937) ([rshade](https://github.com/rshade)) ## [v8.22.1](https://github.com/chef/ohai/tree/v8.22.1) (2016-12-07) [Full Changelog](https://github.com/chef/ohai/compare/8.22.1...v8.22.1) ## [8.22.1](https://github.com/chef/ohai/tree/8.22.1) (2016-12-07) [Full Changelog](https://github.com/chef/ohai/compare/v8.22.0...8.22.1) **Implemented enhancements:** - Pull the complete version string of Erlang [#916](https://github.com/chef/ohai/pull/916) ([tas50](https://github.com/tas50)) - Add sysconf plugin to expose system configuration variables [#893](https://github.com/chef/ohai/pull/893) ([davide125](https://github.com/davide125)) ## [v8.22.0](https://github.com/chef/ohai/tree/v8.22.0) (2016-11-30) [Full Changelog](https://github.com/chef/ohai/compare/v8.21.0...v8.22.0) **Implemented enhancements:** - Detect the global zone of a Solaris system as a virt host even without guests [#908](https://github.com/chef/ohai/pull/908) ([numericillustration](https://github.com/numericillustration)) - Add new haskell language plugin [#902](https://github.com/chef/ohai/pull/902) ([cdituri](https://github.com/cdituri)) - Better handle errors in fetching the hostname on darwin (macOS) systems [#884](https://github.com/chef/ohai/pull/884) ([erikng](https://github.com/erikng)) - Prefer lsb_release tool to /etc/lsb-release data [#873](https://github.com/chef/ohai/pull/873) ([kylev](https://github.com/kylev)) - Extend set_attribute plugin helper method to set sub-attributes. [#822](https://github.com/chef/ohai/pull/822) ([mcquin](https://github.com/mcquin)) **Fixed bugs:** - Rework / fix logic in the joyent plugin and improve specs [#909](https://github.com/chef/ohai/pull/909) ([tas50](https://github.com/tas50)) - Avoid ip_scopes returning tunl/docker interfaces as privateaddress [#890](https://github.com/chef/ohai/pull/890) ([n-marton](https://github.com/n-marton)) ## [v8.21.0](https://github.com/chef/ohai/tree/v8.21.0) (2016-10-18) [Full Changelog](https://github.com/chef/ohai/compare/v8.20.0...v8.21.0) **Implemented enhancements:** - Add shard plugin [#877](https://github.com/chef/ohai/pull/877) ([jaymzh](https://github.com/jaymzh)) **Fixed bugs:** - Ohai uptime plugin hangs in Windows. [#876](https://github.com/chef/ohai/pull/876) ([Aliasgar16](https://github.com/Aliasgar16)) ## [v8.20.0](https://github.com/chef/ohai/tree/v8.20.0) (2016-09-07) [Full Changelog](https://github.com/chef/ohai/compare/v8.19.2...v8.20.0) **Implemented enhancements:** - Retrofit network plugin to work on Windows Nano Server [#872](https://github.com/chef/ohai/pull/872) ([mwrock](https://github.com/mwrock)) - Detect lxd [#871](https://github.com/chef/ohai/pull/871) ([jeunito](https://github.com/jeunito)) - Use chefstyle 0.4.0 for linting and resolve all warnings [#870](https://github.com/chef/ohai/pull/870) ([lamont-granquist](https://github.com/lamont-granquist)) - Add kernel[:update] on Solaris Systems [#869](https://github.com/chef/ohai/pull/869) ([MarkGibbons](https://github.com/MarkGibbons)) - Add hostnamectl plugin for Linux machine information [#867](https://github.com/chef/ohai/pull/867) ([davide125](https://github.com/davide125)) ## [v8.19.2](https://github.com/chef/ohai/tree/v8.19.2) (2016-08-16) [Full Changelog](https://github.com/chef/ohai/compare/v8.19.1...v8.19.2) **Implemented enhancements:** - Require at least mixlib-log 1.7.1 [#866](https://github.com/chef/ohai/pull/866) ([tas50](https://github.com/tas50)) ## [v8.19.1](https://github.com/chef/ohai/tree/v8.19.1) (2016-08-12) [Full Changelog](https://github.com/chef/ohai/compare/v8.19.0...v8.19.1) **Fixed bugs:** - Move log configuration down to Mixlib::Log [#864](https://github.com/chef/ohai/pull/864) ([thommay](https://github.com/thommay)) - Only configure logging if we must [#863](https://github.com/chef/ohai/pull/863) ([thommay](https://github.com/thommay)) ## [v8.19.0](https://github.com/chef/ohai/tree/v8.19.0) (2016-08-11) [Full Changelog](https://github.com/chef/ohai/compare/v8.18.0...v8.19.0) **Implemented enhancements:** - Add plugin for available shells [#854](https://github.com/chef/ohai/issues/854) - Add platform detection for Arista EOS [#860](https://github.com/chef/ohai/pull/860) ([jerearista](https://github.com/jerearista)) **Fixed bugs:** - Fix installs on Ruby 2.1 and rspec testing with rspec 3.5 [#861](https://github.com/chef/ohai/pull/861) ([tas50](https://github.com/tas50)) - Fix solaris2 plugin network interface detection [#859](https://github.com/chef/ohai/pull/859) ([acaiafa](https://github.com/acaiafa)) ## [8.18.0](https://github.com/chef/ohai/tree/8.18.0) (2016-08-04) [Full Changelog](https://github.com/chef/ohai/compare/v8.17.1...8.18.0) **Implemented enhancements:** - Add a plugin for collecting available shells [#856](https://github.com/chef/ohai/pull/856) ([tas50](https://github.com/tas50)) - BlockDevice: Add physical and logical block size [#850](https://github.com/chef/ohai/pull/850) ([sun77](https://github.com/sun77)) - Properly detect PHP 7 [#848](https://github.com/chef/ohai/pull/848) ([tas50](https://github.com/tas50)) - Add support for Linux HugePages [#842](https://github.com/chef/ohai/pull/842) ([bjk-soundcloud](https://github.com/bjk-soundcloud)) - Add detection of Virtualbox and VMware Fusion on OS X [#840](https://github.com/chef/ohai/pull/840) ([tas50](https://github.com/tas50)) - Remove support for Ruby 2.0 [#838](https://github.com/chef/ohai/pull/838) ([tas50](https://github.com/tas50)) - Add hardware plugin for ohai on darwin [#839](https://github.com/chef/ohai/pull/839) ([natewalck](https://github.com/natewalck)) **Fixed bugs:** - Avoid global mutation. [#852](https://github.com/chef/ohai/pull/852) ([coderanger](https://github.com/coderanger)) ## [8.17.1](https://github.com/chef/ohai/tree/8.17.1) (2016-06-30) [Full Changelog](https://github.com/chef/ohai/compare/v8.17.0...8.17.1) **Fixed bugs:** - Move timezone value under time [#836](https://github.com/chef/ohai/pull/836) ([tas50](https://github.com/tas50)) - Update PowerShell Version Compat Detection / Unblock bundler on Appveyor [#832](https://github.com/chef/ohai/pull/832) ([smurawski](https://github.com/smurawski)) ## [v8.17.0](https://github.com/chef/ohai/tree/v8.17.0) (2016-06-20) [Full Changelog](https://github.com/chef/ohai/compare/v8.16.0...v8.17.0) **Implemented enhancements:** - Add additional info to networking interfaces/addresses [#830](https://github.com/chef/ohai/pull/830) ([jaymzh](https://github.com/jaymzh)) - Add a simple plugin to get the local timezone. [#829](https://github.com/chef/ohai/pull/829) ([johnbellone](https://github.com/johnbellone)) - Switch to kernel version to identify platform_version on Gentoo [#828](https://github.com/chef/ohai/pull/828) ([tas50](https://github.com/tas50)) - Expose ring parameters in the network plugin [#827](https://github.com/chef/ohai/pull/827) ([davide125](https://github.com/davide125)) - Improve packages attributes [#820](https://github.com/chef/ohai/pull/820) ([glensc](https://github.com/glensc)) - Add version for linux modules when available [#816](https://github.com/chef/ohai/pull/816) ([jmauro](https://github.com/jmauro)) - Add freebsd support in packages plugin [#814](https://github.com/chef/ohai/pull/814) ([vr](https://github.com/vr)) ## [v8.16.0](https://github.com/chef/ohai/tree/v8.16.0) (2016-05-12) [Full Changelog](https://github.com/chef/ohai/compare/v8.15.1...v8.16.0) **Implemented enhancements:** - Properly poll Openstack metadata + other Openstack improvements [#818](https://github.com/chef/ohai/pull/818) ([tas50](https://github.com/tas50)) - Update packages plugin to support PLD Linux as an RPM distro [#813](https://github.com/chef/ohai/pull/813) ([glensc](https://github.com/glensc)) - Add detection of bhyve guests running Linux/*BSD [#812](https://github.com/chef/ohai/pull/812) ([tas50](https://github.com/tas50)) - Consistent plugin debug logging [#810](https://github.com/chef/ohai/pull/810) ([tas50](https://github.com/tas50)) - Extra debug logging and error handling in plugin loading [#808](https://github.com/chef/ohai/pull/808) ([tas50](https://github.com/tas50)) - Language plugins: Improve failure logging, update specs, general cleanup [#805](https://github.com/chef/ohai/pull/805) ([tas50](https://github.com/tas50)) - Add method to safely get or check the existence of attributes [#796](https://github.com/chef/ohai/pull/796) ([mcquin](https://github.com/mcquin)) **Fixed bugs:** - Prevent parallels spec from checking the filesystem [#811](https://github.com/chef/ohai/pull/811) ([tas50](https://github.com/tas50)) ## [v8.15.1](https://github.com/chef/ohai/tree/v8.15.1) (2016-04-20) [Full Changelog](https://github.com/chef/ohai/compare/v8.15.0...v8.15.1) **Fixed bugs:** - Avoid defining WINDOWS_ATTRIBUTE_ALIASES multiple times [#806](https://github.com/chef/ohai/pull/806) ([mwrock](https://github.com/mwrock)) ## [8.15.0](https://github.com/chef/ohai/tree/8.15.0) (2016-04-18) [Full Changelog](https://github.com/chef/ohai/compare/v8.14.0...8.15.0) **Implemented enhancements:** - Add a fips plugin to detect if fips is enabled [#803](https://github.com/chef/ohai/pull/803) ([mwrock](https://github.com/mwrock)) - Add debug logging to hints and improve cloud specs [#797](https://github.com/chef/ohai/pull/797) ([tas50](https://github.com/tas50)) **Fixed bugs:** - Fix Elixir version detection on newer Elixir releases [#802](https://github.com/chef/ohai/pull/802) ([tas50](https://github.com/tas50)) - Correct the version detection in erlang plugin [#801](https://github.com/chef/ohai/pull/801) ([tas50](https://github.com/tas50)) - Fix mono builddate capture and add debug logging [#800](https://github.com/chef/ohai/pull/800) ([tas50](https://github.com/tas50)) - Fix the scala plugin to properly return data [#799](https://github.com/chef/ohai/pull/799) ([tas50](https://github.com/tas50)) - Don't execute .so libs for Windows [#798](https://github.com/chef/ohai/pull/798) ([chefsalim](https://github.com/chefsalim)) ## [8.14.0](https://github.com/chef/ohai/tree/8.14.0) (2016-04-08) [Full Changelog](https://github.com/chef/ohai/compare/v8.13.0...8.14.0) **Implemented enhancements:** - Improve Linux EC2 detection, fix false detection, and add Windows detection [#793](https://github.com/chef/ohai/pull/793) ([tas50](https://github.com/tas50)) - Ohai shell_out logging, timeouts, and error handling [#788](https://github.com/chef/ohai/pull/788) ([mcquin](https://github.com/mcquin)) - Detect openSUSE Leap as platform opensuseleap [#784](https://github.com/chef/ohai/pull/784) ([tas50](https://github.com/tas50)) - Windows packages plugin - Get packages from registry [#778](https://github.com/chef/ohai/pull/778) ([sh9189](https://github.com/sh9189)) **Fixed bugs:** - AIX: Set os_version to match the output of oslevel -s [#790](https://github.com/chef/ohai/pull/790) ([juliandunn](https://github.com/juliandunn)) - Remove ec2metadata CLI as an EC2 detection method [#787](https://github.com/chef/ohai/pull/787) ([tas50](https://github.com/tas50)) - solaris11_network: Handle solaris 11 zone interfaces [#742](https://github.com/chef/ohai/pull/742) ([MarkGibbons](https://github.com/MarkGibbons)) **Merged pull requests:** - Update chefstyle to 0.3.1 and fix new offenses. [#789](https://github.com/chef/ohai/pull/789) ([mcquin](https://github.com/mcquin)) ## [v8.13.0](https://github.com/chef/ohai/tree/v8.13.0) (2016-03-24) [Full Changelog](https://github.com/chef/ohai/compare/v8.12.1...v8.13.0) **Implemented enhancements:** - Add language scala [#524](https://github.com/chef/ohai/pull/524) ([cmluciano](https://github.com/cmluciano)) **Fixed bugs:** - Lock plist to 3.x [#779](https://github.com/chef/ohai/pull/779) ([danielsdeleo](https://github.com/danielsdeleo)) ## [v8.12.1](https://github.com/chef/ohai/tree/v8.12.1) (2016-03-15) [Full Changelog](https://github.com/chef/ohai/compare/v8.12.0...v8.12.1) **Fixed bugs:** - Fix gem conflicts in ruby environments that load rake 11 [#774](https://github.com/chef/ohai/pull/774) ([danielsdeleo](https://github.com/danielsdeleo)) ## [v8.12.0](https://github.com/chef/ohai/tree/v8.12.0) (2016-03-09) [Full Changelog](https://github.com/chef/ohai/compare/v8.11.1...v8.12.0) **Implemented enhancements:** - add plugin to detect user sessions using loginctl [#766](https://github.com/chef/ohai/pull/766) ([davide125](https://github.com/davide125)) - Improve virtualization detection on Solaris [#760](https://github.com/chef/ohai/pull/760) ([tas50](https://github.com/tas50)) - Improve FreeBSD guest virtualization detection [#756](https://github.com/chef/ohai/pull/756) ([tas50](https://github.com/tas50)) - Detect Openstack hosts [#751](https://github.com/chef/ohai/pull/751) ([tas50](https://github.com/tas50)) - Improve KVM host and guest detection [#750](https://github.com/chef/ohai/pull/750) ([tas50](https://github.com/tas50)) - Update GCE metadata API version and fail better [#736](https://github.com/chef/ohai/pull/736) ([tas50](https://github.com/tas50)) **Fixed bugs:** - Make ohai work with Chef 12.7 and below [#768](https://github.com/chef/ohai/pull/768) ([jkeiser](https://github.com/jkeiser)) - Remove XML output in VirtualizationInfo and need for hpricot gem [#755](https://github.com/chef/ohai/pull/755) ([tas50](https://github.com/tas50)) ## [v8.11.1](https://github.com/chef/ohai/tree/v8.11.1) (2016-03-08) [Full Changelog](https://github.com/chef/ohai/compare/v8.10.0...v8.11.1) **Implemented enhancements:** - Detect Azure on non-bootstrapped hosts [#657](https://github.com/chef/ohai/issues/657) - Deprecate run_command and popen4 in the command mixin [#730](https://github.com/chef/ohai/pull/730) ([tas50](https://github.com/tas50)) - OHAI-726 Regex to support openjdk 1.8 [#727](https://github.com/chef/ohai/pull/727) ([davidnewman](https://github.com/davidnewman)) - Add support for the 2 latest EC2 metadata versions [#725](https://github.com/chef/ohai/pull/725) ([tas50](https://github.com/tas50)) - Improved debug logging for cloud plugins [#724](https://github.com/chef/ohai/pull/724) ([tas50](https://github.com/tas50)) - Detect paravirt amazon instances without hint files [#722](https://github.com/chef/ohai/pull/722) ([tas50](https://github.com/tas50)) - Detect Azure using the Azure agent and DHCP options [#714](https://github.com/chef/ohai/pull/714) ([tas50](https://github.com/tas50)) **Fixed bugs:** - Use escape_glob_dir instead of escape_glob [#747](https://github.com/chef/ohai/pull/747) ([jaym](https://github.com/jaym)) - have a proper dependency on plist [#737](https://github.com/chef/ohai/pull/737) ([thommay](https://github.com/thommay)) - Fix digital ocean ip address detection [#735](https://github.com/chef/ohai/pull/735) ([ctso](https://github.com/ctso)) - Log sigar gem load failures [#731](https://github.com/chef/ohai/pull/731) ([tas50](https://github.com/tas50)) - ipaddress on Linux - default route pointing to unaddressed interface, with route src [#682](https://github.com/chef/ohai/pull/682) ([glennmatthews](https://github.com/glennmatthews)) ## Release 8.10.0 - [pr#720](https://github.com/chef/ohai/pull/720) Make Windows driver plugin opt-in via config - [pr#717](https://github.com/chef/ohai/pull/717) Don't enable packages plugin by default - [pr#711](https://github.com/chef/ohai/pull/711) Improve EC2 detection for HVM instances when a hint isn't present ## Release 8.9.0 - [**phreakocious**](https://github.com/phreakocious): - Collect layer 1 Ethernet information per NIC on Linux hosts - [**Mark Gibbons**](https://www.github.com/MarkGibbons): - Add kernel[:processor] with output of uname -p output - [**Shahul Khajamohideen**](https://github.com/sh9189) - Add packages plugin - [**electrolinux**](https://github.com/electrolinux) - Add "alpine" platform and platform_family - [**Julien Berard**](https://github.com/jujugrrr) - Add instance_id to rackspace plugin - [**Matt Whiteley**](https://github.com/whiteley) - Allow route table override - [**JM Howard Brown**](https://github.com/jmhbrown) - Add tests and queue_depth to block_device - [pr#672](https://github.com/chef/ohai/pull/672) CPU plugin for Darwin (OS X) now properly reports the number of real CPUs adds "cores" to match the CPU output on Linux - [pr#674](https://github.com/chef/ohai/pull/674) CPU plugin for FreeBSD now reports "real" and "core" values to match the CPU output on Linux - [pr#654](https://github.com/chef/ohai/pull/654) Improvements to filesystem and wpar detection on AIX - [pr#683](https://github.com/chef/ohai/pull/683) Properly detect the init package on older Linux kernels - [pr#684](https://github.com/chef/ohai/pull/684) Remove non-functional cucumber tests - [pr#695](https://github.com/chef/ohai/pull/695) Fix detection of mac address on IPv6 only systems - [pr#703](https://github.com/chef/ohai/pull/703) Enable ChefStyle per RFC 64 ## Release 8.8.1 - [pr#677](https://github.com/chef/ohai/pull/677) Remove dependency on mime-types gem - [pr#662](https://github.com/chef/ohai/pull/662) Skip the VMware plugin if DMI data doesn't indicate we're on a VMware system ## Release 8.8.0 - [**James Flemer, NDP LLC**](https://github.com/jflemer-ndp): - Add detection for RHEV (on Linux guests) to virtualization plugin - [**Shahul Khajamohideen**](https://github.com/sh9189): - Fixes Windows :CPU plugin inconsistencies with other platforms: modifies `cpu[:total]` to return total number of logical processors, adds `cpu[:cores]` to return total number of cores. - [**clewis**](https://github.com/clewis): - Don't constrain the width of `ps` output. - [**George Gensure**](https://github.com/werkt): - Prevents invalid memory access on subsequent failed calls to `proc_state` on sigar by throwing exception on returned invalid PID. - [**Hleb Valoshka**](https://github.com/375gnu): - Add support for DragonFly BSD - [**Austin Ziegler**](https://github.com/halostatue): - Bump mime-type dependency to 3.0 - Make collected zfs filesystem properties configurable on solaris2. - Add kernel bitness detection for AIX - Fix CPU detection on FreeBSD 10.2+, add collection CPU family and model data. - Add inode data for filesystems on FreeBSD - Detect Virtualbox, VMware, and KVM on Windows guests and speed up Ohai runs - Add a plugin for Virtualbox to provide host / guest version information - Escape plugin directory path to prevent failures on Windows - Detect Microsoft Hyper-V Linux/BSD guests, which were previously detected as VirtualPC guests - Detect Microsoft VirtualPC Linux/BSD guests on additional releases of VirtualPC - Add KVM, VirtualBox, and Openstack guest detection to BSD platforms and add the node[:virtualization][:systems] syntax ## Release 8.7.0 - [**Shahul Khajamohideen**](https://github.com/sh9189): - Add total cores to linux cpu plugin - Fix behavior when abort called from plug-in (Ohai should exit with error code) ## Release 8.6.0 - [**Phil Dibowitz**](https://github.com/jaymzh): - Provide a new and improved filesystem plugin for Linux & Mac (filesystem2), to support CentOS7, multiple virtual filesystems, etc. - Fix Darwin filesystem plugin on newer MacOSX - [**Jonathan Amiez**](https://github.com/josqu4red): - Linux filesystems plugin report wrong fs-type for logical volumes - [**involucelate**](https://github.com/involucelate) - Fix Windows 2008 hostname truncation #554 - [**Pavel Yudin**](https://github.com/Kasen): - Detect Parallels host and guest virtualization - [**Claire McQuin**](https://github.com/mcquin): - Deprecate Ohai::Config in favor of Ohai::Config.ohai. - Load a configuration file while running as an application. - [PR #597](https//github.com/chef/ohai/pull/597): - Correct platform, platform_family and version detection on Cisco's Nexus platforms. - [**cmluciano**](https://github.com/cmluciano): - add vmware plugin - [**Jean Baptiste Favre**](https://github.com/jbfavre): - Detect updated docker cgroup format - [**Shahul Khajamohideen**](https://github.com/sh9189): - Fix memory plugin output on Solaris - Add swap space attributes for Solaris memory plugin - Add swap space attributes for AIX - Add support for SPARC based processors in Solaris cpu plugin - Make AIX cpu plugin's output consistent with Solaris cpu plugin - Make AIX, Solaris memory output consistent to Linux - [**Sean Horn**](https://github.com/sean-horn): - ec2 plugin should handle binary userdata too - [**Alexey Karpik**](https://github.com/akarpik): - Add support for SoftLayer cloud - [**MichaelSp**](https://github.com/MichaelSp): - return correct ipaddress for openvz guests - [**Anthony Caiafa**](https://github.com/acaiafa): - Only run ifconfig against active interfaces - [**Shahul Khajamohideen**](https://github.com/sh9189) and [**Sean Escriva**](https://github.com/webframp): - Windows Memory plugin - [**Chris Chambers**](https://github.com/cachamber): - Convert Solaris OHAI CPU detection to kstat from psrinfo ## Release 8.5.0 - [PR #548](https://github.com/chef/ohai/pull/548): Coerce non-UTF8 strings to UTF8 in output to suppress UTF8 encoding exceptions - [PR #544](https://github.com/chef/ohai/pull/544) add support for Wind River Linux and Cisco's Nexus platforms ## Release 8.4.0 - Correctly skip unwanted DMI information - Collect DMI information on Solaris/x86 ## Release 8.3.0 - [**Jeremy Mauro**](https://github.com/jmauro): Removing trailing space and '\r' for windows #474 - [**Tim Smith**](https://github.com/tas50): Ensure Gentoo based Linuxen get IP information - [PR #534](https://github.com/chef/ohai/pull/534) Ignore OEM logo on Windows ## Release 8.2.0 - [**Michael Glenney**](https://github.com/Maniacal) Remove redundant if statement - Remove CloudStack support due to GPL licensed library ## Release 8.1.1 - Fix broken DigitalOcean plugin ## Release 8.1.0 - [**Warren Bain**](https://github.com/thoughtcroft) Fix for removal of :Config in ruby 2.2 - [**Chris Luciano**](https://github.com/cmluciano) Add language elixir - [**Chris Luciano**](https://github.com/cmluciano) Update WARNING for ohai 7 syntax docs page - [**Malte Swart**](https://github.com/mswart) ssh_host_key: detect ed25519 host key - [**hirose31**](https://github.com/hirose31) Detect OpenStack guest server using dmidecode - [**Chris Luciano**](https://github.com/cmluciano) Add language rust. - [**Tim Smith**](https://github.com/tas50) Add additional information on the PHP engine versions to PHP plugin - [**Paul Czarkowski**](https://github.com/paulczar) detect if inside Docker container - [**Michael Schmidt**](https://github.com/BugRoger) OHAI-339 Unable to detect IPAddress on CoreOS/Gentoo - [**Stafford Brunk**](https://github.com/wingrunr21) Digital Ocean ohai/cloud support round - [**Sten Spans**](https://github.com/sspans) Fix network.rb for XenServer Creedence - [**Shuo Zhang**](https://github.com/zshuo) Update Linux plugin cpu.rb and spec_cpu.rb to support S390 - [**Alexey Karpik**](https://github.com/akarpik) Fix up incorrect CloudStack metadata - [**Jeff Goldschrafe**](https://github.com/jgoldschrafe) cloud_v2 fails to initialize on GCE hosts without external IP - [**Ryan Chipman**](https://github.com/rychipman) Archlinux Version - [**Jose Luis Salas**](https://github.com/josacar) Add a trailing dot to avoid using search option in resolv.conf - [**Eric G. Wolfe**](https://github.com/atomic-penguin) block_device rotational key - [**Josh Blancett**](https://github.com/jblancett) add extra metadata passed in from hints in knife-linode - Update mime-types dependency ## Release 8.0.0 - [**sawanoboly**](https://github.com/sawanoboly) Retrieve OpenStack-specific metadata. - [**Olle Lundberg**](https://github.com/lndbrg) Add CloudStack support. - [**Tim Smith**](https://github.com/tas50) Remove newlines in CPU strings on Darwin. - [**Nathan Huff**](https://github.com/nhuff) Match zpool output for OmniOS 151006. - [**Pavel Yudin**](https://github.com/Kasen) Add Parallels Cloud Server (PCS) platform support. - [**Christian Vozar**](https://github.com/christianvozar): Add Go language plugin. - [**Phil Dibowitz**](https://github.com/jaymzh): regression: qualify device names from lsblk - [**Chris Read**](https://github.com/cread): Add support for ip version ss131122. - [**carck**](https://github.com/carck): Reduce GCE metadata timeout to 6 seconds. - [**barnabear**](https://github.com/barnabear): Add Pidora platform detection. - [**Ben Carpenter**](https://github.com/bcarpenter): Presume 'latest' API version on 404 from Eucalyptus metadata server. - [**Nabeel Shahzad**](https://github.com/nshahzad): Look for any number of spaces between the VxID and the value. - [**Daniel Searles**](https://github.com/squaresurf): Removed *.static.cloud-ips.com and fixed the DNS resolution on Rackspace hosts. - Update specs to use RSpec 3 syntax - Update mixlib-shellout pin to ~> 2.x ## Release 7.6.0 - This release was yanked due to mixlib-shellout 1.x/2.x issues ## Release 7.4.0 - Added Powershell plugin. ## Release 7.2.4 - [**Phil Dibowitz**](https://github.com/jaymzh): linux::network should handle ECMP routes ## Release 7.2.2 - [**Phil Dibowitz**:](https://github.com/jaymzh) Use lsblk instead of blkid if available. - [**Phil Dibowitz**:](https://github.com/jaymzh) linux::filesystem now reads all of /proc/mounts instead of just 4K ## Release: 7.2.0 - [**Lance Bragstad**:](https://github.com/lbragstad) Added platform_family support for ibm_powerkvm (OHAI-558) - [**Pierre Carrier**:](https://github.com/pcarrier) EC2 metadata errors are unhelpful (OHAI-566) - [**Elan RuusamΓ€e**:](https://github.com/glensc) Support deep virtualization systems in `node[:virtualization][:systems]` (OHAI-182) - [**Sean Walberg**:](https://github.com/swalberg) :Passwd plugin now ignores duplicate users. (OHAI-561) - [**Joe Richards**:](https://github.com/viyh) Fix warning message about constants already defined (OHAI-572) - [**Tim Smith**:](https://github.com/tas50) Present all CPU flags on FreeBSD (OHAI-568) - [**Tim Smith**:](https://github.com/tas50) Ohai doesn't detect all KVM processor types as KVM on FreeBSD (OHAI-575) - [**Tim Smith**:](https://github.com/tas50) Ohai should expose mdadm raid information on Linux systems (OHAI-578) - [**Cam Cope**:](https://github.com/ccope) relax regex to match newer Oracle Solaris releases (OHAI-563) - [**Vasiliy Tolstov**:](https://github.com/vtolstov) add exherbo support (OHAI-570) - [**jasonpgignac**](https://github.com/jasonpgignac) Add inode information to the Linux Filesystem plugin. (OHAI-539) - [**Benedikt BΓΆhm**](https://github.com/hollow) Change log-level from warn to debug for missing gateway IPs. - [**sawanoboly**](https://github.com/sawanoboly) Include Joyent SmartOS specific attributes in Ohai. (OHAI-458) - [**Mike Fiedler**](https://github.com/miketheman) Collect ec2 metadata even if one of the resources returns a 404\. (OHAI-541) - [**Pat Collins**](https://github.com/patcoll) Provide basic memory information for Mac OS X. (OHAI-431) - [**Jerry Chen**](https://github.com/jcsalterego): Rackspace plugin rescues Errno::ENOENT if xenstor-* utils are not found (OHAI-587) - root_group provider not implemented for Windows (OHAI-491) - `Ohai::Exceptions::AttributeNotFound` errors in Chef's ohai resource - Be reluctant to call something an LXC host (OHAI-573) - Assume 'latest' metadata versions on 404 ## Release: 7.0.4 - Added platform_family support for ibm_powerkvm (OHAI-558) - cannot disable Lsb plugin (OHAI-565) - Skip v7 plugins when refreshing a v6 plugin. Fixes (OHAI-562) `Ohai::Exceptions::AttributeNotFound` errors in Chef's ohai resource - Work around libc bug in `hostname --fqdn` - Report Suse and OpenSuse separately in the :platform attribute. - CPU information matching Linux is now available on Darwin. - ip6address detection failure logging is turned down to :debug. - fe80:: link-local address is not reported as ip6addresses anymore. - Private network information is now available as [:rackspace][:private_networks] on Rackspace nodes. - System init mechanism is now reported at [:init_package] on Linux. - Define cloud plugin interface (OHAI-542) - java -version wastes memory (OHAI-550) - Ohai cannot detect running in an lxc container (OHAI-551) - Normalize cloud attributes for Azure (OHAI-554) - Capture FreeBSD osreldate for comparison purposes (OHAI-557) ohai-16.0.7/CODE_OF_CONDUCT.md000066400000000000000000000001331362624620500153270ustar00rootroot00000000000000Please refer to the Chef Community Code of Conduct at https://www.chef.io/code-of-conduct/ ohai-16.0.7/CONTRIBUTING.md000066400000000000000000000001111362624620500147550ustar00rootroot00000000000000Please refer to https://github.com/chef/chef/blob/master/CONTRIBUTING.md ohai-16.0.7/Gemfile000066400000000000000000000011111362624620500140200ustar00rootroot00000000000000source "https://rubygems.org" gemspec # NOTE: do not submit PRs to add pry as a dep, add to your Gemfile.local group :development do gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "master" gem "rake", ">= 10.1.0" gem "rspec-core", "~> 3.0" gem "rspec-expectations", "~> 3.0" gem "rspec-mocks", "~> 3.0" gem "rspec-collection_matchers", "~> 1.0" gem "ipaddr_extensions" end group :docs do gem "yard" gem "redcarpet" gem "github-markup" end group :debug do gem "pry" gem "pry-byebug" gem "pry-stack_explorer" gem "rb-readline" end ohai-16.0.7/LICENSE000066400000000000000000000251421362624620500135440ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ohai-16.0.7/NOTICE000066400000000000000000000016671362624620500134510ustar00rootroot00000000000000============ Ohai Notices ============ Developed at Chef (http://www.chef.io). Contributors and Copyright holders: * Copyright 2008-2015, Chef * Copyright 2008-2015, Adam Jacob * Copyright 2008-2009, Ben Black * Copyright 2008-2009, Ezra Zygmuntowicz * Copyright 2009, Joe Williams * Copyright 2009, Paul Nasrat Parts of Ohai were taken from Chef, a configuration management system. Ohai incorporates functionality from Open4 (http://www.codeforpeople.com/lib/ruby/open4/). ============ Chef Notices ============ Developed at Chef (http://www.chef.io). Contributors and Copyright holders: * Copyright 2008-2015, Adam Jacob * Copyright 2008, Arjuna Christensen * Copyright 2008-2015, Bryan McLellan * Copyright 2008, Ezra Zygmuntowicz ohai-16.0.7/OHAI_MVPS.md000066400000000000000000000100661362624620500144450ustar00rootroot00000000000000### Chef is proud of our community! Every release of Ohai we pick someone from the community to name as the Most Valuable Player for that release. It could be someone who provided a big feature, reported a security vulnerability, or someone doing great things in the community that we want to highlight. #### Hall of Fame After receiving three MVP awards, we add someone to the hall of fame. We want to express our gratitude to their continuing participation and give newer community members the opportunity to be recognized. The [MVP list](https://github.com/chef/chef/blob/master/CHEF_MVPS.md) is kept in the Chef project. #### Ohai Release MVP Recipients | Release | Date | MVP | |---------|------|-----| | Ohai 14.6 | 2018-10-11 | Phil Dibowitz | | Ohai 14.5 | 2018-09-14 | Anton Kvashenkin | | Ohai 14.4 | 2018-08-08 | Alice | | Ohai 14.2 | 2018-06-04 | @cbajumpaa | | Ohai 14.1 | 2018-05-04 | Noah Kantrowitz | | Ohai 14.0 | 2018-03-09 | Eike Waldt | | Ohai 13.7 | 2017-12-04 | Zeal Jagannatha | | Ohai 13.6 | 2017-10-24 | Phil Dibowitz | | Ohai 13.4 | 2017-09-11 | Jeune Asuncion | | Ohai 13.3 | 2017-08-10 | Richard McLeod | | Ohai 13.2 | 2017-06-29 | Phil Dibowitz | | Ohai 13.1 | 2017-05-12 | Akira Kitada | | Ohai 13.0 | 2017-04-06 | Sean Escriva | | Ohai 8.23 | 2017-01-24 | Bob Dean | | Ohai 8.22 | 2016-11-30 | Chris Dituri | | Ohai 8.21 | 2016-10-18 | Phil Dibowitz | | Ohai 8.20 | 2016-09-07 | Davide Cavalca | | Ohai 8.19 | 2016-08-11 | Jere Julian | | Ohai 8.18 | 2016-08-04 | Nate Walck | | Ohai 8.17 | 2016-06-20 | John Bellone | | Ohai 8.16 | 2016-05-12 | Elan RuusamΓ€e | | Ohai 8.14 | 2016-04-08 | Shahul Khajamohideen | | [Ohai 6.20.0](https://www.chef.io/blog/2013/10/31/release-chef-client-11-8-0-ohai-6-20-0/) | 2013-10-31 | Paul Rossman | | [Ohai 6.18.0](http://www.chef.io/blog/2013/07/23/chef-client-11-6-0-ohai-6-18-0-and-more/) | 2013-07-19 | Joseph Anthony Pasquale Holsten | | [Ohai 6.16.0](http://www.chef.io/blog/2013/01/17/ohai-6-16-0-released/) | 2013-01-17 | Sascha Bates | | [Ohai 6.14.0](http://www.chef.io/blog/2012/05/30/ohai-6-14-0-released/) | 2012-05-30 | Laurent DΓ©sarmes, Eric Hankins | | [Ohai 0.6.12](http://www.chef.io/blog/2012/03/22/ohai-0-6-12-released/) | 2012-03-22 | Caleb Tennis | | [Ohai 0.6.10](http://www.chef.io/blog/2011/10/23/ohai-0-6-10-released/) | 2011-10-23 | Nicolas Szalay, James Brinkerhoff | | [Ohai 0.6.8](http://www.chef.io/blog/2011/10/05/ohai-0-6-8-released/) | 2011-10-05 | Bryan W. Berry | | [Ohai 0.6.6](http://www.chef.io/blog/2011/10/03/ohai-0-6-6-released/) | 2011-10-03 | Jason J. W. Williams | | [Ohai 0.6.4](http://www.chef.io/blog/2011/04/28/ohai-0-6-4-released/) | 2011-04-28 | Josh Pasqualetto | | [Ohai 0.6.2](http://www.chef.io/blog/2011/04/14/ohai-0-6-2-bugfix-release/) | 2011-04-14 | Doug MacEachern | | [Ohai 0.6.0](http://www.chef.io/blog/2011/04/13/ohai-0-6-0-released-2/) | 2011-04-13 | Kurt Yoder | | [Ohai 0.5.8](http://www.chef.io/blog/2010/10/19/chef-0-9-10-ohai-0-5-8-and-mixliblog-1-2-0-released/) | 2010-10-19 | Toomas Pelberg, Tommy Bishop | | [Ohai 0.5.6](http://www.chef.io/blog/2010/06/21/chef-0-9-0-and-ohai-0-5-6-released/) | 2010-06-21 | Doug MacEachern | | [Ohai 0.5.4](http://www.chef.io/blog/2010/05/11/chef-0-8-16-and-ohai-0-5-4-release/) | 2010-05-11 | Doug MacEachern | | [Ohai 0.5.0](http://www.chef.io/blog/2010/03/04/ohai-0-5-0-release/) | 2010-03-04 | Tollef Fog Heen | | [Ohai 0.4.0](http://www.chef.io/blog/2010/02/28/ohai-0-4-0-release/) | 2010-02-28 | Mark Giammarco, Jan Zimmek | | [Ohai 0.3.6](http://www.chef.io/blog/2009/10/26/chef-0-7-14-ohai-0-3-6-releases/) | 2009-10-16 | Thom May | | [Ohai 0.3.4](http://www.chef.io/blog/2009/10/06/chef-0-7-12rc0-ohai-0-3-4rc0-releases/) | 2009-10-06 | Diego Algorta | | [Ohai 0.3.2](http://www.chef.io/blog/2009/07/13/ohai-0-3-2-release/) | 2009-07-13 | James Gartrell | | [Ohai 0.3.0](http://www.chef.io/blog/2009/06/18/ohai-0-3-0-release/) | 2009-06-18 | Bryan McLellan | | [Ohai 0.2.0](http://www.chef.io/blog/2009/03/06/ohai-0-2-0/) | 2009-03-06 | Thom May | | [Ohai 0.1.4](http://www.chef.io/blog/2009/02/01/chef-0-5-2-and-ohai-0-1-4/) | 2009-02-01 | Bryan McLellan | ohai-16.0.7/README.md000066400000000000000000000076421362624620500140230ustar00rootroot00000000000000# ohai [![Build status](https://badge.buildkite.com/aa0b961fc3e5bed315c7035c6d60a4aaee57af9610cbde9a15.svg?branch=master)](https://buildkite.com/chef-oss/chef-ohai-master-verify) [![Gem Version](https://badge.fury.io/rb/ohai.svg)](https://badge.fury.io/rb/ohai) **Umbrella Project**: [Chef Infra](https://github.com/chef/chef-oss-practices/blob/master/projects/chef-infra.md) **Project State**: [Active](https://github.com/chef/chef-oss-practices/blob/master/repo-management/repo-states.md#active) **Issues Response SLA**: 10 business days **Pull Request Response SLA**: 10 business days ## Description Ohai detects data about your operating system. It can be used standalone, but its primary purpose is to provide node data to Chef. Ohai will print out a JSON data blob for all the known data about your system. When used with Chef, that data is reported back via node attributes. Chef distributes ohai as a RubyGem. This README is for developers who want to modify the Ohai source code. For users who want to write plugins for Ohai, see the docs: - General documentation: - Writing Ohai Plugins documentation: ## Development Environment: Ohai's development dependencies should be installed with bundler. Just run `bundle install` in the root of the repo. ## Spec Testing: We use RSpec for unit/spec tests. To run the full suite, run: ``` bundle exec rake spec ``` You can run individual test files by running the rspec executable: ``` bundle exec rspec spec/unit/FILE.rb ``` ## Style: We use [Chefstyle](https://github.com/chef/chefstyle), as a code [linter](https://en.wikipedia.org/wiki/Lint_(software)), to enforce style guidelines. To run: ``` bundle exec rake style ``` You can run and automatically correct the issues: ``` bundle exec rake style:auto_correct ``` ## Rake Tasks Ohai has some Rake tasks for doing various things. ``` bundle exec rake -T rake build # Build ohai-$VERSION.gem into the pkg directory rake clean # Remove any temporary products rake clobber # Remove any generated files rake docs # Generate YARD Documentation rake install # Build and install ohai-$VERSION.gem into system gems rake install:local # Build and install ohai-$VERSION.gem into system gems without network access rake release[remote] # Create tag $VERSION and build and push ohai-$VERSION.gem to rubygems.org rake spec # Run RSpec code examples rake style # Run Chefstyle tests rake style:auto_correct # Auto-correct RuboCop offenses ($VERSION is the current version, from the GemSpec in Rakefile) ``` ## Links: Source: - Issues: - ## Contributing For information on contributing to this project see 1. Fork it 1. Create your feature branch (git checkout -b my-new-feature) 1. Commit your changes (git commit -am 'Add some feature') 1. Run the tests `bundle exec rake spec` 1. Run the style tests `bundle exec rake style` 1. Push to the branch (git push origin my-new-feature) 1. Create new Pull Request ## License Ohai - system information application - Author:: Adam Jacob ([adam@chef.io](mailto:adam@chef.io)) - Copyright:: Copyright (c) 2008-2019 Chef Software, Inc. - License:: Apache License, Version 2.0 ```text Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ohai-16.0.7/RELEASE_NOTES.md000066400000000000000000000504401362624620500151100ustar00rootroot00000000000000 # Ohai Release Notes 15.6 ## filesystem2 Ohai Data on Windows Ohai 15.6 includes new `node['filesystem2']` data on Windows hosts. Fileystem2 presents filesystem data by both mountpoint and by device name. This data structure matches that of the filesystem plugin on Linux and other *nix operating systems. Thanks [@jaymzh](https://github.com/jaymzh) for this new data structure. # Ohai Release Notes 15.3 ## Passwd Is Once Again Optional The Passwd plugin, which provides information on all users and groups on a node, was intented to be made optional with the release of Ohai/Chef 14.0. Howerver, due to the way data was used in the OpenStack plugin, the Passwd plugin was never actually disabled. The Passwd plugin has been historically problematic for users with nodes that are connected to LDAP or Active Directory. Due to this we've chosen to fix our OpenStack bug and once again disable the Passwd plugin. If you relied on the data in node['etc'] you'll need to set the `optional_plugins` configuration value in your `client.rb` config. Example segment of client.rb ```ruby ohai.optional_plugins = [ :Passwd ] ``` # Ohai Release Notes 15.2 ## Openstack Plugin Enhancements The Openstack plugin now uses data from the Virtualization plugin to determine if a host is running on Openstack. This not only speeds up the plugin, but also better detects when running on Openstack. The plugin has also been updated to run on Windows hosts. Thanks @jjustice6 ## other_versions in Packages Plugin Since multiple versions of the same package can exist on RPM based systems a new `other_versions` field has been introduced to list other versions of packages such as the Linux kernel. Thanks @jjustice6 ## Other Enhancements - When debugging Ohai the elapsed time for plugins will include time spent waiting for programs to shell out, not just time the plugin spent executing Ruby code - The Linux Network plugin has been improved to not mark interfaces down if stp_state is marked as down. Thanks @josephmilla - Arch running on Arm processors is now detected as the `arm` platform. Thanks @BackSlasher # Ohai Release Notes 15.1 ## Virtualbox Plugin Enhancements The Virtualbox plugin now gathers a large amount of data on Virtualbox hosts. Additionally the plugin has been updated to better detect when running on a Virtualbox guest or host. ## Other Enhancements - Ohai performance improved by changing how Ruby requires libraries - Multiple fixes to the Shard plugin to ensure the hash is created # Ohai Release Notes 15.0 ## Improvements ### Improved Linux Platform / Platform Family Detection Platform and plaform_family detection on Linux has been rewritten to utilize the latest config files on modern Linux distributions before falling back to slower and fragile legacy detection methods. Ohai will now begin by parsing the contents of /etc/os-release for OS information if available. This improves the reliability of detection on modern distros and allows detection of new distros as they're released. With this change we now detect `sles_sap` as a member of the `suse` platform_family. Additionally this change corrects our detection of the platform_version on Cisco Nexus switches where we previously incorrectly appended the build number to the version string. ### Improved Virtualization Detection Hypervisor detection on multiple platforms has been updated to use DMI data and a single set of hypervisors. This greatly improves the detection of hypervisors on Windows, BSD and Solaris platforms. It also means that as new hypervisors detection is added in the future we will automatically support the majority of platforms. ### Fix Windows 2016 FQDN Detection Ohai 14 incorrectly detected a Windows 2016 node's `fqdn` as the node's `hostname`. Ohai 15 now correctly reports the FQDN value. ### Improved Memory Usage Ohai now uses less memory due to internal optimizations of how we track plugin information. ### FIPS Detection Improvements The FIPS plugin now uses the built-in FIPS detection in Ruby for improved detection. ## Breaking Changes ### system_profiler plugin removal The `system_profiler` plugin which ran on macOS systems has been removed. This plugin took longer to run than all other plugins on macOS combined and no longer produced usable information on modern macOS releases. If you're looking for similar information it can now be found in the `hardware` plugin. ### Ohai::Util::Win32::GroupHelper helper removal The deprecated `Ohai::Util::Win32::GroupHelper` helper has been removed from Ohai. Any custom Ohai plugins using this helper will need to be updated. ### Ohai::System.refresh_plugins method removal The `refresh_plugins` method in the `Ohai::System` class has been removed as it has been unused for multiple major Ohai releases. If you are programatically using Ohai in your own Ruby application you will need to update your code to use the `load_plugins` method instead. ### Microsoft VirtualPC / VirtualServer detection removal The Virtualization plugin will no longer detect systems running on the circa ~2005 VirtualPC or VirtualServer hypervisors. These hypervisors were long ago deprecated by Microsoft and support can no longer be tested. # Ohai Release Notes 14.8 ## Improved Virtualization Detection ### Hyper-V Hypervisor Detection Detection of Linux guests running on Hyper-V has been improved. In addition, Linux guests on Hyper-V hypervisors will also now detect their hypervisor's hostname. Thank you [@safematix](https://github.com/safematix) for contributing this enhancement. Example `node['virtualization']` data: ```json { "systems": { "hyperv": "guest" }, "system": "hyperv", "role": "guest", "hypervisor_host": "hyper_v.example.com" } ``` ### LXC / LXD Detection On Linux systems running lxc or lxd containers, the lxc/lxd virtualization system will now properly populate the `node['virtualization']['systems']` attribute. ### BSD Hypervisor Detection BSD-based systems can now detect guests running on KVM and Amazon's hypervisor without the need for the dmidecode package. ## New Platform Support - Ohai now properly detects the openSUSE 15.X platform. Thank you [@megamorf](https://github.com/megamorf) for reporting this issue. - Suse Linux Enterprise Desktop now identified as platform_family 'suse' - XCP-NG is now identified as platform 'xcp' and platform_family 'rhel'. Thank you [@heyjodom](http://github.com/heyjodom) for submitting this enhancement. - Mangeia Linux is now identified as platform 'mangeia' and platform_family 'mandriva' - Antergos Linux now identified as platform_family 'arch' - Manjaro Linux now identified as platform_family 'arch' # Ohai Release Notes 14.6 ## Filesystem Plugin on AIX and Solaris AIX and Solaris now ship with a filesystem2 plugin that updates the filesystem data to match that of Linux, macOS, amd BSD hosts. This new data structure makes accessing filesystem data in recipes easier and especially improves the layout and depth of data on ZFS filesystems. In Chef 15 (April 2019) we will begin wrting this same format of data to the existing `node['filesystem']` namespace. In Chef 16 (April 2020) we will remove the `node['filesystem2']` namspace, completing the transition to the new format. Thank you @jaymzh for continuing the updates to our filesystem plugins with this change. ## macOS Improvements The system_profile plugin has been improved to skip over uncessary data, which reduces macOS node sizes on the Chef Server. Additionally the CPU plugin has been updated to limit what sysctl values it polls, which prevents hanging on some system configurations. ## SLES 15 Detection SLES 15 is now correctly detected as the platform "suse" instead of "sles". This matches the behavior of SLES 11 and 12 hosts. ## New Deprecations ### system_profile plugin removal The system_profile plugin will be removed from Chef/Ohai 15 in April 2019. This plugin does not correctly return data on modern Mac systems. Additionally the same data is provided by the hardware plugin, which has a format that is simpler to consume. Removing this plugin will reduce Ohai return by ~3 seconds and greatly reduce the size of the node object on the Chef server. # Ohai Release Notes 14.5 ## Windows Improvements Detection for the `root_group` attribute on Windows has been simplified and improved to properly support non-English systems. With this change, we've also deprecated the `Ohai::Util::Win32::GroupHelper` helper, which is no longer necessary. Thanks to [@jugatsu](https://github.com/jugatsu) for putting this together. We've also added a new `encryption_status` attribute to volumes on Windows. Thanks to [@kmf](https://github.com/kmf) for suggesting this new feature. ## Configuration Improvements The timeout period for communicating with OpenStack metadata servers can now be configured with the `openstack_metadata_timeout` config option. Thanks to [@sawanoboly](https://github.com/sawanoboly) for this improvement. Ohai now properly handles relative paths to config files when running on the command line. This means commands like `ohai -c ../client.rb` will now properly use your config values. # Ohai Release Notes 14.4 ## Multiple plugin directories You can now specify more than one directory to load additional Ohai plugins from by using the `--directory` / `-d` flag more than once. Example: ```bash ohai -d /path/to/more/plugins -d /another/path/to/more/plugins ``` Thanks @jaymzh for reporting this. ## Shellout Timeout Configuration By default, the timeout for any shellout in Ohai is 30 seconds. If this is too short for you, due to slow systems or large numbers of mounts, you may need to increase this timeout. You can now configure your own timeout (lower or higher) via the new `shellout_timeout` config setting. Thanks @WheresAlice for this change. ## System Enclosure Plugin On Windows, we have a new System Enclosure plugin that provides you with the `manufacturer` and `serialnumber` of the underlying system. Thanks [@kmf](https://github.com/kmf) for suggesting this plugin. # Ohai Release Notes 14.3 ## Detection of Amazon Linux 2.0 Ohai now properly detects the platform_version of the final release of Amazon Linux 2.0 in addition to the previous detection of the RC platform_version. # Ohai Release Notes 14.2 ## Virtualization detection on AWS Ohai now detects the virtualization hypervisor `amazonec2` when running on Amazon's new C5/M5 instances. # Ohai Release Notes 14.1 ## Configurable DMI Whitelist The whitelist of DMI IDs is now user configurable using the `additional_dmi_ids` configuration setting, which takes an Array. ## Shard plugin The Shard plugin has been returned to a default plugin rather than an optional one. To ensure we work in FIPS environments, the plugin will use SHA256 rather than MD5 in those environments. ## SCSI plugin A new plugin to enumerate SCSI devices has been added. This plugin is optional. # Ohai Release Notes 14.0 ## Windows Kernel information The kernel plugin now reports the following information on Windows: - `node['kernel']['product_type']` - Workstation vs. Server editions of Windows - `node['kernel']['system_type']` - What kind of hardware are we installed on (Desktop, Mobile, Workstation, Enterprise Server, etc.) - `node['kernel']['server_core']` - Are we on Windows Server Core edition? ## Cloud Detection Ohai now detects the Scaleway cloud and provides additional configuration information for systems running on Azure. ## Virtualization / Container Detection In addition to detecting if a system is a Docker host, we now provide a large amount of Docker configuration information available at `node['docker']`. This includes the release of Docker, installed plugins, network config, and the number of running containers. Ohai also now properly detects LXD containers and macOS guests running on VirtualBox / VMware. This data is available in `node['virtualization']['systems']` ## Optional Ohai Plugins Ohai now includes the ability to mark plugins as optional, which skips those plugins by default. This allows us to ship additional plugins, which some users may find useful, but not all users would want being written to their Chef server. The change introduces two new configuration options; `run_all_plugins` which runs everything including optional plugins, and `optional_plugins` which allows you to run plugins marked as optional. By default we will now be marking the `lspci`, `sessions` and `passwd` plugins as optional. Passwd has been particularly problematic for nodes attached LDAP or AD where it attempts to write the entire directory to the node. If you previously disabled this plugin via Ohai config, you no longer need to. Hurray! ## Logging Improvements Chef and Ohai now includes a new log level of `:trace` in addition to the existing `:info`, `:warn`, and `:debug` levels. With the introduction of `trace` level logging we've moved a large amount of logging that more useful for developers from `debug` to `trace`. If you want a complete insight into what is going on internally in Ohai run -l trace not -l debug. ## Breaking Changes ### cloud_v2 and filesystem2 Plugins In Chef 13 the `cloud_v2` plugin replaced data at `node['cloud']` and `filesystem2` replaced data at `node['filesystem']`. For compatibility with cookbooks that were previously using the "v2" data we continued to write data to both locations (ie: both node['filesystem'] and node['filesystem2']). We now no longer write data to the "v2" locations which greatly reduces the amount of data we need to store on the Chef server. ### Ipscopes Plugin Removed The ipscopes plugin has been removed as it duplicated data already present in the network plugins and required the user to install an additional gem into the Chef installation. ### libvirt attributes moved The libvirt Ohai plugin now writes data to `node['libvirt']` instead of writing to various locations in `node['virtualization']`. This plugin required installing an additional gem into the Chef installation and thus was infrequently used. ### Ohai Plugin V6 Support Removed In 2014 we introduced Ohai v7 with a greatly improved plugin format. With Chef 14 we no longer support loading of the legacy "v6" plugin format. ### Newly-disabled Ohai Plugins As mentioned above we now support an `optional` flag for Ohai plugins and have marked the `sessions`, `lspci`, and `passwd` plugins as optional, which disables them by default. If you need one of these plugins you can include them using `optional_plugins`. optional_plugins in the client.rb file: ```ruby optional_plugins [ "lspci", "passwd" ] ``` # Ohai Release Notes 13.8.0 ## Softlayer metadata polling fixed We now use TLS 1.2 for polling Softlayer metadata since 1.0/1.1 were disabled on 3/1/2018 # Ohai Release Notes 13.7.1 ## Network Tunnel Information The Network plugin on Linux hosts now gathers additional information on tunnels ## LsPci Plugin The new LsPci plugin provides a `node[:pci]` hash with information about the PCI bus based on `lspci`. Only runs on Linux. # Ohai Release Notes 13.7 ## EC2 C5 Detection The EC2 plugin has been updated to properly detect the new AWS hypervisor used in the C5 instance types ## mdadm The mdadm plugin has been updated to properly handle arrays with more than 10 disks and to properly handle journal and spare drives in the disk counts # Ohai Release Notes 13.6 ## Critical Plugins Users can now specify a list of plugins which are `critical`. Critical plugins will cause Ohai to fail if they do not run successfully (and thus cause a Chef run using Ohai to fail). The syntax for this is: ``` ohai.critical_plugins << :Filesystem ``` ## Filesystem now has a `allow_partial_data` configuration option The Filesystem plugin now has a `allow_partial_data` configuration option. If set, the filesystem will return whatever data it can even if some commands it ran failed. ## Rackspace detection on Windows Windows nodes running on Rackspace will now properly detect themselves as running on Rackspace without a hint file. ## Package data on Amazon Linux The Packages plugin now supports gathering packages data on Amazon Linux ## Deprecation updates In Ohai 13 we replaced the filesystem and cloud plugins with the filesystem2 and cloud_v2 plugins. To maintain compatibility with users of the previous V2 plugins we write data to both locations. We had originally planned to continue writing data to both locations until Chef 15\. Instead due to the large amount of duplicate node data this introduces we are updating OHAI-11 and OHAI-12 deprecations to remove node['cloud_v2'] and node['filesystem2'] with the release of Chef 14 in April 2018. # Ohai Release Notes 13.5 ## Correctly detect IPv6 routes ending in :: Previously we would ignore routes that ended `::`, and now we properly detect them. ## Plugin run time is now measured Debug logs will show the length of time each plugin takes to run, making debugging of long ohai runs easier. # Ohai Release Notes 13.4 ## Windows EC2 Detection Detection of nodes running in EC2 has been greatly improved and should now detect nodes 100% of the time including nodes that have been migrated to EC2 or were built with custom AMIs. ## Azure Metadata Endpoint Detection Ohai now polls the new Azure metadata endpoint, giving us additional configuration details on nodes running in Azure Sample data now available under azure: ```javascript { "metadata": { "compute": { "location": "westus", "name": "timtest", "offer": "UbuntuServer", "osType": "Linux", "platformFaultDomain": "0", "platformUpdateDomain": "0", "publisher": "Canonical", "sku": "17.04", "version": "17.04.201706191", "vmId": "8d523242-71cf-4dff-94c3-1bf660878743", "vmSize": "Standard_DS1_v2" }, "network": { "interfaces": { "000D3A33AF03": { "mac": "000D3A33AF03", "public_ipv6": [ ], "public_ipv4": [ "52.160.95.99", "23.99.10.211" ], "local_ipv6": [ ], "local_ipv4": [ "10.0.1.5", "10.0.1.4", "10.0.1.7" ] } }, "public_ipv4": [ "52.160.95.99", "23.99.10.211" ], "local_ipv4": [ "10.0.1.5", "10.0.1.4", "10.0.1.7" ], "public_ipv6": [ ], "local_ipv6": [ ] } } } ``` ## Package Plugin Supports Arch Linux The Package plugin has been updated to include package information on Arch Linux systems. # Ohai Release Notes 13.3 ## Additional Platform Support Ohai now properly detects the [F5 Big-IP](https://www.f5.com/) platform and platform_version. - platform: bigip - platform_family: rhel # Ohai Release Notes 13.2: Ohai 13.2 has been a fantastic release in terms of community involvement with new plugins, platform support, and critical bug fixes coming from community members. A huge thank you to msgarbossa, albertomurillo, jaymzh, and davide125 for their work. ## New Features ### Systemd Paths Plugin A new plugin has been added to expose system and user paths from systemd-path (see for details). ### Linux Network, Filesystem, and Mdadm Plugin Resilience The Network, Filesystem, and Mdadm plugins have been improved to greatly reduce failures to collect data. The Network plugin now better finds the binaries it requires for shelling out, filesystem plugin utilizes data from multiple sources, and mdadm handles arrays in bad states. ### Zpool Plugin Platform Expansion The Zpool plugin has been updated to support BSD and Linux in addition to Solaris. ### RPM version parsing on AIX The packages plugin now correctly parses RPM package name / version information on AIX systems. ### Additional Platform Support Ohai now properly detects the [Clear](https://clearlinux.org/) and [ClearOS](https://www.clearos.com/) Linux distributions. #### Clear Linux - platform: clearlinux - platform_family: clearlinux #### ClearOS - platform: clearos - platform_family: rhel ## New Deprecations ### Removal of IpScopes plugin. (OHAI-13) In Chef/Ohai 14 (April 2018) we will remove the IpScopes plugin. The data returned by this plugin is nearly identical to information already returned by individual network plugins and this plugin required the installation of an additional gem into the Chef installation. We believe that few users were installing the gem and users would be better served by the data returned from the network plugins. ohai-16.0.7/Rakefile000066400000000000000000000017301362624620500142010ustar00rootroot00000000000000require "bundler/gem_tasks" begin require "rspec/core/rake_task" RSpec::Core::RakeTask.new do |t| t.pattern = "spec/**/*_spec.rb" end rescue LoadError desc "rspec is not installed, this task is disabled" task :spec do abort "rspec is not installed. bundle install first to make sure all dependencies are installed." end end begin require "chefstyle" require "rubocop/rake_task" desc "Run Chefstyle tests" RuboCop::RakeTask.new(:style) do |task| task.options += ["--display-cop-names", "--no-color"] end rescue LoadError puts "chefstyle gem is not installed. bundle install first to make sure all dependencies are installed." end begin require "yard" YARD::Rake::YardocTask.new(:docs) rescue LoadError puts "yard is not available. bundle install first to make sure all dependencies are installed." end task :console do require "irb" require "irb/completion" require "ohai" ARGV.clear IRB.start end task default: %i{style spec} ohai-16.0.7/VERSION000066400000000000000000000000061362624620500135770ustar00rootroot0000000000000016.0.7ohai-16.0.7/bin/000077500000000000000000000000001362624620500133035ustar00rootroot00000000000000ohai-16.0.7/bin/ohai000077500000000000000000000016541362624620500141570ustar00rootroot00000000000000#!/usr/bin/env ruby # # ./ohai - I'm in ur serverz, showin you the daters # # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # if we're in a source code checkout, we want to run the code from that. $:.unshift File.expand_path("../../lib", __FILE__) require "ohai/application" Ohai::Application.new.run ohai-16.0.7/lib/000077500000000000000000000000001362624620500133015ustar00rootroot00000000000000ohai-16.0.7/lib/ohai.rb000066400000000000000000000014601362624620500145470ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "ohai/version" require_relative "ohai/config" require_relative "ohai/system" require_relative "ohai/exception" ohai-16.0.7/lib/ohai/000077500000000000000000000000001362624620500142215ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/application.rb000066400000000000000000000104271362624620500170550ustar00rootroot00000000000000# # Author:: Mathieu Sauve-Frankel # Copyright:: Copyright (c) 2009 Mathieu Sauve-Frankel. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "chef-config/path_helper" require "chef-config/workstation_config_loader" require_relative "../ohai" require_relative "log" require "mixlib/cli" unless defined?(Mixlib::CLI) require "benchmark" # The Application class is what is called by the Ohai CLI binary. It handles: # - CLI options and attribute arguments # - Collecting data via the Ohai::System class # - Printing the results returned via the Ohai::System class class Ohai::Application include Mixlib::CLI option :config_file, short: "-c CONFIG", long: "--config CONFIG", description: "A configuration file to use", proc: lambda { |path| File.expand_path(path, Dir.pwd) } option :directory, short: "-d DIRECTORY", long: "--directory DIRECTORY", description: "A directory to add to the Ohai plugin search path. If passing multiple directories use this option more than once.", proc: lambda { |path, path_array| (path_array ||= []) << Ohai::Config.platform_specific_path(path) path_array } option :log_level, short: "-l LEVEL", long: "--log_level LEVEL", description: "Set the log level (debug, info, warn, error, fatal)", proc: lambda { |l| l.to_sym } option :log_location, short: "-L LOGLOCATION", long: "--logfile LOGLOCATION", description: "Set the log file location, defaults to STDOUT - recommended for daemonizing", proc: nil option :help, short: "-h", long: "--help", description: "Show this message", on: :tail, boolean: true, show_options: true, exit: 0 option :version, short: "-v", long: "--version", description: "Show Ohai version", boolean: true, proc: lambda { |v| puts "Ohai: #{::Ohai::VERSION}" }, exit: 0 # the method called by the Ohai binary to actually run the whole application # # @return void def run elapsed = Benchmark.realtime do configure_ohai run_application end Ohai::Log.debug("Ohai took #{elapsed} total seconds to run.") end # parses the CLI options, loads the config file if present, and initializes logging # # @return void def configure_ohai @attributes = parse_options @attributes = nil if @attributes.empty? load_workstation_config Ohai::Log.init(Ohai.config[:log_location]) end # Passes config and attributes arguments to Ohai::System then prints the results. # Called by the run method after config / logging have been initialized # # @return void def run_application config[:invoked_from_cli] = true config[:logger] = Ohai::Log.with_child ohai = Ohai::System.new(config) ohai.all_plugins(@attributes) if @attributes @attributes.each do |a| puts ohai.attributes_print(a) end else puts ohai.json_pretty_print end end class << self # Log a fatal error message to both STDERR and the Logger, exit the application # @param msg [String] the message to log # @param err [Integer] the exit code def fatal!(msg, err = -1) STDERR.puts("FATAL: #{msg}") Ohai::Log.fatal(msg) Process.exit err end # Log a debug message to the Logger and then exit the application # @param msg [String] the message to log # @param err [Integer] the exit code def exit!(msg, err = -1) Ohai::Log.debug(msg) Process.exit err end end private def load_workstation_config config_loader = ChefConfig::WorkstationConfigLoader.new( config[:config_file], Ohai::Log ) begin config_loader.load rescue ChefConfig::ConfigurationError => config_error Ohai::Application.fatal!(config_error.message) end end end ohai-16.0.7/lib/ohai/common/000077500000000000000000000000001362624620500155115ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/common/dmi.rb000066400000000000000000000122441362624620500166120ustar00rootroot00000000000000# # Author:: Kurt Yoder (ktyopscode@yoderhome.com) # Copyright:: Copyright (c) 2010 Kurt Yoder # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai module Common module DMI # List of IDs and what they translate to # from 'man 8 dmidecode' # all-lowercase, all non-alphanumeric converted to '_' # 128-255 are 'oem_data_[id]' # Everything else is 'unknown' ID_TO_DESCRIPTION = { 0 => "bios", 1 => "system", 2 => "base_board", 3 => "chassis", 4 => "processor", 5 => "memory_controller", 6 => "memory_module", 7 => "cache", 8 => "port_connector", 9 => "system_slots", 10 => "on_board_devices", 11 => "oem_strings", 12 => "system_configuration_options", 13 => "bios_language", 14 => "group_associations", 15 => "system_event_log", 16 => "physical_memory_array", 17 => "memory_device", 18 => "32_bit_memory_error", 19 => "memory_array_mapped_address", 20 => "memory_device_mapped_address", 21 => "built_in_pointing_device", 22 => "portable_battery", 23 => "system_reset", 24 => "hardware_security", 25 => "system_power_controls", 26 => "voltage_probe", 27 => "cooling_device", 28 => "temperature_probe", 29 => "electrical_current_probe", 30 => "out_of_band_remote_access", 31 => "boot_integrity_services", 32 => "system_boot", 33 => "64_bit_memory_error", 34 => "management_device", 35 => "management_device_component", 36 => "management_device_threshold_data", 37 => "memory_channel", 38 => "ipmi_device", 39 => "power_supply", 40 => "additional_information", 41 => "onboard_devices_extended_information", 42 => "management_controller_host_interfaces", 126 => "disabled_entries", 127 => "end_of_table_marker", }.freeze # list of IDs to collect from config or default to a sane list that prunes # away some of the less useful IDs ID_TO_CAPTURE = [ 0, 1, 2, 3, 4, 6, 11 ].freeze # the whitelisted DMI IDs. This is combination of the defaults + any additional # IDs defined in the :additional_dmi_ids config # # @return [Array] the list of DMI IDs to capture def whitelisted_ids if Ohai.config[:additional_dmi_ids] if [ Integer, Array ].include?(Ohai.config[:additional_dmi_ids].class) return ID_TO_CAPTURE + Array(Ohai.config[:additional_dmi_ids]) else Ohai::Log.warn("The DMI plugin additional_dmi_ids config must be an array of IDs!") end end ID_TO_CAPTURE end # the human readable description from a DMI ID # # @param id [String, Integer] the ID to lookup # # @return [String] def id_lookup(id) id = id.to_i if (id >= 128) && (id <= 255) id = "oem_data_#{id}" elsif DMI::ID_TO_DESCRIPTION.key?(id) id = DMI::ID_TO_DESCRIPTION[id] else Ohai::Log.debug("unrecognized header id; falling back to 'unknown'") id = "unknown_dmi_id_#{id}" end rescue Ohai::Log.debug("failed to look up id #{id}, returning unchanged") id end # create simplified convenience access keys for each record type # for single occurrences of one type, copy to top level all fields and values # for multiple occurrences of same type, copy to top level all fields and values that are common to all records def convenience_keys(dmi) dmi.each do |type, records| in_common = Mash.new next unless records.is_a?(Mash) next unless records.key?("all_records") records[:all_records].each do |record| record.each do |field, value| next if value.is_a?(Mash) next if field.to_s == "application_identifier" next if field.to_s == "size" next if field.to_s == "record_id" translated = field.downcase.gsub(/[^a-z0-9]/, "_") value = value.strip if in_common.key?(translated) in_common[translated] = nil unless in_common[translated] == value else in_common[translated] = value end end end in_common.each do |field, value| next if value.nil? dmi[type][field] = value.strip end end end module_function :id_lookup, :convenience_keys, :whitelisted_ids end end end ohai-16.0.7/lib/ohai/config.rb000066400000000000000000000036061362624620500160200ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Claire McQuin () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef-config/config" require_relative "exception" require_relative "plugin_config" module Ohai Config = ChefConfig::Config # Reopens ChefConfig::Config to add Ohai configuration settings. # see: https://github.com/chef/chef/blob/master/lib/chef/config.rb class Config config_context :ohai do default :disabled_plugins, [] default :hints_path, [ ChefConfig::Config.platform_specific_path("/etc/chef/ohai/hints") ] default :log_level, :auto default :log_location, STDERR default :plugin, ( Ohai::PluginConfig.new { |h, k| h[k] = Ohai::PluginConfig.new } ) default :plugin_path, [ File.expand_path(File.join(File.dirname(__FILE__), "plugins")), ChefConfig::Config.platform_specific_path("/etc/chef/ohai/plugins") ] default :critical_plugins, [] # causes all optional plugins to be run. default :run_all_plugins, false # optional plugins are the set of plugins that are marked optional but you wish to run. default(:optional_plugins, []).writes_value { |arr| arr.map(&:to_sym) } default :shellout_timeout, 30 end end # Shortcut for Ohai::Config.ohai def self.config Config.ohai end end ohai-16.0.7/lib/ohai/dsl.rb000066400000000000000000000013751362624620500153360ustar00rootroot00000000000000# # Author:: Serdar Sutay () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "dsl/plugin" require_relative "dsl/plugin/versionvii" ohai-16.0.7/lib/ohai/dsl/000077500000000000000000000000001362624620500150035ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/dsl/plugin.rb000066400000000000000000000132711362624620500166320ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Claire McQuin () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "../mixin/os" require_relative "../mixin/command" require_relative "../mixin/seconds_to_human" require_relative "../hints" require_relative "../util/file_helper" module Ohai # For plugin namespacing module NamedPlugin # Is the plugin a Symbol starting with a capital letter that has no underscores # # @param name [String] the plugin name # @return [Boolean] def self.valid_name?(name) name.is_a?(Symbol) && name.to_s.match(/^[^A-Z]|_/).nil? end # @return [Boolean] def self.strict_const_defined?(const) const_defined?(const, false) end end # @param name [String] def self.plugin(name, &block) raise Ohai::Exceptions::InvalidPluginName, "#{name} is not a valid plugin name. A valid plugin name is a symbol which begins with a capital letter and contains no underscores" unless NamedPlugin.valid_name?(name) plugin = nil # avoid already initialized constant warnings if already defined if NamedPlugin.strict_const_defined?(name) plugin = NamedPlugin.const_get(name) plugin.class_eval(&block) else klass = Class.new(DSL::Plugin::VersionVII, &block) plugin = NamedPlugin.const_set(name, klass) end plugin end # Cross platform /dev/null to support testability # # @return [String] def self.dev_null if RUBY_PLATFORM =~ /mswin|mingw|windows/ "NUL" else "/dev/null" end end # Extracted abs_path to support testability: # This method gets overridden at test time, to force the shell to check # ohai/spec/unit/path/original/absolute/path/to/exe def self.abs_path( abs_path ) abs_path end module DSL class Plugin include Ohai::Mixin::OS include Ohai::Mixin::Command include Ohai::Mixin::SecondsToHuman include Ohai::Util::FileHelper attr_reader :data attr_reader :failed attr_reader :logger def initialize(data, logger) @data = data @logger = logger.with_child({ subsystem: "plugin", plugin: name }) @has_run = false @failed = false end def run @has_run = true if Ohai.config[:disabled_plugins].include?(name) logger.trace("Skipping disabled plugin #{name}") else run_plugin end end def has_run? @has_run end def reset! @has_run = false end def [](key) @data[key] end def []=(key, value) @data[key] = value end def each(&block) @data.each do |key, value| yield(key, value) end end def has_key?(name) @data.key?(name) end def attribute?(name, *keys) !safe_get_attribute(name, *keys).nil? end def set(name, *value) set_attribute(name, *value) end def from(cmd) _status, stdout, _stderr = run_command(command: cmd) return "" if stdout.nil? || stdout.empty? stdout.strip end # Set the value equal to the stdout of the command, plus # run through a regex - the first piece of match data is\ # the value. def from_with_regex(cmd, *regex_list) regex_list.flatten.each do |regex| _status, stdout, _stderr = run_command(command: cmd) return "" if stdout.nil? || stdout.empty? stdout.chomp!.strip md = stdout.match(regex) return md[1] end end def set_attribute(name, *attrs, value) # Initialize the path in the @data Mash with new Mashes, if needed. # Will raise a TypeError if we hit a subattribute that is not a # Hash, Mash, or Array. keys = [name] + attrs attribute = keys[0..-2].inject(@data) do |atts, key| atts[key] ||= Mash.new atts[key] end # Set the subattribute to the value. attr_name = attrs.empty? ? name : attrs[-1] attribute[attr_name] = value @data[name] end def get_attribute(name, *keys) safe_get_attribute(name, *keys) end def hint?(name) Ohai::Hints.hint?(name) end # emulates the old plugin loading behavior def safe_run run rescue Ohai::Exceptions::Error => e @failed = true raise e rescue => e @failed = true logger.trace("Plugin #{name} threw #{e.inspect}") e.backtrace.each { |line| logger.trace( line ) } end def method_missing(name, *args) return get_attribute(name) if args.length == 0 set_attribute(name, *args) end private def safe_get_attribute(*keys) keys.inject(@data) do |attrs, key| unless attrs.nil? || attrs.is_a?(Array) || attrs.is_a?(Hash) raise TypeError.new("Expected Hash but got #{attrs.class}.") end attrs[key] end rescue NoMethodError # NoMethodError occurs when trying to access a key on nil nil end end end end ohai-16.0.7/lib/ohai/dsl/plugin/000077500000000000000000000000001362624620500163015ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/dsl/plugin/versionvii.rb000066400000000000000000000141151362624620500210250ustar00rootroot00000000000000# # Author:: Serdar Sutay () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai module DSL class Plugin # The class for the "Version 7" plugin format we introduced in Ohai 7. This is the 2nd # generation of Ohai plugin and the previous generation (V6) was removed in Ohai 14 class VersionVII < Plugin attr_reader :version attr_reader :source def initialize(data, logger) super(data, logger) @source = self.class.sources @version = :version7 end # the plugin name we use through Ohai (Foo) vs. the class name (Ohai::NamedPlugin::Foo) # # @return [String] def name self.class.name.split("Ohai::NamedPlugin::")[1].to_sym end # return that we're a v7 plugin # # @return [Symbol] def self.version :version7 end # the source of the plugin on disk. This is an array since a plugin may exist for multiple platforms and this would include each of those platform specific file paths # # @return [Array] def self.sources @source_list ||= [] end def self.provides_attrs @provides_attrs ||= [] end def self.depends_attrs @depends_attrs ||= [] end # A block per platform for actually performing data collection constructed # by the collect_data method # # @return [Mash] def self.data_collector @data_collector ||= Mash.new end # set the attributes provided by the plugin # # @param attrs [Array] def self.provides(*attrs) attrs.each do |attr| provides_attrs << attr unless provides_attrs.include?(attr) end end # set the attributes depended on by the plugin # # @param attrs [Array] def self.depends(*attrs) attrs.each do |attr| depends_attrs << attr unless depends_attrs.include?(attr) end end # set the plugin optional state # # @param opt [Boolean] def self.optional(opt = true) @optional = opt end # check if the plugin is optional # # @return [Boolean] def self.optional? !!@optional end # define data collection methodology per platform # # @param platform [Symbol] the platform to collect data for # @param other_platforms [Array] additional platforms to collect data for # @param block [block] the actual code to collect data for the specified platforms def self.collect_data(platform = :default, *other_platforms, &block) [platform, other_platforms].flatten.each do |plat| Ohai::Log.warn("collect_data already defined on platform '#{plat}' for #{self}, last plugin seen will be used") if data_collector.key?(plat) data_collector[plat] = block end end # @return [Array] def dependencies self.class.depends_attrs end def run_plugin collector = self.class.data_collector platform = collect_os if collector.key?(platform) instance_eval(&collector[platform]) elsif collector.key?(:default) instance_eval(&collector[:default]) else logger.trace("Plugin #{name}: No data to collect. Skipping...") end end def optional? self.class.optional? end def provides(*paths) logger.warn("[UNSUPPORTED OPERATION] \'provides\' is no longer supported in a \'collect_data\' context. Please specify \'provides\' before collecting plugin data. Ignoring command \'provides #{paths.join(", ")}") end def require_plugin(*args) logger.warn("[UNSUPPORTED OPERATION] \'require_plugin\' is no longer supported. Please use \'depends\' instead.\nIgnoring plugin(s) #{args.join(", ")}") end def configuration(option, *options) return nil if plugin_config.nil? || !plugin_config.key?(option) value = plugin_config[option] options.each do |opt| return nil unless value.key?(opt) value = value[opt] end value end private def plugin_config @plugin_config ||= fetch_plugin_config end def fetch_plugin_config # DMI => ["DMI"] # Memory => ["", "Memory"] # NetworkListeners => ["", "Network", "", "Listeners"] # SSHHostKey => ["SSH", "Host", "", "Key"] parts = name.to_s.split(/([A-Z][a-z]+)/) # ["DMI"] => ["DMI"] # ["", "Memory"] => ["Memory"] # ["", "Network", "", "Listeners"] => ["Network", "Listeners"] # ["SSH", "Host", "", "Key"] => ["SSH", "Host", "Key"] parts.delete_if(&:empty?) # ["DMI"] => :dmi # ["Memory"] => :memory # ["Network", "Listeners"] => :network_listeners # ["SSH", "Host", "Key"] => :ssh_host_key snake_case_name = parts.map(&:downcase).join("_").to_sym # Plugin names in config hashes are auto-vivified, so we check with # key? to avoid falsely instantiating a configuration hash. if Ohai.config[:plugin].key?(snake_case_name) Ohai.config[:plugin][snake_case_name] else nil end end end end end end ohai-16.0.7/lib/ohai/exception.rb000066400000000000000000000023401362624620500165430ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai # Ohai specific exceptions module Exceptions class Exec < RuntimeError; end class Error < StandardError; end class InvalidPlugin < Error; end class InvalidPluginName < Error; end class IllegalPluginDefinition < Error; end class AttributeNotFound < Error; end class ProviderNotFound < Error; end class DependencyCycle < Error; end class DependencyNotFound < Error; end class AttributeSyntaxError < Error; end class PluginConfigError < Error; end class CriticalPluginFailure < Error; end end end ohai-16.0.7/lib/ohai/hints.rb000066400000000000000000000051371362624620500157010ustar00rootroot00000000000000# # Author:: Serdar Sutay () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # require "ffi_yajl" unless defined?(FFI_Yajl) module Ohai # Ohai hints are json files on disk that give ohai a hint to things that are often # difficult to discover like certain clouds. Previously they were used for just about # every cloud, but we've since discoverd better ways to auto-detect these clouds. # They are generally dropped off by the knife plugins for those clouds during bootstrap, # but may also be manually dropped off and consumed by 3rd party plugins. module Hints # clear out any known hints in the @hints variable def self.refresh_hints @hints = {} end # parse the JSON contents of a hint file. Return an empty hash if the file has # no JSON content # @param filename [String] the hint file path def self.parse_hint_file(filename) json_parser = FFI_Yajl::Parser.new hash = json_parser.parse(File.read(filename)) hash || {} # hint # should exist because the file did, even if it didn't # contain anything rescue FFI_Yajl::ParseError => e Ohai::Log.error("Could not parse hint file at #{filename}: #{e.message}") end # retrieve hint contents given a hint name. Looks up in @hints variable first. Attempts # to load from file in config's :hints_path if not already cached. Saves the contents # to the hash if the file was successfully parsed # @param name [String] the name of the hint (not the path) def self.hint?(name) @hints ||= {} return @hints[name] if @hints[name] Ohai.config[:hints_path].each do |path| filename = File.join(path, "#{name}.json") next unless File.exist?(filename) Ohai::Log.trace("Found hint #{name}.json at #{filename}") @hints[name] = parse_hint_file(filename) end Ohai::Log.trace("Did not find hint #{name}.json in the hint path(s): #{Ohai.config[:hints_path].join(", ")} ") unless @hints.key?(name) @hints[name] end end end ohai-16.0.7/lib/ohai/loader.rb000066400000000000000000000146541362624620500160260ustar00rootroot00000000000000# # Author:: Claire McQuin () # Copyright:: Copyright (c) 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef-config/path_helper" require_relative "log" require_relative "mash" require_relative "dsl" require "pathname" unless defined?(Pathname) module Ohai # Ohai plugin loader. Finds all the plugins specified in the # Ohai.config :plugin_path (supports a single or multiple path setting # here), evaluates them and returns plugin objects. class Loader attr_reader :logger def initialize(controller) @controller = controller @logger = controller.logger.with_child(subsystem: "loader") @v7_plugin_classes = [] end # Searches all plugin paths and returns an Array of file paths to plugins # # @param dir [Array, String] directory/directories to load plugins from # @return [Array] def plugin_files_by_dir(plugin_dir = Ohai.config[:plugin_path]) Array(plugin_dir).map do |path| if Dir.exist?(path) Ohai::Log.trace("Searching for Ohai plugins in #{path}") escaped = ChefConfig::PathHelper.escape_glob_dir(path) Dir[File.join(escaped, "**", "*.rb")] else Ohai::Log.debug("The plugin path #{path} does not exist. Skipping...") [] end end.flatten end # loads all plugin classes # # @return [Array] def load_all plugin_files_by_dir.each do |plugin_file| load_plugin_class(plugin_file) end collect_v7_plugins end # load additional plugins classes from a given directory # @param from [String] path to a directory with additional plugins to load def load_additional(from) from = [ Ohai.config[:plugin_path], from].flatten plugin_files_by_dir(from).collect do |plugin_file| logger.trace "Loading additional plugin: #{plugin_file}" plugin = load_plugin_class(plugin_file) load_v7_plugin(plugin) end end # Load a specified file as an ohai plugin and creates an instance of it. # Not used by ohai itself, but is used in the specs to load plugins for testing # # @private # @param plugin_path [String] def load_plugin(plugin_path) plugin_class = load_plugin_class(plugin_path) return nil unless plugin_class.is_a?(Class) if plugin_class < Ohai::DSL::Plugin::VersionVII load_v7_plugin(plugin_class) else raise Exceptions::IllegalPluginDefinition, "cannot create plugin of type #{plugin_class}" end end # load an ohai plugin object class from file # @param plugin_path String the path to the ohai plugin # # @return [Object] class object for the ohai plugin defined in the file def load_plugin_class(plugin_path) # Read the contents of the plugin to understand if it's a V6 or V7 plugin. contents = "" begin logger.trace("Loading plugin at #{plugin_path}") contents << IO.read(plugin_path) rescue IOError, Errno::ENOENT logger.warn("Unable to open or read plugin at #{plugin_path}") return nil end # We assume that a plugin is a V7 plugin if it contains Ohai.plugin in its contents. if contents.include?("Ohai.plugin") load_v7_plugin_class(contents, plugin_path) else raise Exceptions::IllegalPluginDefinition, "[DEPRECATION] Plugin at #{plugin_path}"\ " is a version 6 plugin. Version 6 plugins are no longer supported by Ohai. This"\ " plugin will need to be updated to the v7 Ohai plugin format. See"\ " https://docs.chef.io/ohai_custom.html for v7 syntax." end end private def collect_provides(plugin) plugin_provides = plugin.class.provides_attrs @controller.provides_map.set_providers_for(plugin, plugin_provides) end def collect_v7_plugins @v7_plugin_classes.each do |plugin_class| load_v7_plugin(plugin_class) end end # load an Ohai v7 plugin class from a string of the object # @param contents [String] text of the plugin object # @param plugin_path [String] the path to the plugin file where the contents came from # # @return [Ohai::DSL::Plugin::VersionVII] Ohai plugin object def load_v7_plugin_class(contents, plugin_path) plugin_class = eval(contents, TOPLEVEL_BINDING, plugin_path) # rubocop: disable Security/Eval unless plugin_class.is_a?(Class) && plugin_class < Ohai::DSL::Plugin raise Ohai::Exceptions::IllegalPluginDefinition, "Plugin file cannot contain any statements after the plugin definition" end plugin_class.sources << plugin_path @v7_plugin_classes << plugin_class unless @v7_plugin_classes.include?(plugin_class) plugin_class rescue SystemExit, Interrupt # rubocop: disable Lint/ShadowedException raise rescue Ohai::Exceptions::InvalidPluginName => e logger.warn("Plugin Name Error: <#{plugin_path}>: #{e.message}") rescue Ohai::Exceptions::IllegalPluginDefinition => e logger.warn("Plugin Definition Error: <#{plugin_path}>: #{e.message}") rescue NoMethodError => e logger.warn("Plugin Method Error: <#{plugin_path}>: unsupported operation \'#{e.name}\'") rescue SyntaxError => e # split on occurrences of # : syntax error, # :##: syntax error, # to remove from error message parts = e.message.split(/<.*>[:[0-9]+]*: syntax error, /) parts.each do |part| next if part.length == 0 logger.warn("Plugin Syntax Error: <#{plugin_path}>: #{part}") end rescue Exception => e logger.warn("Plugin Error: <#{plugin_path}>: #{e.message}") logger.trace("Plugin Error: <#{plugin_path}>: #{e.inspect}, #{e.backtrace.join('\n')}") end def load_v7_plugin(plugin_class) plugin = plugin_class.new(@controller.data, @controller.logger) collect_provides(plugin) plugin end end end ohai-16.0.7/lib/ohai/log.rb000066400000000000000000000021061362624620500153260ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2017, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "mixlib/log" module Ohai # the Ohai Logger which is just Mixlib::Log defaulting to STDERR and :info level # unless otherwise configured via CLI or config class Log extend Mixlib::Log # this class loading initialization is so that we don't lose early logger # messages when run from the CLI? init(STDERR) level = :info # rubocop:disable Lint/UselessAssignment end end ohai-16.0.7/lib/ohai/mash.rb000066400000000000000000000146431362624620500155060ustar00rootroot00000000000000# Copyright (c) 2009 Dan Kubb # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # --- # --- # Some portions of blank.rb and mash.rb are verbatim copies of software # licensed under the MIT license. That license is included below: # Copyright (c) 2005-2008 David Heinemeier Hansson # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # This class has dubious semantics and we only have it so that people can write # params[:key] instead of params['key']. class Mash < Hash # @param constructor [Object] The default value for the mash. # If constructor is a Hash, a new mash will be created based on the keys of the hash and # no default value will be set. def initialize(constructor = {}) if constructor.is_a?(Hash) super() update(constructor) else super(constructor) end end # @param key [Object] The default value for the mash. # If key is a Symbol and it is a key in the mash, then the default value will be set to # the value matching the key. def default(key = nil) if key.is_a?(Symbol) && include?(key = key.to_s) self[key] else super end end alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) alias_method :regular_update, :update unless method_defined?(:regular_update) # @param key [Object] The key to set. # @param value [Object] The value to set the key to. # # @see Mash#convert_key # @see Mash#convert_value def []=(key, value) regular_writer(convert_key(key), convert_value(value)) end # @param other_hash [Hash] # A hash to update values in the mash with. The keys and the values will be # converted to Mash format. # # @return [Mash] The updated mash. def update(other_hash) other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) } self end alias_method :merge!, :update # @param key [Object] The key to check for. This will be run through convert_key. # # @return [Boolean] True if the key exists in the mash. def key?(key) super(convert_key(key)) end # def include? def has_key? def member? alias_method :include?, :key? alias_method :has_key?, :key? alias_method :member?, :key? # @param key [Object] The key to fetch. This will be run through convert_key. # @param extras [Array] Default value. # # @return [Object] The value at key or the default value. def fetch(key, *extras) super(convert_key(key), *extras) end # @param indices [Array] The keys to retrieve values for. These will be run through +convert_key+. # # @return [Array] The values at each of the provided keys def values_at(*indices) indices.collect { |key| self[convert_key(key)] } end # @param hash [Hash] The hash to merge with the mash. # # @return [Mash] A new mash with the hash values merged in. def merge(hash) dup.update(hash) end # @param key [Object] The key to delete from the mash. def delete(key) super(convert_key(key)) end # @param keys [Array] The mash keys to exclude. # # @return [Mash] A new mash without the selected keys. # # @example # { :one => 1, :two => 2, :three => 3 }.except(:one) # #=> { "two" => 2, "three" => 3 } def except(*keys) super(*keys.map { |k| convert_key(k) }) end # Used to provide the same interface as Hash. # # @return [Mash] This mash unchanged. def stringify_keys!; self end # @return [Hash] The mash as a Hash with symbolized keys. def symbolize_keys h = Hash.new(default) each { |key, val| h[key.to_sym] = val } h end # @return [Hash] The mash as a Hash with string keys. def to_hash Hash.new(default).merge(self) end # Convert a Hash into a Mash. The input Hash's default value is maintained # @return [Mash] def self.from_hash(hash) mash = Mash.new(hash) mash.default = hash.default mash end protected # @param key [Object] The key to convert. # @return [Object] The converted key. If the key was a symbol, it will be converted to a string. # # @api private def convert_key(key) key.is_a?(Symbol) ? key.to_s : key end # @param value [Object] The value to convert. # # @return [Object] # The converted value. A Hash or an Array of hashes, will be converted to # their Mash equivalents. # # @api private def convert_value(value) if value.class == Hash Mash.from_hash(value) elsif value.is_a?(Array) value.collect { |e| convert_value(e) } else value end end end ohai-16.0.7/lib/ohai/mixin/000077500000000000000000000000001362624620500153455ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/mixin/azure_metadata.rb000066400000000000000000000034521362624620500206640ustar00rootroot00000000000000# # Author:: Tim Smith () # Copyright:: Copyright 2017 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "net/http" unless defined?(Net::HTTP) module Ohai module Mixin module AzureMetadata AZURE_METADATA_ADDR ||= "169.254.169.254".freeze AZURE_METADATA_URL ||= "/metadata/instance?api-version=2017-08-01".freeze # fetch the meta content with a timeout and the required header def http_get(uri) conn = Net::HTTP.start(AZURE_METADATA_ADDR) conn.read_timeout = 6 conn.get(uri, { "Metadata" => "true" }) end def fetch_metadata logger.trace("Mixin AzureMetadata: Fetching metadata from host #{AZURE_METADATA_ADDR} at #{AZURE_METADATA_URL}") response = http_get(AZURE_METADATA_URL) if response.code == "200" begin data = StringIO.new(response.body) parser = FFI_Yajl::Parser.new parser.parse(data) rescue FFI_Yajl::ParseError logger.warn("Mixin AzureMetadata: Metadata response is NOT valid JSON") nil end else logger.warn("Mixin AzureMetadata: Received response code #{response.code} requesting metadata") nil end end end end end ohai-16.0.7/lib/ohai/mixin/command.rb000066400000000000000000000041741362624620500173160ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Tim Smith () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "../exception" require_relative "../log" require "mixlib/shellout" unless defined?(Mixlib::ShellOut::DEFAULT_READ_TIMEOUT) module Ohai module Mixin module Command # DISCLAIMER: Logging only works in the context of a plugin!! # accept a command and any of the mixlib-shellout options def shell_out(cmd, **options) options = options.dup # unless specified by the caller timeout after configured timeout (default 30 seconds) options[:timeout] ||= Ohai::Config.ohai[:shellout_timeout] unless RUBY_PLATFORM =~ /mswin|mingw32|windows/ options[:env] = options.key?(:env) ? options[:env].dup : {} options[:env]["PATH"] ||= ((ENV["PATH"] || "").split(":") + %w{/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin}).join(":") end so = Mixlib::ShellOut.new(cmd, options) begin so.run_command logger.trace("Plugin #{name}: ran '#{cmd}' and returned #{so.exitstatus}") so rescue Errno::ENOENT => e logger.trace("Plugin #{name}: ran '#{cmd}' and failed #{e.inspect}") raise Ohai::Exceptions::Exec, e rescue Mixlib::ShellOut::CommandTimeout => e logger.trace("Plugin #{name}: ran '#{cmd}' and timed out after #{options[:timeout]} seconds") raise Ohai::Exceptions::Exec, e end end module_function :shell_out end end end ohai-16.0.7/lib/ohai/mixin/constant_helper.rb000066400000000000000000000031631362624620500210650ustar00rootroot00000000000000# # Author:: Serdar Sutay () # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai module Mixin module ConstantHelper def remove_constants new_object_constants = Object.constants - @object_pristine.constants new_object_constants.each do |constant| Object.send(:remove_const, constant) unless Object.const_get(constant).is_a?(Module) end recursive_remove_constants(Ohai::NamedPlugin) end def recursive_remove_constants(object) if object.respond_to?(:constants) object.constants.each do |const| next unless strict_const_defined?(object, const) recursive_remove_constants(object.const_get(const)) object.send(:remove_const, const) end end end def strict_const_defined?(object, const) if object.method(:const_defined?).arity == 1 object.const_defined?(const) else object.const_defined?(const, false) end end end end end ohai-16.0.7/lib/ohai/mixin/dmi_decode.rb000066400000000000000000000027611362624620500177540ustar00rootroot00000000000000# # Author:: Tim Smith # Copyright:: Copyright (c) 2015-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # http://www.dmo.ca/blog/detecting-virtualization-on-linux module ::Ohai::Mixin::DmiDecode def guest_from_dmi_data(manufacturer, product, version) case manufacturer when /OpenStack/ return "openstack" when /Xen/ return "xen" when /VMware/ return "vmware" when /Microsoft/ return "hyperv" if product =~ /Virtual Machine/ when /Amazon EC2/ return "amazonec2" when /QEMU/ return "kvm" when /Veertu/ return "veertu" when /Parallels/ return "parallels" end case product when /VirtualBox/ return "vbox" when /OpenStack/ # yes this is here twice. Product catches Redhat's version return "openstack" when /(KVM|RHEV)/ return "kvm" when /BHYVE/ return "bhyve" end nil # doesn't look like a virt end end ohai-16.0.7/lib/ohai/mixin/do_metadata.rb000066400000000000000000000027471362624620500201460ustar00rootroot00000000000000 # Author:: Dylan Page () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "net/http" unless defined?(Net::HTTP) module Ohai module Mixin module DOMetadata DO_METADATA_ADDR ||= "169.254.169.254".freeze DO_METADATA_URL ||= "/metadata/v1.json".freeze def http_client Net::HTTP.start(DO_METADATA_ADDR).tap { |h| h.read_timeout = 6 } end def fetch_metadata uri = (DO_METADATA_URL).to_s response = http_client.get(uri) case response.code when "200" parser = FFI_Yajl::Parser.new parser.parse(response.body) when "404" logger.trace("Mixin DOMetadata: Encountered 404 response retrieving Digital Ocean metadata: #{uri} ; continuing.") {} else raise "Mixin DOMetadata: Encountered error retrieving Digital Ocean metadata (#{uri} returned #{response.code} response)" end end end end end ohai-16.0.7/lib/ohai/mixin/ec2_metadata.rb000066400000000000000000000177011362624620500202110ustar00rootroot00000000000000# # Author:: Tim Dysinger () # Author:: Benjamin Black () # Author:: Christopher Brown () # Copyright:: 2009-2017 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "net/http" unless defined?(Net::HTTP) module Ohai module Mixin ## # This code parses the EC2 Instance Metadata API to provide details # of the running instance. # # Earlier version of this code assumed a specific version of the # metadata API was available. Unfortunately the API versions # supported by a particular instance are determined at instance # launch and are not extended over the life of the instance. As such # the earlier code would fail depending on the age of the instance. # # The updated code probes the instance metadata endpoint for # available versions, determines the most advanced version known to # work and executes the metadata retrieval using that version. # # If no compatible version is found, an empty hash is returned. # module Ec2Metadata EC2_METADATA_ADDR ||= "169.254.169.254".freeze EC2_SUPPORTED_VERSIONS ||= %w{ 1.0 2007-01-19 2007-03-01 2007-08-29 2007-10-10 2007-12-15 2008-02-01 2008-09-01 2009-04-04 2011-01-01 2011-05-01 2012-01-12 2014-02-25 2014-11-05 2015-10-20 2016-04-19 2016-06-30 2016-09-02 }.freeze EC2_ARRAY_VALUES ||= %w{security-groups local_ipv4s}.freeze EC2_ARRAY_DIR ||= %w{network/interfaces/macs}.freeze EC2_JSON_DIR ||= %w{iam}.freeze def best_api_version @api_version ||= begin logger.trace("Mixin EC2: Fetching http://#{EC2_METADATA_ADDR}/ to determine the latest supported metadata release") response = http_client.get("/") if response.code == "404" logger.trace("Mixin EC2: Received HTTP 404 from metadata server while determining API version, assuming 'latest'") return "latest" elsif response.code != "200" raise "Mixin EC2: Unable to determine EC2 metadata version (returned #{response.code} response)" end # Note: Sorting the list of versions may have unintended consequences in # non-EC2 environments. It appears to be safe in EC2 as of 2013-04-12. versions = response.body.split("\n").sort until versions.empty? || EC2_SUPPORTED_VERSIONS.include?(versions.last) pv = versions.pop logger.trace("Mixin EC2: EC2 lists metadata version: #{pv} not yet supported by Ohai") unless pv == "latest" end logger.trace("Mixin EC2: Latest supported EC2 metadata version: #{versions.last}") if versions.empty? raise "Mixin EC2: Unable to determine EC2 metadata version (no supported entries found)" end versions.last end end # a net/http client with a timeout of 10s and a keepalive of 10s # # @return [Net::HTTP] def http_client @conn ||= Net::HTTP.start(EC2_METADATA_ADDR).tap do |h| h.read_timeout = 10 h.keep_alive_timeout = 10 end end # Get metadata for a given path and API version # # Typically, a 200 response is expected for valid metadata. # On certain instance types, traversing the provided metadata path # produces a 404 for some unknown reason. In that event, return # `nil` and continue the run instead of failing it. def metadata_get(id, api_version) path = "/#{api_version}/meta-data/#{id}" logger.trace("Mixin EC2: Fetching http://#{EC2_METADATA_ADDR}#{path}") response = http_client.get(path) case response.code when "200" response.body when "404" logger.trace("Mixin EC2: Encountered 404 response retrieving EC2 metadata path: #{path} ; continuing.") nil else raise "Mixin EC2: Encountered error retrieving EC2 metadata (#{path} returned #{response.code} response)" end end def fetch_metadata(id = "", api_version = nil) metadata = {} retrieved_metadata = metadata_get(id, best_api_version) if retrieved_metadata retrieved_metadata.split("\n").each do |o| key = expand_path("#{id}#{o}") if key[-1..-1] != "/" metadata[metadata_key(key)] = if EC2_ARRAY_VALUES.include? key retr_meta = metadata_get(key, best_api_version) retr_meta ? retr_meta.split("\n") : retr_meta else metadata_get(key, best_api_version) end elsif (not key.eql?(id)) && (not key.eql?("/")) name = key[0..-2] sym = metadata_key(name) if EC2_ARRAY_DIR.include?(name) metadata[sym] = fetch_dir_metadata(key, best_api_version) elsif EC2_JSON_DIR.include?(name) metadata[sym] = fetch_json_dir_metadata(key, best_api_version) else fetch_metadata(key, best_api_version).each { |k, v| metadata[k] = v } end end end metadata end end def fetch_dir_metadata(id, api_version) metadata = {} retrieved_metadata = metadata_get(id, api_version) if retrieved_metadata retrieved_metadata.split("\n").each do |o| key = expand_path(o) if key[-1..-1] != "/" retr_meta = metadata_get("#{id}#{key}", api_version) metadata[metadata_key(key)] = retr_meta ? retr_meta : "" elsif not key.eql?("/") metadata[key[0..-2]] = fetch_dir_metadata("#{id}#{key}", api_version) end end metadata end end def fetch_json_dir_metadata(id, api_version) metadata = {} retrieved_metadata = metadata_get(id, api_version) if retrieved_metadata retrieved_metadata.split("\n").each do |o| key = expand_path(o) if key[-1..-1] != "/" retr_meta = metadata_get("#{id}#{key}", api_version) data = retr_meta ? retr_meta : "" json = StringIO.new(data) parser = FFI_Yajl::Parser.new metadata[metadata_key(key)] = parser.parse(json) elsif not key.eql?("/") metadata[key[0..-2]] = fetch_json_dir_metadata("#{id}#{key}", api_version) end end metadata end end def fetch_userdata logger.trace("Mixin EC2: Fetching http://#{EC2_METADATA_ADDR}/#{best_api_version}/user-data/") response = http_client.get("/#{best_api_version}/user-data/") response.code == "200" ? response.body : nil end def fetch_dynamic_data @fetch_dynamic_data ||= begin response = http_client.get("/#{best_api_version}/dynamic/instance-identity/document/") if json?(response.body) && response.code == "200" FFI_Yajl::Parser.parse(response.body) else {} end end end private def expand_path(file_name) path = file_name.gsub(/\=.*$/, "/") # ignore "./" and "../" path.gsub(%r{/\.\.?(?:/|$)}, "/") .sub(%r{^\.\.?(?:/|$)}, "") .sub(/^$/, "/") end def metadata_key(key) key.gsub(%r{\-|/}, "_") end end end end ohai-16.0.7/lib/ohai/mixin/gce_metadata.rb000066400000000000000000000046261362624620500203000ustar00rootroot00000000000000# # Author:: Ranjib Dey () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "net/http" unless defined?(Net::HTTP) module Ohai module Mixin module GCEMetadata # Trailing dot to host is added to avoid DNS search path GCE_METADATA_ADDR ||= "metadata.google.internal.".freeze GCE_METADATA_URL ||= "/computeMetadata/v1/?recursive=true".freeze # fetch the meta content with a timeout and the required header def http_get(uri) conn = Net::HTTP.start(GCE_METADATA_ADDR) conn.read_timeout = 6 conn.get(uri, { "Metadata-Flavor" => "Google", "User-Agent" => "chef-ohai/#{Ohai::VERSION}", }) end def fetch_metadata(id = "") response = http_get("#{GCE_METADATA_URL}/#{id}") return nil unless response.code == "200" if json?(response.body) data = StringIO.new(response.body) parser = FFI_Yajl::Parser.new parser.parse(data) elsif has_trailing_slash?(id) || (id == "") temp = {} response.body.split("\n").each do |sub_attr| temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}#{sub_attr}") end temp else response.body end end # @param [String] data that might be JSON # # @return [Boolean] is the data JSON or not? def json?(data) data = StringIO.new(data) parser = FFI_Yajl::Parser.new begin parser.parse(data) true rescue FFI_Yajl::ParseError false end end # @param data [String] # # @return [Boolean] is there a trailing /? def has_trailing_slash?(data) !! ( data =~ %r{/$} ) end def sanitize_key(key) key.gsub(%r{\-|/}, "_") end end end end ohai-16.0.7/lib/ohai/mixin/http_helper.rb000066400000000000000000000037611362624620500202170ustar00rootroot00000000000000# # Copyright:: 2017, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "socket" unless defined?(Socket) module Ohai module Mixin module HttpHelper # see if we can socket connect to an address/port # # @param addr [String] the address to connect to # @param port [Integer] the port to connect to # @param timeout [Integer] the seconds before timing out # # @return [Boolean] can we connect? def can_socket_connect?(addr, port, timeout = 2) t = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0) begin saddr = Socket.pack_sockaddr_in(port, addr) rescue SocketError => e # generally means dns resolution error logger.trace("Mixin HttpHelper: can_socket_connect? failed setting up socket connection: #{e}") return false end connected = false begin t.connect_nonblock(saddr) rescue Errno::EINPROGRESS _r, w, _e = IO.select(nil, [t], nil, timeout) if !w.nil? connected = true else begin t.connect_nonblock(saddr) rescue Errno::EISCONN t.close connected = true rescue SystemCallError end end rescue SystemCallError end logger.trace("Mixin HttpHelper: can_socket_connect? == #{connected}") connected end end end end ohai-16.0.7/lib/ohai/mixin/network_helper.rb000066400000000000000000000021151362624620500207210ustar00rootroot00000000000000# # Author:: Serdar Sutay () # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai module Mixin module NetworkHelper FAMILIES = { "inet" => "default", "inet6" => "default_inet6", }.freeze def hex_to_dec_netmask(netmask) # example 'ffff0000' -> '255.255.0.0' dec = netmask[0..1].to_i(16).to_s(10) [2, 4, 6].each { |n| dec = dec + "." + netmask[n..n + 1].to_i(16).to_s(10) } dec end end end end ohai-16.0.7/lib/ohai/mixin/os.rb000066400000000000000000000034441362624620500163200ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # require "rbconfig" module Ohai module Mixin module OS # Using ruby configuration determine the OS we're running on # # @return [String] the OS def collect_os case ::RbConfig::CONFIG["host_os"] when /aix(.+)$/ "aix" when /darwin(.+)$/ "darwin" when /linux/ "linux" when /freebsd(.+)$/ "freebsd" when /openbsd(.+)$/ "openbsd" when /netbsd(.*)$/ "netbsd" when /dragonfly(.*)$/ "dragonflybsd" when /solaris2/ "solaris2" when /mswin|mingw32|windows/ # After long discussion in IRC the "powers that be" have come to a consensus # that no Windows platform exists that was not based on the # Windows_NT kernel, so we herby decree that "windows" will refer to all # platforms built upon the Windows_NT kernel and have access to win32 or win64 # subsystems. "windows" else ::RbConfig::CONFIG["host_os"] end end module_function :collect_os end end end ohai-16.0.7/lib/ohai/mixin/scaleway_metadata.rb000066400000000000000000000032541362624620500213460ustar00rootroot00000000000000# # Author:: Jonathan Amiez () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "net/http" unless defined?(Net::HTTP) module Ohai module Mixin module ScalewayMetadata SCALEWAY_METADATA_ADDR ||= "169.254.42.42".freeze SCALEWAY_METADATA_URL ||= "/conf?format=json".freeze # @return [Net::HTTP] net/http object without timeout set to 6 def http_client Net::HTTP.start(SCALEWAY_METADATA_ADDR).tap { |h| h.read_timeout = 6 } end # fetch scaleway metadata and parse the resulting JSON # # @return [Hash] def fetch_metadata uri = (SCALEWAY_METADATA_URL).to_s response = http_client.get(uri) case response.code when "200" parser = FFI_Yajl::Parser.new parser.parse(response.body) when "404" logger.trace("Mixin ScalewayMetadata: Encountered 404 response retrieving Scaleway metadata: #{uri} ; continuing.") {} else raise "Mixin ScalewayMetadata: Encountered error retrieving Scaleway metadata (#{uri} returned #{response.code} response)" end end end end end ohai-16.0.7/lib/ohai/mixin/seconds_to_human.rb000066400000000000000000000032011362624620500212160ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai module Mixin module SecondsToHuman # given the number of seconds return a day/hours/minutes/seconds human form # # @param seconds [Integer] # # @return String def seconds_to_human(seconds) days = seconds.to_i / 86400 seconds -= 86400 * days hours = seconds.to_i / 3600 seconds -= 3600 * hours minutes = seconds.to_i / 60 seconds -= 60 * minutes if days > 1 sprintf("%d days %02d hours %02d minutes %02d seconds", days, hours, minutes, seconds) elsif days == 1 sprintf("%d day %02d hours %02d minutes %02d seconds", days, hours, minutes, seconds) elsif hours > 0 sprintf("%d hours %02d minutes %02d seconds", hours, minutes, seconds) elsif minutes > 0 sprintf("%d minutes %02d seconds", minutes, seconds) else sprintf("%02d seconds", seconds) end end end end end ohai-16.0.7/lib/ohai/mixin/softlayer_metadata.rb000066400000000000000000000052651362624620500215520ustar00rootroot00000000000000# # Author:: Alexey Karpik # Author:: Peter Schroeter # Author:: Stas Turlo # Copyright:: Copyright (c) 2010-2014 RightScale Inc # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "net/https" require "uri" unless defined?(URI) # https://softlayer.github.io/reference/services/SoftLayer_Resource_Metadata/ module ::Ohai::Mixin::SoftlayerMetadata SOFTLAYER_API_QUERY_URL ||= "https://api.service.softlayer.com/rest/v3.1/SoftLayer_Resource_Metadata".freeze # fetch metadata items and build out hash of data # # @return [Hash] def fetch_metadata { "public_fqdn" => fetch_metadata_item("getFullyQualifiedDomainName.txt"), "local_ipv4" => fetch_metadata_item("getPrimaryBackendIpAddress.txt"), "public_ipv4" => fetch_metadata_item("getPrimaryIpAddress.txt"), "region" => fetch_metadata_item("getDatacenter.txt"), "instance_id" => fetch_metadata_item("getId.txt"), } end # Softlayer's metadata api is only available over HTTPS. # Ruby by default does not link to the system's CA bundle # however Chef-omnibus should set SSL_CERT_FILE to point to a valid file. # Manually supply and specify a suitable CA bundle here or # set the SSL_CERT_FILE file environment variable to a valid value otherwise. # # @return [String] def ca_file_location ::Ohai::Config[:ca_file] end # fetch a specified item from the Softlayer metadata API # @param item [String] the metadata item to fetch # # @return [String] the response body def fetch_metadata_item(item) full_url = "#{SOFTLAYER_API_QUERY_URL}/#{item}" u = URI(full_url) net = ::Net::HTTP.new(u.hostname, u.port) net.ssl_version = :TLSv1_2 net.use_ssl = true net.ca_file = ca_file_location res = net.get(u.request_uri) if res.code.to_i.between?(200, 299) res.body else logger.error("Mixin Softlayer: Unable to fetch item #{full_url}: status (#{res.code}) body (#{res.body})") nil end rescue => e logger.error("Mixin Softlayer: Unable to fetch softlayer metadata from #{u}: #{e.class}: #{e.message}") raise e end end ohai-16.0.7/lib/ohai/mixin/string.rb000066400000000000000000000023401362624620500171770ustar00rootroot00000000000000# # Author:: James Gartrell () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # class String # Add string function to handle WMI property conversion to json hash keys # Makes an underscored, lowercase form from the expression in the string. # underscore will also change ’::’ to ’/’ to convert namespaces to paths. # This should implement the same functionality as underscore method in # ActiveSupport::CoreExtensions::String::Inflections # @return [String] def wmi_underscore gsub(/::/, "/").gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(/([a-z\d])([A-Z])/, '\1_\2').tr("-", "_").downcase end end ohai-16.0.7/lib/ohai/plugin_config.rb000066400000000000000000000023621362624620500173740ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "exception" module Ohai class PluginConfig < Hash def []=(key, value_or_hash) enforce_symbol(key) enforce_symbol_keys(value_or_hash) if value_or_hash.is_a?(Hash) super(key, value_or_hash) end private def enforce_symbol(key) unless key.is_a?(Symbol) msg = "Expected Symbol, got #{key.inspect}" raise Ohai::Exceptions::PluginConfigError, msg end end def enforce_symbol_keys(hash) hash.each do |key, value| enforce_symbol(key) enforce_symbol_keys(value) if value.is_a?(Hash) end end end end ohai-16.0.7/lib/ohai/plugins/000077500000000000000000000000001362624620500157025ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/aix/000077500000000000000000000000001362624620500164635ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/aix/kernel.rb000066400000000000000000000034501362624620500202720ustar00rootroot00000000000000# # Author:: Joshua Timberman # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Kernel) do provides "kernel", "kernel/modules" collect_data(:aix) do kernel Mash.new kernel[:name] = shell_out("uname -s").stdout.split($/)[0].downcase kernel[:release] = shell_out("uname -r").stdout.split($/)[0] kernel[:version] = shell_out("uname -v").stdout.split($/)[0] kernel[:machine] = shell_out("uname -p").stdout.split($/)[0] kernel[:bits] = shell_out("getconf KERNEL_BITMODE").stdout.strip modules = Mash.new so = shell_out("genkex -d") # Text address Size Data address Size File # # f1000000c0338000 77000 f1000000c0390000 1ec8c /usr/lib/drivers/cluster # 6390000 20000 63a0000 ba8 /usr/lib/drivers/if_en # f1000000c0318000 20000 f1000000c0320000 17138 /usr/lib/drivers/random so.stdout.lines do |line| if line =~ %r{\s*([0-9a-f]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+([a-zA-Z0-9/\._]+)} modules[$5] = { text: { address: $1, size: $2 }, data: { address: $3, size: $4 } } end end kernel[:modules] = modules end end ohai-16.0.7/lib/ohai/plugins/aix/memory.rb000066400000000000000000000024221362624620500203200ustar00rootroot00000000000000# # Author:: Joshua Timberman # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory" collect_data(:aix) do memory Mash.new memory[:swap] = Mash.new meminfo = shell_out("svmon -G -O unit=MB,summary=longreal | grep '[0-9]'").stdout total_in_mb, _u, free_in_mb = meminfo.split memory[:total] = "#{total_in_mb.to_i * 1024}kB" memory[:free] = "#{free_in_mb.to_i * 1024}kB" swapinfo = shell_out("swap -s").stdout.split # returns swap info in 4K blocks memory[:swap]["total"] = "#{(swapinfo[2].to_i) * 4}kB" memory[:swap]["free"] = "#{(swapinfo[10].to_i) * 4}kB" end end ohai-16.0.7/lib/ohai/plugins/aix/network.rb000066400000000000000000000130271362624620500205040ustar00rootroot00000000000000# # Author:: Kaustubh Deorukhkar () # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do require "ipaddr" require_relative "../../mixin/network_helper" provides "network", "counters/network", "macaddress" include Ohai::Mixin::NetworkHelper collect_data(:aix) do # Loads following information. # :default_interface, :default_gateway - route -n get 0 # :interfaces # => routes(netstat -nr | grep en0) # => addresses (ifconfig en0 or lsattr -El en0), macaddress (entstat -d en0 = Hardware Address: be:42:80:00:b0:05) # => flags (ifconfig en0) # => state up/down (ifconfig/lsattr) # => arp (arp -an) iface = Mash.new network Mash.new unless network network[:interfaces] ||= Mash.new # We unfortunately have to do things a bit different here, if ohai is running # within a WPAR. For instance, the WPAR isn't aware of some of its own networking # minutia such as default gateway/route. unless shell_out("uname -W").stdout.to_i > 0 # :default_interface, :default_gateway - route -n get 0 so = shell_out("netstat -rn |grep default") so.stdout.lines.each do |line| items = line.split(" ") if items[0] == "default" network[:default_gateway] = items[1] network[:default_interface] = items[5] end end end # Splits the ifconfig output to 1 line per interface if_so = shell_out("ifconfig -a") if_so.stdout.gsub(/\n(\w+\d+)/, '___\1').split("___").each do |intraface| splat = intraface.split(":") interface = splat[0] line = splat[1..-1][0] iface[interface] = Mash.new iface[interface][:state] = (line.include?("/ iface[interface][:flags] = $1.split(",") iface[interface][:metric] = $1 if lin =~ /metric\s(\S+)/ else # We have key value pairs. if lin =~ %r{inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(/(\d{1,2}))?} tmp_addr, tmp_prefix = $1, $3 if tmp_prefix.nil? netmask = hex_to_dec_netmask($1) if lin =~ /netmask\s0x(\S+)\s/ unless netmask tmp_prefix ||= "32" netmask = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s end else netmask = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s end iface[interface][:addresses] ||= Mash.new iface[interface][:addresses][tmp_addr] = { "family" => "inet", "prefixlen" => tmp_prefix } iface[interface][:addresses][tmp_addr][:netmask] = netmask if lin =~ /broadcast\s(\S+)\s/ iface[interface][:addresses][tmp_addr][:broadcast] = $1 end elsif lin =~ %r{inet6 ([a-f0-9\:]+)%?([\d]*)/?(\d*)?} # TODO do we have more properties on inet6 in aix? broadcast iface[interface][:addresses] ||= Mash.new iface[interface][:addresses][$1] = { "family" => "inet6", "zone_index" => $2, "prefixlen" => $3 } else # load all key-values, example "tcp_sendspace 131072 tcp_recvspace 131072 rfc1323 1" properties = lin.split n = properties.length / 2 - 1 (0..n).each do |i| iface[interface][properties[i * 2]] = properties[(i * 2 + 1)] end end end end # Query macaddress e_so = shell_out("entstat -d #{interface} | grep \"Hardware Address\"") iface[interface][:addresses] ||= Mash.new e_so.stdout.lines.each do |l| if l =~ /Hardware Address: (\S+)/ iface[interface][:addresses][$1.upcase] = { "family" => "lladdr" } macaddress $1.upcase unless shell_out("uname -W").stdout.to_i > 0 end end end # ifconfig stdout # Query routes information %w{inet inet6}.each do |family| so_n = shell_out("netstat -nrf #{family}") so_n.stdout.lines.each do |line| if line =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)/ interface = $6 iface[interface][:routes] = [] unless iface[interface][:routes] iface[interface][:routes] << Mash.new( destination: $1, family: family, via: $2, flags: $3) end end end # List the arp entries in system. so = shell_out("arp -an") count = 0 so.stdout.lines.each do |line| network[:arp] ||= Mash.new if line =~ /\s*(\S+) \((\S+)\) at ([a-fA-F0-9\:]+) \[(\w+)\] stored in bucket/ network[:arp][count] ||= Mash.new network[:arp][count][:remote_host] = $1 network[:arp][count][:remote_ip] = $2 network[:arp][count][:remote_mac] = $3.downcase count += 1 end end network["interfaces"] = iface end end ohai-16.0.7/lib/ohai/plugins/aix/platform.rb000066400000000000000000000017451362624620500206430ustar00rootroot00000000000000# # Author:: Joshua Timberman # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" depends "kernel" collect_data(:aix) do platform kernel[:name] platform_version [kernel[:version], kernel[:release]].join(".") platform_family platform end end ohai-16.0.7/lib/ohai/plugins/aix/uptime.rb000066400000000000000000000042411362624620500203140ustar00rootroot00000000000000# # Author:: Kurt Yoder () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Uptime) do provides "uptime", "uptime_seconds" collect_data(:aix) do require "date" # below we're going to assume that PID 1 is init (this is true 99.99999% of the time) # output will look like this # 1148-20:54:50 # This reads as 1148 days, 20 hours, 54 minutes, 50 seconds since the process was started (elapsed) # who -b does not return the YEAR, so we need something more concrete so = shell_out("LC_ALL=POSIX ps -o etime= -p 1").stdout.strip # Here we'll check our shell_out for a dash, which indicates there is a # of days involved # We'll chunk off the days, hours (where applicable), minutes, seconds into seperate vars # We also need to do this because ps -o etime= will not display days if the machine has been up for less than 24 hours # If the machine has been up for less than one hour, the shell_out will not output hours hence our else # see here: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.cmds4/ps.htm#ps__row-d3e109655 d = nil h = nil case so when /^\d+-\d/ (d, h, m, s) = so.split(/[-:]/) when /^\d+:\d+:\d/ (h, m, s) = so.split(/[:]/) else (m, s) = so.split(/[:]/) end elapsed_seconds = ((d.to_i * 86400) + (h.to_i * 3600) + (m.to_i * 60) + s.to_i) # uptime seconds below will return the elapsed time since boot uptime_seconds elapsed_seconds uptime seconds_to_human(elapsed_seconds) end end ohai-16.0.7/lib/ohai/plugins/aix/virtualization.rb000066400000000000000000000120171362624620500220750ustar00rootroot00000000000000# # Author:: Julian C. Dunn () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualization) do provides "virtualization", "virtualization/wpars" collect_data(:aix) do virtualization Mash.new so = shell_out("uname -L") lpar_no = so.stdout.split($/)[0].split(/\s/)[0] lpar_name = so.stdout.split($/)[0].split(/\s/)[1] unless lpar_no.to_i == -1 || (lpar_no.to_i == 1 && lpar_name == "NULL") virtualization[:lpar_no] = lpar_no virtualization[:lpar_name] = lpar_name end so = shell_out("uname -W") wpar_no = so.stdout.split($/)[0] if wpar_no.to_i > 0 virtualization[:wpar_no] = wpar_no else # the below parses the output of lswpar in the long format so = shell_out("lswpar -L").stdout.scan(/={65}.*?(?:EXPORTED\n\n)+/m) wpars = Mash.new so.each do |wpar| wpar_name = wpar.lines[1].split[0] wpars[wpar_name] = Mash.new wpar.scan(/^[A-Z]{4,}.*?[A-Z\:0-9]$.*?\n\n/m).each do |section| # retrieve title of section title = section.lines.first[0..-2].downcase wpars[wpar_name][title] = Mash.new # discard trailing section newline+title # and save as array sections = section.lines[1..-2] sections.each do |line| case title when "network" next if line =~ /^Interface|^---/ splat = line.strip.split key = splat[0].downcase value = { "address" => splat[1], "netmask" => splat[2], "broadcast" => splat[3], } wpars[wpar_name][title][key] = value when "user-specified routes" next if line =~ /^Type|^---/ splat = line.strip.split key = splat[2].downcase value = { "destination" => splat[0], "gateway" => splat[1], } wpars[wpar_name][title][key] = value when "file systems" next if line =~ /^MountPoint|^---/ splat = line.strip.split key = splat[1].downcase value = { "mountpoint" => splat[0], "device" => splat[1], "vfs" => splat[2], "options" => splat[3].split(","), } wpars[wpar_name][title][key] = value when "security settings" privileges ||= "" wpars[wpar_name][title]["Privileges"] ||= [] if line =~ /^Privileges/ privileges << line.split(":")[1].strip else privileges << line.strip end wpars[wpar_name][title]["Privileges"] += privileges.split(",") when "device exports" next if line =~ /^Name|^---/ splat = line.strip.split key = splat[0].downcase value = { "type" => splat[1], "status" => splat[2], } wpars[wpar_name][title][key] = value else # key-value pairs are handled here # such as GENERAL and RESOURCE- # CONTROL splat = line.strip.split(":") key = splat[0].downcase value = splat[1..-1].join(", ").strip value = value.empty? ? nil : value case value when "yes" value = true when "no" value = false end wpars[wpar_name][title][key] = value end end end top_level = [ "general.directory", "general.hostname", "general.private /usr", "general.type", "general.uuid", "resource controls.active", "network.en0.address", ] top_level.each do |attribute| evalstr = "wpars['#{wpar_name}']" breadcrumb = attribute.split(".") breadcrumb.each do |node| evalstr << "[\'#{node}\']" end wpars[wpar_name][breadcrumb[-1]] = eval evalstr # rubocop: disable Security/Eval end end virtualization[:wpars] = wpars unless wpars.empty? end end end ohai-16.0.7/lib/ohai/plugins/azure.rb000066400000000000000000000112121362624620500173520ustar00rootroot00000000000000# Copyright:: Copyright 2013-2017 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Azure) do require_relative "../mixin/azure_metadata" require_relative "../mixin/http_helper" include Ohai::Mixin::AzureMetadata include Ohai::Mixin::HttpHelper provides "azure" collect_data do # Before we had the metadata endpoint we relied exclusively on # the knife-azure plugin populating data to the hint file. # Please see the lib/chef/knife/azure_server_create.rb file in that # project for details azure_metadata_from_hints = hint?("azure") if azure_metadata_from_hints logger.trace("Plugin Azure: Azure hint is present. Parsing any hint data.") azure Mash.new azure_metadata_from_hints.each { |k, v| azure[k] = v } azure["metadata"] = parse_metadata elsif has_waagent? || has_dhcp_option_245? logger.trace("Plugin Azure: No hints present, but system appears to be on Azure.") azure Mash.new azure["metadata"] = parse_metadata else logger.trace("Plugin Azure: No hints present and doesn't appear to be on Azure.") false end end # check for either the waagent or the unknown-245 DHCP option that Azure uses # http://blog.mszcool.com/index.php/2015/04/detecting-if-a-virtual-machine-runs-in-microsoft-azure-linux-windows-to-protect-your-software-when-distributed-via-the-azure-marketplace/ def has_waagent? if File.exist?("/usr/sbin/waagent") || Dir.exist?('C:\WindowsAzure') logger.trace("Plugin Azure: Found waagent used by Azure.") true end end def has_dhcp_option_245? has_245 = false if File.exist?("/var/lib/dhcp/dhclient.eth0.leases") File.open("/var/lib/dhcp/dhclient.eth0.leases").each do |line| if line =~ /unknown-245/ logger.trace("Plugin Azure: Found unknown-245 DHCP option used by Azure.") has_245 = true break end end end has_245 end # create the basic structure we'll store our data in def initialize_metadata_mash_compute metadata = Mash.new metadata["compute"] = Mash.new metadata end def initialize_metadata_mash_network(metadata) metadata["network"] = Mash.new metadata["network"]["interfaces"] = Mash.new %w{public_ipv4 local_ipv4 public_ipv6 local_ipv6}.each do |type| metadata["network"][type] = [] end metadata end def fetch_ip_data(data, type, field) ips = [] data[type]["ipAddress"].each do |val| ips << val[field] unless val[field].empty? end ips end def parse_metadata return nil unless can_socket_connect?(Ohai::Mixin::AzureMetadata::AZURE_METADATA_ADDR, 80) endpoint_data = fetch_metadata return nil if endpoint_data.nil? metadata = initialize_metadata_mash_compute # blindly add everything in compute to our data structure endpoint_data["compute"].each do |k, v| metadata["compute"][k] = v end # receiving network output is not guaranteed unless endpoint_data["network"].nil? metadata = initialize_metadata_mash_network(metadata) # parse out per interface interface IP data endpoint_data["network"]["interface"].each do |int| metadata["network"]["interfaces"][int["macAddress"]] = Mash.new metadata["network"]["interfaces"][int["macAddress"]]["mac"] = int["macAddress"] metadata["network"]["interfaces"][int["macAddress"]]["public_ipv6"] = fetch_ip_data(int, "ipv6", "publicIpAddress") metadata["network"]["interfaces"][int["macAddress"]]["public_ipv4"] = fetch_ip_data(int, "ipv4", "publicIpAddress") metadata["network"]["interfaces"][int["macAddress"]]["local_ipv6"] = fetch_ip_data(int, "ipv6", "privateIpAddress") metadata["network"]["interfaces"][int["macAddress"]]["local_ipv4"] = fetch_ip_data(int, "ipv4", "privateIpAddress") end # aggregate the total IP data %w{public_ipv4 local_ipv4 public_ipv6 local_ipv6}.each do |type| metadata["network"]["interfaces"].each_value do |val| metadata["network"][type].concat val[type] unless val[type].empty? end end end metadata end end ohai-16.0.7/lib/ohai/plugins/bsd/000077500000000000000000000000001362624620500164525ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/bsd/virtualization.rb000066400000000000000000000107631362624620500220720ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # Copyright:: Copyright (c) 2015-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualization) do provides "virtualization" depends "dmi" require_relative "../../mixin/dmi_decode" include Ohai::Mixin::DmiDecode collect_data(:freebsd, :openbsd, :netbsd, :dragonflybsd) do virtualization Mash.new unless virtualization virtualization[:systems] ||= Mash.new # detect when in a jail or when a jail is actively running (not in stopped state) so = shell_out("sysctl -n security.jail.jailed") if so.stdout.split($/)[0].to_i == 1 virtualization[:system] = "jail" virtualization[:role] = "guest" virtualization[:systems][:jail] = "guest" logger.trace("Plugin Virtualization: Guest running in FreeBSD jail detected") end # run jls to get a list of running jails # -n: name=value 1 line per jail format # -d: list the dying jails as well as active jails so = shell_out("jls -nd") if (so.stdout || "").lines.count >= 1 virtualization[:system] = "jail" virtualization[:role] = "host" virtualization[:systems][:jail] = "host" logger.trace("Plugin Virtualization: Host running FreeBSD jails detected") end # detect from modules so = shell_out((Ohai.abs_path("/sbin/kldstat")).to_s) so.stdout.lines do |line| case line when /vboxdrv/ virtualization[:system] = "vbox" virtualization[:role] = "host" virtualization[:systems][:vbox] = "host" logger.trace("Plugin Virtualization: Guest running on VirtualBox detected") when /vboxguest/ virtualization[:system] = "vbox" virtualization[:role] = "guest" virtualization[:systems][:vbox] = "guest" logger.trace("Plugin Virtualization: Host running VirtualBox detected") end end # Detect bhyve by presence of /dev/vmm if File.exist?("/dev/vmm") virtualization[:system] = "bhyve" virtualization[:role] = "host" virtualization[:systems][:bhyve] = "host" logger.trace("Plugin Virtualization: Host running bhyve detected") end # Detect KVM/QEMU paravirt guests from cpu, report as KVM # hw.model: QEMU Virtual CPU version 0.9.1 so = shell_out("sysctl -n hw.model") if so.stdout =~ /QEMU Virtual CPU|KVM processor/ virtualization[:system] = "kvm" virtualization[:role] = "guest" virtualization[:systems][:kvm] = "guest" logger.trace("Plugin Virtualization: Guest running on KVM detected") end # gather hypervisor of guests from sysctl kern.vm_guest # there are a limited number of hypervisors detected here, BUT it doesn't # require dmidecode to be installed and dmidecode isn't in freebsd out of the box so = shell_out("sysctl -n kern.vm_guest") hypervisor = case so.stdout when /vmware/ "vmware" when /hv/ "hyperv" when /xen/ "xen" when /kvm/ so = shell_out("sysctl -n kern.hostuuid") so.stdout =~ /^ec2/ ? "amazonec2" : "kvm" when /bhyve/ "bhyve" end if hypervisor virtualization[:system] = hypervisor virtualization[:role] = "guest" virtualization[:systems][hypervisor.to_sym] = "guest" logger.trace("Plugin Virtualization: Guest running on #{hypervisor} detected") end # parse dmi to discover various virtualization guests guest = guest_from_dmi_data(get_attribute(:dmi, :system, :manufacturer), get_attribute(:dmi, :system, :product), get_attribute(:dmi, :system, :version)) if guest logger.trace("Plugin Virtualization: DMI data indicates #{guest} guest") virtualization[:system] = guest virtualization[:role] = "guest" virtualization[:systems][guest.to_sym] = "guest" end end end ohai-16.0.7/lib/ohai/plugins/c.rb000066400000000000000000000140741362624620500164570ustar00rootroot00000000000000# # Author:: Doug MacEachern # Copyright:: Copyright (c) 2010 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:C) do provides "languages/c" depends "languages" def collect(cmd, &block) so = shell_out(cmd) if so.exitstatus == 0 yield(so) else logger.trace("Plugin C: '#{cmd}' failed. Skipping data.") end rescue Ohai::Exceptions::Exec logger.trace("Plugin C: '#{cmd}' binary could not be found. Skipping data.") end def xcode_installed? logger.trace("Plugin C: Checking for Xcode Command Line Tools.") so = shell_out("/usr/bin/xcode-select -p") if so.exitstatus == 0 logger.trace("Plugin C: Xcode Command Line Tools found.") true else logger.trace("Plugin C: Xcode Command Line Tools not found.") false end rescue Ohai::Exceptions::Exec logger.trace("Plugin C: xcode-select binary could not be found. Skipping data.") end def collect_gcc # gcc # Sample output on os x: # Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 # Apple LLVM version 7.3.0 (clang-703.0.29) # Target: x86_64-apple-darwin15.4.0 # Thread model: posix # InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin # # # Sample output on Linux: # Using built-in specs. # COLLECT_GCC=gcc # COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper # Target: x86_64-linux-gnu # Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-trace --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu # Thread model: posix # gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) gcc = Mash.new collect("gcc -v") do |so| so.stderr.each_line do |line| case line when /^(.*version\s(\S*).*)/ gcc[:description] = $1 gcc[:version] = $2 when /^Target:\s(.*)/ gcc[:target] = $1 when /^Configured with:\s(.*)/ gcc[:configured_with] = $1 when /^Thread model:\s(.*)/ gcc[:thread_model] = $1 end end end @c[:gcc] = gcc unless gcc.empty? end def collect_glibc # glibc ["/lib/libc.so.6", "/lib64/libc.so.6"].each do |glibc| collect( Ohai.abs_path( glibc )) do |so| description = so.stdout.split($/).first if description =~ /(\d+\.\d+\.?\d*)/ @c[:glibc] = Mash.new @c[:glibc][:version] = $1 @c[:glibc][:description] = description end end end end def check_for_cl # ms cl collect("cl /?") do |so| description = so.stderr.lines.first.chomp if description =~ /Compiler Version ([\d\.]+)/ @c[:cl] = Mash.new @c[:cl][:version] = $1 @c[:cl][:description] = description end end end def check_for_devenv # ms vs collect("devenv.com /?") do |so| lines = so.stdout.split($/) description = lines[0].length == 0 ? lines[1] : lines[0] if description =~ /Visual Studio Version ([\d\.]+)/ @c[:vs] = Mash.new @c[:vs][:version] = $1.chop @c[:vs][:description] = description end end end def collect_xlc # ibm xlc so = shell_out("xlc -qversion") if so.exitstatus == 0 || (so.exitstatus >> 8) == 249 description = so.stdout.split($/).first if description =~ /V(\d+\.\d+)/ @c[:xlc] = Mash.new @c[:xlc][:version] = $1 @c[:xlc][:description] = description.strip end end rescue Ohai::Exceptions::Exec logger.trace("Plugin C: 'xlc' binary could not be found. Skipping data.") end def collect_sunpro # sun pro collect("cc -V -flags") do |so| output = so.stderr.split if so.stderr =~ /^cc: Sun C/ && output.size >= 4 @c[:sunpro] = Mash.new @c[:sunpro][:version] = output[3] @c[:sunpro][:description] = so.stderr.chomp end end end collect_data(:aix) do @c = Mash.new collect_xlc collect_gcc languages[:c] = @c unless @c.empty? end collect_data(:darwin) do @c = Mash.new collect_gcc if xcode_installed? languages[:c] = @c unless @c.empty? end collect_data(:windows) do @c = Mash.new check_for_cl check_for_devenv languages[:c] = @c unless @c.empty? end collect_data(:default) do @c = Mash.new collect_gcc collect_glibc collect_sunpro languages[:c] = @c unless @c.empty? end end ohai-16.0.7/lib/ohai/plugins/chef.rb000066400000000000000000000025071362624620500171400ustar00rootroot00000000000000# # Author:: Tollef Fog Heen # Copyright:: Copyright (c) 2010 Tollef Fog Heen # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Chef) do provides "chef_packages/chef" collect_data do begin require "chef/version" rescue Gem::LoadError logger.trace("Plugin Chef: Unable to load the chef gem to determine the version") # this catches when you've done a major version bump of ohai, but # your chef gem is incompatible, so we can't load it in the same VM # (affects mostly internal testing) next # avoids us writing an empty mash end chef_packages Mash.new unless chef_packages chef_packages[:chef] = Mash.new chef_packages[:chef][:version] = Chef::VERSION chef_packages[:chef][:chef_root] = Chef::CHEF_ROOT end end ohai-16.0.7/lib/ohai/plugins/cloud.rb000066400000000000000000000255151362624620500173450ustar00rootroot00000000000000# # Author:: Cary Penniman () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Cloud) do provides "cloud" depends "ec2" depends "gce" depends "rackspace" depends "eucalyptus" depends "linode" depends "openstack" depends "azure" depends "digital_ocean" depends "softlayer" # Class to help enforce the interface exposed to node[:cloud] (OHAI-542) # # cloud[:provider] - (String) the cloud provider the VM is running on. # # cloud[:public_hostname] - (String) a fully qualified hostname # cloud[:local_hostname] - (String) a hostname resolvable on the internal (private) network # # cloud[:public_ipv4_addrs] - (Array) a list of all publicly accessible IPv4 addresses # cloud[:local_ipv4_addrs] - (Array) a list of all private IPv4 addresses # cloud[:public_ipv4] - (String) the first public IPv4 address detected # cloud[:local_ipv4] - (String) the first private IPv4 address detected # # cloud[:public_ipv6_addrs] - (Array) a list of all publicly accessible IPv6 addresses # cloud[:local_ipv6_addrs] - (Array) a list of all private IPv6 addresses # cloud[:public_ipv6] - (String) the first public IPv6 address detected # cloud[:local_ipv6] - (String) the first private IPv6 address detected # class CloudAttrs attr_writer :provider, :public_hostname, :local_hostname def initialize @cloud = Mash.new end def add_ipv4_addr(ip, accessibility) return if ip.nil? # just skip if ip is nil ipaddr = validate_ip_addr(ip, :ipv4) case accessibility when :public @cloud[:public_ipv4_addrs] ||= [] @cloud[:public_ipv4_addrs] << ipaddr.to_s when :private @cloud[:local_ipv4_addrs] ||= [] @cloud[:local_ipv4_addrs] << ipaddr.to_s else raise "ERROR: invalid accessibility param of '#{accessibility}'. must be :public or :private." end end def add_ipv6_addr(ip, accessibility) return if ip.nil? # just skip if ip is nil ipaddr = validate_ip_addr(ip, :ipv6) raise "ERROR: invalid ipv6 address of '#{ip}' detected. " unless ipaddr.ipv6? case accessibility when :public @cloud[:public_ipv6_addrs] ||= [] @cloud[:public_ipv6_addrs] << ipaddr.to_s when :private @cloud[:local_ipv6_addrs] ||= [] @cloud[:local_ipv6_addrs] << ipaddr.to_s else raise "ERROR: invalid accessibility param of '#{accessibility}'. must be :public or :private." end end def cloud_mash @cloud[:provider] = @provider if @provider @cloud[:public_hostname] = @public_hostname if @public_hostname @cloud[:local_hostname] = @local_hostname if @local_hostname @cloud[:public_ipv4] = @cloud[:public_ipv4_addrs][0] if @cloud[:public_ipv4_addrs] @cloud[:local_ipv4] = @cloud[:local_ipv4_addrs][0] if @cloud[:local_ipv4_addrs] @cloud[:public_ipv6] = @cloud[:public_ipv6_addrs][0] if @cloud[:public_ipv6_addrs] @cloud[:local_ipv6] = @cloud[:local_ipv6_addrs][0] if @cloud[:local_ipv6_addrs] # if empty, return nil (@cloud.empty?) ? nil : @cloud end private def validate_ip_addr(ip, address_family = :ipv4) ipaddr = "" begin ipaddr = IPAddr.new(ip) raise ArgumentError, "not valid #{address_family} address" unless (address_family == :ipv4) ? ipaddr.ipv4? : ipaddr.ipv6? rescue ArgumentError => e raise "ERROR: the ohai 'cloud' plugin failed with an IP address of '#{ip}' : #{e.message}" end ipaddr end end #--------------------------------------- # Google Compute Engine (gce) #-------------------------------------- def on_gce? gce != nil end def get_gce_values public_ips = gce["instance"]["networkInterfaces"].collect do |interface| if interface.key?("accessConfigs") interface["accessConfigs"].collect { |ac| ac["externalIp"] unless ac["externalIp"] == "" } end end.flatten.compact private_ips = gce["instance"]["networkInterfaces"].collect do |interface| interface["ip"] end.compact public_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) } private_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) } @cloud_attr_obj.local_hostname = gce["instance"]["hostname"] @cloud_attr_obj.provider = "gce" end # ---------------------------------------- # ec2 # ---------------------------------------- # Is current cloud ec2? # # === Return # true:: If ec2 Hash is defined # false:: Otherwise def on_ec2? ec2 != nil end # Fill cloud hash with ec2 values def get_ec2_values @cloud_attr_obj.add_ipv4_addr(ec2["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(ec2["local_ipv4"], :private) @cloud_attr_obj.public_hostname = ec2["public_hostname"] @cloud_attr_obj.local_hostname = ec2["local_hostname"] @cloud_attr_obj.provider = "ec2" end # ---------------------------------------- # rackspace # ---------------------------------------- # Is current cloud rackspace? # # === Return # true:: If rackspace Hash is defined # false:: Otherwise def on_rackspace? rackspace != nil end # Fill cloud hash with rackspace values def get_rackspace_values @cloud_attr_obj.add_ipv4_addr(rackspace["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(rackspace["local_ipv4"], :private) @cloud_attr_obj.add_ipv6_addr(rackspace["public_ipv6"], :public) @cloud_attr_obj.add_ipv6_addr(rackspace["local_ipv6"], :private) @cloud_attr_obj.public_hostname = rackspace["public_hostname"] @cloud_attr_obj.local_hostname = rackspace["local_hostname"] @cloud_attr_obj.provider = "rackspace" end # ---------------------------------------- # linode # ---------------------------------------- # Is current cloud linode? # # === Return # true:: If linode Hash is defined # false:: Otherwise def on_linode? linode != nil end # Fill cloud hash with linode values def get_linode_values @cloud_attr_obj.add_ipv4_addr(linode["public_ip"], :public) @cloud_attr_obj.add_ipv4_addr(linode["private_ip"], :private) @cloud_attr_obj.public_hostname = linode["public_hostname"] @cloud_attr_obj.local_hostname = linode["local_hostname"] @cloud_attr_obj.provider = "linode" end # ---------------------------------------- # eucalyptus # ---------------------------------------- # Is current cloud eucalyptus? # # === Return # true:: If eucalyptus Hash is defined # false:: Otherwise def on_eucalyptus? eucalyptus != nil end def get_eucalyptus_values @cloud_attr_obj.add_ipv4_addr(eucalyptus["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(eucalyptus["local_ipv4"], :private) @cloud_attr_obj.public_hostname = eucalyptus["public_hostname"] @cloud_attr_obj.local_hostname = eucalyptus["local_hostname"] @cloud_attr_obj.provider = "eucalyptus" end # ---------------------------------------- # openstack # ---------------------------------------- # Is current cloud openstack-based? # # === Return # true:: If openstack Hash is defined # false:: Otherwise def on_openstack? openstack != nil end # Fill cloud hash with openstack values def get_openstack_values @cloud_attr_obj.add_ipv4_addr(openstack["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(openstack["local_ipv4"], :private) @cloud_attr_obj.public_hostname = openstack["public_hostname"] @cloud_attr_obj.local_hostname = openstack["local_hostname"] @cloud_attr_obj.provider = openstack["provider"] end # ---------------------------------------- # azure # ---------------------------------------- # Is current cloud azure? # # === Return # true:: If azure Hash is defined # false:: Otherwise def on_azure? azure != nil end # Fill cloud hash with azure values def get_azure_values azure["metadata"]["network"]["public_ipv4"].each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) } azure["metadata"]["network"]["public_ipv6"].each { |ipaddr| @cloud_attr_obj.add_ipv6_addr(ipaddr, :public) } azure["metadata"]["network"]["local_ipv4"].each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) } azure["metadata"]["network"]["local_ipv6"].each { |ipaddr| @cloud_attr_obj.add_ipv6_addr(ipaddr, :private) } @cloud_attr_obj.public_hostname = azure["public_fqdn"] @cloud_attr_obj.provider = "azure" end # ---------------------------------------- # digital_ocean # ---------------------------------------- # Is current cloud digital_ocean? # # === Return # true:: If digital_ocean Mash is defined # false:: Otherwise def on_digital_ocean? digital_ocean != nil end # Fill cloud hash with digital_ocean values def get_digital_ocean_values @cloud_attr_obj.add_ipv4_addr(digital_ocean["interfaces"]["public"][0]["ipv4"]["ip_address"], :public) rescue NoMethodError @cloud_attr_obj.add_ipv4_addr(digital_ocean["interfaces"]["private"][0]["ipv4"]["ip_address"], :private) rescue NoMethodError @cloud_attr_obj.add_ipv6_addr(digital_ocean["interfaces"]["public"][0]["ipv6"]["ip_address"], :public) rescue NoMethodError @cloud_attr_obj.add_ipv6_addr(digital_ocean["interfaces"]["private"][0]["ipv6"]["ip_address"], :private) rescue NoMethodError @cloud_attr_obj.provider = "digital_ocean" end # ---------------------------------------- # softlayer # ---------------------------------------- # Is current cloud softlayer? # # === Return # true:: If softlayer Hash is defined # false:: Otherwise def on_softlayer? softlayer != nil end # Fill cloud hash with softlayer values def get_softlayer_values @cloud_attr_obj.add_ipv4_addr(softlayer["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(softlayer["local_ipv4"], :private) @cloud_attr_obj.public_hostname = softlayer["public_fqdn"] @cloud_attr_obj.provider = "softlayer" end collect_data do require "ipaddr" @cloud_attr_obj = CloudAttrs.new get_gce_values if on_gce? get_ec2_values if on_ec2? get_rackspace_values if on_rackspace? get_linode_values if on_linode? get_eucalyptus_values if on_eucalyptus? get_openstack_values if on_openstack? get_azure_values if on_azure? get_digital_ocean_values if on_digital_ocean? get_softlayer_values if on_softlayer? cloud @cloud_attr_obj.cloud_mash end end ohai-16.0.7/lib/ohai/plugins/command.rb000066400000000000000000000014201362624620500176420ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Command) do provides "command" collect_data do command Mash.new end end ohai-16.0.7/lib/ohai/plugins/cpu.rb000066400000000000000000000346201362624620500170230ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Bryan McLellan (btm@loftninjas.org) # Author:: Tim Smith (tsmith@chef.io) # Author:: Mathieu Sauve-Frankel # Author:: Nathan L Smith () # Author:: Joshua Timberman # Author:: Prabhu Das () # Author:: Isa Farnik () # Author:: Doug MacEachern # Copyright:: Copyright (c) 2008-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:CPU) do provides "cpu" def parse_bsd_dmesg(&block) cpuinfo = Mash.new cpuinfo["flags"] = [] File.open("/var/run/dmesg.boot").each do |line| case line when /CPU:\s+(.+) \(([\d.]+).+\)/ cpuinfo["model_name"] = $1 cpuinfo["mhz"] = $2 when /Features=.+<(.+)>/ cpuinfo["flags"].concat($1.downcase.split(",")) # Features2=0x80000001> when /Features2=[a-f\dx]+<(.+)>/ cpuinfo["flags"].concat($1.downcase.split(",")) else yield(cpuinfo, line) end end cpuinfo end collect_data(:linux) do cpuinfo = Mash.new real_cpu = Mash.new cpu_number = 0 current_cpu = nil File.open("/proc/cpuinfo").each do |line| case line when /processor\s+:\s(.+)/ cpuinfo[$1] = Mash.new current_cpu = $1 cpu_number += 1 when /vendor_id\s+:\s(.+)/ vendor_id = $1 if vendor_id =~ (%r{IBM/S390}) cpuinfo["vendor_id"] = vendor_id else cpuinfo[current_cpu]["vendor_id"] = vendor_id end when /cpu family\s+:\s(.+)/ cpuinfo[current_cpu]["family"] = $1 when /model\s+:\s(.+)/ cpuinfo[current_cpu]["model"] = $1 when /stepping\s+:\s(.+)/ cpuinfo[current_cpu]["stepping"] = $1 when /physical id\s+:\s(.+)/ cpuinfo[current_cpu]["physical_id"] = $1 real_cpu[$1] = true when /core id\s+:\s(.+)/ cpuinfo[current_cpu]["core_id"] = $1 when /cpu cores\s+:\s(.+)/ cpuinfo[current_cpu]["cores"] = $1 when /model name\s+:\s(.+)/ cpuinfo[current_cpu]["model_name"] = $1 when /cpu MHz\s+:\s(.+)/ cpuinfo[current_cpu]["mhz"] = $1 when /cache size\s+:\s(.+)/ cpuinfo[current_cpu]["cache_size"] = $1 when /flags\s+:\s(.+)/ cpuinfo[current_cpu]["flags"] = $1.split(" ") when /BogoMIPS\s+:\s(.+)/ cpuinfo[current_cpu]["bogomips"] = $1 when /Features\s+:\s(.+)/ cpuinfo[current_cpu]["features"] = $1.split(" ") when /bogomips per cpu:\s(.+)/ cpuinfo["bogomips_per_cpu"] = $1 when /features\s+:\s(.+)/ cpuinfo["features"] = $1.split(" ") when /processor\s(\d):\s(.+)/ current_cpu = $1 cpu_number += 1 cpuinfo[current_cpu] = Mash.new current_cpu_info = $2.split(",") current_cpu_info.each do |i| name_value = i.split("=") name = name_value[0].strip value = name_value[1].strip cpuinfo[current_cpu][name] = value end end end cpu cpuinfo cpu[:total] = cpu_number # use data we collected unless cpuinfo is lacking core information # which is the case on older linux distros if !real_cpu.empty? && cpu["0"]["cores"] cpu[:real] = real_cpu.keys.length cpu[:cores] = real_cpu.keys.length * cpu["0"]["cores"].to_i else begin logger.trace("Plugin CPU: Falling back to aggregate data from lscpu as real cpu & core data is missing in /proc/cpuinfo") so = shell_out("lscpu") if so.exitstatus == 0 lscpu_data = Mash.new so.stdout.each_line do |line| case line when /^Thread\(s\) per core:\s(.+)/ # http://rubular.com/r/lOw2pRrw1q lscpu_data[:threads] = $1.to_i when /^Core\(s\) per socket:\s(.+)/ # http://rubular.com/r/lOw2pRrw1q lscpu_data[:cores] = $1.to_i when /^Socket\(s\):\s(.+)/ # http://rubular.com/r/DIzmPtJFvK lscpu_data[:sockets] = $1.to_i end end cpu[:total] = lscpu_data[:sockets] * lscpu_data[:cores] * lscpu_data[:threads] cpu[:real] = lscpu_data[:sockets] cpu[:cores] = lscpu_data[:sockets] * lscpu_data[:cores] else logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.") end rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.") end end end collect_data(:freebsd) do # all dmesg output for smp I can find only provides info about a single processor # identical processors is probably a hardware requirement so we'll duplicate data for each cpu # old examples: http://www.bnv-bamberg.de/home/ba3294/smp/rbuild/index.htm # /var/run/dmesg.boot # CPU: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz (2793.59-MHz K8-class CPU) # Origin="GenuineIntel" Id=0x40661 Family=0x6 Model=0x46 Stepping=1 # Features=0x783fbff # Features2=0x5ed8220b # AMD Features=0x28100800 # AMD Features2=0x21 # Structured Extended Features=0x2000 # TSC: P-state invariant # ... # FreeBSD/SMP: Multiprocessor System Detected: 16 CPUs # FreeBSD/SMP: 2 package(s) x 4 core(s) x 2 SMT threads info = parse_bsd_dmesg do |cpuinfo, line| case line when /Origin.*"(.*)".*Family.*0x(\S+).*Model.*0x(\S+).*Stepping.*(\S+)/ cpuinfo["vendor_id"] = $1 # convert from hex value to int, but keep a string to match Linux ohai cpuinfo["family"] = $2.to_i(16).to_s cpuinfo["model"] = $3.to_i(16).to_s cpuinfo["stepping"] = $4 # These _should_ match /AMD Features2?/ lines as well when %r{FreeBSD/SMP: Multiprocessor System Detected: (\d*) CPUs} cpuinfo["total"] = $1.to_i when %r{FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)} cpuinfo["real"] = $1.to_i cpuinfo["cores"] = $1.to_i * $2.to_i end end cpu info end collect_data(:dragonflybsd) do # /var/run/dmesg.boot # CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz (3516.61-MHz K8-class CPU) # Origin = "GenuineIntel" Id = 0x306a9 Family = 6 Model = 3a Stepping = 9 # Features=0x783fbff # Features2=0x209 # AMD Features=0x28100800 # AMD Features2=0x1 info = parse_bsd_dmesg do |cpuinfo, line| case line when /Origin = "(.+)"\s+Id = (.+)\s+Stepping = (.+)/ cpuinfo["vendor_id"] = $1 cpuinfo["stepping"] = $3 end end so = shell_out("sysctl -n hw.ncpu") info[:total] = so.stdout.split($/)[0].to_i cpu info end collect_data(:openbsd) do cpuinfo = Mash.new # OpenBSD provides most cpu information via sysctl, the only thing we need to # to scrape from dmesg.boot is the cpu feature list. # cpu0: FPU,V86,DE,PSE,TSC,MSR,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,TM,SBF,EST,TM2 File.open("/var/run/dmesg.boot").each do |line| case line when /cpu\d+:\s+([A-Z]+$|[A-Z]+,.*$)/ cpuinfo["flags"] = $1.downcase.split(",") end end [["hw.model", :model_name], ["hw.ncpu", :total], ["hw.cpuspeed", :mhz]].each do |param, node| so = shell_out("sysctl -n #{param}") cpuinfo[node] = so.stdout.split($/)[0] end cpu cpuinfo end collect_data(:netbsd) do cpuinfo = Mash.new # NetBSD provides some cpu information via sysctl, and a little via dmesg.boot # unlike OpenBSD and FreeBSD, NetBSD does not provide information about the # available instruction set # cpu0 at mainbus0 apid 0: Intel 686-class, 2134MHz, id 0x6f6 File.open("/var/run/dmesg.boot").each do |line| case line when /cpu[\d\w\s]+:\s([\w\s\-]+),\s+(\w+),/ cpuinfo[:model_name] = $1 cpuinfo[:mhz] = $2.gsub(/mhz/i, "") end end flags = [] so = shell_out("dmidecode") so.stdout.lines do |line| if line =~ /^\s+([A-Z\d-]+)\s+\([\w\s-]+\)$/ flags << $1.downcase end end cpuinfo[:flags] = flags unless flags.empty? cpu cpuinfo end collect_data(:darwin) do cpu Mash.new shell_out("sysctl hw machdep").stdout.lines.each do |line| case line when /^hw.packages: (.*)$/ cpu[:real] = Regexp.last_match[1].to_i when /^hw.physicalcpu: (.*)$/ cpu[:cores] = Regexp.last_match[1].to_i when /^hw.logicalcpu: (.*)$/ cpu[:total] = Regexp.last_match[1].to_i when /^hw.cpufrequency: (.*)$/ cpu[:mhz] = Regexp.last_match[1].to_i / 1000000 when /^machdep.cpu.vendor: (.*)$/ cpu[:vendor_id] = Regexp.last_match[1].chomp when /^machdep.cpu.brand_string: (.*)$/ cpu[:model_name] = Regexp.last_match[1].chomp when /^machdep.cpu.model: (.*)$/ cpu[:model] = Regexp.last_match[1].to_i when /^machdep.cpu.family: (.*)$/ cpu[:family] = Regexp.last_match[1].to_i when /^machdep.cpu.stepping: (.*)$/ cpu[:stepping] = Regexp.last_match[1].to_i when /^machdep.cpu.features: (.*)$/ cpu[:flags] = Regexp.last_match[1].downcase.split(" ") end end end collect_data(:aix) do cpu Mash.new cpu[:total] = shell_out("pmcycles -m").stdout.lines.length # The below is only relevent on an LPAR if shell_out("uname -W").stdout.strip == "0" # At least one CPU will be available, but we'll wait to increment this later. cpu[:available] = 0 cpudevs = shell_out("lsdev -Cc processor").stdout.lines # from http://www-01.ibm.com/software/passportadvantage/pvu_terminology_for_customers.html # on AIX number of cores and processors are considered same cpu[:real] = cpu[:cores] = cpudevs.length cpudevs.each.with_index do |c, i| name, status, location = c.split index = i.to_s cpu[index] = Mash.new cpu[index][:status] = status cpu[index][:location] = location if status =~ /Available/ cpu[:available] += 1 lsattr = shell_out("lsattr -El #{name}").stdout.lines lsattr.each do |attribute| attrib, value = attribute.split if attrib == "type" cpu[index][:model_name] = value elsif attrib == "frequency" cpu[index][:mhz] = value.to_i / (1000 * 1000) # convert from hz to MHz else cpu[index][attrib] = value end end # IBM is the only maker of CPUs for AIX systems. cpu[index][:vendor_id] = "IBM" end end end end collect_data(:solaris2) do cpu Mash.new # This does assume that /usr/bin/kstat is in the path processor_info = shell_out("kstat -p cpu_info").stdout.lines cpu["total"] = 0 cpu["sockets"] = 0 cpu["cores"] = 0 cpu["corethreads"] = 0 cpu["cpustates"] = Mash.new currentcpu = 0 cpucores = [] cpusockets = [] processor_info.each do |processor| _desc, instance, _record, keyvalue = processor.split(":") cpu[instance] ||= Mash.new if currentcpu != instance cpu["total"] += 1 currentcpu = instance end kv = keyvalue.split(/\s+/) key = kv.shift value = kv.join(" ").chomp case key when /chip_id/ cpu[instance]["socket"] = value cpusockets.push(value) if cpusockets.index(value).nil? when /cpu_type/ cpu[instance]["arch"] = value when /clock_MHz/ cpu[instance]["mhz"] = value when /brand/ cpu[instance]["model_name"] = value.sub(/\s+/, " ") when /^state$/ cpu[instance]["state"] = value cpu["cpustates"][value] ||= 0 cpu["cpustates"][value] += 1 when /core_id/ cpu[instance]["core_id"] = value # Detect hyperthreading/multithreading cpucores.push(value) if cpucores.index(value).nil? when /family|fpu_type|model|stepping|vendor_id/ cpu[instance][key] = value end end cpu["cores"] = cpucores.size cpu["corethreads"] = (cpu["total"] / cpucores.size) cpu["sockets"] = cpusockets.size cpu["real"] = cpusockets.size end collect_data(:windows) do require "wmi-lite/wmi" cpu Mash.new cores = 0 logical_processors = 0 wmi = WmiLite::Wmi.new processors = wmi.instances_of("Win32_Processor") processors.each_with_index do |processor, index| current_cpu = index.to_s cpu[current_cpu] = Mash.new cpu[current_cpu]["cores"] = processor["numberofcores"] cores += processor["numberofcores"] logical_processors += processor["numberoflogicalprocessors"] cpu[current_cpu]["vendor_id"] = processor["manufacturer"] cpu[current_cpu]["family"] = processor["family"].to_s cpu[current_cpu]["model"] = processor["revision"].to_s cpu[current_cpu]["stepping"] = if processor["stepping"].nil? processor["description"].match(/Stepping\s+(\d+)/)[1] else processor["stepping"] end cpu[current_cpu]["physical_id"] = processor["deviceid"] cpu[current_cpu]["model_name"] = processor["name"] cpu[current_cpu]["description"] = processor["description"] cpu[current_cpu]["mhz"] = processor["maxclockspeed"].to_s cpu[current_cpu]["cache_size"] = "#{processor["l2cachesize"]} KB" end cpu[:total] = logical_processors cpu[:cores] = cores cpu[:real] = processors.length end end ohai-16.0.7/lib/ohai/plugins/darwin/000077500000000000000000000000001362624620500171665ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/darwin/hardware.rb000066400000000000000000000067641362624620500213250ustar00rootroot00000000000000# # Author:: Nate Walck () # Copyright:: Copyright (c) 2016-present Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Hardware) do provides "hardware" def system_profiler(datatype) sp_cmd = "system_profiler #{datatype} -xml" # Hardware queries sp_std = shell_out(sp_cmd) Plist.parse_xml(sp_std.stdout) end collect_data(:darwin) do unless hardware hardware Mash.new else logger.trace("Plugin Hardware: namespace already exists") next end require "plist" hw_hash = system_profiler("SPHardwareDataType") hw_hash[0]["_items"][0].delete("_name") hardware.merge!(hw_hash[0]["_items"][0]) # ProductName: Mac OS X # ProductVersion: 10.12.5 # BuildVersion: 16F73 shell_out("sw_vers").stdout.lines.each do |line| case line when /^ProductName:\s*(.*)$/ hardware["operating_system"] = Regexp.last_match[1].strip when /^ProductVersion:\s*(.*)$/ hardware["operating_system_version"] = Regexp.last_match[1].strip when /^BuildVersion:\s*(.*)$/ hardware["build_version"] = Regexp.last_match[1].strip end end hardware["architecture"] = shell_out("uname -m").stdout.strip # Storage queries storage = [] storage_hash = system_profiler("SPStorageDataType") drives = storage_hash[0]["_items"] drives.each do |drive_entry| drive = Mash.new drive[:name] = drive_entry["_name"] drive[:bsd_name] = drive_entry["bsd_name"] drive[:capacity] = drive_entry["size_in_bytes"] if drive_entry.key?("com.apple.corestorage.pv") drive[:drive_type] = drive_entry["com.apple.corestorage.pv"][0]["medium_type"] drive[:smart_status] = drive_entry["com.apple.corestorage.pv"][0]["smart_status"] drive[:partitions] = drive_entry["com.apple.corestorage.pv"].count end storage << drive end hardware["storage"] = storage # Battery queries battery_hash = system_profiler("SPPowerDataType") power_entries = battery_hash[0]["_items"] battery = Mash.new power_entries.each do |entry| if entry.value?("spbattery_information") charge = entry["sppower_battery_charge_info"] health = entry["sppower_battery_health_info"] battery[:current_capacity] = charge["sppower_battery_current_capacity"] battery[:max_capacity] = charge["sppower_battery_max_capacity"] battery[:fully_charged] = charge["sppower_battery_fully_charged"].eql?("TRUE") battery[:is_charging] = charge["sppower_battery_is_charging"].eql?("TRUE") battery[:charge_cycle_count] = health["sppower_battery_cycle_count"] battery[:health] = health["sppower_battery_health"] battery[:serial] = entry["sppower_battery_model_info"]["sppower_battery_serial_number"] battery[:remaining] = (battery["current_capacity"].to_f / battery["max_capacity"].to_f * 100).to_i end end hardware[:battery] = battery end end ohai-16.0.7/lib/ohai/plugins/darwin/memory.rb000066400000000000000000000037571362624620500210370ustar00rootroot00000000000000# # Author:: Patrick Collins () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory" collect_data(:darwin) do memory Mash.new installed_memory = shell_out("sysctl -n hw.memsize").stdout.to_i / 1024 / 1024.0 memory[:total] = "#{installed_memory.to_i}MB" total_consumed = 0 active = 0 inactive = 0 vm_stat = shell_out("vm_stat").stdout vm_stat_match = /page size of (\d+) bytes/.match(vm_stat) page_size = if vm_stat_match && vm_stat_match[1] vm_stat_match[1].to_i else 4096 end vm_stat.split("\n").each do |line| ["wired down", "active", "inactive"].each do |match| unless line.index("Pages #{match}:").nil? pages = line.split.last.to_i megabyte_val = (pages * page_size) / 1024 / 1024.0 total_consumed += megabyte_val case match when "wired down" active += megabyte_val.to_i when "active" active += megabyte_val.to_i when "inactive" inactive += megabyte_val.to_i end end end end memory[:active] = "#{active}MB" if active > 0 memory[:inactive] = "#{inactive}MB" if inactive > 0 free_memory = installed_memory - total_consumed memory[:free] = "#{free_memory.to_i}MB" if total_consumed > 0 end end ohai-16.0.7/lib/ohai/plugins/darwin/network.rb000066400000000000000000000162601362624620500212110ustar00rootroot00000000000000# # Author:: Benjamin Black () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do require_relative "../../mixin/network_helper" provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" include Ohai::Mixin::NetworkHelper def parse_media(media_string) media = {} line_array = media_string.split(" ") 0.upto(line_array.length - 1) do |i| unless line_array[i].eql?("none") if line_array[i + 1] =~ /^\<([a-zA-Z\-\,]+)\>$/ media[line_array[i]] = {} unless media.key?(line_array[i]) if media[line_array[i]].key?("options") $1.split(",").each do |opt| media[line_array[i]]["options"] << opt unless media[line_array[i]]["options"].include?(opt) end else media[line_array[i]]["options"] = $1.split(",") end else if line_array[i].eql?("autoselect") media["autoselect"] = {} unless media.key?("autoselect") media["autoselect"]["options"] = [] end end else media["none"] = { "options" => [] } end end media end def darwin_encaps_lookup(ifname) return "Loopback" if ifname.eql?("lo") return "1394" if ifname.eql?("fw") return "IPIP" if ifname.eql?("gif") return "6to4" if ifname.eql?("stf") return "dot1q" if ifname.eql?("vlan") "Unknown" end def scope_lookup(scope) return "Node" if scope.eql?("::1") return "Link" if scope =~ /^fe80\:/ return "Site" if scope =~ /^fec0\:/ "Global" end def excluded_setting?(setting) setting.match("_sw_cksum") end def locate_interface(ifaces, ifname, mac) return ifname unless ifaces[ifname].nil? # oh well, time to go hunting! return ifname.chop if ifname =~ /\*$/ ifaces.each_key do |ifc| ifaces[ifc][:addresses].each_key do |addr| return ifc if addr.eql? mac end end nil end collect_data(:darwin) do network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new so = shell_out("route -n get default") so.stdout.lines do |line| if line =~ /(\w+): ([\w\.]+)/ case $1 when "gateway" network[:default_gateway] = $2 when "interface" network[:default_interface] = $2 end end end iface = Mash.new so = shell_out("ifconfig -a") cint = nil so.stdout.lines do |line| if line =~ /^([0-9a-zA-Z\.\:\-]+): \S+ mtu (\d+)$/ cint = $1 iface[cint] ||= Mash.new iface[cint][:addresses] ||= Mash.new iface[cint][:mtu] = $2 if line =~ /\sflags\=\d+\<((UP|BROADCAST|DEBUG|SMART|SIMPLEX|LOOPBACK|POINTOPOINT|NOTRAILERS|RUNNING|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC|,)+)\>\s/ flags = $1.split(",") else flags = [] end iface[cint][:flags] = flags.flatten if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 iface[cint][:encapsulation] = darwin_encaps_lookup($1) end end if line =~ /^\s+ether ([0-9a-f\:]+)/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } iface[cint][:encapsulation] = "Ethernet" end if line =~ /^\s+lladdr ([0-9a-f\:]+)\s/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } end if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask 0x(([0-9a-f]){1,8})\s*$/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => hex_to_dec_netmask($2) } end if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask 0x(([0-9a-f]){1,8}) broadcast (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => hex_to_dec_netmask($2) , "broadcast" => $4 } end if line =~ /\s+inet6 ([a-f0-9\:]+)(\s*|(\%[a-z0-9]+)\s*) prefixlen (\d+)\s*/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $4 , "scope" => scope_lookup($1) } end if line =~ /\s+inet6 ([a-f0-9\:]+)(\s*|(\%[a-z0-9]+)\s*) prefixlen (\d+) scopeid 0x([a-f0-9]+)/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $4 , "scope" => scope_lookup($1) } end if line =~ /^\s+media: ((\w+)|(\w+ [a-zA-Z0-9\-\<\>]+)) status: (\w+)/ iface[cint][:media] ||= Mash.new iface[cint][:media][:selected] = parse_media($1) iface[cint][:status] = $4 end if line =~ /^\s+supported media: (.*)/ iface[cint][:media] ||= Mash.new iface[cint][:media][:supported] = parse_media($1) end end so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /^\S+ \((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([a-zA-Z0-9\.\:\-]+).*\[(\w+)\]/ # MAC addr really should be normalized to include all the zeroes. next if iface[$3].nil? # this should never happen iface[$3][:arp] ||= Mash.new iface[$3][:arp][$1] = $2 end end settings = Mash.new so = shell_out("sysctl net") so.stdout.lines do |line| if line =~ /^([a-zA-Z0-9\.\_]+)\: (.*)/ # should normalize names between platforms for the same settings. settings[$1] = $2 unless excluded_setting?($1) end end network[:settings] = settings network[:interfaces] = iface net_counters = Mash.new so = shell_out("netstat -i -d -l -b -n") so.stdout.lines do |line| if line =~ /^([a-zA-Z0-9\.\:\-\*]+)\s+\d+\s+\<[a-zA-Z0-9\#]+\>\s+([a-f0-9\:]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ || line =~ /^([a-zA-Z0-9\.\:\-\*]+)\s+\d+\s+\<[a-zA-Z0-9\#]+\>(\s+)(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ ifname = locate_interface(iface, $1, $2) next if iface[ifname].nil? # this shouldn't happen, but just in case net_counters[ifname] ||= Mash.new net_counters[ifname] = { rx: { bytes: $5, packets: $3, errors: $4, drop: 0, overrun: 0, frame: 0, compressed: 0, multicast: 0 }, tx: { bytes: $8, packets: $6, errors: $7, drop: 0, overrun: 0, collisions: $9, carrier: 0, compressed: 0 }, } end end counters[:network][:interfaces] = net_counters end end ohai-16.0.7/lib/ohai/plugins/darwin/platform.rb000066400000000000000000000023471362624620500213450ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_build", "platform_family" collect_data(:darwin) do so = shell_out((Ohai.abs_path( "/usr/bin/sw_vers" )).to_s) so.stdout.lines do |line| case line when /^ProductName:\s+(.+)$/ macname = $1 macname.downcase! macname.tr!(" ", "_") platform macname when /^ProductVersion:\s+(.+)$/ platform_version $1 when /^BuildVersion:\s+(.+)$/ platform_build $1 end end platform_family "mac_os_x" end end ohai-16.0.7/lib/ohai/plugins/darwin/virtualization.rb000066400000000000000000000047431362624620500226070ustar00rootroot00000000000000# # Author:: Pavel Yudin () # Author:: Tim Smith () # Copyright:: Copyright (c) 2015 Pavel Yudin # Copyright:: Copyright (c) 2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualization) do provides "virtualization" depends "hardware" def vboxmanage_exists? which("VBoxManage") end def prlctl_exists? which("prlctl") end def ioreg_exists? which("ioreg") end def fusion_exists? ::File.exist?("/Applications/VMware\ Fusion.app/") end def docker_exists? which("docker") end collect_data(:darwin) do virtualization Mash.new unless virtualization virtualization[:systems] ||= Mash.new if docker_exists? virtualization[:system] = "docker" virtualization[:role] = "host" virtualization[:systems][:docker] = "host" end if vboxmanage_exists? virtualization[:system] = "vbox" virtualization[:role] = "host" virtualization[:systems][:vbox] = "host" end if hardware[:boot_rom_version].match?(/VirtualBox/i) virtualization[:system] = "vbox" virtualization[:role] = "guest" virtualization[:systems][:vbox] = "guest" end if fusion_exists? virtualization[:system] = "vmware" virtualization[:role] = "host" virtualization[:systems][:vmware] = "host" end if hardware[:boot_rom_version].match?(/VMW/i) virtualization[:system] = "vmware" virtualization[:role] = "guest" virtualization[:systems][:vmware] = "guest" end if prlctl_exists? virtualization[:system] = "parallels" virtualization[:role] = "host" virtualization[:systems][:parallels] = "host" elsif ioreg_exists? so = shell_out("ioreg -l") if so.stdout =~ /pci1ab8,4000/ virtualization[:system] = "parallels" virtualization[:role] = "guest" virtualization[:systems][:parallels] = "guest" end end end end ohai-16.0.7/lib/ohai/plugins/digital_ocean.rb000066400000000000000000000037411362624620500210160ustar00rootroot00000000000000# # Author:: Dylan Page () # Author:: Stafford Brunk () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:DigitalOcean) do require_relative "../mixin/do_metadata" require_relative "../mixin/http_helper" include Ohai::Mixin::DOMetadata include Ohai::Mixin::HttpHelper provides "digital_ocean" depends "dmi" # look for digitalocean string in dmi bios data def has_do_dmi? begin # detect a vendor of "DigitalOcean" if dmi[:bios][:all_records][0][:Vendor] == "DigitalOcean" logger.trace("Plugin DigitalOcean: has_do_dmi? == true") return true end rescue NoMethodError # dmi[:bios][:all_records][0][:Vendor] may not exist end logger.trace("Plugin DigitalOcean: has_do_dmi? == false") false end def looks_like_digital_ocean? return true if hint?("digital_ocean") return true if has_do_dmi? && can_socket_connect?(Ohai::Mixin::DOMetadata::DO_METADATA_ADDR, 80) false end collect_data do if looks_like_digital_ocean? logger.trace("Plugin Digitalocean: looks_like_digital_ocean? == true") digital_ocean Mash.new fetch_metadata.each do |k, v| next if k == "vendor_data" # this may have sensitive data we shouldn't store digital_ocean[k] = v end else logger.trace("Plugin Digitalocean: No hints present for and doesn't look like digitalocean") false end end end ohai-16.0.7/lib/ohai/plugins/dmi.rb000066400000000000000000000120101362624620500167720ustar00rootroot00000000000000# # Author:: Kurt Yoder (ktyopscode@yoderhome.com) # Copyright:: Copyright (c) 2010 Kurt Yoder # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:DMI) do provides "dmi" # dmidecode does not return data without access to /dev/mem (or its equivalent) collect_data do require_relative "../common/dmi" dmi Mash.new # all output lines should fall within one of these patterns handle_line = /^Handle (0x[0-9A-F]{4}), DMI type (\d+), (\d+) bytes/ type_line = /^([A-Z][a-zA-Z ]+)( Information)?/ blank_line = /^\s*$/ data_line = /^\t([^:]+):(?: (.*))?/ extended_data_line = /^\t\t(.+)/ # first lines may contain some interesting information: # # dmidecode 2.10 # SMBIOS 2.5 present. # 5 structures occupying 352 bytes. # Table at 0x000E1000. dmidecode_version_line = /^# dmidecode (\d+\.\d+)/ smbios_version_line = /^SMBIOS (\d+\.\d+) present\./ structures_line = /^(\d+) structures occupying (\d+) bytes\./ table_location_line = /^Table at (0x[0-9A-E]+)\./ dmi_record = nil field = nil begin so = shell_out("dmidecode") # ==== EXAMPLE RECORD: ==== # Handle 0x0000, DMI type 0, 24 bytes # BIOS Information # Vendor: American Megatrends Inc. # Version: 080012 # ... similar lines trimmed # Characteristics: # ISA is supported # PCI is supported # ... similar lines trimmed so.stdout.lines do |line| next if blank_line.match(line) line = line.encode(line.encoding, universal_newline: true) if ( dmidecode_version = dmidecode_version_line.match(line) ) dmi[:dmidecode_version] = dmidecode_version[1] elsif ( smbios_version = smbios_version_line.match(line) ) dmi[:smbios_version] = smbios_version[1] elsif ( structures = structures_line.match(line) ) dmi[:structures] = Mash.new dmi[:structures][:count] = structures[1] dmi[:structures][:size] = structures[2] elsif ( table_location = table_location_line.match(line) ) dmi[:table_location] = table_location[1] elsif ( handle = handle_line.match(line) ) unless Ohai::Common::DMI.whitelisted_ids.include?(handle[2].to_i) dmi_record = nil next end dmi_record = { type: Ohai::Common::DMI.id_lookup(handle[2]) } dmi[dmi_record[:type]] ||= Mash.new dmi[dmi_record[:type]][:all_records] ||= [] dmi_record[:position] = dmi[dmi_record[:type]][:all_records].length dmi[dmi_record[:type]][:all_records].push(Mash.new) dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:record_id] = handle[1] dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:size] = handle[2] field = nil elsif ( type = type_line.match(line) ) if dmi_record .nil? logger.trace("Plugin DMI: unexpected data line found before header; discarding:\n#{line}") next end dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:application_identifier] = type[1] elsif ( data = data_line.match(line) ) if dmi_record .nil? logger.trace("Plugin DMI: unexpected data line found before header; discarding:\n#{line}") next end dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = data[2] field = data[1] elsif ( extended_data = extended_data_line.match(line) ) if dmi_record .nil? logger.trace("Plugin DMI: unexpected extended data line found before header; discarding:\n#{line}") next end if field .nil? logger.trace("Plugin DMI: unexpected extended data line found outside data section; discarding:\n#{line}") next end # overwrite "raw" value with a new Mash dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field] = Mash.new unless dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field].class.to_s == "Mash" dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field][extended_data[1]] = nil else logger.trace("Plugin DMI: unrecognized output line; discarding:\n#{line}") end end Ohai::Common::DMI.convenience_keys(dmi) rescue Ohai::Exceptions::Exec logger.trace('Plugin DMI: Could not shell_out "dmidecode". Skipping data') end end end ohai-16.0.7/lib/ohai/plugins/docker.rb000066400000000000000000000042021362624620500174740ustar00rootroot00000000000000# # Copyright:: 2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Docker) do require "json" provides "docker" depends "virtualization" def docker_info_json so = shell_out("docker info --format '{{json .}}'") if so.exitstatus == 0 JSON.parse(so.stdout) end rescue Ohai::Exceptions::Exec logger.trace('Plugin Docker: Could not shell_out "docker info --format \'{{json .}}\'". Skipping plugin') end def docker_ohai_data(shellout_data) docker Mash.new docker[:version_string] = shellout_data["ServerVersion"] docker[:version] = shellout_data["ServerVersion"].split("-")[0] if shellout_data["ServerVersion"] # guard this so missing data doesn't fail the run docker[:runtimes] = shellout_data["Runtimes"] docker[:root_dir] = shellout_data["DockerRootDir"] docker[:containers] = {} docker[:containers][:total] = shellout_data["Containers"] docker[:containers][:running] = shellout_data["ContainersRunning"] docker[:containers][:paused] = shellout_data["ContainersPaused"] docker[:containers][:stopped] = shellout_data["ContainersStopped"] docker[:plugins] = shellout_data["Plugins"] docker[:networking] = {} docker[:networking][:ipv4_forwarding] = shellout_data["IPv4Forwarding"] docker[:networking][:bridge_nf_iptables] = shellout_data["BridgeNfIptables"] docker[:networking][:bridge_nf_ipv6_iptables] = shellout_data["BridgeNfIp6tables"] docker[:swarm] = shellout_data["Swarm"] end collect_data do if virtualization[:systems][:docker] docker_ohai_data(docker_info_json) end end end ohai-16.0.7/lib/ohai/plugins/dragonflybsd/000077500000000000000000000000001362624620500203605ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/dragonflybsd/memory.rb000066400000000000000000000045541362624620500222250ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory", "memory/swap" collect_data(:dragonflybsd) do memory Mash.new memory[:swap] = Mash.new # /usr/src/sys/sys/vmmeter.h so = shell_out("sysctl -n vm.stats.vm.v_page_size") memory[:page_size] = so.stdout.split($/)[0] so = shell_out("sysctl -n vm.stats.vm.v_page_count") memory[:page_count] = so.stdout.split($/)[0] memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i so = shell_out("sysctl -n vm.stats.vm.v_free_count") memory[:free] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.status.vm.v_active_count") memory[:active] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.status.vm.v_inactive_count") memory[:inactive] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.stats.vm.v_cache_count") memory[:cache] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.stats.vm.v_wire_count") memory[:wired] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vfs.bufspace") memory[:buffers] = so.stdout.split($/)[0] so = shell_out("swapinfo") so.stdout.lines do |line| # Device 1K-blocks Used Avail Capacity # /dev/ad0s1b 253648 0 253648 0% if line =~ %r{^([\d\w/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)} mdev = $1 memory[:swap][mdev] = Mash.new memory[:swap][mdev][:total] = $2 memory[:swap][mdev][:used] = $3 memory[:swap][mdev][:free] = $4 memory[:swap][mdev][:percent_free] = $5 end end end end ohai-16.0.7/lib/ohai/plugins/dragonflybsd/network.rb000066400000000000000000000113411362624620500223760ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" collect_data(:dragonflybsd) do network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new so = shell_out("route -n get default") so.stdout.lines do |line| if line =~ /(\w+): ([\w\.]+)/ case $1 when "gateway" network[:default_gateway] = $2 when "interface" network[:default_interface] = $2 end end end iface = Mash.new so = shell_out("#{Ohai.abs_path( "/sbin/ifconfig" )} -a") cint = nil so.stdout.lines do |line| if line =~ /^([0-9a-zA-Z\.]+):\s+/ cint = $1 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end end # call the family lladdr to match linux for consistency if line =~ /\s+ether (.+?)\s/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } end if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ iface[cint][:addresses] ||= Mash.new # convert the netmask to decimal for consistency netmask = "#{$2[2, 2].hex}.#{$2[4, 2].hex}.#{$2[6, 2].hex}.#{$2[8, 2].hex}" if $3.empty? iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } else # found a broadcast address iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } end end if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ iface[cint][:addresses] ||= Mash.new if $4.empty? iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } else # found a zone_id / scope iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } end end if line =~ /flags=\d+<(.+)>/ flags = $1.split(",") iface[cint][:flags] = flags if flags.length > 0 end if line =~ /metric: (\d+) mtu: (\d+)/ iface[cint][:metric] = $1 iface[cint][:mtu] = $2 end end so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ next unless iface[$3] # this should never happen iface[$3][:arp] ||= Mash.new iface[$3][:arp][$1] = $2.downcase end end network["interfaces"] = iface net_counters = Mash.new # From netstat(1), not sure of the implications: # Show the state of all network interfaces or a single interface # which have been auto-configured (interfaces statically configured # into a system, but not located at boot time are not shown). so = shell_out("netstat -ibdn") so.stdout.lines do |line| # Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop # ed0 1500 54:52:00:68:92:85 333604 26 151905886 175472 0 24897542 0 905 # $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 if line =~ /^([\w\.\*]+)\s+\d+\s+\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ net_counters[$1] ||= Mash.new net_counters[$1]["rx"] ||= Mash.new net_counters[$1]["tx"] ||= Mash.new net_counters[$1]["rx"]["packets"] = $3 net_counters[$1]["rx"]["errors"] = $4 net_counters[$1]["rx"]["bytes"] = $5 net_counters[$1]["tx"]["packets"] = $6 net_counters[$1]["tx"]["errors"] = $7 net_counters[$1]["tx"]["bytes"] = $8 net_counters[$1]["tx"]["collisions"] = $9 net_counters[$1]["tx"]["dropped"] = $10 end end counters[:network][:interfaces] = net_counters end end ohai-16.0.7/lib/ohai/plugins/dragonflybsd/platform.rb000066400000000000000000000017531362624620500225370ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" collect_data(:dragonflybsd) do so = shell_out("uname -s") platform so.stdout.split($/)[0].downcase so = shell_out("uname -r") platform_version so.stdout.split($/)[0] platform_family "dragonflybsd" end end ohai-16.0.7/lib/ohai/plugins/ec2.rb000066400000000000000000000126151362624620500167050ustar00rootroot00000000000000# # Author:: Tim Dysinger () # Author:: Benjamin Black () # Author:: Christopher Brown () # Author:: Tim Smith () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # How we detect EC2 from easiest to hardest & least reliable # 1. Ohai ec2 hint exists. This always works # 2. Xen hypervisor UUID starts with 'ec2'. This catches Linux HVM & paravirt instances # 3. DMI bios version data mentions amazon. This catches HVM instances in a VPC on the Xen based hypervisor # 3. DMI bios vendor data mentions amazon. This catches HVM instances in a VPC on the non-Xen based hypervisor # 4. Kernel data mentioned Amazon. This catches Windows HVM & paravirt instances Ohai.plugin(:EC2) do require_relative "../mixin/ec2_metadata" require_relative "../mixin/http_helper" require "base64" include Ohai::Mixin::Ec2Metadata include Ohai::Mixin::HttpHelper provides "ec2" # look for amazon string in dmi vendor bios data within the sys tree. # this works even if the system lacks dmidecode use by the Dmi plugin # this gets us detection of new Xen-less HVM instances that are within a VPC # @return [Boolean] do we have Amazon DMI data? def has_ec2_amazon_dmi? # detect a version of '4.2.amazon' if file_val_if_exists("/sys/class/dmi/id/bios_vendor") =~ /Amazon/ logger.trace("Plugin EC2: has_ec2_amazon_dmi? == true") true else logger.trace("Plugin EC2: has_ec2_amazon_dmi? == false") false end end # look for amazon string in dmi bios version data within the sys tree. # this works even if the system lacks dmidecode use by the Dmi plugin # this gets us detection of HVM instances that are within a VPC # @return [Boolean] do we have Amazon DMI data? def has_ec2_xen_dmi? # detect a version of '4.2.amazon' if file_val_if_exists("/sys/class/dmi/id/bios_version") =~ /amazon/ logger.trace("Plugin EC2: has_ec2_xen_dmi? == true") true else logger.trace("Plugin EC2: has_ec2_xen_dmi? == false") false end end # looks for a xen UUID that starts with ec2 from within the Linux sys tree # @return [Boolean] do we have a Xen UUID or not? def has_ec2_xen_uuid? if file_val_if_exists("/sys/hypervisor/uuid") =~ /^ec2/ logger.trace("Plugin EC2: has_ec2_xen_uuid? == true") return true end logger.trace("Plugin EC2: has_ec2_xen_uuid? == false") false end # looks at the identifying number WMI value to see if it starts with ec2. # this is actually the same value we're looking at in has_ec2_xen_uuid? on # linux hosts # @return [Boolean] do we have a Xen Identifying Number or not? def has_ec2_identifying_number? if RUBY_PLATFORM =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new if wmi.first_of("Win32_ComputerSystemProduct")["identifyingnumber"] =~ /^ec2/ logger.trace("Plugin EC2: has_ec2_identifying_number? == true") true end else logger.trace("Plugin EC2: has_ec2_identifying_number? == false") false end end # return the contents of a file if the file exists # @param path[String] abs path to the file # @return [String] contents of the file if it exists def file_val_if_exists(path) if ::File.exist?(path) ::File.read(path) end end # a single check that combines all the various detection methods for EC2 # @return [Boolean] Does the system appear to be on EC2 def looks_like_ec2? return true if hint?("ec2") # Even if it looks like EC2 try to connect first if has_ec2_xen_uuid? || has_ec2_amazon_dmi? || has_ec2_xen_dmi? || has_ec2_identifying_number? return true if can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80) end end collect_data do if looks_like_ec2? logger.trace("Plugin EC2: looks_like_ec2? == true") ec2 Mash.new fetch_metadata.each do |k, v| # fetch_metadata returns IAM security credentials, including the IAM user's # secret access key. We'd rather not have ohai send this information # to the server. # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html#instancedata-data-categories next if k == "iam" && !hint?("iam") ec2[k] = v end ec2[:userdata] = fetch_userdata ec2[:account_id] = fetch_dynamic_data["accountId"] ec2[:availability_zone] = fetch_dynamic_data["availabilityZone"] ec2[:region] = fetch_dynamic_data["region"] # ASCII-8BIT is equivalent to BINARY in this case if ec2[:userdata] && ec2[:userdata].encoding.to_s == "ASCII-8BIT" logger.trace("Plugin EC2: Binary UserData Found. Storing in base64") ec2[:userdata] = Base64.encode64(ec2[:userdata]) end else logger.trace("Plugin EC2: looks_like_ec2? == false") false end end end ohai-16.0.7/lib/ohai/plugins/elixir.rb000066400000000000000000000022671362624620500175320ustar00rootroot00000000000000# Author:: Christopher M Luciano () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Elixir) do provides "languages/elixir" depends "languages" collect_data do so = shell_out("elixir -v") # Sample output: # Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] # # Elixir 1.2.4 if so.exitstatus == 0 && so.stdout =~ /^Elixir (\S*)/ elixir = Mash.new elixir[:version] = $1 languages[:elixir] = elixir end rescue Ohai::Exceptions::Exec logger.trace('Plugin Elixir: Could not shell_out "elixir -v". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/erlang.rb000066400000000000000000000043651362624620500175070ustar00rootroot00000000000000# # Author:: Joe Williams () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Erlang) do provides "languages/erlang" depends "languages" collect_data do erlang = Mash.new begin so = shell_out("erl -eval '{ok, Ver} = file:read_file(filename:join([code:root_dir(), \"releases\", erlang:system_info(otp_release), \"OTP_VERSION\"])), Vsn = binary:bin_to_list(Ver, {0, byte_size(Ver) - 1}), io:format(\"~s,~s,~s\", [Vsn, erlang:system_info(version), erlang:system_info(nif_version)]), halt().' -noshell") # Sample output: # 19.1,8.1,2.11 if so.exitstatus == 0 output = so.stdout.split(",") erlang[:version] = output[0] erlang[:erts_version] = output[1] erlang[:nif_version] = output[2] end rescue Ohai::Exceptions::Exec logger.trace('Plugin Erlang: Could not shell_out "erl -eval \'erlang:display(erlang:system_info(otp_release)), erlang:display(erlang:system_info(version)), erlang:display(erlang:system_info(nif_version)), halt().\' -noshell". Skipping data') end begin so = shell_out("erl +V") # Sample output: # Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 7.3 if so.exitstatus == 0 output = so.stderr.split if output.length >= 6 options = output[1] options.gsub!(/(\(|\))/, "") erlang[:options] = options.split(",") erlang[:emulator] = output[2].gsub!(/(\(|\))/, "") end end rescue Ohai::Exceptions::Exec logger.trace('Plugin Erlang: Could not shell_out "erl +V". Skipping data') end languages[:erlang] = erlang unless erlang.empty? end end ohai-16.0.7/lib/ohai/plugins/eucalyptus.rb000066400000000000000000000055311362624620500204310ustar00rootroot00000000000000# # Author:: Tim Dysinger () # Author:: Benjamin Black () # Author:: Christopher Brown () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Eucalyptus) do # eucalyptus metadata service is compatible with the ec2 service calls require_relative "../mixin/ec2_metadata" require_relative "../mixin/http_helper" include Ohai::Mixin::Ec2Metadata include Ohai::Mixin::HttpHelper provides "eucalyptus" depends "network/interfaces" # returns the mac address from the collection of all address types def get_mac_address(addresses) detected_addresses = addresses.detect { |address, keypair| keypair == { "family" => "lladdr" } } if detected_addresses detected_addresses.first else "" end end # detect if the mac address starts with d0:0d def has_euca_mac? network[:interfaces].each_value do |iface| mac = get_mac_address(iface[:addresses]) if mac =~ /^[dD]0:0[dD]:/ logger.trace("Plugin Eucalyptus: has_euca_mac? == true (#{mac})") return true end end logger.trace("Plugin Eucalyptus: has_euca_mac? == false") false end def looks_like_euca? # Try non-blocking connect so we don't "block" if # the metadata service doesn't respond hint?("eucalyptus") || has_euca_mac? && can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80) end collect_data do if looks_like_euca? logger.trace("Plugin Eucalyptus: looks_like_euca? == true") eucalyptus Mash.new fetch_metadata.each do |k, v| # Eucalyptus 3.4+ supports IAM roles and Instance Profiles much like AWS # https://www.eucalyptus.com/blog/2013/10/15/iam-roles-and-instance-profiles-eucalyptus-34 # # fetch_metadata returns IAM security credentials, including the IAM user's # secret access key. We'd rather not have ohai send this information # to the server. # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html#instancedata-data-categories next if k == "iam" && !hint?("iam") eucalyptus[k] = v end eucalyptus[:userdata] = fetch_userdata else logger.trace("Plugin Eucalyptus: looks_like_euca? == false") false end end end ohai-16.0.7/lib/ohai/plugins/filesystem.rb000066400000000000000000000527561362624620500204320ustar00rootroot00000000000000# # Author:: Phil Dibowitz # Author:: Adam Jacob # Author:: Kurt Yoder (ktyopscode@yoderhome.com) # Author:: Deepali Jagtap () # Author:: Prabhu Das () # Author:: Isa Farnik () # Author:: James Gartrell () # Copyright:: Copyright (c) 2008-2020 Chef Software, Inc. # Copyright:: Copyright (c) 2015 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Filesystem) do provides "filesystem" def find_device(name) %w{/dev /dev/mapper}.each do |dir| path = File.join(dir, name) return path if File.exist?(path) end name end def parse_line(line, cmdtype) case cmdtype when "lsblk" regex = /NAME="(\S+).*?" UUID="(\S*)" LABEL="(\S*)" FSTYPE="(\S*)"/ if line =~ regex dev = $1 dev = find_device(dev) unless dev.start_with?("/") uuid = $2 label = $3 fs_type = $4 return { dev: dev, uuid: uuid, label: label, fs_type: fs_type } end when "blkid" bits = line.split dev = bits.shift.split(":")[0] f = { dev: dev } bits.each do |keyval| if keyval =~ /(\S+)="(\S+)"/ key = $1.downcase.to_sym key = :fs_type if key == :type f[key] = $2 end end return f end nil end def generate_device_view(fs) view = {} fs.each_value do |entry| view[entry[:device]] ||= Mash.new entry.each do |key, val| next if %w{device mount}.include?(key) view[entry[:device]][key] = val end view[entry[:device]][:mounts] ||= [] if entry[:mount] view[entry[:device]][:mounts] << entry[:mount] end end view end def generate_mountpoint_view(fs) view = {} fs.each_value do |entry| next unless entry[:mount] view[entry[:mount]] ||= Mash.new entry.each do |key, val| next if %w{mount device}.include?(key) view[entry[:mount]][key] = val end view[entry[:mount]][:devices] ||= [] if entry[:device] view[entry[:mount]][:devices] << entry[:device] end end view end def generate_deprecated_windows_view(fs) view = generate_mountpoint_view(fs) view.each do |mp, entry| view[mp].delete("devices") end view end def parse_common_df(out) fs = {} out.each_line do |line| case line when /^Filesystem\s+1024-blocks/ next when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ key = "#{$1},#{$6}" fs[key] = Mash.new fs[key][:device] = $1 fs[key][:kb_size] = $2 fs[key][:kb_used] = $3 fs[key][:kb_available] = $4 fs[key][:percent_used] = $5 fs[key][:mount] = $6 end end fs end def run_with_check(bin, &block) yield rescue Ohai::Exceptions::Exec => e unless Ohai.config[:plugin][:filesystem][:allow_partial_data] raise e end logger.warn("Plugin Filesystem: #{bin} binary is not available. Some data will not be available.") end ### Windows specific methods BEGINS # Drive types DRIVE_TYPE ||= %w{unknown no_root_dir removable local network cd ram}.freeze # Volume encryption or decryption status # # @see https://docs.microsoft.com/en-us/windows/desktop/SecProv/getconversionstatus-win32-encryptablevolume#parameters # CONVERSION_STATUS ||= %w{ FullyDecrypted FullyEncrypted EncryptionInProgress DecryptionInProgress EncryptionPaused DecryptionPaused }.freeze # Returns a Mash loaded with logical details # # Uses Win32_LogicalDisk and logical_properties to return general details of volumes. # # Returns an empty Mash in case of any WMI exception. # # @see https://docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-logicaldisk # # @return [Mash] # def logical_info wmi = WmiLite::Wmi.new("Root\\CIMV2") # TODO: We should really be parsing Win32_Volume and Win32_MountPoint. disks = wmi.instances_of("Win32_LogicalDisk") logical_properties(disks) rescue WmiLite::WmiException Ohai::Log.debug("Unable to access Win32_LogicalDisk. Skipping logical details") Mash.new end # Returns a Mash loaded with encryption details # # Uses Win32_EncryptableVolume and encryption_properties to return encryption details of volumes. # # Returns an empty Mash in case of any WMI exception. # # @note We are fetching Encryption Status only as of now # # @see https://msdn.microsoft.com/en-us/library/windows/desktop/aa376483(v=vs.85).aspx # # @return [Mash] # def encryptable_info wmi = WmiLite::Wmi.new("Root\\CIMV2\\Security\\MicrosoftVolumeEncryption") disks = wmi.instances_of("Win32_EncryptableVolume") encryption_properties(disks) rescue WmiLite::WmiException Ohai::Log.debug("Unable to access Win32_EncryptableVolume. Skipping encryptable details") Mash.new end # Refines and calculates logical properties out of given instances. # # Note that :device here is the same as Volume name and there for compatibility with other OSes. # # @param [WmiLite::Wmi::Instance] disks # # @return [Mash] Each drive containing following properties: # # * :kb_size (Integer) # * :kb_available (Integer) # * :kb_used (Integer) # * :percent_used (Integer) # * :mount (String) # * :fs_type (String) # * :volume_name (String) # * :device (String) # def logical_properties(disks) properties = Mash.new disks.each do |disk| property = Mash.new # In windows the closest thing we have to a device is the volume name # and the "mountpoint" is the drive letter... device = disk["volumename"].to_s.downcase mount = disk["deviceid"] property[:kb_size] = disk["size"] ? disk["size"].to_i / 1000 : 0 property[:kb_available] = disk["freespace"].to_i / 1000 property[:kb_used] = property[:kb_size] - property[:kb_available] property[:percent_used] = (property[:kb_size] == 0 ? 0 : (property[:kb_used] * 100 / property[:kb_size])) property[:mount] = mount property[:fs_type] = disk["filesystem"].to_s.downcase property[:drive_type] = disk["drivetype"].to_i property[:drive_type_string] = DRIVE_TYPE[disk["drivetype"].to_i] property[:drive_type_human] = disk["description"].to_s property[:volume_name] = disk["volumename"].to_s property[:device] = device key = "#{device},#{mount}" properties[key] = property end properties end # Refines and calculates encryption properties out of given instances # # @param [WmiLite::Wmi::Instance] disks # # @return [Mash] Each drive containing following properties: # # * :encryption_status (String) # def encryption_properties(disks) properties = Mash.new disks.each do |disk| property = Mash.new property[:encryption_status] = disk["conversionstatus"] ? CONVERSION_STATUS[disk["conversionstatus"]] : "" key = disk["driveletter"] properties[key] = property end properties end # Merges all the various properties of filesystems # # @param [Array] disks_info # Array of the Mashes containing disk properties # # @return [Mash] # def merge_info(logical_info, encryption_info) fs = Mash.new encryption_keys_used = Set.new logical_info.each do |key, info| if encryption_info[info["mount"]] encryption_keys_used.add(info["mount"]) fs[key] = info.merge(encryption_info[info["mount"]]) else fs[key] = info.dup end end left_enc = encryption_info.reject { |x| encryption_keys_used.include?(x) } left_enc.each do |key, info| fs[",#{key}"] = info end fs end collect_data(:linux) do fs = Mash.new # Grab filesystem data from df run_with_check("df") do so = shell_out("df -P") fs.merge!(parse_common_df(so.stdout)) # Grab filesystem inode data from df so = shell_out("df -iP") so.stdout.each_line do |line| case line when /^Filesystem\s+Inodes/ next when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ key = "#{$1},#{$6}" fs[key] ||= Mash.new fs[key][:device] = $1 fs[key][:total_inodes] = $2 fs[key][:inodes_used] = $3 fs[key][:inodes_available] = $4 fs[key][:inodes_percent_used] = $5 fs[key][:mount] = $6 end end end # Grab mount information from /bin/mount run_with_check("mount") do so = shell_out("mount") so.stdout.each_line do |line| if line =~ /^(.+?) on (.+?) type (.+?) \((.+?)\)$/ key = "#{$1},#{$2}" fs[key] ||= Mash.new fs[key][:device] = $1 fs[key][:mount] = $2 fs[key][:fs_type] = $3 fs[key][:mount_options] = $4.split(",") end end end # We used to try to decide if we wanted to run lsblk or blkid # but they each have a variety of cases were they fail to report # data. For example, there are a variety of cases where lsblk won't # report unmounted filesystems, but blkid will. And vise-versa. Sweet. # So for reliability, we'll run both, if we have them. lsblk = which("lsblk") blkid = which("blkid") cmds = [] # These should be in order of preference... first writer wins. if lsblk cmds << "#{lsblk} -n -P -o NAME,UUID,LABEL,FSTYPE" end if blkid cmds << blkid end cmds.each do |cmd| cmdtype = File.basename(cmd.split.first) # setting the timeout here for `lsblk` and `blkid` commands to 60 # this is to allow machines with large amounts of attached LUNs # to respond back to the command successfully run_with_check(cmdtype) do so = shell_out(cmd, timeout: 60) so.stdout.each_line do |line| parsed = parse_line(line, cmdtype) next if parsed.nil? # lsblk lists each device once, so we need to update all entries # in the hash that are related to this device keys_to_update = [] fs.each_key do |key| keys_to_update << key if key.start_with?("#{parsed[:dev]},") end if keys_to_update.empty? key = "#{parsed[:dev]}," fs[key] = Mash.new fs[key][:device] = parsed[:dev] keys_to_update << key end keys_to_update.each do |k| %i{fs_type uuid label}.each do |subkey| if parsed[subkey] && !parsed[subkey].empty? fs[k][subkey] = parsed[subkey] end end end end end end # Grab any missing mount information from /proc/mounts if File.exist?("/proc/mounts") mounts = "" # Due to https://tickets.opscode.com/browse/OHAI-196 # we have to non-block read dev files. Ew. f = File.open("/proc/mounts") loop do data = f.read_nonblock(4096) mounts << data # We should just catch EOFError, but the kernel had a period of # bugginess with reading virtual files, so we're being extra # cautious here, catching all exceptions, and then we'll read # whatever data we might have rescue Exception break end f.close mounts.each_line do |line| if line =~ /^(\S+) (\S+) (\S+) (\S+) \S+ \S+$/ key = "#{$1},#{$2}" next if fs.key?(key) fs[key] = Mash.new fs[key][:device] = $1 fs[key][:mount] = $2 fs[key][:fs_type] = $3 fs[key][:mount_options] = $4.split(",") end end end by_pair = fs by_device = generate_device_view(fs) by_mountpoint = generate_mountpoint_view(fs) fs_data = Mash.new fs_data["by_device"] = by_device fs_data["by_mountpoint"] = by_mountpoint fs_data["by_pair"] = by_pair # Set the filesystem data filesystem fs_data end collect_data(:freebsd, :openbsd, :netbsd, :dragonflybsd) do fs = Mash.new # Grab filesystem data from df run_with_check("df") do so = shell_out("df") fs.merge!(parse_common_df(so.stdout)) so = shell_out("df -iP") so.stdout.lines do |line| case line when /^Filesystem/ # skip the header next when /^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\%\s+(\d+)\s+(\d+)\s+(\d+)%\s+(\S+)$/ key = "#{$1},#{$9}" fs[key] ||= Mash.new fs[key][:device] = $1 fs[key][:inodes_used] = $6 fs[key][:inodes_available] = $7 fs[key][:total_inodes] = ($6.to_i + $7.to_i).to_s fs[key][:inodes_percent_used] = $8 fs[key][:mount] = $9 end end end # Grab mount information from mount run_with_check("mount") do so = shell_out("mount -l") so.stdout.lines do |line| if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ key = "#{$1},#{$2}" fs[key] ||= Mash.new fs[key][:device] = $1 fs[key][:mount] = $2 fs[key][:fs_type] = $3 fs[key][:mount_options] = $4.split(/,\s*/) end end end # create views by_pair = fs by_device = generate_device_view(fs) by_mountpoint = generate_mountpoint_view(fs) fs_data = Mash.new fs_data["by_device"] = by_device fs_data["by_mountpoint"] = by_mountpoint fs_data["by_pair"] = by_pair # @todo in Chef 17 the filesystem2 part of this goes away filesystem fs_data filesystem2 fs_data end collect_data(:darwin) do fs = Mash.new block_size = 0 # on new versions of OSX, -i is default, on old versions it's not, so # specifying it gets consistent output run_with_check("df") do so = shell_out("df -i") so.stdout.each_line do |line| case line when /^Filesystem\s+(\d+)-/ block_size = $1.to_i next when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(\d+)\s+(\d+)\s+(\d+%)\s+(.+)$/ key = "#{$1},#{$9}" fs[key] = Mash.new fs[key][:block_size] = block_size fs[key][:device] = $1 fs[key][:kb_size] = ($2.to_i / (1024 / block_size)).to_s fs[key][:kb_used] = ($3.to_i / (1024 / block_size)).to_s fs[key][:kb_available] = ($4.to_i / (1024 / block_size)).to_s fs[key][:percent_used] = $5 fs[key][:inodes_used] = $6 fs[key][:inodes_available] = $7 fs[key][:total_inodes] = ($6.to_i + $7.to_i).to_s fs[key][:inodes_percent_used] = $8 fs[key][:mount] = $9 end end end run_with_check("mount") do so = shell_out("mount") so.stdout.lines do |line| if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ key = "#{$1},#{$2}" fs[key] ||= Mash.new fs[key][:mount] = $2 fs[key][:fs_type] = $3 fs[key][:mount_options] = $4.split(/,\s*/) end end end by_pair = fs by_device = generate_device_view(fs) by_mountpoint = generate_mountpoint_view(fs) fs_data = Mash.new fs_data["by_device"] = by_device fs_data["by_mountpoint"] = by_mountpoint fs_data["by_pair"] = by_pair filesystem fs_data end collect_data(:solaris2) do fs = Mash.new # Grab filesystem data from df run_with_check("df") do so = shell_out("df -Pka") fs.merge!(parse_common_df(so.stdout)) # Grab file system type from df (must be done separately) so = shell_out("df -na") so.stdout.lines do |line| next unless line =~ /^(.+?)\s*: (\S+)\s*$/ mount = $1 fs.each do |key, fs_attributes| next unless fs_attributes[:mount] == mount fs[key][:fs_type] = $2 end end end # Grab mount information from /bin/mount run_with_check("mount") do so = shell_out("mount") so.stdout.lines do |line| next unless line =~ /^(.+?) on (.+?) (.+?) on (.+?)$/ key = "#{$2},#{$1}" fs[key] ||= Mash.new fs[key][:mount] = $1 fs[key][:mount_time] = $4 # $4 must come before "split", else it becomes nil fs[key][:mount_options] = $3.split("/") end end # Grab any zfs data from "zfs get" zfs = Mash.new zfs_get = "zfs get -p -H all" run_with_check("zfs") do so = shell_out(zfs_get) so.stdout.lines do |line| next unless line =~ /^([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)$/ filesystem = $1 property = $2 value = $3 source = $4.chomp zfs[filesystem] ||= Mash.new # if this fs doesn't exist, put in the bare minimum zfs[filesystem][property] = { value: value, source: source, } end end zfs.each do |fsname, attributes| mountpoint = attributes[:mountpoint][:value] if attributes[:mountpoint] key = "#{fsname},#{mountpoint}" fs[key] ||= Mash.new fs[key][:fs_type] = "zfs" fs[key][:mount] = mountpoint if mountpoint fs[key][:device] = fsname fs[key][:zfs_properties] = attributes # find all zfs parents parents = fsname.split("/") zfs_parents = [] (0..parents.length - 1).to_a.each do |parent_index| next_parent = parents[0..parent_index].join("/") zfs_parents.push(next_parent) end zfs_parents.pop fs[key][:zfs_parents] = zfs_parents fs[key][:zfs_zpool] = (zfs_parents.length == 0) end # create views by_pair = fs by_device = generate_device_view(fs) by_mountpoint = generate_mountpoint_view(fs) fs_data = Mash.new fs_data["by_device"] = by_device fs_data["by_mountpoint"] = by_mountpoint fs_data["by_pair"] = by_pair # @todo in Chef 17 the filesystem2 plugin goes away filesystem fs_data filesystem2 fs_data end collect_data(:aix) do def parse_df_or_mount(shell_out) oldie = Mash.new shell_out.lines.each do |line| fields = line.split case line # headers and horizontal rules to skip when /^\s*(node|---|^Filesystem\s+1024-blocks)/ next # strictly a df entry when /^(.+?)\s+([0-9-]+)\s+([0-9-]+)\s+([0-9-]+)\s+([0-9-]+\%*)\s+(.+)$/ if $1 == "Global" dev = "#{$1}:#{$6}" else dev = $1 end mountpoint = $6 key = "#{dev},#{mountpoint}" oldie[key] ||= Mash.new oldie[key][:kb_size] = $2 oldie[key][:kb_used] = $3 oldie[key][:kb_available] = $4 oldie[key][:percent_used] = $5 oldie[key][:mount] = mountpoint oldie[key][:device] = dev # an entry starting with 'G' or / (E.G. /tmp or /var) when %r{^\s*(G.*?|/\w)} if fields[0] == "Global" dev = fields[0] + ":" + fields[1] else dev = fields[0] end mountpoint = fields[1] key = "#{dev},#{mountpoint}" oldie[key] ||= Mash.new oldie[key][:mount] = mountpoint oldie[key][:fs_type] = fields[2] oldie[key][:mount_options] = fields[6].split(",") oldie[key][:device] = dev # entries occupying the 'Node' column parsed here else dev = fields[0] + ":" + fields[1] mountpoint = fields[2] key = "#{dev},#{mountpoint}" oldie[key] ||= Mash.new oldie[key][:mount] = mountpoint oldie[key][:device] = dev oldie[key][:fs_type] = fields[3] oldie[key][:mount_options] = fields[7].split(",") end end oldie end def collect_old_version(shell_outs) mount_hash = parse_df_or_mount shell_outs[:mount] df_hash = parse_df_or_mount shell_outs[:df_Pk] mount_hash.each do |key, hash| df_hash[key].merge!(hash) if df_hash.key?(key) end mount_hash.merge(df_hash) end # Cache the command output shell_outs = Mash.new run_with_check("mount") do shell_outs[:mount] = shell_out("mount").stdout end run_with_check("df") do shell_outs[:df_Pk] = shell_out("df -Pk").stdout end fs = collect_old_version(shell_outs) by_pair = fs by_device = generate_device_view(fs) by_mountpoint = generate_mountpoint_view(fs) fs_data = Mash.new fs_data["by_device"] = by_device fs_data["by_mountpoint"] = by_mountpoint fs_data["by_pair"] = by_pair # @todo in Chef 17 the filesystem2 plugin goes away here filesystem fs_data filesystem2 fs_data end collect_data(:windows) do require "wmi-lite/wmi" require_relative "../mash" fs = merge_info(logical_info, encryptable_info) by_pair = fs by_device = generate_device_view(fs) by_mountpoint = generate_mountpoint_view(fs) fs_data = Mash.new fs_data["by_device"] = by_device fs_data["by_mountpoint"] = by_mountpoint fs_data["by_pair"] = by_pair # Set the filesystem data - Windows didn't do the conversion when everyone # else did, so 15 will have both be the new API and 16 will drop the old API filesystem generate_deprecated_windows_view(fs) filesystem2 fs_data end end ohai-16.0.7/lib/ohai/plugins/freebsd/000077500000000000000000000000001362624620500173145ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/freebsd/memory.rb000066400000000000000000000045471362624620500211630ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory", "memory/swap" collect_data(:freebsd) do memory Mash.new memory[:swap] = Mash.new # /usr/src/sys/sys/vmmeter.h so = shell_out("sysctl -n vm.stats.vm.v_page_size") memory[:page_size] = so.stdout.split($/)[0] so = shell_out("sysctl -n vm.stats.vm.v_page_count") memory[:page_count] = so.stdout.split($/)[0] memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i so = shell_out("sysctl -n vm.stats.vm.v_free_count") memory[:free] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.status.vm.v_active_count") memory[:active] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.status.vm.v_inactive_count") memory[:inactive] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.stats.vm.v_cache_count") memory[:cache] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vm.stats.vm.v_wire_count") memory[:wired] = memory[:page_size].to_i * so.stdout.split($/)[0].to_i so = shell_out("sysctl -n vfs.bufspace") memory[:buffers] = so.stdout.split($/)[0] so = shell_out("swapinfo") so.stdout.lines do |line| # Device 1K-blocks Used Avail Capacity # /dev/ad0s1b 253648 0 253648 0% if line =~ %r{^([\d\w/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)} mdev = $1 memory[:swap][mdev] = Mash.new memory[:swap][mdev][:total] = $2 memory[:swap][mdev][:used] = $3 memory[:swap][mdev][:free] = $4 memory[:swap][mdev][:percent_free] = $5 end end end end ohai-16.0.7/lib/ohai/plugins/freebsd/network.rb000066400000000000000000000113341362624620500213340ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" collect_data(:freebsd) do network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new so = shell_out("route -n get default") so.stdout.lines do |line| if line =~ /(\w+): ([\w\.]+)/ case $1 when "gateway" network[:default_gateway] = $2 when "interface" network[:default_interface] = $2 end end end iface = Mash.new so = shell_out("#{Ohai.abs_path( "/sbin/ifconfig" )} -a") cint = nil so.stdout.lines do |line| if line =~ /^([0-9a-zA-Z\.]+):\s+/ cint = $1 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end end # call the family lladdr to match linux for consistency if line =~ /\s+ether (.+?)\s/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } end if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ iface[cint][:addresses] ||= Mash.new # convert the netmask to decimal for consistency netmask = "#{$2[2, 2].hex}.#{$2[4, 2].hex}.#{$2[6, 2].hex}.#{$2[8, 2].hex}" if $3.empty? iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } else # found a broadcast address iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } end end if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ iface[cint][:addresses] ||= Mash.new if $4.empty? iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } else # found a zone_id / scope iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } end end if line =~ /flags=\d+<(.+)>/ flags = $1.split(",") iface[cint][:flags] = flags if flags.length > 0 end if line =~ /metric: (\d+) mtu: (\d+)/ iface[cint][:metric] = $1 iface[cint][:mtu] = $2 end end so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ next unless iface[$3] # this should never happen iface[$3][:arp] ||= Mash.new iface[$3][:arp][$1] = $2.downcase end end network["interfaces"] = iface net_counters = Mash.new # From netstat(1), not sure of the implications: # Show the state of all network interfaces or a single interface # which have been auto-configured (interfaces statically configured # into a system, but not located at boot time are not shown). so = shell_out("netstat -ibdn") so.stdout.lines do |line| # Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop # ed0 1500 54:52:00:68:92:85 333604 26 151905886 175472 0 24897542 0 905 # $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 if line =~ /^([\w\.\*]+)\s+\d+\s+\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ net_counters[$1] ||= Mash.new net_counters[$1]["rx"] ||= Mash.new net_counters[$1]["tx"] ||= Mash.new net_counters[$1]["rx"]["packets"] = $3 net_counters[$1]["rx"]["errors"] = $4 net_counters[$1]["rx"]["bytes"] = $5 net_counters[$1]["tx"]["packets"] = $6 net_counters[$1]["tx"]["errors"] = $7 net_counters[$1]["tx"]["bytes"] = $8 net_counters[$1]["tx"]["collisions"] = $9 net_counters[$1]["tx"]["dropped"] = $10 end end counters[:network][:interfaces] = net_counters end end ohai-16.0.7/lib/ohai/plugins/freebsd/platform.rb000066400000000000000000000017411362624620500214700ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" collect_data(:freebsd) do so = shell_out("uname -s") platform so.stdout.split($/)[0].downcase so = shell_out("uname -r") platform_version so.stdout.split($/)[0] platform_family "freebsd" end end ohai-16.0.7/lib/ohai/plugins/gce.rb000066400000000000000000000052601362624620500167700ustar00rootroot00000000000000# # Author:: Ranjib Dey () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:GCE) do require_relative "../mixin/gce_metadata" require_relative "../mixin/http_helper" include Ohai::Mixin::GCEMetadata include Ohai::Mixin::HttpHelper provides "gce" # look for GCE string in dmi vendor bios data within the sys tree. # this works even if the system lacks dmidecode use by the Dmi plugin # @return [Boolean] do we have Google Compute Engine DMI data? def has_gce_dmi? if file_val_if_exists("/sys/class/dmi/id/product_name") =~ /Google Compute Engine/ logger.trace("Plugin GCE: has_gce_dmi? == true") true else logger.trace("Plugin GCE: has_gce_dmi? == false") false end end # return the contents of a file if the file exists # @param path[String] abs path to the file # @return [String] contents of the file if it exists def file_val_if_exists(path) if ::File.exist?(path) ::File.read(path) end end # looks at the Manufacturer and Model WMI values to see if they starts with Google. # @return [Boolean] Are the manufacturer and model Google? def has_gce_system_info? if RUBY_PLATFORM =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new computer_system = wmi.first_of("Win32_ComputerSystem") if computer_system["Manufacturer"] =~ /^Google/ && computer_system["Model"] =~ /^Google/ logger.trace("Plugin GCE: has_gce_system_info? == true") true end else logger.trace("Plugin GCE: has_gce_system_info? == false") false end end # Identifies gce # # === Return # true:: If gce can be identified # false:: Otherwise def looks_like_gce? return true if hint?("gce") if has_gce_dmi? || has_gce_system_info? return true if can_socket_connect?(Ohai::Mixin::GCEMetadata::GCE_METADATA_ADDR, 80) end end collect_data do if looks_like_gce? logger.trace("Plugin GCE: looks_like_gce? == true") gce Mash.new fetch_metadata.each { |k, v| gce[k] = v } else logger.trace("Plugin GCE: looks_like_gce? == false") false end end end ohai-16.0.7/lib/ohai/plugins/go.rb000066400000000000000000000020611362624620500166330ustar00rootroot00000000000000# Author:: Christian Vozar () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Go) do provides "languages/go" depends "languages" collect_data do so = shell_out("go version") # Sample output: # go version go1.6.1 darwin/amd64 if so.exitstatus == 0 && so.stdout =~ /go(\S+)/ go = Mash.new go[:version] = $1 languages[:go] = go end rescue Ohai::Exceptions::Exec logger.trace('Plugin Go: Could not shell_out "go version". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/groovy.rb000066400000000000000000000023251362624620500175560ustar00rootroot00000000000000# # Author:: Doug MacEachern # Copyright:: Copyright (c) 2009 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Groovy) do provides "languages/groovy" depends "languages" collect_data do so = shell_out("groovy -v") # Sample output: # Groovy Version: 2.4.6 JVM: 1.8.0_60 Vendor: Oracle Corporation OS: Mac OS X if so.exitstatus == 0 && so.stdout =~ /Groovy Version: (\S+).*JVM: (\S+)/ groovy = Mash.new groovy[:version] = $1 groovy[:jvm] = $2 languages[:groovy] = groovy end rescue Ohai::Exceptions::Exec logger.trace('Plugin Groovy: Could not shell_out "groovy -v". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/haskell.rb000066400000000000000000000060271362624620500176570ustar00rootroot00000000000000# Author:: Chris Dituri () # Copyright:: Copyright (c) 2016 Chris Dituri # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Haskell) do provides "languages/haskell", "languages/haskell/ghc", "languages/haskell/ghci", "languages/haskell/cabal", "languages/haskell/stack" depends "languages" collect_data(:default) do haskell = Mash.new # Check for ghc begin so = shell_out("ghc --version") # Sample output: # The Glorious Glasgow Haskell Compilation System, version 7.6.3 if so.exitstatus == 0 haskell[:ghc] = Mash.new haskell[:ghc][:version] = so.stdout.split[-1] haskell[:ghc][:description] = so.stdout.chomp end rescue Ohai::Exceptions::Exec logger.trace('Plugin Haskell: Could not shell_out "ghc --version". Skipping data') end # Check for ghci begin so = shell_out("ghci --version") # Sample output: # The Glorious Glasgow Haskell Compilation System, version 7.6.3 if so.exitstatus == 0 haskell[:ghci] = Mash.new haskell[:ghci][:version] = so.stdout.split[-1] haskell[:ghci][:description] = so.stdout.chomp end rescue Ohai::Exceptions::Exec logger.trace('Plugin Haskell: Could not shell_out "ghci --version". Skipping data') end # Check for cabal begin so = shell_out("cabal --version") # Sample output: # cabal-install version 1.16.0.2 # using version 1.16.0 of the Cabal library if so.exitstatus == 0 haskell[:cabal] = Mash.new haskell[:cabal][:version] = so.stdout.split("\n")[0].split[-1] haskell[:cabal][:description] = so.stdout.split("\n")[0].chomp end rescue Ohai::Exceptions::Exec logger.trace('Plugin Haskell: Could not shell_out "cabal --version". Skipping data') end # Check for stack begin so = shell_out("stack --version") # Sample output: # Version 1.1.0, Git revision 0e9430aad55841b5ff2c6c2851f0548c16bce7cf (3540 commits) x86_64 hpack-0.13.0 # or # Version 1.2.0 x86_64 hpack-0.14.0 if so.exitstatus == 0 haskell[:stack] = Mash.new haskell[:stack][:version] = /Version ([^\s,]*)/.match(so.stdout)[1] rescue nil haskell[:stack][:description] = so.stdout.chomp end rescue Ohai::Exceptions::Exec logger.trace('Plugin Haskell: Could not shell_out "stack --version". Skipping data') end languages[:haskell] = haskell unless haskell.empty? end end ohai-16.0.7/lib/ohai/plugins/hostname.rb000066400000000000000000000126031362624620500200470ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Benjamin Black () # Author:: Bryan McLellan () # Author:: Daniel DeLeo () # Author:: Doug MacEachern () # Author:: James Gartrell () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2008-2018, Chef Software Inc. # Copyright:: Copyright (c) 2009 Bryan McLellan # Copyright:: Copyright (c) 2009 Daniel DeLeo # Copyright:: Copyright (c) 2010 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Hostname) do require "socket" unless defined?(Socket) require "ipaddr" provides "domain", "hostname", "fqdn", "machinename" # hostname : short hostname # machinename : output of hostname command (might be short on solaris) # fqdn : result of canonicalizing hostname using DNS or /etc/hosts # domain : domain part of FQDN # # hostname and machinename should always exist # fqdn and domain may be broken if DNS is broken on the host def from_cmd(cmd) so = shell_out(cmd) so.stdout.split($/)[0] end # forward and reverse lookup to canonicalize FQDN (hostname -f equivalent) # this is ipv6-safe, works on ruby 1.8.7+ def resolve_fqdn hostname = from_cmd("hostname") addrinfo = Socket.getaddrinfo(hostname, nil).first iaddr = IPAddr.new(addrinfo[3]) Socket.gethostbyaddr(iaddr.hton)[0] rescue nil end def collect_domain # Domain is everything after the first dot if fqdn fqdn =~ /.+?\.(.*)/ domain $1 end end def collect_hostname # Hostname is everything before the first dot if machinename machinename =~ /([^.]+)\.?/ hostname $1 elsif fqdn fqdn =~ /(.+?)\./ hostname $1 end end collect_data(:default) do machinename from_cmd("hostname") fqdn resolve_fqdn collect_hostname collect_domain end collect_data(:aix) do machinename from_cmd("hostname -s") fqdn resolve_fqdn || from_cmd("hostname") collect_hostname collect_domain end collect_data(:netbsd, :openbsd, :dragonflybsd) do hostname from_cmd("hostname -s") fqdn resolve_fqdn machinename from_cmd("hostname") collect_domain end collect_data(:darwin) do hostname from_cmd("hostname -s") machinename from_cmd("hostname") begin ourfqdn = resolve_fqdn # Sometimes... very rarely, but sometimes, 'hostname --fqdn' falsely # returns a blank string. WTF. if ourfqdn.nil? || ourfqdn.empty? logger.trace("Plugin Hostname: hostname returned an empty string, retrying once.") ourfqdn = resolve_fqdn end if ourfqdn.nil? || ourfqdn.empty? logger.trace("Plugin Hostname: hostname returned an empty string twice and will" + "not be set.") else fqdn ourfqdn end rescue logger.trace( "Plugin Hostname: hostname returned an error, probably no domain set" ) end domain collect_domain end collect_data(:freebsd) do hostname from_cmd("hostname -s") machinename from_cmd("hostname") fqdn from_cmd("hostname -f") collect_domain end collect_data(:linux) do hostname from_cmd("hostname -s") machinename from_cmd("hostname") begin ourfqdn = from_cmd("hostname --fqdn") # Sometimes... very rarely, but sometimes, 'hostname --fqdn' falsely # returns a blank string. WTF. if ourfqdn.nil? || ourfqdn.empty? logger.trace("Plugin Hostname: hostname --fqdn returned an empty string, retrying " + "once.") ourfqdn = from_cmd("hostname --fqdn") end if ourfqdn.nil? || ourfqdn.empty? logger.trace("Plugin Hostname: hostname --fqdn returned an empty string twice and " + "will not be set.") else fqdn ourfqdn end rescue logger.trace("Plugin Hostname: hostname --fqdn returned an error, probably no domain set") end domain collect_domain end collect_data(:solaris2) do machinename from_cmd("hostname") hostname from_cmd("hostname") fqdn resolve_fqdn domain collect_domain end collect_data(:windows) do require "wmi-lite/wmi" require "socket" unless defined?(Socket) wmi = WmiLite::Wmi.new host = wmi.first_of("Win32_ComputerSystem") hostname host["dnshostname"].to_s machinename host["name"].to_s info = Socket.gethostbyname(Socket.gethostname) if info.first =~ /.+?\.(.*)/ fqdn info.first else # host is not in dns. optionally use: # C:\WINDOWS\system32\drivers\etc\hosts info[3..info.length].reverse_each do |addr| hostent = Socket.gethostbyaddr(addr) if hostent.first =~ /.+?\.(.*)/ fqdn hostent.first break end end fqdn info.first unless fqdn end domain collect_domain end end ohai-16.0.7/lib/ohai/plugins/init_package.rb000066400000000000000000000015651362624620500206540ustar00rootroot00000000000000# # Author:: Caleb Tennis () # Copyright:: Copyright (c) 2012-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:InitPackage) do provides "init_package" collect_data(:linux) do init_package File.exist?("/proc/1/comm") ? File.open("/proc/1/comm").gets.chomp : "init" end end ohai-16.0.7/lib/ohai/plugins/java.rb000066400000000000000000000051311362624620500171500ustar00rootroot00000000000000# # Author:: Benjamin Black () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Java) do provides "languages/java" depends "languages" def get_java_info so = shell_out("java -mx64m -version") # Sample output: # java version "1.8.0_60" # Java(TM) SE Runtime Environment (build 1.8.0_60-b27) # Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode) if so.exitstatus == 0 java = Mash.new so.stderr.split(/\r?\n/).each do |line| case line when /(?:java|openjdk) version \"([0-9\.\_]+)\"/ java[:version] = $1 when /^(.+Runtime Environment.*) \((build)\s*(.+)\)$/ java[:runtime] = { "name" => $1, "build" => $3 } when /^(.+ (Client|Server) VM) \(build\s*(.+)\)$/ java[:hotspot] = { "name" => $1, "build" => $3 } end end languages[:java] = java unless java.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Java: Could not shell_out "java -mx64m -version". Skipping plugin') end # On Mac OS X, the development tools include "stubs" for JVM executables that # prompt the user to install the JVM if they desire. In our case we simply # wish to detect if the JVM is there and do not want to trigger a popup # window. As a workaround, we can run the java_home executable and check its # exit status to determine if the `java` executable is the real one or the OS # X stub. In the terminal, it looks like this: # # $ /usr/libexec/java_home # Unable to find any JVMs matching version "(null)". # No Java runtime present, try --request to install. # # $ echo $? # 1 # # This check always returns true when not on darwin because it is just a # workaround for this particular annoyance. def has_real_java? return true unless on_darwin? shell_out("/usr/libexec/java_home").status.success? end def on_darwin? RUBY_PLATFORM.downcase.include?("darwin") end collect_data do get_java_info if has_real_java? end end ohai-16.0.7/lib/ohai/plugins/joyent.rb000066400000000000000000000037211362624620500175420ustar00rootroot00000000000000# # Author: sawanoboriyu@higanworks.com # Copyright (C) 2014 HiganWorks LLC # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Reference from: sm-summary command Ohai.plugin(:Joyent) do provides "joyent" provides "virtualization/guest_id" depends "os", "platform", "virtualization" def collect_product_file data = ::File.read("/etc/product") rescue nil if data data.strip.split("\n") else [] end end def collect_pkgsrc data = ::File.read("/opt/local/etc/pkg_install.conf") rescue nil if data /PKG_PATH=(.*)/.match(data)[1] rescue nil end end def is_smartos? platform == "smartos" end collect_data do if is_smartos? joyent Mash.new # copy uuid joyent[:sm_uuid] = virtualization[:guest_uuid] # get zone id unless globalzone unless joyent[:sm_uuid] == "global" joyent[:sm_id] = virtualization[:guest_id] end # retrieve image name and pkgsrc collect_product_file.each do |line| case line when /^Image/ sm_image = line.split(" ") joyent[:sm_image_id] = sm_image[1] joyent[:sm_image_ver] = sm_image[2] when /^Base Image/ sm_baseimage = line.split(" ") joyent[:sm_baseimage_id] = sm_baseimage[2] joyent[:sm_baseimage_ver] = sm_baseimage[3] end end ## retrieve pkgsrc joyent[:sm_pkgsrc] = collect_pkgsrc end end end ohai-16.0.7/lib/ohai/plugins/kernel.rb000066400000000000000000000226061362624620500175150ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Benjamin Black () # Author:: Bryan McLellan () # Author:: Claire McQuin () # Author:: James Gartrell () # Copyright:: Copyright (c) 2008-2018 Chef Software, Inc. # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Kernel) do provides "kernel", "kernel/modules" # common initial kernel attribute values # @return [Mash] basic kernel properties from uname def init_kernel kernel Mash.new [["uname -s", :name], ["uname -r", :release], ["uname -v", :version], ["uname -m", :machine], ["uname -p", :processor]].each do |cmd, property| so = shell_out(cmd) kernel[property] = so.stdout.split($/)[0] end kernel end # common *bsd code for collecting modules data # @return [Mash] def bsd_modules(path) modules = Mash.new so = shell_out((Ohai.abs_path(path)).to_s) so.stdout.lines do |line| # 1 7 0xc0400000 97f830 kernel if line =~ /(\d+)\s+(\d+)\s+([0-9a-fx]+)\s+([0-9a-fx]+)\s+([a-zA-Z0-9\_]+)/ modules[$5] = { size: $4, refcount: $2 } end end modules end # given the OperatingSystemSKU value from WMI's Win32_OperatingSystem class # https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx # return if we're on a Server Core installation # @param [String] sku OperatingSystemSKU value from Win32_OperatingSystem # @return [boolean] def server_core?(sku) return true if [ 12, # Server Datacenter Core 39, # Server Datacenter without Hyper-V Core 14, # Server Enterprise Core 41, # Server Enterprise without Hyper-V Core 13, # Server Standard Core 40, # Server Standard without Hyper-V Core 63, # Small Business Server Premium Core 53, # Server Solutions Premium Core 46, # Storage Server Enterprise Core 43, # Storage Server Express Core 44, # Storage Server Standard Core 45, # Storage Server Workgroup Core 29, # Web Server Core ].include?(sku) false end # given the SystemType value from WMI's Win32_ComputerSystem class # https://msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx # return the architecture type # @param [String] sys_type SystemType value from Win32_ComputerSystem # @return [String] x86_64 or i386 def arch_lookup(sys_type) return "x86_64" if sys_type == "x64-based PC" return "i386" if sys_type == "X86-based PC" sys_type end # given the ProductType value from WMI's Win32_OperatingSystem class # https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx # return either workstation or server # @param [Integer] type ProductType value from Win32_OperatingSystem # @return [String] Workstation or Server def product_type_decode(type) return "Workstation" if type == 1 "Server" end # decode the OSType field from WMI Win32_OperatingSystem class # https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx # @param [Integer] sys_type OSType value from Win32_OperatingSystem # @return [String] the human consumable OS type value def os_type_decode(sys_type) case sys_type when 18 then "WINNT" # most likely so first when 0 then "Unknown" when 1 then "Other" when 14 then "MSDOS" when 15 then "WIN3x" when 16 then "WIN95" when 17 then "WIN98" when 19 then "WINCE" else nil end end # decode the PCSystemType field from WMI Win32_OperatingSystem class # https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx # @param [Integer] type the integer value from PCSystemType # @return [String] the human consumable OS type value def pc_system_type_decode(type) case type when 4 then "Enterprise Server" # most likely so first when 0 then "Unspecified" when 1 then "Desktop" when 2 then "Mobile" when 3 then "Workstation" when 5 then "SOHO Server" when 6 then "Appliance PC" when 7 then "Performance Server" when 8 then "Maximum" else nil end end # see if a WMI name is blacklisted so we can avoid writing out # useless data to ohai # @param [String] name the wmi name to check # @return [Boolean] is the wmi name blacklisted def blacklisted_wmi_name?(name) [ "creation_class_name", # this is just the wmi name "cs_creation_class_name", # this is just the wmi name "oem_logo_bitmap", # this is the entire OEM bitmap file "total_swap_space_size", # already in memory plugin "total_virtual_memory_size", # already in memory plugin "total_virtual_memory_size", # already in memory plugin "free_physical_memory", # already in memory plugin "free_space_in_paging_files", # already in memory plugin "free_virtual_memory", # already in memory plugin ].include?(name) end collect_data(:default) do kernel init_kernel end collect_data(:darwin) do kernel init_kernel kernel[:os] = kernel[:name] so = shell_out("sysctl -n hw.optional.x86_64") if so.stdout.split($/)[0].to_i == 1 kernel[:machine] = "x86_64" end modules = Mash.new so = shell_out("kextstat -k -l") so.stdout.lines do |line| if line =~ /(\d+)\s+(\d+)\s+0x[0-9a-f]+\s+0x([0-9a-f]+)\s+0x[0-9a-f]+\s+([a-zA-Z0-9\.]+) \(([0-9\.]+)\)/ modules[$4] = { version: $5, size: $3.hex, index: $1, refcount: $2 } end end kernel[:modules] = modules end collect_data(:freebsd, :dragonflybsd) do kernel init_kernel kernel[:os] = kernel[:name] so = shell_out("uname -i") kernel[:ident] = so.stdout.split($/)[0] so = shell_out("sysctl kern.securelevel") kernel[:securelevel] = so.stdout.split($/).select { |e| e =~ /kern.securelevel: (.+)$/ } kernel[:modules] = bsd_modules("/sbin/kldstat") end collect_data(:linux) do kernel init_kernel so = shell_out("uname -o") kernel[:os] = so.stdout.split($/)[0] modules = Mash.new so = shell_out("env lsmod") so.stdout.lines do |line| if line =~ /([a-zA-Z0-9\_]+)\s+(\d+)\s+(\d+)/ modules[$1] = { size: $2, refcount: $3 } # Making sure to get the module version that has been loaded if File.exist?("/sys/module/#{$1}/version") version = File.read("/sys/module/#{$1}/version").chomp.strip modules[$1]["version"] = version unless version.empty? end end end kernel[:modules] = modules end collect_data(:netbsd, :openbsd) do kernel init_kernel kernel[:os] = kernel[:name] so = shell_out("sysctl kern.securelevel") kernel[:securelevel] = so.stdout.split($/).select { |e| e =~ /kern.securelevel:\ (.+)$/ } kernel[:modules] = bsd_modules("/usr/bin/modstat") end collect_data(:solaris2) do kernel init_kernel so = shell_out("uname -s") kernel[:os] = so.stdout.split($/)[0] so = File.open("/etc/release", &:gets) md = /(?\d.*\d)/.match(so) kernel[:update] = md[:update] if md modules = Mash.new so = shell_out("modinfo") # EXAMPLE: # Id Loadaddr Size Info Rev Module Name # 6 1180000 4623 1 1 specfs (filesystem for specfs) module_description = /[\s]*([\d]+)[\s]+([a-f\d]+)[\s]+([a-f\d]+)[\s]+(?:[\-\d]+)[\s]+(?:[\d]+)[\s]+([\S]+)[\s]+\((.+)\)$/ so.stdout.lines do |line| if ( mod = module_description.match(line) ) modules[mod[4]] = { id: mod[1].to_i, loadaddr: mod[2], size: mod[3].to_i(16), description: mod[5] } end end kernel[:modules] = modules end collect_data(:windows) do require "win32ole" unless defined?(WIN32OLE) require "wmi-lite/wmi" WIN32OLE.codepage = WIN32OLE::CP_UTF8 wmi = WmiLite::Wmi.new kernel Mash.new host = wmi.first_of("Win32_OperatingSystem") kernel[:os_info] = Mash.new host.wmi_ole_object.properties_.each do |p| next if blacklisted_wmi_name?(p.name.wmi_underscore) kernel[:os_info][p.name.wmi_underscore.to_sym] = host[p.name.downcase] end kernel[:name] = (kernel[:os_info][:caption]).to_s kernel[:release] = (kernel[:os_info][:version]).to_s kernel[:version] = "#{kernel[:os_info][:version]} #{kernel[:os_info][:csd_version]} Build #{kernel[:os_info][:build_number]}" kernel[:os] = os_type_decode(kernel[:os_info][:os_type]) || languages[:ruby][:host_os] kernel[:product_type] = product_type_decode(kernel[:os_info][:product_type]) kernel[:server_core] = server_core?(kernel[:os_info][:operating_system_sku]) kernel[:cs_info] = Mash.new host = wmi.first_of("Win32_ComputerSystem") host.wmi_ole_object.properties_.each do |p| next if blacklisted_wmi_name?(p.name.wmi_underscore) kernel[:cs_info][p.name.wmi_underscore.to_sym] = host[p.name.downcase] end kernel[:machine] = arch_lookup((kernel[:cs_info][:system_type]).to_s) kernel[:system_type] = pc_system_type_decode(kernel[:cs_info][:pc_system_type]) end end ohai-16.0.7/lib/ohai/plugins/keys.rb000066400000000000000000000013271362624620500172050ustar00rootroot00000000000000# # Cookbook Name:: apache2 # Recipe:: default # # Copyright 2008-2016 Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Keys) do provides "keys" collect_data do keys Mash.new end end ohai-16.0.7/lib/ohai/plugins/languages.rb000066400000000000000000000014261362624620500202000ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Languages) do provides "languages" collect_data do languages Mash.new end end ohai-16.0.7/lib/ohai/plugins/libvirt.rb000066400000000000000000000075341362624620500177130ustar00rootroot00000000000000# # Author:: Benjamin Black () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Note: This plugin requires libvirt-bin/libvirt-dev as well as the ruby-libvirt # gem to be installed before it will properly parse data Ohai.plugin(:Libvirt) do %w{ uri capabilities nodeinfo domains networks storage }.each do |info| provides "libvirt/#{info}" depends "virtualization" end def emu @emu ||= (virtualization[:system].eql?("kvm") ? "qemu" : virtualization[:system]) end def load_libvirt require "libvirt" # this is the ruby-libvirt gem not the libvirt gem logger.trace("Plugin Libvirt: Successfully loaded ruby-libvirt gem") rescue LoadError logger.trace("Plugin Libvirt: Can't load gem ruby-libvirt.") end def virtconn @virt_connect ||= Libvirt.open_read_only("#{emu}:///system") end def get_node_data node_data = Mash.new ni = virtconn.node_get_info %w{cores cpus memory mhz model nodes sockets threads}.each { |a| node_data[a] = ni.send(a) } node_data end def get_domain_data domain_data = Mash.new virtconn.list_domains.each do |d| dv = virtconn.lookup_domain_by_id d domain_data[dv.name] = Mash.new domain_data[dv.name][:id] = d %w{os_type uuid}.each { |a| domain_data[dv.name][a] = dv.send(a) } %w{cpu_time max_mem memory nr_virt_cpu state}.each { |a| domain_data[dv.name][a] = dv.info.send(a) } end domain_data end def get_network_data network_data = Mash.new virtconn.list_networks.each do |n| nv = virtconn.lookup_network_by_name n network_data[n] = Mash.new %w{bridge_name uuid}.each { |a| network_data[n][a] = nv.send(a) } end network_data end def get_storage_data storage_data = Mash.new virtconn.list_storage_pools.each do |pool| sp = virtconn.lookup_storage_pool_by_name pool storage_data[pool] = Mash.new %w{autostart uuid}.each { |a| storage_data[pool][a] = sp.send(a) } %w{allocation available capacity state}.each { |a| storage_data[pool][a] = sp.info.send(a) } storage_data[pool][:volumes] = Mash.new sp.list_volumes.each do |v| storage_data[pool][:volumes][v] = Mash.new sv = sp.lookup_volume_by_name v %w{key name path}.each { |a| storage_data[pool][:volumes][v][a] = sv.send(a) } %w{allocation capacity type}.each { |a| storage_data[pool][:volumes][v][a] = sv.info.send(a) } end end storage_data end collect_data do if virtualization[:role].eql?("host") load_libvirt begin libvirt_data = Mash.new libvirt_data[:uri] = virtconn.uri libvirt_data[:libvirt_version] = Libvirt.version(emu)[0].to_s libvirt_data[:nodeinfo] = get_node_data libvirt_data[:domains] = get_domain_data libvirt_data[:networks] = get_network_data libvirt_data[:storage] = get_storage_data virtconn.close libvirt libvirt_data rescue NameError logger.trace("Plugin Libvirt: Cannot load ruby-libvirt gem. Skipping...") rescue Libvirt::ConnectionError logger.trace("Plugin Libvirt: Failed to connect to #{emu}:///system. Skipping...") end else logger.trace("Plugin Libvirt: Node is not a virtualization host. Skipping...") end end end ohai-16.0.7/lib/ohai/plugins/linode.rb000066400000000000000000000036211362624620500175030ustar00rootroot00000000000000# # Author:: Aaron Kalin () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Linode) do provides "linode" depends "kernel" depends "network/interfaces" # Checks for matching linode kernel name # # Returns true or false def has_linode_kernel? if ( kernel_data = kernel ) kernel_data[:release].split("-").last =~ /linode/ end end # Identifies the linode cloud by preferring the hint, then # # Returns true or false def looks_like_linode? hint?("linode") || has_linode_kernel? end # Names linode ip address # # name - symbol of ohai name (e.g. :public_ip) # eth - Interface name (e.g. :eth0) # # Alters linode mash with new interface based on name parameter def get_ip_address(name, eth) if ( eth_iface = network[:interfaces][eth] ) eth_iface[:addresses].each do |key, info| linode[name] = key if info["family"] == "inet" end end end collect_data do # Setup linode mash if it is a linode system if looks_like_linode? logger.trace("Plugin Linode: looks_like_linode? == true") linode Mash.new get_ip_address(:public_ip, :eth0) get_ip_address(:private_ip, "eth0:1") hint?("linode").each { |k, v| linode[k] = v } if hint?("linode").is_a?(Hash) else logger.trace("Plugin Linode: looks_like_linode? == false") end end end ohai-16.0.7/lib/ohai/plugins/linux/000077500000000000000000000000001362624620500170415ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/linux/block_device.rb000066400000000000000000000034011362624620500217750ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:BlockDevice) do provides "block_device" collect_data(:linux) do if File.exist?("/sys/block") block = Mash.new Dir["/sys/block/*"].each do |block_device_dir| dir = File.basename(block_device_dir) block[dir] = Mash.new %w{size removable}.each do |check| if File.exist?("/sys/block/#{dir}/#{check}") File.open("/sys/block/#{dir}/#{check}") { |f| block[dir][check] = f.read_nonblock(1024).strip } end end %w{model rev state timeout vendor queue_depth}.each do |check| if File.exist?("/sys/block/#{dir}/device/#{check}") File.open("/sys/block/#{dir}/device/#{check}") { |f| block[dir][check] = f.read_nonblock(1024).strip } end end %w{rotational physical_block_size logical_block_size}.each do |check| if File.exist?("/sys/block/#{dir}/queue/#{check}") File.open("/sys/block/#{dir}/queue/#{check}") { |f| block[dir][check] = f.read_nonblock(1024).strip } end end end block_device block end end end ohai-16.0.7/lib/ohai/plugins/linux/fips.rb000066400000000000000000000024751362624620500203370ustar00rootroot00000000000000# # Author:: Matt Wrock () # Copyright:: Copyright (c) 2016-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # After long discussion in IRC the "powers that be" have come to a concensus # that there is no other Windows platforms exist that were not based on the # Windows_NT kernel, so we herby decree that "windows" will refer to all # platforms built upon the Windows_NT kernel and have access to win32 or win64 # subsystems. Ohai.plugin(:Fips) do provides "fips" collect_data(:linux) do fips Mash.new require "openssl" unless defined?(OpenSSL) if defined?(OpenSSL.fips_mode) && OpenSSL.fips_mode && !$FIPS_TEST_MODE fips["kernel"] = { "enabled" => true } else fips["kernel"] = { "enabled" => false } end end end ohai-16.0.7/lib/ohai/plugins/linux/hostnamectl.rb000066400000000000000000000021431362624620500217070ustar00rootroot00000000000000# # Author:: Davide Cavalca () # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Hostnamectl) do provides "hostnamectl" collect_data(:linux) do hostnamectl Mash.new unless hostnamectl hostnamectl_path = which("hostnamectl") if hostnamectl_path hostnamectl_cmd = shell_out(hostnamectl_path) hostnamectl_cmd.stdout.split("\n").each do |line| key, val = line.split(":") hostnamectl[key.chomp.lstrip.tr(" ", "_").downcase] = val.chomp.lstrip end end end end ohai-16.0.7/lib/ohai/plugins/linux/lsb.rb000066400000000000000000000035751362624620500201600ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:LSB) do provides "lsb" collect_data(:linux) do lsb Mash.new if File.exist?("/usr/bin/lsb_release") # From package redhat-lsb on Fedora/Redhat, lsb-release on Debian/Ubuntu so = shell_out("lsb_release -a") so.stdout.lines do |line| case line when /^Distributor ID:\s+(.+)$/ lsb[:id] = $1 when /^Description:\s+(.+)$/ lsb[:description] = $1 when /^Release:\s+(.+)$/ lsb[:release] = $1 when /^Codename:\s+(.+)$/ lsb[:codename] = $1 else lsb[:id] = line end end elsif File.exist?("/etc/lsb-release") # Old, non-standard Debian support File.open("/etc/lsb-release").each do |line| case line when /^DISTRIB_ID=["']?(.+?)["']?$/ lsb[:id] = $1 when /^DISTRIB_RELEASE=["']?(.+?)["']?$/ lsb[:release] = $1 when /^DISTRIB_CODENAME=["']?(.+?)["']?$/ lsb[:codename] = $1 when /^DISTRIB_DESCRIPTION=["']?(.+?)["']?$/ lsb[:description] = $1 end end else logger.trace("Plugin LSB: Skipping LSB, cannot find /etc/lsb-release or /usr/bin/lsb_release") end end end ohai-16.0.7/lib/ohai/plugins/linux/lspci.rb000066400000000000000000000046031362624620500205030ustar00rootroot00000000000000# # Author:: Joerg Herzinger # Author:: Phil Dibowitz # Copyright:: Copyright (c) 2011 GLOBAL 2000/Friends of the Earth Austria # Copyright:: Copyright (c) 2017 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Lspci) do depends "platform" provides "pci" optional true collect_data(:linux) do devices = Mash.new lspci = shell_out("lspci -vnnmk") h = /[0-9a-fA-F]/ # any hex digit hh = /#{h}#{h}/ # any 2 hex digits hhhh = /#{h}#{h}#{h}#{h}/ # any 4 hex digits d_id = "" # This identifies our pci devices def standard_form(devices, d_id, hhhh, tag, line) tmp = line.scan(/(.*)\s\[(#{hhhh})\]/)[0] devices[d_id]["#{tag}_name"] = tmp[0] devices[d_id]["#{tag}_id"] = tmp[1] end def standard_array(devices, d_id, tag, line) if !devices[d_id][tag].is_a?(Array) devices[d_id][tag] = [line] else devices[d_id][tag].push(line) end end lspci.stdout.split("\n").each do |line| dev = line.scan(/^(.*):\s(.*)$/)[0] next if dev.nil? case dev[0] when "Device" # There are two different Device tags if ( tmp = dev[1].match(/(#{hh}:#{hh}.#{h})/) ) # We have a device id d_id = tmp[0] # From now on we will need this id devices[d_id] = Mash.new else standard_form(devices, d_id, hhhh, "device", dev[1]) end when "Class" standard_form(devices, d_id, hhhh, "class", dev[1]) when "Vendor" standard_form(devices, d_id, hhhh, "vendor", dev[1]) when "Driver" standard_array(devices, d_id, "driver", dev[1]) when "Module" standard_array(devices, d_id, "module", dev[1]) when "SDevice" standard_form(devices, d_id, hhhh, "sdevice", dev[1]) end end pci devices end end ohai-16.0.7/lib/ohai/plugins/linux/machineid.rb000066400000000000000000000020061362624620500213050ustar00rootroot00000000000000# # Author:: Davide Cavalca () # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Machineid) do provides "machine_id" collect_data(:linux) do mid = nil if ::File.exist?("/etc/machine-id") mid = ::File.read("/etc/machine-id").chomp elsif ::File.exist?("/var/lib/dbus/machine-id") mid = ::File.read("/var/lib/dbus/machine-id").chomp end if mid machine_id mid end end end ohai-16.0.7/lib/ohai/plugins/linux/mdadm.rb000066400000000000000000000105261362624620500204540ustar00rootroot00000000000000# # Author:: Tim Smith # Author:: Phil Dibowitz # Copyright:: Copyright (c) 2013-2014, Limelight Networks, Inc. # Copyright:: Copyright (c) 2017 Facebook, Inc. # Plugin:: mdadm # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Mdadm) do provides "mdadm" def create_raid_device_mash(stdout) device_mash = Mash.new device_mash[:device_counts] = Mash.new stdout.lines.each do |line| case line when /Version\s+: ([0-9.]+)/ device_mash[:version] = Regexp.last_match[1].to_f when /Raid Level\s+: raid([0-9]+)/ device_mash[:level] = Regexp.last_match[1].to_i when /Array Size.*\(([0-9.]+)/ device_mash[:size] = Regexp.last_match[1].to_f when /State\s+: ([a-z]+)/ device_mash[:state] = Regexp.last_match[1] when /Total Devices\s+: ([0-9]+)/ device_mash[:device_counts][:total] = Regexp.last_match[1].to_i when /Raid Devices\s+: ([0-9]+)/ device_mash[:device_counts][:raid] = Regexp.last_match[1].to_i when /Working Devices\s+: ([0-9]+)/ device_mash[:device_counts][:working] = Regexp.last_match[1].to_i when /Failed Devices\s+: ([0-9]+)/ device_mash[:device_counts][:failed] = Regexp.last_match[1].to_i when /Active Devices\s+: ([0-9]+)/ device_mash[:device_counts][:active] = Regexp.last_match[1].to_i when /Spare Devices\s+: ([0-9]+)/ device_mash[:device_counts][:spare] = Regexp.last_match[1].to_i end end device_mash end collect_data(:linux) do # gather a list of all raid arrays if File.exist?("/proc/mdstat") devices = {} File.open("/proc/mdstat").each do |line| if line =~ /(md[0-9]+)/ device = Regexp.last_match[1] pieces = line.split(/\s+/) # there are variable numbers of fields until you hit the raid level # everything after that is members... # unless the array is inactive, in which case you don't get a raid # level. members = pieces.drop_while { |x| !x.start_with?("raid", "inactive") } # and drop that too members.shift unless members.empty? devices[device] = { "active" => [], "spare" => [], "journal" => nil, } members.each do |member| # We want to match the device, and optionally the type # most entries will look like: # sdc1[5] # but some will look like: # sdc1[5](J) # where the format is: # []() # Type can be things like "J" for a journal device, or "S" for # a spare device. m = member.match(/(.+)\[\d+\](?:\((\w)\))?/) member_device = m[1] member_type = m[2] case member_type when "J" devices[device]["journal"] = member_device when "S" devices[device]["spare"] << member_device else devices[device]["active"] << member_device end end end end # create the mdadm mash and gather individual information if devices are present unless devices.empty? mdadm Mash.new devices.keys.sort.each do |device| mdadm[device] = Mash.new # gather detailed information on the array so = shell_out("mdadm --detail /dev/#{device}") # if the mdadm command was sucessful pass so.stdout to create_raid_device_mash to grab the tidbits we want mdadm[device] = create_raid_device_mash(so.stdout) if so.stdout mdadm[device]["members"] = devices[device]["active"] mdadm[device]["spares"] = devices[device]["spare"] mdadm[device]["journal"] = devices[device]["journal"] end end end end end ohai-16.0.7/lib/ohai/plugins/linux/memory.rb000066400000000000000000000075551362624620500207120ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory", "memory/swap" collect_data(:linux) do memory Mash.new memory[:swap] = Mash.new memory[:hugepages] = Mash.new memory[:directmap] = Mash.new File.open("/proc/meminfo").each do |line| case line when /^MemTotal:\s+(\d+) (.+)$/ memory[:total] = "#{$1}#{$2}" when /^MemFree:\s+(\d+) (.+)$/ memory[:free] = "#{$1}#{$2}" when /^MemAvailable:\s+(\d+) (.+)$/ memory[:available] = "#{$1}#{$2}" when /^Buffers:\s+(\d+) (.+)$/ memory[:buffers] = "#{$1}#{$2}" when /^Cached:\s+(\d+) (.+)$/ memory[:cached] = "#{$1}#{$2}" when /^Active:\s+(\d+) (.+)$/ memory[:active] = "#{$1}#{$2}" when /^Inactive:\s+(\d+) (.+)$/ memory[:inactive] = "#{$1}#{$2}" when /^HighTotal:\s+(\d+) (.+)$/ memory[:high_total] = "#{$1}#{$2}" when /^HighFree:\s+(\d+) (.+)$/ memory[:high_free] = "#{$1}#{$2}" when /^LowTotal:\s+(\d+) (.+)$/ memory[:low_total] = "#{$1}#{$2}" when /^LowFree:\s+(\d+) (.+)$/ memory[:low_free] = "#{$1}#{$2}" when /^Dirty:\s+(\d+) (.+)$/ memory[:dirty] = "#{$1}#{$2}" when /^Writeback:\s+(\d+) (.+)$/ memory[:writeback] = "#{$1}#{$2}" when /^AnonPages:\s+(\d+) (.+)$/ memory[:anon_pages] = "#{$1}#{$2}" when /^Mapped:\s+(\d+) (.+)$/ memory[:mapped] = "#{$1}#{$2}" when /^Slab:\s+(\d+) (.+)$/ memory[:slab] = "#{$1}#{$2}" when /^SReclaimable:\s+(\d+) (.+)$/ memory[:slab_reclaimable] = "#{$1}#{$2}" when /^SUnreclaim:\s+(\d+) (.+)$/ memory[:slab_unreclaim] = "#{$1}#{$2}" when /^PageTables:\s+(\d+) (.+)$/ memory[:page_tables] = "#{$1}#{$2}" when /^NFS_Unstable:\s+(\d+) (.+)$/ memory[:nfs_unstable] = "#{$1}#{$2}" when /^Bounce:\s+(\d+) (.+)$/ memory[:bounce] = "#{$1}#{$2}" when /^CommitLimit:\s+(\d+) (.+)$/ memory[:commit_limit] = "#{$1}#{$2}" when /^Committed_AS:\s+(\d+) (.+)$/ memory[:committed_as] = "#{$1}#{$2}" when /^VmallocTotal:\s+(\d+) (.+)$/ memory[:vmalloc_total] = "#{$1}#{$2}" when /^VmallocUsed:\s+(\d+) (.+)$/ memory[:vmalloc_used] = "#{$1}#{$2}" when /^VmallocChunk:\s+(\d+) (.+)$/ memory[:vmalloc_chunk] = "#{$1}#{$2}" when /^SwapCached:\s+(\d+) (.+)$/ memory[:swap][:cached] = "#{$1}#{$2}" when /^SwapTotal:\s+(\d+) (.+)$/ memory[:swap][:total] = "#{$1}#{$2}" when /^SwapFree:\s+(\d+) (.+)$/ memory[:swap][:free] = "#{$1}#{$2}" when /^HugePages_Total:\s+(\d+)$/ memory[:hugepages][:total] = $1.to_s when /^HugePages_Free:\s+(\d+)$/ memory[:hugepages][:free] = $1.to_s when /^HugePages_Rsvd:\s+(\d+)$/ memory[:hugepages][:reserved] = $1.to_s when /^HugePages_Surp:\s+(\d+)$/ memory[:hugepages][:surplus] = $1.to_s when /^Hugepagesize:\s+(\d+) (.+)$/ memory[:hugepage_size] = "#{$1}#{$2}" when /^Hugetlb:\s+(\d+) (.+)$/ memory[:hugetlb] = "#{$1}#{$2}" when /^DirectMap([0-9]+[a-zA-Z]):\s+(\d+) (.+)$/ memory[:directmap][$1.to_sym] = "#{$2}#{$3}" end end end end ohai-16.0.7/lib/ohai/plugins/linux/network.rb000066400000000000000000000610311362624620500210600ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Chris Read # Copyright:: Copyright (c) 2008-2017, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" provides "ipaddress", "ip6address", "macaddress" def linux_encaps_lookup(encap) return "Loopback" if encap.eql?("Local Loopback") || encap.eql?("loopback") return "PPP" if encap.eql?("Point-to-Point Protocol") return "SLIP" if encap.eql?("Serial Line IP") return "VJSLIP" if encap.eql?("VJ Serial Line IP") return "IPIP" if encap.eql?("IPIP Tunnel") return "6to4" if encap.eql?("IPv6-in-IPv4") return "Ethernet" if encap.eql?("ether") encap end def ipv6_enabled? File.exist? "/proc/net/if_inet6" end def ethtool_binary_path @ethtool ||= which("ethtool") end def is_openvz? @openvz ||= ::File.directory?("/proc/vz") end def is_openvz_host? is_openvz? && ::File.directory?("/proc/bc") end def extract_neighbors(family, iface, neigh_attr) so = shell_out("ip -f #{family[:name]} neigh show") so.stdout.lines do |line| if line =~ /^([a-f0-9\:\.]+)\s+dev\s+([^\s]+)\s+lladdr\s+([a-fA-F0-9\:]+)/ interface = iface[$2] unless interface logger.warn("neighbor list has entries for unknown interface #{interface}") next end interface[neigh_attr] ||= Mash.new interface[neigh_attr][$1] = $3.downcase end end iface end # checking the routing tables # why ? # 1) to set the default gateway and default interfaces attributes # 2) on some occasions, the best way to select node[:ipaddress] is to look at # the routing table source field. # 3) and since we're at it, let's populate some :routes attributes # (going to do that for both inet and inet6 addresses) def check_routing_table(family, iface, default_route_table) so = shell_out("ip -o -f #{family[:name]} route show table #{default_route_table}") so.stdout.lines do |line| line.strip! logger.trace("Plugin Network: Parsing #{line}") if line =~ /\\/ parts = line.split('\\') route_dest = parts.shift.strip route_endings = parts elsif line =~ /^([^\s]+)\s(.*)$/ route_dest = $1 route_endings = [$2] else next end route_endings.each do |route_ending| if route_ending =~ /\bdev\s+([^\s]+)\b/ route_int = $1 else logger.trace("Plugin Network: Skipping route entry without a device: '#{line}'") next end route_int = "venet0:0" if is_openvz? && !is_openvz_host? && route_int == "venet0" && iface["venet0:0"] unless iface[route_int] logger.trace("Plugin Network: Skipping previously unseen interface from 'ip route show': #{route_int}") next end route_entry = Mash.new(destination: route_dest, family: family[:name]) %w{via scope metric proto src}.each do |k| # http://rubular.com/r/pwTNp65VFf route_entry[k] = $1 if route_ending =~ /\b#{k}\s+([^\s]+)/ end # a sanity check, especially for Linux-VServer, OpenVZ and LXC: # don't report the route entry if the src address isn't set on the node # unless the interface has no addresses of this type at all if route_entry[:src] addr = iface[route_int][:addresses] unless addr.nil? || addr.key?(route_entry[:src]) || addr.values.all? { |a| a["family"] != family[:name] } logger.trace("Plugin Network: Skipping route entry whose src does not match the interface IP") next end end iface[route_int][:routes] = [] unless iface[route_int][:routes] iface[route_int][:routes] << route_entry end end iface end # now looking at the routes to set the default attributes # for information, default routes can be of this form : # - default via 10.0.2.4 dev br0 # - default dev br0 scope link # - default dev eth0 scope link src 1.1.1.1 # - default via 10.0.3.1 dev eth1 src 10.0.3.2 metric 10 # - default via 10.0.4.1 dev eth2 src 10.0.4.2 metric 20 # using a temporary var to hold routes and their interface name def parse_routes(family, iface) iface.collect do |i, iv| if iv[:routes] iv[:routes].collect do |r| r.merge(dev: i) if r[:family] == family[:name] end.compact end end.compact.flatten end # determine layer 1 details for the interface using ethtool def ethernet_layer_one(iface) return iface unless ethtool_binary_path keys = %w{ Speed Duplex Port Transceiver Auto-negotiation MDI-X } iface.each_key do |tmp_int| next unless iface[tmp_int][:encapsulation] == "Ethernet" so = shell_out("#{ethtool_binary_path} #{tmp_int}") so.stdout.lines do |line| line.chomp! logger.trace("Plugin Network: Parsing ethtool output: #{line}") line.lstrip! k, v = line.split(": ") next unless keys.include? k k.downcase!.tr!("-", "_") if k == "speed" k = "link_speed" # This is not necessarily the maximum speed the NIC supports v = v[/\d+/].to_i end iface[tmp_int][k] = v end end iface end # determine ring parameters for the interface using ethtool def ethernet_ring_parameters(iface) return iface unless ethtool_binary_path iface.each_key do |tmp_int| next unless iface[tmp_int][:encapsulation] == "Ethernet" so = shell_out("#{ethtool_binary_path} -g #{tmp_int}") logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}") type = nil iface[tmp_int]["ring_params"] = {} so.stdout.lines.each do |line| next if line.start_with?("Ring parameters for") next if line.strip.nil? if line =~ /Pre-set maximums/ type = "max" next end if line =~ /Current hardware settings/ type = "current" next end key, val = line.split(/:\s+/) if type && val ring_key = "#{type}_#{key.downcase.tr(" ", "_")}" iface[tmp_int]["ring_params"][ring_key] = val.to_i end end end iface end # determine link stats, vlans, queue length, and state for an interface using ip def link_statistics(iface, net_counters) so = shell_out("ip -d -s link") tmp_int = nil on_rx = true so.stdout.lines do |line| if line =~ IPROUTE_INT_REGEX tmp_int = $2 iface[tmp_int] ||= Mash.new net_counters[tmp_int] ||= Mash.new end if line =~ /^\s+(ip6tnl|ipip)/ iface[tmp_int][:tunnel_info] = {} words = line.split words.each_with_index do |word, index| case word when "external" iface[tmp_int][:tunnel_info][word] = true when "any", "ipip6", "ip6ip6" iface[tmp_int][:tunnel_info][:proto] = word when "remote", "local", "encaplimit", "hoplimit", "tclass", "flowlabel", "addrgenmode", "numtxqueues", "numrxqueues", "gso_max_size", "gso_max_segs" iface[tmp_int][:tunnel_info][word] = words[index + 1] end end end if line =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ int = on_rx ? :rx : :tx net_counters[tmp_int][int] ||= Mash.new net_counters[tmp_int][int][:bytes] = $1 net_counters[tmp_int][int][:packets] = $2 net_counters[tmp_int][int][:errors] = $3 net_counters[tmp_int][int][:drop] = $4 if int == :rx net_counters[tmp_int][int][:overrun] = $5 else net_counters[tmp_int][int][:carrier] = $5 net_counters[tmp_int][int][:collisions] = $6 end on_rx = !on_rx end if line =~ /qlen (\d+)/ net_counters[tmp_int][:tx] ||= Mash.new net_counters[tmp_int][:tx][:queuelen] = $1 end if line =~ /vlan id (\d+)/ || line =~ /vlan protocol ([\w\.]+) id (\d+)/ if $2 tmp_prot = $1 tmp_id = $2 else tmp_id = $1 end iface[tmp_int][:vlan] ||= Mash.new iface[tmp_int][:vlan][:id] = tmp_id iface[tmp_int][:vlan][:protocol] = tmp_prot if tmp_prot vlan_flags = line.scan(/(REORDER_HDR|GVRP|LOOSE_BINDING)/) if vlan_flags.length > 0 iface[tmp_int][:vlan][:flags] = vlan_flags.flatten.uniq end end # https://rubular.com/r/JRp6lNANmpcLV5 if line =~ /\sstate (\w+)/ iface[tmp_int]["state"] = $1.downcase end end iface end def match_iproute(iface, line, cint) if line =~ IPROUTE_INT_REGEX cint = $2 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end if line =~ /mtu (\d+)/ iface[cint][:mtu] = $1 end flags = line.scan(/(UP|BROADCAST|DEBUG|LOOPBACK|POINTTOPOINT|NOTRAILERS|LOWER_UP|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC)/) if flags.length > 1 iface[cint][:flags] = flags.flatten.uniq end end cint end def parse_ip_addr(iface) so = shell_out("ip addr") cint = nil so.stdout.lines do |line| cint = match_iproute(iface, line, cint) parse_ip_addr_link_line(cint, iface, line) cint = parse_ip_addr_inet_line(cint, iface, line) parse_ip_addr_inet6_line(cint, iface, line) end end def parse_ip_addr_link_line(cint, iface, line) if line =~ %r{link/(\w+) ([\da-f\:]+) } iface[cint][:encapsulation] = linux_encaps_lookup($1) unless $2 == "00:00:00:00:00:00" iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$2.upcase] = { "family" => "lladdr" } end end end def parse_ip_addr_inet_line(cint, iface, line) if line =~ %r{inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(/(\d{1,2}))?} tmp_addr, tmp_prefix = $1, $3 tmp_prefix ||= "32" original_int = nil # Are we a formerly aliased interface? if line =~ /#{cint}:(\d+)$/ sub_int = $1 alias_int = "#{cint}:#{sub_int}" original_int = cint cint = alias_int end iface[cint] ||= Mash.new # Create the fake alias interface if needed iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][tmp_addr] = { "family" => "inet", "prefixlen" => tmp_prefix } iface[cint][:addresses][tmp_addr][:netmask] = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s if line =~ /peer (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses][tmp_addr][:peer] = $1 end if line =~ /brd (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses][tmp_addr][:broadcast] = $1 end if line =~ /scope (\w+)/ iface[cint][:addresses][tmp_addr][:scope] = ($1.eql?("host") ? "Node" : $1.capitalize) end # If we found we were an alias interface, restore cint to its original value cint = original_int unless original_int.nil? end cint end def parse_ip_addr_inet6_line(cint, iface, line) if line =~ %r{inet6 ([a-f0-9\:]+)/(\d+) scope (\w+)( .*)?} iface[cint][:addresses] ||= Mash.new tmp_addr = $1 tags = $4 || "" tags = tags.split(" ") iface[cint][:addresses][tmp_addr] = { "family" => "inet6", "prefixlen" => $2, "scope" => ($3.eql?("host") ? "Node" : $3.capitalize), "tags" => tags, } end end # returns the macaddress for interface from a hash of interfaces (iface elsewhere in this file) def get_mac_for_interface(interfaces, interface) interfaces[interface][:addresses].select { |k, v| v["family"] == "lladdr" }.first.first unless interfaces[interface][:addresses].nil? || interfaces[interface][:flags].include?("NOARP") end # returns the default route with the lowest metric (unspecified metric is 0) def choose_default_route(routes) routes.select do |r| r[:destination] == "default" end.min do |x, y| (x[:metric].nil? ? 0 : x[:metric].to_i) <=> (y[:metric].nil? ? 0 : y[:metric].to_i) end end def interface_has_no_addresses_in_family?(iface, family) return true if iface[:addresses].nil? iface[:addresses].values.all? { |addr| addr["family"] != family } end def interface_have_address?(iface, address) return false if iface[:addresses].nil? iface[:addresses].key?(address) end def interface_address_not_link_level?(iface, address) !(iface[:addresses][address][:scope].casecmp("link") == 0) end def interface_valid_for_route?(iface, address, family) return true if interface_has_no_addresses_in_family?(iface, family) interface_have_address?(iface, address) && interface_address_not_link_level?(iface, address) end def route_is_valid_default_route?(route, default_route) # if the route destination is a default route, it's good return true if route[:destination] == "default" # the default route has a gateway and the route matches the gateway !default_route[:via].nil? && IPAddress(route[:destination]).include?(IPAddress(default_route[:via])) end # ipv4/ipv6 routes are different enough that having a single algorithm to select the favored route for both creates unnecessary complexity # this method attempts to deduce the route that is most important to the user, which is later used to deduce the favored values for {ip,mac,ip6}address # we only consider routes that are default routes, or those routes that get us to the gateway for a default route def favored_default_route_linux(routes, iface, default_route, family) routes.select do |r| if family[:name] == "inet" # the route must have a source address next if r[:src].nil? || r[:src].empty? # the interface specified in the route must exist route_interface = iface[r[:dev]] next if route_interface.nil? # the interface specified in the route must exist # the interface must have no addresses, or if it has the source address, the address must not # be a link-level address next unless interface_valid_for_route?(route_interface, r[:src], "inet") # the route must either be a default route, or it must have a gateway which is accessible via the route next unless route_is_valid_default_route?(r, default_route) true elsif family[:name] == "inet6" iface[r[:dev]] && iface[r[:dev]][:state] == "up" && route_is_valid_default_route?(r, default_route) end end.min_by do |r| # sorting the selected routes: # - getting default routes first # - then sort by metric # - then by prefixlen [ r[:destination] == "default" ? 0 : 1, r[:metric].nil? ? 0 : r[:metric].to_i, # for some reason IPAddress doesn't accept "::/0", it doesn't like prefix==0 # just a quick workaround: use 0 if IPAddress fails begin IPAddress( r[:destination] == "default" ? family[:default_route] : r[:destination] ).prefix rescue 0 end, ] end end # Both the network plugin and this plugin (linux/network) are run on linux. This plugin runs first. # If the 'ip' binary is available, this plugin may set {ip,mac,ip6}address. The network plugin should not overwrite these. # The older code section below that relies on the deprecated net-tools, e.g. netstat and ifconfig, provides less functionality. collect_data(:linux) do require "ipaddr" iface = Mash.new net_counters = Mash.new network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new # ohai.plugin[:network][:default_route_table] = 'default' if configuration(:default_route_table).nil? || configuration(:default_route_table).empty? default_route_table = "main" else default_route_table = configuration(:default_route_table) end logger.trace("Plugin Network: default route table is '#{default_route_table}'") # Match the lead line for an interface from iproute2 # 3: eth0.11@eth0: mtu 1500 qdisc noqueue state UP # The '@eth0:' portion doesn't exist on primary interfaces and thus is optional in the regex IPROUTE_INT_REGEX ||= /^(\d+): ([0-9a-zA-Z@:\.\-_]*?)(@[0-9a-zA-Z]+|):\s/.freeze if which("ip") # families to get default routes from families = [{ name: "inet", default_route: "0.0.0.0/0", default_prefix: :default, neighbour_attribute: :arp, }] if ipv6_enabled? families << { name: "inet6", default_route: "::/0", default_prefix: :default_inet6, neighbour_attribute: :neighbour_inet6, } end parse_ip_addr(iface) iface = link_statistics(iface, net_counters) families.each do |family| neigh_attr = family[:neighbour_attribute] default_prefix = family[:default_prefix] iface = extract_neighbors(family, iface, neigh_attr) iface = check_routing_table(family, iface, default_route_table) routes = parse_routes(family, iface) default_route = choose_default_route(routes) if default_route.nil? || default_route.empty? attribute_name = if family[:name] == "inet" "default_interface" else "default_#{family[:name]}_interface" end logger.trace("Plugin Network: Unable to determine '#{attribute_name}' as no default routes were found for that interface family") else network["#{default_prefix}_interface"] = default_route[:dev] logger.trace("Plugin Network: #{default_prefix}_interface set to #{default_route[:dev]}") # setting gateway to 0.0.0.0 or :: if the default route is a link level one network["#{default_prefix}_gateway"] = default_route[:via] ? default_route[:via] : family[:default_route].chomp("/0") logger.trace("Plugin Network: #{default_prefix}_gateway set to #{network["#{default_prefix}_gateway"]}") # deduce the default route the user most likely cares about to pick {ip,mac,ip6}address below favored_route = favored_default_route_linux(routes, iface, default_route, family) # FIXME: This entire block should go away, and the network plugin should be the sole source of {ip,ip6,mac}address # since we're at it, let's populate {ip,mac,ip6}address with the best values # if we don't set these, the network plugin may set them afterwards if favored_route && !favored_route.empty? if family[:name] == "inet" ipaddress favored_route[:src] m = get_mac_for_interface(iface, favored_route[:dev]) logger.trace("Plugin Network: Overwriting macaddress #{macaddress} with #{m} from interface #{favored_route[:dev]}") if macaddress macaddress m elsif family[:name] == "inet6" # this rarely does anything since we rarely have src for ipv6, so this usually falls back on the network plugin ip6address favored_route[:src] if macaddress logger.trace("Plugin Network: Not setting macaddress from ipv6 interface #{favored_route[:dev]} because macaddress is already set") else macaddress get_mac_for_interface(iface, favored_route[:dev]) end end else logger.trace("Plugin Network: Unable to deduce the favored default route for family '#{family[:name]}' despite finding a default route, and is not setting ipaddress/ip6address/macaddress. the network plugin may provide fallbacks.") logger.trace("Plugin Network: This potential default route was excluded: #{default_route}") end end end # end families.each else # ip binary not available, falling back to net-tools, e.g. route, ifconfig begin so = shell_out("route -n") route_result = so.stdout.split($/).grep( /^0.0.0.0/ )[0].split( /[ \t]+/ ) network[:default_gateway], network[:default_interface] = route_result.values_at(1, 7) rescue Ohai::Exceptions::Exec logger.trace("Plugin Network: Unable to determine default interface") end so = shell_out("ifconfig -a") cint = nil so.stdout.lines do |line| tmp_addr = nil # dev_valid_name in the kernel only excludes slashes, nulls, spaces # http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=blob;f=net/core/dev.c#l851 if line =~ /^([0-9a-zA-Z@\.\:\-_]+)\s+/ cint = $1 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end end if line =~ /Link encap:(Local Loopback)/ || line =~ /Link encap:(.+?)\s/ iface[cint][:encapsulation] = linux_encaps_lookup($1) end if line =~ /HWaddr (.+?)\s/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } end if line =~ /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet" } tmp_addr = $1 end if line =~ %r{inet6 addr: ([a-f0-9\:]+)/(\d+) Scope:(\w+)} iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $2, "scope" => ($3.eql?("Host") ? "Node" : $3) } end if line =~ /Bcast:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses][tmp_addr]["broadcast"] = $1 end if line =~ /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses][tmp_addr]["netmask"] = $1 end flags = line.scan(/(UP|BROADCAST|DEBUG|LOOPBACK|POINTTOPOINT|NOTRAILERS|RUNNING|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC)\s/) if flags.length > 1 iface[cint][:flags] = flags.flatten end if line =~ /MTU:(\d+)/ iface[cint][:mtu] = $1 end if line =~ /P-t-P:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:peer] = $1 end if line =~ /RX packets:(\d+) errors:(\d+) dropped:(\d+) overruns:(\d+) frame:(\d+)/ net_counters[cint] ||= Mash.new net_counters[cint][:rx] = { "packets" => $1, "errors" => $2, "drop" => $3, "overrun" => $4, "frame" => $5 } end if line =~ /TX packets:(\d+) errors:(\d+) dropped:(\d+) overruns:(\d+) carrier:(\d+)/ net_counters[cint][:tx] = { "packets" => $1, "errors" => $2, "drop" => $3, "overrun" => $4, "carrier" => $5 } end if line =~ /collisions:(\d+)/ net_counters[cint][:tx]["collisions"] = $1 end if line =~ /txqueuelen:(\d+)/ net_counters[cint][:tx]["queuelen"] = $1 end if line =~ /RX bytes:(\d+) \((\d+?\.\d+ .+?)\)/ net_counters[cint][:rx]["bytes"] = $1 end if line =~ /TX bytes:(\d+) \((\d+?\.\d+ .+?)\)/ net_counters[cint][:tx]["bytes"] = $1 end end so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /^\S+ \((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) \[(\w+)\] on ([0-9a-zA-Z\.\:\-]+)/ next unless iface[$4] # this should never happen iface[$4][:arp] ||= Mash.new iface[$4][:arp][$1] = $2.downcase end end end # end "ip else net-tools" block iface = ethernet_layer_one(iface) iface = ethernet_ring_parameters(iface) counters[:network][:interfaces] = net_counters network["interfaces"] = iface end end ohai-16.0.7/lib/ohai/plugins/linux/platform.rb000066400000000000000000000275361362624620500212270ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2015-2017, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" depends "lsb" # the platform mappings between the 'ID' field in /etc/os-release and the value # ohai uses. If you're adding a new platform here and you want to change the name # you'll want to add it here and then add a spec for the platform_id_remap method PLATFORM_MAPPINGS ||= { "rhel" => "redhat", "amzn" => "amazon", "ol" => "oracle", "sles" => "suse", "sles_sap" => "suse", "opensuse-leap" => "opensuseleap", "xenenterprise" => "xenserver", "cumulus-linux" => "cumulus", "archarm" => "arch", }.freeze # @deprecated def get_redhatish_platform(contents) contents[/^Red Hat/i] ? "redhat" : contents[/(\w+)/i, 1].downcase end # See https://rubular.com/r/78c1yXYa7zDhdV for example matches # # @param contents [String] the contents of /etc/redhat-release # # @returns [String] the version string # def get_redhatish_version(contents) contents[/(release)? ([\d\.]+)/, 2] end # # Reads an os-release-info file and parse it into a hash # # @param file [String] the filename to read (e.g. '/etc/os-release') # # @returns [Hash] the file parsed into a Hash or nil # def read_os_release_info(file) return nil unless File.exist?(file) File.read(file).split.inject({}) do |map, line| key, value = line.split("=") map[key] = value.gsub(/\A"|"\Z/, "") if value map end end # # Cached /etc/os-release info Hash. Also has logic for Cisco Nexus # switches that pulls the chained CISCO_RELEASE_INFO file into the Hash (other # distros can also reuse this method safely). # # @returns [Hash] the canonical, cached Hash of /etc/os-release info or nil # def os_release_info @os_release_info ||= begin os_release_info = read_os_release_info("/etc/os-release") cisco_release_info = os_release_info["CISCO_RELEASE_INFO"] if os_release_info if cisco_release_info && File.exist?(cisco_release_info) os_release_info.merge!(read_os_release_info(cisco_release_info)) end os_release_info end end # # If /etc/os-release indicates we are Cisco based # # @returns [Boolean] if we are Cisco according to /etc/os-release # def os_release_file_is_cisco? File.exist?("/etc/os-release") && os_release_info["CISCO_RELEASE_INFO"] end # # Determines the platform version for F5 Big-IP systems # # @deprecated # # @returns [String] bigip Linux version from /etc/f5-release # def bigip_version release_contents = File.read("/etc/f5-release") release_contents.match(/BIG-IP release (\S*)/)[1] # http://rubular.com/r/O8nlrBVqSb rescue NoMethodError, Errno::ENOENT, Errno::EACCES # rescue regex failure, file missing, or permission denied logger.warn("Detected F5 Big-IP, but /etc/f5-release could not be parsed to determine platform_version") nil end # our platform names don't match os-release. given a time machine they would but ohai # came before the os-release file. This method remaps the os-release names to # the ohai names # # @param id [String] the platform ID from /etc/os-release # # @returns [String] the platform name to use in Ohai # def platform_id_remap(id) # this catches the centos guest shell in the nexus switch which identifies itself as centos return "nexus_centos" if id == "centos" && os_release_file_is_cisco? # remap based on the hash of platforms PLATFORM_MAPPINGS[id] || id end # # Determines the platform_family based on the platform # # @param plat [String] the platform name # # @returns [String] platform_family value # def platform_family_from_platform(plat) case plat when /debian/, /ubuntu/, /linuxmint/, /raspbian/, /cumulus/, /kali/ # apt-get+dpkg almost certainly goes here "debian" when /oracle/, /centos/, /redhat/, /scientific/, /enterpriseenterprise/, /xcp/, /xenserver/, /cloudlinux/, /ibm_powerkvm/, /parallels/, /nexus_centos/, /clearos/, /bigip/ # Note that 'enterpriseenterprise' is oracle's LSB "distributor ID" # NOTE: "rhel" should be reserved exclusively for recompiled rhel versions that are nearly perfectly compatible down to the platform_version. # The operating systems that are "rhel" should all be as compatible as rhel7 = centos7 = oracle7 = scientific7 (98%-ish core RPM version compatibility # and the version numbers MUST track the upstream). The appropriate EPEL version repo should work nearly perfectly. Some variation like the # oracle kernel version differences and tuning and extra packages are clearly acceptable. Almost certainly some distros above (xenserver?) # should not be in this list. Please use fedora, below, instead. Also note that this is the only platform_family with this strict of a rule, # see the example of the debian platform family for how the rest of the platform_family designations should be used. "rhel" when /amazon/ "amazon" when /suse/, /sles/, /opensuse/, /opensuseleap/, /sled/ "suse" when /fedora/, /pidora/, /arista_eos/ # In the broadest sense: RPM-based, fedora-derived distributions which are not strictly re-compiled RHEL (if it uses RPMs, and smells more like redhat and less like # SuSE it probably goes here). "fedora" when /nexus/, /ios_xr/ "wrlinux" when /gentoo/ "gentoo" when /slackware/ "slackware" when /arch/, /manjaro/, /antergos/ "arch" when /exherbo/ "exherbo" when /alpine/ "alpine" when /clearlinux/ "clearlinux" when /mangeia/ "mandriva" end end # modern linux distros include a /etc/os-release file, which we now rely on for # OS detection. For older distros that do not include that file we fall back to # our pre-Ohai 15 detection logic, which is the method below. No new functionality # should be added to this logic. # # @deprecated def legacy_platform_detection # platform [ and platform_version ? ] should be lower case to avoid dealing with RedHat/Redhat/redhat matching if File.exist?("/etc/oracle-release") contents = File.read("/etc/oracle-release").chomp platform "oracle" platform_version get_redhatish_version(contents) elsif File.exist?("/etc/enterprise-release") contents = File.read("/etc/enterprise-release").chomp platform "oracle" platform_version get_redhatish_version(contents) elsif File.exist?("/etc/f5-release") platform "bigip" platform_version bigip_version elsif File.exist?("/etc/debian_version") # Ubuntu and Debian both have /etc/debian_version # Ubuntu should always have a working lsb, debian does not by default if lsb[:id] =~ /Ubuntu/i platform "ubuntu" platform_version lsb[:release] else platform "debian" platform_version File.read("/etc/debian_version").chomp end elsif File.exist?("/etc/parallels-release") contents = File.read("/etc/parallels-release").chomp platform get_redhatish_platform(contents) platform_version contents.match(/(\d\.\d\.\d)/)[0] elsif File.exist?("/etc/Eos-release") platform "arista_eos" platform_version File.read("/etc/Eos-release").strip.split[-1] elsif File.exist?("/etc/redhat-release") contents = File.read("/etc/redhat-release").chomp platform get_redhatish_platform(contents) platform_version get_redhatish_version(contents) elsif File.exist?("/etc/system-release") contents = File.read("/etc/system-release").chomp platform get_redhatish_platform(contents) platform_version get_redhatish_version(contents) elsif File.exist?("/etc/SuSE-release") suse_release = File.read("/etc/SuSE-release") suse_version = suse_release.scan(/VERSION = (\d+)\nPATCHLEVEL = (\d+)/).flatten.join(".") suse_version = suse_release[/VERSION = ([\d\.]{2,})/, 1] if suse_version == "" platform_version suse_version if suse_release =~ /^openSUSE/ # opensuse releases >= 42 are openSUSE Leap if platform_version.to_i < 42 platform "opensuse" else platform "opensuseleap" end else platform "suse" end elsif os_release_file_is_cisco? raise "unknown Cisco /etc/os-release or /etc/cisco-release ID_LIKE field" if os_release_info["ID_LIKE"].nil? || !os_release_info["ID_LIKE"].include?("wrlinux") case os_release_info["ID"] when "nexus" platform "nexus" when "ios_xr" platform "ios_xr" else raise "unknown Cisco /etc/os-release or /etc/cisco-release ID field" end platform_version os_release_info["VERSION"] elsif File.exist?("/etc/slackware-version") platform "slackware" platform_version File.read("/etc/slackware-version").scan(/(\d+|\.+)/).join elsif File.exist?("/etc/exherbo-release") platform "exherbo" # no way to determine platform_version in a rolling release distribution # kernel release will be used - ex. 3.13 platform_version shell_out("/bin/uname -r").stdout.strip elsif File.exist?("/usr/lib/os-release") contents = File.read("/usr/lib/os-release") if /clear-linux-os/ =~ contents # Clear Linux https://clearlinux.org/ platform "clearlinux" platform_version contents[/VERSION_ID=(\d+)/, 1] end elsif lsb[:id] =~ /RedHat/i platform "redhat" platform_version lsb[:release] elsif lsb[:id] =~ /Amazon/i platform "amazon" platform_version lsb[:release] elsif lsb[:id] =~ /ScientificSL/i platform "scientific" platform_version lsb[:release] elsif lsb[:id] =~ /XenServer/i platform "xenserver" platform_version lsb[:release] elsif lsb[:id] =~ /XCP/i platform "xcp" platform_version lsb[:release] elsif lsb[:id] # LSB can provide odd data that changes between releases, so we currently fall back on it rather than dealing with its subtleties platform lsb[:id].downcase platform_version lsb[:release] end end # Grab the version from the VERSION_ID field and use the kernel release if that's not # available. It should be there for everything, but rolling releases like arch / gentoo # where we've traditionally used the kernel as the version # @return String the OS version def determine_os_version # centos only includes the major version in os-release for some reason if os_release_info["ID"] == "centos" get_redhatish_version(File.read("/etc/redhat-release").chomp) else os_release_info["VERSION_ID"] || shell_out("/bin/uname -r").stdout.strip end end collect_data(:linux) do if ::File.exist?("/etc/os-release") logger.trace("Plugin platform: Using /etc/os-release for platform detection") # fixup os-release names to ohai platform names platform platform_id_remap(os_release_info["ID"]) platform_version determine_os_version else # we're on an old Linux distro legacy_platform_detection end # unless we set it in a specific way with the platform logic above set based on platform data platform_family platform_family_from_platform(platform) if platform_family.nil? end end ohai-16.0.7/lib/ohai/plugins/linux/sessions.rb000066400000000000000000000031501362624620500212330ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Sessions) do provides "sessions/by_session", "sessions/by_user" optional true collect_data(:linux) do loginctl_path = which("loginctl") if loginctl_path cmd = "#{loginctl_path} --no-pager --no-legend --no-ask-password " + "list-sessions" loginctl = shell_out(cmd) sessions Mash.new unless sessions sessions[:by_session] ||= Mash.new sessions[:by_user] ||= Mash.new loginctl.stdout.split("\n").each do |line| session, uid, user, seat = line.split s = { "session" => session, "uid" => uid, "user" => user, "seat" => seat, } sessions[:by_session][session] = s if sessions[:by_user][user] sessions[:by_user][user] << s else sessions[:by_user][user] = [s] end end else logger.trace("Plugin Sessions: Could not find loginctl. Skipping plugin.") end end end ohai-16.0.7/lib/ohai/plugins/linux/sysctl.rb000066400000000000000000000021151362624620500207060ustar00rootroot00000000000000# # Author:: Joshua Miller # Copyright:: Copyright (c) 2019 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Sysctl) do provides "sysctl" optional true collect_data(:linux) do sysctl_path = which("sysctl") if sysctl_path sysctl_cmd = shell_out("#{sysctl_path} -a") if sysctl_cmd.exitstatus == 0 sysctl Mash.new unless sysctl sysctl_cmd.stdout.lines.each do |line| k, v = line.split("=").map(&:strip) sysctl[k] = v end end end end end ohai-16.0.7/lib/ohai/plugins/linux/systemd_paths.rb000066400000000000000000000020721362624620500222560ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2017 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:SystemdPaths) do provides "systemd_paths" collect_data(:linux) do systemd_path_path = which("systemd-path") if systemd_path_path systemd_path = shell_out(systemd_path_path) systemd_paths Mash.new unless systemd_paths systemd_path.stdout.each_line do |line| key, val = line.split(":") systemd_paths[key] = val.strip end end end end ohai-16.0.7/lib/ohai/plugins/linux/virtualization.rb000066400000000000000000000266131362624620500224620ustar00rootroot00000000000000# # Author:: Thom May () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualization) do provides "virtualization" depends "dmi" require_relative "../../mixin/dmi_decode" include Ohai::Mixin::DmiDecode def lxc_version_exists? which("lxc-version") || which("lxc-start") end def nova_exists? which("nova") end def docker_exists? which("docker") end collect_data(:linux) do virtualization Mash.new unless virtualization virtualization[:systems] ||= Mash.new # Docker hosts if docker_exists? virtualization[:system] = "docker" virtualization[:role] = "host" virtualization[:systems][:docker] = "host" end # Xen Notes: # - /proc/xen is an empty dir for EL6 + Linode Guests + Paravirt EC2 instances # - cpuid of guests, if we could get it, would also be a clue # - may be able to determine if under paravirt from /dev/xen/evtchn (See OHAI-253) # - Additional edge cases likely should not change the above assumptions # but rather be additive - btm if File.exist?("/proc/xen") virtualization[:system] = "xen" # Assume guest virtualization[:role] = "guest" virtualization[:systems][:xen] = "guest" # This file should exist on most Xen systems, normally empty for guests if File.exist?("/proc/xen/capabilities") if File.read("/proc/xen/capabilities") =~ /control_d/i logger.trace("Plugin Virtualization: /proc/xen/capabilities contains control_d. Detecting as Xen host") virtualization[:role] = "host" virtualization[:systems][:xen] = "host" end end end # Detect Virtualbox from kernel module if File.exist?("/proc/modules") modules = File.read("/proc/modules") if modules =~ /^vboxdrv/ logger.trace("Plugin Virtualization: /proc/modules contains vboxdrv. Detecting as vbox host") virtualization[:system] = "vbox" virtualization[:role] = "host" virtualization[:systems][:vbox] = "host" elsif modules =~ /^vboxguest/ logger.trace("Plugin Virtualization: /proc/modules contains vboxguest. Detecting as vbox guest") virtualization[:system] = "vbox" virtualization[:role] = "guest" virtualization[:systems][:vbox] = "guest" end end # if nova binary is present we're on an openstack host if nova_exists? logger.trace("Plugin Virtualization: nova command exists. Detecting as openstack host") virtualization[:system] = "openstack" virtualization[:role] = "host" virtualization[:systems][:openstack] = "host" end # Detect paravirt KVM/QEMU from cpuinfo, report as KVM if File.exist?("/proc/cpuinfo") if File.read("/proc/cpuinfo") =~ /QEMU Virtual CPU|Common KVM processor|Common 32-bit KVM processor/ logger.trace("Plugin Virtualization: /proc/cpuinfo lists a KVM paravirt CPU string. Detecting as kvm guest") virtualization[:system] = "kvm" virtualization[:role] = "guest" virtualization[:systems][:kvm] = "guest" end end # Detect KVM systems via /sys # guests will have the hypervisor cpu feature that hosts don't have if File.exist?("/sys/devices/virtual/misc/kvm") virtualization[:system] = "kvm" if File.read("/proc/cpuinfo") =~ /hypervisor/ logger.trace("Plugin Virtualization: /sys/devices/virtual/misc/kvm present and /proc/cpuinfo lists the hypervisor feature. Detecting as kvm guest") virtualization[:role] = "guest" virtualization[:systems][:kvm] = "guest" else logger.trace("Plugin Virtualization: /sys/devices/virtual/misc/kvm present and /proc/cpuinfo does not list the hypervisor feature. Detecting as kvm host") virtualization[:role] = "host" virtualization[:systems][:kvm] = "host" end end # parse dmi to discover various virtualization guests # we do this *after* the kvm detection so that OpenStack isn't detected as KVM logger.trace("Looking up DMI data manufacturer: '#{get_attribute(:dmi, :system, :manufacturer)}' product: '#{get_attribute(:dmi, :system, :product)}' version: '#{get_attribute(:dmi, :system, :version)}'") guest = guest_from_dmi_data(get_attribute(:dmi, :system, :manufacturer), get_attribute(:dmi, :system, :product), get_attribute(:dmi, :system, :version)) if guest logger.trace("Plugin Virtualization: DMI data indicates #{guest} guest") virtualization[:system] = guest virtualization[:role] = "guest" virtualization[:systems][guest.to_sym] = "guest" end # Detect OpenVZ / Virtuozzo. # http://wiki.openvz.org/BC_proc_entries if File.exist?("/proc/bc/0") logger.trace("Plugin Virtualization: /proc/bc/0 exists. Detecting as openvz host") virtualization[:system] = "openvz" virtualization[:role] = "host" virtualization[:systems][:openvz] = "host" elsif File.exist?("/proc/vz") logger.trace("Plugin Virtualization: /proc/vz exists. Detecting as openvz guest") virtualization[:system] = "openvz" virtualization[:role] = "guest" virtualization[:systems][:openvz] = "guest" end # Detect Hyper-V guest and the hostname of the host if File.exist?("/var/lib/hyperv/.kvp_pool_3") logger.trace("Plugin Virtualization: /var/lib/hyperv/.kvp_pool_3 contains string indicating Hyper-V guest") data = File.read("/var/lib/hyperv/.kvp_pool_3") hyperv_host = data[/\HostName(.*?)HostingSystemEditionId/, 1].scan(/[[:print:]]/).join.downcase virtualization[:system] = "hyperv" virtualization[:role] = "guest" virtualization[:systems][:hyperv] = "guest" virtualization[:hypervisor_host] = hyperv_host end # Detect Linux-VServer if File.exist?("/proc/self/status") proc_self_status = File.read("/proc/self/status") vxid = proc_self_status.match(/^(s_context|VxID):\s*(\d+)$/) if vxid && vxid[2] virtualization[:system] = "linux-vserver" if vxid[2] == "0" logger.trace("Plugin Virtualization: /proc/self/status contains 's_context' or 'VxID' with a value of 0. Detecting as linux-vserver host") virtualization[:role] = "host" virtualization[:systems]["linux-vserver"] = "host" else logger.trace("Plugin Virtualization: /proc/self/status contains 's_context' or 'VxID' with a non-0 value. Detecting as linux-vserver guest") virtualization[:role] = "guest" virtualization[:systems]["linux-vserver"] = "guest" end end end # Detect LXC/Docker/Nspawn # # /proc/self/cgroup will look like this inside a docker container: # ::/lxc/ # # /proc/self/cgroup could have a name including alpha/digit/dashes # ::/lxc/ # # /proc/self/cgroup could have a non-lxc cgroup name indicating other uses # of cgroups. This is probably not LXC/Docker. # ::/Charlie # # A host which supports cgroups, and has capacity to host lxc containers, # will show the subsystems and root (/) namespace. # ::/ # # Full notes, https://tickets.opscode.com/browse/OHAI-551 # Kernel docs, https://www.kernel.org/doc/Documentation/cgroups if File.exist?("/proc/self/cgroup") cgroup_content = File.read("/proc/self/cgroup") if cgroup_content =~ %r{^\d+:[^:]+:/(lxc|docker)/.+$} || cgroup_content =~ %r{^\d+:[^:]+:/[^/]+/(lxc|docker)-?.+$} logger.trace("Plugin Virtualization: /proc/self/cgroup indicates #{$1} container. Detecting as #{$1} guest") virtualization[:system] = $1 virtualization[:role] = "guest" virtualization[:systems][$1.to_sym] = "guest" elsif File.read("/proc/1/environ") =~ /container=lxc/ logger.trace("Plugin Virtualization: /proc/1/environ indicates lxc container. Detecting as lxc guest") virtualization[:system] = "lxc" virtualization[:role] = "guest" virtualization[:systems][:lxc] = "guest" elsif File.read("/proc/1/environ") =~ /container=systemd-nspawn/ logger.trace("Plugin Virtualization: /proc/1/environ indicates nspawn container. Detecting as nspawn guest") virtualization[:system] = "nspawn" virtualization[:role] = "guest" virtualization[:systems][:nspawn] = "guest" elsif lxc_version_exists? && File.read("/proc/self/cgroup") =~ %r{\d:[^:]+:/$} # lxc-version shouldn't be installed by default # Even so, it is likely we are on an LXC capable host that is not being used as such # So we're cautious here to not overwrite other existing values (OHAI-573) unless virtualization[:system] && virtualization[:role] logger.trace("Plugin Virtualization: /proc/self/cgroup and lxc-version command exist. Detecting as lxc host") virtualization[:system] = "lxc" virtualization[:role] = "host" virtualization[:systems][:lxc] = "host" end # In general, the 'systems' framework from OHAI-182 is less susceptible to conflicts # But, this could overwrite virtualization[:systems][:lxc] = "guest" # If so, we may need to look further for a differentiator (OHAI-573) virtualization[:systems][:lxc] = "host" end elsif File.exist?("/.dockerenv") || File.exist?("/.dockerinit") logger.trace("Plugin Virtualization: .dockerenv or .dockerinit exist. Detecting as docker guest") virtualization[:system] = "docker" virtualization[:role] = "guest" virtualization[:systems][:docker] = "guest" end # Detect LXD # See https://github.com/lxc/lxd/blob/master/doc/dev-lxd.md if File.exist?("/dev/lxd/sock") logger.trace("Plugin Virtualization: /dev/lxd/sock exists. Detecting as lxd guest") virtualization[:system] = "lxd" virtualization[:role] = "guest" virtualization[:systems][:lxd] = "guest" else # 'How' LXD is installed dictates the runtime data location # # Installations of LXD from a .deb (Ubuntu's main and backports repos) utilize '/var/lib/lxd/' for runtime data # - used by stable releases 2.0.x in trusty/xenial, and 3.0.x in bionic # - xenial-backports includes versions 2.1 through 2.21 # # Snap based installations utilize '/var/snap/lxd/common/lxd/' # - includes all future releases starting with 2.21, and will be the only source of 3.1+ feature releases post-bionic ["/var/lib/lxd/devlxd", "/var/snap/lxd/common/lxd/devlxd"].each do |devlxd| if File.exist?(devlxd) logger.trace("Plugin Virtualization: #{devlxd} exists. Detecting as lxd host") virtualization[:system] = "lxd" virtualization[:role] = "host" virtualization[:systems][:lxd] = "host" break end end end end end ohai-16.0.7/lib/ohai/plugins/lua.rb000066400000000000000000000024651362624620500170170ustar00rootroot00000000000000# # Author:: Doug MacEachern # Copyright:: Copyright (c) 2009 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Lua) do provides "languages/lua" depends "languages" collect_data do so = shell_out("lua -v") # Sample output: # Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio if so.exitstatus == 0 lua = Mash.new # at some point in lua's history they went from outputting the version # on stderr to doing it on stdout. This handles old / new versions lua[:version] = so.stdout.empty? ? so.stderr.split[1] : so.stdout.split[1] languages[:lua] = lua if lua[:version] end rescue Ohai::Exceptions::Exec logger.trace('Plugin Lua: Could not shell_out "lua -v". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/mono.rb000066400000000000000000000033221362624620500171770ustar00rootroot00000000000000# # Author:: Doug MacEachern # Copyright:: Copyright (c) 2009 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Mono) do provides "languages/mono" depends "languages" collect_data do so = shell_out("mono -V") # Sample output: # Mono JIT compiler version 4.2.3 (Stable 4.2.3.4/832de4b Wed Mar 30 13:57:48 PDT 2016) # Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com # TLS: normal # SIGSEGV: altstack # Notification: kqueue # Architecture: amd64 # Disabled: none # Misc: softtrace # LLVM: supported, not enabled. # GC: sgen if so.exitstatus == 0 mono = Mash.new output = so.stdout.split mono[:version] = output[4] unless output[4].nil? if output.length >= 12 mono[:builddate] = "%s %s %s %s %s %s" % [output[7], output[8], output[9], output[10], output[11], output[12].delete!(")")] end languages[:mono] = mono unless mono.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Mono: Could not shell_out "mono -V". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/netbsd/000077500000000000000000000000001362624620500171615ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/netbsd/memory.rb000066400000000000000000000065441362624620500210270ustar00rootroot00000000000000# # Author:: Mathieu Sauve-Frankel # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory" collect_data(:netbsd) do memory Mash.new memory[:swap] = Mash.new # $ vmstat -s # 4096 bytes per page # 514011 pages managed # 224519 pages free # 209339 pages active # 4647 pages inactive # 0 pages being paged out # 5 pages wired # 0 pages zeroed # 4 pages reserved for pagedaemon # 6 pages reserved for kernel # 262205 swap pages # 0 swap pages in use # 0 total anon's in system # 0 free anon's # 1192991609 page faults # 1369579301 traps # 814549706 interrupts # 771702498 cpu context switches # 208810590 fpu context switches # 492361360 software interrupts # 1161998825 syscalls # 0 pagein operations # 0 swap ins # 0 swap outs # 768352 forks # 16 forks where vmspace is shared # 1763 kernel map entries # 0 number of times the pagedaemon woke up # 0 revolutions of the clock hand # 0 pages freed by pagedaemon # 0 pages scanned by pagedaemon # 0 pages reactivated by pagedaemon # 0 busy pages found by pagedaemon # 1096393776 total name lookups # cache hits (37% pos + 2% neg) system 1% per-directory # deletions 0%, falsehits 6%, toolong 26% # 0 select collisions so = shell_out("vmstat -s") so.stdout.lines do |line| case line when /(\d+) bytes per page/ memory[:page_size] = $1 when /(\d+) pages managed/ memory[:page_count] = $1 memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i when /(\d+) pages free/ memory[:free] = memory[:page_size].to_i * $1.to_i when /(\d+) pages active/ memory[:active] = memory[:page_size].to_i * $1.to_i when /(\d+) pages inactive/ memory[:inactive] = memory[:page_size].to_i * $1.to_i when /(\d+) pages wired/ memory[:wired] = memory[:page_size].to_i * $1.to_i end end so = shell_out("swapctl -l") so.stdout.lines do |line| # Device 1024-blocks Used Avail Capacity Priority # swap_device 1048824 0 1048824 0% 0 if line =~ %r{^([\d\w/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)} mdev = $1 memory[:swap][mdev] = Mash.new memory[:swap][mdev][:total] = $2 memory[:swap][mdev][:used] = $3 memory[:swap][mdev][:free] = $4 memory[:swap][mdev][:percent_free] = $5 end end end end ohai-16.0.7/lib/ohai/plugins/netbsd/network.rb000066400000000000000000000110541362624620500212000ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" collect_data(:netbsd) do network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new so = shell_out("route -n get default") so.stdout.lines do |line| if line =~ /(\w+): ([\w\.]+)/ case $1 when "gateway" network[:default_gateway] = $2 when "interface" network[:default_interface] = $2 end end end iface = Mash.new so = shell_out("#{Ohai.abs_path( "/sbin/ifconfig" )} -a") cint = nil so.stdout.lines do |line| if line =~ /^([0-9a-zA-Z\.]+):\s+/ cint = $1 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end end # call the family lladdr to match linux for consistency if line =~ /\s+address: (.+?)\s/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } end if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ iface[cint][:addresses] ||= Mash.new # convert the netmask to decimal for consistency netmask = "#{$2[2, 2].hex}.#{$2[4, 2].hex}.#{$2[6, 2].hex}.#{$2[8, 2].hex}" if $3.empty? iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } else # found a broadcast address iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } end end if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ iface[cint][:addresses] ||= Mash.new if $4.empty? iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } else # found a zone_id / scope iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } end end if line =~ /flags=\d+<(.+)>/ flags = $1.split(",") iface[cint][:flags] = flags if flags.length > 0 end if line =~ /metric: (\d+) mtu: (\d+)/ iface[cint][:metric] = $1 iface[cint][:mtu] = $2 end end so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ next unless iface[$3] # this should never happen iface[$3][:arp] ||= Mash.new iface[$3][:arp][$1] = $2.downcase end end network["interfaces"] = iface net_counters = Mash.new # From netstat(1), not sure of the implications: # Show the state of all network interfaces or a single interface # which have been auto-configured (interfaces statically configured # into a system, but not located at boot time are not shown). so = shell_out("netstat -idn") so.stdout.lines do |line| # Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll Drop # em0 1500 00:11:25:2d:90:be 3719557 0 3369969 0 0 0 # $1 $2 $3 $4 $5 $6 $7 $8 if line =~ /^([\w\.\*]+)\s+\d+\s+\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ net_counters[$1] ||= Mash.new net_counters[$1]["rx"] ||= Mash.new net_counters[$1]["tx"] ||= Mash.new net_counters[$1]["rx"]["packets"] = $3 net_counters[$1]["rx"]["errors"] = $4 net_counters[$1]["tx"]["packets"] = $5 net_counters[$1]["tx"]["errors"] = $6 net_counters[$1]["tx"]["collisions"] = $7 net_counters[$1]["tx"]["dropped"] = $8 end end counters[:network][:interfaces] = net_counters end end ohai-16.0.7/lib/ohai/plugins/netbsd/platform.rb000066400000000000000000000017371362624620500213420ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" collect_data(:netbsd) do so = shell_out("uname -s") platform so.stdout.split($/)[0].downcase so = shell_out("uname -r") platform_version so.stdout.split($/)[0] platform_family "netbsd" end end ohai-16.0.7/lib/ohai/plugins/network.rb000066400000000000000000000161061362624620500177240ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:NetworkAddresses) do require "ipaddress" require_relative "../mixin/network_helper" include Ohai::Mixin::NetworkHelper provides "ipaddress", "ip6address", "macaddress" depends "network/interfaces" # from interface data create array of hashes with ipaddress, scope, and iface # sorted by scope, prefixlen and then ipaddress where longest prefixes first def sorted_ips(family = "inet") raise "bad family #{family}" unless %w{inet inet6}.include? family # priority of ipv6 link scopes to sort by later scope_prio = [ "global", "site", "link", "host", "node", nil ] # grab ipaddress, scope, and iface for sorting later ipaddresses = [] Mash[network["interfaces"]].each do |iface, iface_v| next if iface_v.nil? || !iface_v.key?("addresses") iface_v["addresses"].each do |addr, addr_v| next if addr_v.nil? || (not addr_v.key? "family") || addr_v["family"] != family ipaddresses << { ipaddress: addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"), scope: addr_v["scope"].nil? ? nil : addr_v["scope"].downcase, iface: iface, } end end # sort ip addresses by scope, by prefixlen and then by ip address # 128 - prefixlen: longest prefixes first ipaddresses.sort_by do |v| [ ( scope_prio.index(v[:scope]) || 999999 ), 128 - v[:ipaddress].prefix.to_i, ( family == "inet" ? v[:ipaddress].to_u32 : v[:ipaddress].to_u128 ), ] end end # finds ip address / interface for interface with default route based on # passed in family. returns [ipaddress, interface] uses 1st ip if no default # route is found def find_ip(family = "inet") ips = sorted_ips(family) # return if there aren't any #{family} addresses! return [ nil, nil ] if ips.empty? # shortcuts to access default #{family} interface and gateway int_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_interface" gw_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_gateway" if network[int_attr] # working with the address(es) of the default network interface gw_if_ips = ips.select do |v| v[:iface] == network[int_attr] end if gw_if_ips.empty? logger.warn("Plugin Network: [#{family}] no ip address on #{network[int_attr]}") elsif network[gw_attr] && network["interfaces"][network[int_attr]] && network["interfaces"][network[int_attr]]["addresses"] if [ "0.0.0.0", "::", /^fe80:/ ].any? { |pat| pat === network[gw_attr] } # link level default route logger.trace("Plugin Network: link level default #{family} route, picking ip from #{network[gw_attr]}") r = gw_if_ips.first else # checking network masks r = gw_if_ips.select do |v| network_contains_address(network[gw_attr], v[:ipaddress], v[:iface]) end.first if r.nil? r = gw_if_ips.first logger.trace("Plugin Network: [#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}") else logger.trace("Plugin Network: [#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}") end end else # return the first ip address on network[int_attr] r = gw_if_ips.first end else r = ips.first logger.trace("Plugin Network: [#{family}] no default interface, picking the first ipaddress") end return [ nil, nil ] if r.nil? || r.empty? [ r[:ipaddress].to_s, r[:iface] ] end # select mac address of first interface with family of lladdr def find_mac_from_iface(iface) r = network["interfaces"][iface]["addresses"].select { |k, v| v["family"] == "lladdr" } r.nil? || r.first.nil? ? nil : r.first.first end # address_to_match: String # ipaddress: IPAddress # iface: String def network_contains_address(address_to_match, ipaddress, iface) if ( peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer] ) IPAddress(peer) == IPAddress(address_to_match) else ipaddress.include? IPAddress(address_to_match) end end # ipaddress, ip6address and macaddress are set for each interface by the # #{os}::network plugin. atm it is expected macaddress is set at the same # time as ipaddress. if ipaddress is set and macaddress is nil, that means # the interface ipaddress is bound to has the NOARP flag collect_data do results = {} network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new # inet family is processed before inet6 to give ipv4 precedence Ohai::Mixin::NetworkHelper::FAMILIES.keys.sort.each do |family| r = {} # find the ip/interface with the default route for this family (r["ip"], r["iface"]) = find_ip(family) r["mac"] = find_mac_from_iface(r["iface"]) unless r["iface"].nil? # don't overwrite attributes if they've already been set by the "#{os}::network" plugin if (family == "inet") && ipaddress.nil? if r["ip"].nil? logger.warn("Plugin Network: unable to detect ipaddress") else ipaddress r["ip"] end elsif (family == "inet6") && ip6address.nil? if r["ip"].nil? logger.trace("Plugin Network: unable to detect ip6address") else ip6address r["ip"] end end # set the macaddress [only if we haven't already]. this allows the #{os}::network plugin to set macaddress # otherwise we set macaddress on a first-found basis (and we started with ipv4) if macaddress.nil? if r["mac"] logger.trace("Plugin Network: setting macaddress to '#{r["mac"]}' from interface '#{r["iface"]}' for family '#{family}'") macaddress r["mac"] else logger.trace("Plugin Network: unable to detect macaddress for family '#{family}'") end end results[family] = r end if results["inet"]["iface"] && results["inet6"]["iface"] && (results["inet"]["iface"] != results["inet6"]["iface"]) logger.trace("Plugin Network: ipaddress and ip6address are set from different interfaces (#{results["inet"]["iface"]} & #{results["inet6"]["iface"]})") end end end ohai-16.0.7/lib/ohai/plugins/nodejs.rb000066400000000000000000000023371362624620500175160ustar00rootroot00000000000000# # Author:: Jacques Marneweck () # Copyright:: Copyright (c) 2012 Jacques Marneweck. All rights reserved. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Nodejs) do provides "languages/nodejs" depends "languages" collect_data do so = shell_out("node -v") # Sample output: # v5.10.1 if so.exitstatus == 0 nodejs = Mash.new output = so.stdout.split if output.length >= 1 nodejs[:version] = output[0][1..output[0].length] end languages[:nodejs] = nodejs if nodejs[:version] end rescue Ohai::Exceptions::Exec logger.trace('Plugin Nodejs: Could not shell_out "node -v". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/ohai.rb000066400000000000000000000016741362624620500171570ustar00rootroot00000000000000# # Author:: Tollef Fog Heen # Copyright:: Copyright (c) 2010 Tollef Fog Heen # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Ohai) do provides "chef_packages/ohai" collect_data do chef_packages Mash.new unless chef_packages chef_packages[:ohai] = Mash.new chef_packages[:ohai][:version] = Ohai::VERSION chef_packages[:ohai][:ohai_root] = Ohai::OHAI_ROOT end end ohai-16.0.7/lib/ohai/plugins/ohai_time.rb000066400000000000000000000014321362624620500201650ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:OhaiTime) do provides "ohai_time" collect_data do ohai_time Time.now.to_f end end ohai-16.0.7/lib/ohai/plugins/openbsd/000077500000000000000000000000001362624620500173345ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/openbsd/memory.rb000066400000000000000000000065641362624620500212040ustar00rootroot00000000000000# # Author:: Mathieu Sauve-Frankel # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory", "memory/swap" collect_data(:openbsd) do memory Mash.new memory[:swap] = Mash.new # $ vmstat -s # 4096 bytes per page # 514011 pages managed # 224519 pages free # 209339 pages active # 4647 pages inactive # 0 pages being paged out # 5 pages wired # 0 pages zeroed # 4 pages reserved for pagedaemon # 6 pages reserved for kernel # 262205 swap pages # 0 swap pages in use # 0 total anon's in system # 0 free anon's # 1192991609 page faults # 1369579301 traps # 814549706 interrupts # 771702498 cpu context switches # 208810590 fpu context switches # 492361360 software interrupts # 1161998825 syscalls # 0 pagein operations # 0 swap ins # 0 swap outs # 768352 forks # 16 forks where vmspace is shared # 1763 kernel map entries # 0 number of times the pagedaemon woke up # 0 revolutions of the clock hand # 0 pages freed by pagedaemon # 0 pages scanned by pagedaemon # 0 pages reactivated by pagedaemon # 0 busy pages found by pagedaemon # 1096393776 total name lookups # cache hits (37% pos + 2% neg) system 1% per-directory # deletions 0%, falsehits 6%, toolong 26% # 0 select collisions so = shell_out("vmstat -s") so.stdout.lines do |line| case line when /(\d+) bytes per page/ memory[:page_size] = $1 when /(\d+) pages managed/ memory[:page_count] = $1 memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i when /(\d+) pages free/ memory[:free] = memory[:page_size].to_i * $1.to_i when /(\d+) pages active/ memory[:active] = memory[:page_size].to_i * $1.to_i when /(\d+) pages inactive/ memory[:inactive] = memory[:page_size].to_i * $1.to_i when /(\d+) pages wired/ memory[:wired] = memory[:page_size].to_i * $1.to_i end end so = shell_out("swapctl -l") so.stdout.lines do |line| # Device 1024-blocks Used Avail Capacity Priority # swap_device 1048824 0 1048824 0% 0 if line =~ %r{^([\d\w/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)} mdev = $1 memory[:swap][mdev] = Mash.new memory[:swap][mdev][:total] = $2 memory[:swap][mdev][:used] = $3 memory[:swap][mdev][:free] = $4 memory[:swap][mdev][:percent_free] = $5 end end end end ohai-16.0.7/lib/ohai/plugins/openbsd/network.rb000066400000000000000000000110551362624620500213540ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" collect_data(:openbsd) do network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new so = shell_out("route -n get default") so.stdout.lines do |line| if line =~ /(\w+): ([\w\.]+)/ case $1 when "gateway" network[:default_gateway] = $2 when "interface" network[:default_interface] = $2 end end end iface = Mash.new so = shell_out( "#{Ohai.abs_path( "/sbin/ifconfig" )} -a" ) cint = nil so.stdout.lines do |line| if line =~ /^([0-9a-zA-Z\.]+):\s+/ cint = $1 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end end # call the family lladdr to match linux for consistency if line =~ /\s+lladdr (.+?)\s/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "lladdr" } end if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ iface[cint][:addresses] ||= Mash.new # convert the netmask to decimal for consistency netmask = "#{$2[2, 2].hex}.#{$2[4, 2].hex}.#{$2[6, 2].hex}.#{$2[8, 2].hex}" if $3.empty? iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } else # found a broadcast address iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } end end if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ iface[cint][:addresses] ||= Mash.new if $4.empty? iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } else # found a zone_id / scope iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } end end if line =~ /flags=\d+<(.+)>/ flags = $1.split(",") iface[cint][:flags] = flags if flags.length > 0 end if line =~ /metric: (\d+) mtu: (\d+)/ iface[cint][:metric] = $1 iface[cint][:mtu] = $2 end end so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ next unless iface[$3] # this should never happen iface[$3][:arp] ||= Mash.new iface[$3][:arp][$1] = $2.downcase end end network["interfaces"] = iface net_counters = Mash.new # From netstat(1), not sure of the implications: # Show the state of all network interfaces or a single interface # which have been auto-configured (interfaces statically configured # into a system, but not located at boot time are not shown). so = shell_out("netstat -idn") so.stdout.lines do |line| # Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll Drop # em0 1500 00:11:25:2d:90:be 3719557 0 3369969 0 0 0 # $1 $2 $3 $4 $5 $6 $7 $8 if line =~ /^([\w\.\*]+)\s+\d+\s+\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ net_counters[$1] ||= Mash.new net_counters[$1]["rx"] ||= Mash.new net_counters[$1]["tx"] ||= Mash.new net_counters[$1]["rx"]["packets"] = $3 net_counters[$1]["rx"]["errors"] = $4 net_counters[$1]["tx"]["packets"] = $5 net_counters[$1]["tx"]["errors"] = $6 net_counters[$1]["tx"]["collisions"] = $7 net_counters[$1]["tx"]["dropped"] = $8 end end counters[:network][:interfaces] = net_counters end end ohai-16.0.7/lib/ohai/plugins/openbsd/platform.rb000066400000000000000000000017411362624620500215100ustar00rootroot00000000000000# # Author:: Bryan McLellan (btm@loftninjas.org) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" collect_data(:openbsd) do so = shell_out("uname -s") platform so.stdout.split($/)[0].downcase so = shell_out("uname -r") platform_version so.stdout.split($/)[0] platform_family "openbsd" end end ohai-16.0.7/lib/ohai/plugins/openstack.rb000066400000000000000000000054271362624620500202260ustar00rootroot00000000000000# # Author:: Matt Ray () # Author:: Tim Smith () # Copyright:: Copyright (c) 2012-2019 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Openstack) do require_relative "../mixin/ec2_metadata" require_relative "../mixin/http_helper" require "etc" unless defined?(Etc) include Ohai::Mixin::Ec2Metadata include Ohai::Mixin::HttpHelper provides "openstack" depends "virtualization" # use virtualization data def openstack_virtualization? if get_attribute(:virtualization, :systems, :openstack) logger.trace("Plugin Openstack: has_openstack_virtualization? == true") true end end # check for the ohai hint and log trace messaging def openstack_hint? if hint?("openstack") logger.trace("Plugin Openstack: openstack hint present") true else logger.trace("Plugin Openstack: openstack hint not present") false end end # dreamhost systems *had* the dhc-user on them < 2016. We should probably remove all this logic # https://help.dreamhost.com/hc/en-us/articles/228377408-How-to-find-the-default-user-of-an-image def openstack_provider # dream host doesn't support windows so bail early if we're on windows return "openstack" if RUBY_PLATFORM =~ /mswin|mingw32|windows/ if Etc::Passwd.entries.map(&:name).include?("dhc-user") "dreamhost" else "openstack" end end collect_data do # fetch data if we look like openstack if openstack_hint? || openstack_virtualization? openstack Mash.new openstack[:provider] = openstack_provider timeout = Ohai::Config.ohai[:openstack_metadata_timeout] || 2 # fetch the metadata if we can do a simple socket connect first if can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, timeout) fetch_metadata.each do |k, v| openstack[k] = v unless v.empty? end logger.trace("Plugin Openstack: Successfully fetched Openstack metadata from the metadata endpoint") else logger.trace("Plugin Openstack: Timed out connecting to Openstack metadata endpoint. Skipping metadata.") end else logger.trace("Plugin Openstack: Node does not appear to be an Openstack node") end end end ohai-16.0.7/lib/ohai/plugins/os.rb000066400000000000000000000026071362624620500166550ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Isa Farnik () # Author:: Richard Manyanza () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2014 Richard Manyanza. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:OS) do require_relative "../mixin/os" provides "os", "os_version" depends "kernel" collect_data(:aix) do os collect_os os_version shell_out("oslevel -s").stdout.strip end collect_data(:dragonflybsd, :freebsd) do os collect_os # This is __DragonFly_version / __FreeBSD_version. See sys/param.h or # http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html. os_version shell_out("sysctl -n kern.osreldate").stdout.split($/)[0] end collect_data do os collect_os os_version kernel[:release] end end ohai-16.0.7/lib/ohai/plugins/packages.rb000066400000000000000000000173011362624620500200070ustar00rootroot00000000000000# Author:: "Christian HΓΆltje" # Author:: "Christopher M. Luciano" # Author:: Shahul Khajamohideen () # Copyright (C) 2015 IBM Corp. # Copyright (C) 2015 Bloomberg Finance L.P. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Ohai.plugin(:Packages) do provides "packages" depends "platform_family" WINDOWS_ATTRIBUTE_ALIASES ||= { "DisplayVersion" => "version", "Publisher" => "publisher", "InstallDate" => "installdate", }.freeze collect_data(:linux) do packages Mash.new case platform_family when "debian" format = '${Package}\t${Version}\t${Architecture}\n' so = shell_out("dpkg-query -W -f='#{format}'") pkgs = so.stdout.lines pkgs.each do |pkg| name, version, arch = pkg.split packages[name] = { "version" => version, "arch" => arch } end when "rhel", "fedora", "suse", "pld", "amazon" format = '%{NAME}\t%|EPOCH?{%{EPOCH}}:{0}|\t%{VERSION}\t%{RELEASE}\t%{INSTALLTIME}\t%{ARCH}\n' so = shell_out("rpm -qa --qf '#{format}'") pkgs = so.stdout.lines pkgs.each do |pkg| name, epoch, version, release, installdate, arch = pkg.split if packages[name] # We have more than one package with this exact name! # Create an "versions" array for tracking all versions of packages with this name. # The top-level package information will be the first one returned by rpm -qa, # all versions go in this list, with the same information they'd normally have. if packages[name]["versions"].nil? # add the data of the first package to the list, so that all versions are in the list. packages[name]["versions"] = [] packages[name]["versions"] << Mash.new({ "epoch" => packages[name]["epoch"], "version" => packages[name]["version"], "release" => packages[name]["release"], "installdate" => packages[name]["installdate"], "arch" => packages[name]["arch"] }) end packages[name]["versions"] << Mash.new({ "epoch" => epoch, "version" => version, "release" => release, "installdate" => installdate, "arch" => arch }) # Add this package version to the list # When this was originally written, it didn't account for multiple versions of the same package # so it just kept clobbering the package data if it encountered multiple versions # of the same package. As a result, the last duplicate returned by rpm -qa was what was present; # here we clobber that data for compatibility. Note that we can't overwrite the entire hash # without losing the versions array. packages[name]["epoch"] = epoch packages[name]["version"] = version packages[name]["release"] = release packages[name]["installdate"] = installdate packages[name]["arch"] = arch else packages[name] = { "epoch" => epoch, "version" => version, "release" => release, "installdate" => installdate, "arch" => arch } end end when "arch" require "date" # Set LANG=C to force an easy to parse date format so = shell_out("LANG=C pacman -Qi") so.stdout.split("\n\n").each do |record| pacman_info = {} record.lines.each do |line| if line =~ /\A(.*?)\s+:\s(.*)\z/m key, value = Regexp.last_match[1..2] key = key.strip.downcase.gsub(/\s+/, "") pacman_info[key] = value.strip end end name = pacman_info["name"] installdate = DateTime.strptime(pacman_info["installdate"], "%Ec").strftime("%s") packages[name] = { "version" => pacman_info["version"], "installdate" => installdate, "arch" => pacman_info["architecture"], } end end end def collect_programs_from_registry_key(key_path) # from http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx if ::RbConfig::CONFIG["target_cpu"] == "i386" reg_type = Win32::Registry::KEY_READ | 0x100 elsif ::RbConfig::CONFIG["target_cpu"] == "x86_64" reg_type = Win32::Registry::KEY_READ | 0x200 else reg_type = Win32::Registry::KEY_READ end Win32::Registry::HKEY_LOCAL_MACHINE.open(key_path, reg_type) do |reg| reg.each_key do |key, _wtime| pkg = reg.open(key) name = pkg["DisplayName"] rescue nil next if name.nil? package = packages[name] = Mash.new WINDOWS_ATTRIBUTE_ALIASES.each do |registry_attr, package_attr| value = pkg[registry_attr] rescue nil package[package_attr] = value unless value.nil? end end end end collect_data(:windows) do require "win32/registry" unless defined?(Win32::Registry) packages Mash.new collect_programs_from_registry_key('Software\Microsoft\Windows\CurrentVersion\Uninstall') # on 64 bit systems, 32 bit programs are stored here collect_programs_from_registry_key('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') end collect_data(:aix) do packages Mash.new so = shell_out("lslpp -L -q -c") pkgs = so.stdout.lines # Output format is # Package Name:Fileset:Level # On aix, filesets are packages and levels are versions pkgs.each do |pkg| name, fileset, version, _, _, _, pkg_type = pkg.split(":") if pkg_type == "R" # RPM packages[name] = { "version" => version } else # LPP packages[fileset] = { "version" => version } end end end collect_data(:freebsd) do packages Mash.new so = shell_out('pkg query -a "%n %v"') # Output format is # name version so.stdout.lines do |pkg| name, version = pkg.split(" ") packages[name] = { "version" => version } end end def collect_ips_packages so = shell_out("pkg list -H") # Output format is # NAME (PUBLISHER) VERSION IFO so.stdout.lines.each do |pkg| tokens = pkg.split if tokens.length == 3 # No publisher info name, version, = tokens else name, publisher, version, = tokens publisher = publisher[1..-2] end packages[name] = { "version" => version } packages[name]["publisher"] = publisher if publisher end end def collect_sysv_packages so = shell_out("pkginfo -l") # Each package info is separated by a blank line chunked_lines = so.stdout.lines.map(&:strip).chunk do |line| !line.empty? || nil end chunked_lines.each do |_, lines| # rubocop: disable Performance/HashEachMethods package = {} lines.each do |line| key, value = line.split(":", 2) package[key.strip.downcase] = value.strip unless value.nil? end # pkginst is the installed package name packages[package["pkginst"]] = package.tap do |p| p.delete("pkginst") end end end collect_data(:solaris2) do packages Mash.new collect_ips_packages collect_sysv_packages end end ohai-16.0.7/lib/ohai/plugins/passwd.rb000066400000000000000000000022241362624620500175300ustar00rootroot00000000000000 Ohai.plugin(:Passwd) do require "etc" unless defined?(Etc) provides "etc", "current_user" optional true # @param [String] str # # @return [String] # def fix_encoding(str) str.force_encoding(Encoding.default_external) if str.respond_to?(:force_encoding) str end collect_data do unless etc etc Mash.new etc[:passwd] = Mash.new etc[:group] = Mash.new Etc.passwd do |entry| user_passwd_entry = Mash.new(dir: entry.dir, gid: entry.gid, uid: entry.uid, shell: entry.shell, gecos: entry.gecos) user_passwd_entry.each_value { |v| fix_encoding(v) } entry_name = fix_encoding(entry.name) etc[:passwd][entry_name] = user_passwd_entry unless etc[:passwd].key?(entry_name) end Etc.group do |entry| group_entry = Mash.new(gid: entry.gid, members: entry.mem.map { |u| fix_encoding(u) }) etc[:group][fix_encoding(entry.name)] = group_entry end end unless current_user current_user fix_encoding(Etc.getpwuid(Process.euid).name) end end collect_data(:windows) do # Etc returns nil on Windows end end ohai-16.0.7/lib/ohai/plugins/perl.rb000066400000000000000000000025621362624620500171760ustar00rootroot00000000000000# # Author:: Joshua Timberman () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Perl) do provides "languages/perl" depends "languages" collect_data do so = shell_out("perl -V:version -V:archname") # Sample output: # version='5.18.2'; # archname='darwin-thread-multi-2level'; if so.exitstatus == 0 perl = Mash.new so.stdout.split(/\r?\n/).each do |line| case line when /^version=\'(.+)\';$/ perl[:version] = $1 when /^archname=\'(.+)\';$/ perl[:archname] = $1 end end languages[:perl] = perl unless perl.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Perl: Could not shell_out "perl -V:version -V:archname". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/php.rb000066400000000000000000000031521362624620500170170ustar00rootroot00000000000000# # Author:: Doug MacEachern # Author:: Tim Smith # Copyright:: Copyright (c) 2009 VMware, Inc. # Copyright:: Copyright (c) 2014 Cozy Services, Ltd. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:PHP) do provides "languages/php" depends "languages" collect_data do so = shell_out("php -v") # Sample output: # PHP 5.5.31 (cli) (built: Feb 20 2016 20:33:10) # Copyright (c) 1997-2015 The PHP Group # Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies if so.exitstatus == 0 php = Mash.new so.stdout.each_line do |line| case line when /^PHP (\S+)(?:.*built: ([^)]+))?/ php[:version] = $1 php[:builddate] = $2 when /Zend Engine v([^\s]+),/ php[:zend_engine_version] = $1 when /Zend OPcache v([^\s]+),/ php[:zend_opcache_version] = $1 end end languages[:php] = php unless php.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Php: Could not shell_out "php -v". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/platform.rb000066400000000000000000000020011362624620500200440ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" depends "os", "os_version" collect_data(:default) do platform os unless attribute?("platform") platform_version os_version unless attribute?("platform_version") platform_family platform unless attribute?("platform_family") end end ohai-16.0.7/lib/ohai/plugins/powershell.rb000066400000000000000000000054161362624620500204210ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Powershell) do provides "languages/powershell" depends "languages" collect_data(:windows) do so = shell_out("powershell.exe -NoLogo -NonInteractive -NoProfile -command $PSVersionTable") # Sample output: # # Name Value # ---- ----- # PSVersion 4.0 # WSManStackVersion 3.0 # SerializationVersion 1.1.0.1 # CLRVersion 4.0.30319.34014 # BuildVersion 6.3.9600.16394 # PSCompatibleVersions {1.0, 2.0, 3.0, 4.0} # PSRemotingProtocolVersion 2.2 if so.exitstatus == 0 powershell = Mash.new version_info = {} so.stdout.strip.each_line do |line| kv = line.strip.split(/\s+/, 2) version_info[kv[0]] = kv[1] if kv.length == 2 end powershell[:version] = version_info["PSVersion"] powershell[:ws_man_stack_version] = version_info["WSManStackVersion"] powershell[:serialization_version] = version_info["SerializationVersion"] powershell[:clr_version] = version_info["CLRVersion"] powershell[:build_version] = version_info["BuildVersion"] powershell[:compatible_versions] = parse_compatible_versions powershell[:remoting_protocol_version] = version_info["PSRemotingProtocolVersion"] languages[:powershell] = powershell unless powershell.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Powershell: Could not shell_out "powershell.exe -NoLogo -NonInteractive -NoProfile -command $PSVersionTable". Skipping plugin') end def version_command [ "$progresspreference = 'silentlycontinue'", "$PSVersionTable.PSCompatibleVersions | foreach {$_.tostring()}", ].join("; ") end def powershell_command ["powershell.exe", "-NoLogo", "-NonInteractive", "-NoProfile", "-Command", ].join(" ") end def parse_compatible_versions so = shell_out("#{powershell_command} \"#{version_command}\"") versions = [] so.stdout.strip.each_line do |line| versions << line.strip end versions end end ohai-16.0.7/lib/ohai/plugins/ps.rb000066400000000000000000000020551362624620500166530ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Bryan McLellan () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:PS) do provides "command/ps" depends "command" collect_data(:aix, :darwin, :linux, :solaris2) do command[:ps] = "ps -ef" end collect_data(:freebsd, :netbsd, :openbsd, :dragonflybsd) do # ps -e requires procfs command[:ps] = "ps -axww" end end ohai-16.0.7/lib/ohai/plugins/python.rb000066400000000000000000000027051362624620500175540ustar00rootroot00000000000000# # Author:: Thom May () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Python) do provides "languages/python" depends "languages" collect_data do so = shell_out("python -c \"import sys; print (sys.version)\"") # Sample output: # 2.7.11 (default, Dec 26 2015, 17:47:53) # [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] if so.exitstatus == 0 python = Mash.new output = so.stdout.split python[:version] = output[0] if output.length >= 6 python[:builddate] = "%s %s %s %s" % [output[2], output[3], output[4], output[5].delete!(")")] end languages[:python] = python unless python.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Python: Could not shell_out "python -c "import sys; print (sys.version)"". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/rackspace.rb000066400000000000000000000132631362624620500201700ustar00rootroot00000000000000# # Author:: Cary Penniman () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Rackspace) do require "resolv" provides "rackspace" depends "kernel", "network/interfaces" # Checks for matching rackspace kernel name # # === Return # true:: If kernel name matches # false:: Otherwise def has_rackspace_kernel? kernel[:release].split("-").last.eql?("rscloud") end # Checks for rackspace provider attribute # # === Return # true:: If rackspace provider attribute found # false:: Otherwise def has_rackspace_metadata? so = shell_out("xenstore-read vm-data/provider_data/provider") if so.exitstatus == 0 so.stdout.strip.casecmp("rackspace") == 0 end rescue Ohai::Exceptions::Exec false end # Checks for the rackspace manufacturer on Windows # === Return # true:: If the rackspace cloud can be identified # false:: Otherwise def has_rackspace_manufacturer? return false unless RUBY_PLATFORM =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new if wmi.first_of("Win32_ComputerSystem")["PrimaryOwnerName"] == "Rackspace" logger.trace("Plugin Rackspace: has_rackspace_manufacturer? == true") true end end # Identifies the rackspace cloud # # === Return # true:: If the rackspace cloud can be identified # false:: Otherwise def looks_like_rackspace? hint?("rackspace") || has_rackspace_metadata? || has_rackspace_kernel? || has_rackspace_manufacturer? end # Names rackspace ip address # # === Parameters # name:: Use :public_ip or :private_ip # eth:: Interface name of public or private ip def get_ip_address(name, eth) network[:interfaces][eth][:addresses].each do |key, info| if info["family"] == "inet" rackspace[name] = key break # break when we found an address end end end # Names rackspace ipv6 address for interface # # === Parameters # name:: Use :public_ip or :private_ip # eth:: Interface name of public or private ip def get_global_ipv6_address(name, eth) network[:interfaces][eth][:addresses].each do |key, info| # check if we got an ipv6 address and if its in global scope if info["family"] == "inet6" && info["scope"] == "Global" rackspace[name] = key break # break when we found an address end end end # Get the rackspace region # def get_region so = shell_out("xenstore-ls vm-data/provider_data") if so.exitstatus == 0 so.stdout.split("\n").each do |line| rackspace[:region] = line.split[2].delete('\"') if line =~ /^region/ end end rescue Ohai::Exceptions::Exec logger.trace("Plugin Rackspace: Unable to find xenstore-ls, cannot capture region information for Rackspace cloud") nil end # Get the rackspace instance_id # def get_instance_id so = shell_out("xenstore-read name") if so.exitstatus == 0 rackspace[:instance_id] = so.stdout.gsub(/instance-/, "") end rescue Ohai::Exceptions::Exec logger.trace("Plugin Rackspace: Unable to find xenstore-read, cannot capture instance ID information for Rackspace cloud") nil end # Get the rackspace private networks # def get_private_networks so = shell_out("xenstore-ls vm-data/networking") if so.exitstatus == 0 networks = [] so.stdout.split("\n").map { |l| l.split("=").first.strip }.map do |item| so = shell_out("xenstore-read vm-data/networking/#{item}") if so.exitstatus == 0 networks.push(FFI_Yajl::Parser.new.parse(so.stdout)) else logger.trace("Plugin Rackspace: Unable to capture custom private networking information for Rackspace cloud") return false end end # these networks are already known to ohai, and are not 'private networks' networks.delete_if { |hash| hash["label"] == "private" } networks.delete_if { |hash| hash["label"] == "public" } end rescue Ohai::Exceptions::Exec logger.trace("Plugin Rackspace: Unable to capture custom private networking information for Rackspace cloud") nil end collect_data do # Adds rackspace Mash if looks_like_rackspace? rackspace Mash.new get_ip_address(:public_ip, :eth0) get_ip_address(:private_ip, :eth1) get_region get_instance_id # public_ip + private_ip are deprecated in favor of public_ipv4 and local_ipv4 to standardize. rackspace[:public_ipv4] = rackspace[:public_ip] get_global_ipv6_address(:public_ipv6, :eth0) unless rackspace[:public_ip].nil? rackspace[:public_hostname] = begin Resolv.getname(rackspace[:public_ip]) rescue Resolv::ResolvError, Resolv::ResolvTimeout rackspace[:public_ip] end end rackspace[:local_ipv4] = rackspace[:private_ip] get_global_ipv6_address(:local_ipv6, :eth1) rackspace[:local_hostname] = hostname private_networks = get_private_networks rackspace[:private_networks] = private_networks if private_networks end end end ohai-16.0.7/lib/ohai/plugins/root_group.rb000066400000000000000000000031121362624620500204230ustar00rootroot00000000000000# # Author:: Joseph Anthony Pasquale Holsten () # Copyright:: Copyright (c) 2013 Joseph Anthony Pasquale Holsten # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:RootGroup) do provides "root_group" collect_data(:windows) do require "wmi-lite/wmi" wmi = WmiLite::Wmi.new # Per http://support.microsoft.com/kb/243330 SID: S-1-5-32-544 is the # internal name for the Administrators group, which lets us work # properly in environments with a renamed or localized name for the # Administrators group. # Use LocalAccount=True because otherwise WMI will attempt to include # (unneeded) Active Directory groups by querying AD, which is a performance # and reliability issue since AD might not be reachable. groups = wmi.query("select * from Win32_Group where sid like 'S-1-5-32-544' and LocalAccount=True") windows_root_group_name = groups[0]["name"] root_group windows_root_group_name end collect_data(:default) do root_group Etc.getgrgid(Etc.getpwnam("root").gid).name end end ohai-16.0.7/lib/ohai/plugins/ruby.rb000066400000000000000000000050051362624620500172100ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Ruby) do provides "languages/ruby" depends "languages" def run_ruby(command) cmd = "ruby -e \"require 'rbconfig'; #{command}\"" so = shell_out(cmd) so.stdout.strip end collect_data do languages[:ruby] = Mash.new values = { platform: "RUBY_PLATFORM", version: "RUBY_VERSION", release_date: "RUBY_RELEASE_DATE", target: "RbConfig::CONFIG['target']", target_cpu: "RbConfig::CONFIG['target_cpu']", target_vendor: "RbConfig::CONFIG['target_vendor']", target_os: "RbConfig::CONFIG['target_os']", host: "RbConfig::CONFIG['host']", host_cpu: "RbConfig::CONFIG['host_cpu']", host_os: "RbConfig::CONFIG['host_os']", host_vendor: "RbConfig::CONFIG['host_vendor']", bin_dir: "RbConfig::CONFIG['bindir']", ruby_bin: "::File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])", } # Create a query string from above hash env_string = "" values.each_key do |v| env_string << "#{v}=\#{#{values[v]}}," end # Query the system ruby result = run_ruby "puts %Q(#{env_string})" # Parse results to plugin hash result.split(",").each do |entry| key, value = entry.split("=") languages[:ruby][key.to_sym] = value || "" end # Perform one more (conditional) query bin_dir = languages[:ruby][:bin_dir] ruby_bin = languages[:ruby][:ruby_bin] gem_binaries = [ run_ruby("require 'rubygems'; puts ::Gem.default_exec_format % 'gem'"), "gem", ].map { |bin| ::File.join(bin_dir, bin) } gem_binary = gem_binaries.find { |bin| ::File.exist? bin } if gem_binary languages[:ruby][:gems_dir] = run_ruby "puts %x{#{ruby_bin} #{gem_binary} env gemdir}.chomp!" languages[:ruby][:gem_bin] = gem_binary end end end ohai-16.0.7/lib/ohai/plugins/rust.rb000066400000000000000000000020761362624620500172310ustar00rootroot00000000000000# Author:: Christopher M Luciano () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Rust) do provides "languages/rust" depends "languages" collect_data do so = shell_out("rustc --version") # Sample output: # rustc 1.7.0 if so.exitstatus == 0 rust = Mash.new rust[:version] = so.stdout.split[1] languages[:rust] = rust if rust[:version] end rescue Ohai::Exceptions::Exec logger.trace('Plugin Rust: Could not shell_out "rustc --version". Skipping plugin') end end ohai-16.0.7/lib/ohai/plugins/scala.rb000066400000000000000000000024361362624620500173170ustar00rootroot00000000000000# Author:: Christopher M Luciano () # Β© Copyright IBM Corporation 2015. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Scala) do provides "languages/scala" depends "languages" collect_data(:default) do scala = Mash.new begin so = shell_out("scala -version") # Sample output: # cat: /release: No such file or directory # Scala code runner version 2.12.1 -- Copyright 2002-2016, LAMP/EPFL and Lightbend, Inc. if so.exitstatus == 0 scala[:version] = so.stderr.match(/.*version (\S*)/)[1] end rescue Ohai::Exceptions::Exec logger.trace('Plugin Scala: Could not shell_out "scala -version". Skipping data') end languages[:scala] = scala unless scala.empty? end end ohai-16.0.7/lib/ohai/plugins/scaleway.rb000066400000000000000000000035501362624620500200420ustar00rootroot00000000000000# # Author:: Jonathan Amiez () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Scaleway) do require_relative "../mixin/scaleway_metadata" require_relative "../mixin/http_helper" include Ohai::Mixin::ScalewayMetadata include Ohai::Mixin::HttpHelper provides "scaleway" # looks for `scaleway` keyword in kernel command line # @return [Boolean] do we have the keyword or not? def has_scaleway_cmdline? if ::File.read("/proc/cmdline") =~ /scaleway/ logger.trace("Plugin Scaleway: has_scaleway_cmdline? == true") return true end logger.trace("Plugin Scaleway: has_scaleway_cmdline? == false") false end # a single check that combines all the various detection methods for Scaleway # @return [Boolean] Does the system appear to be on Scaleway def looks_like_scaleway? return true if hint?("scaleway") return true if has_scaleway_cmdline? && can_socket_connect?(Ohai::Mixin::ScalewayMetadata::SCALEWAY_METADATA_ADDR, 80) false end collect_data do if looks_like_scaleway? logger.trace("Plugin Scaleway: looks_like_scaleway? == true") scaleway Mash.new fetch_metadata.each do |k, v| scaleway[k] = v end else logger.trace("Plugin Scaleway: No hints present for and doesn't look like scaleway") end end end ohai-16.0.7/lib/ohai/plugins/scsi.rb000066400000000000000000000027731362624620500172010ustar00rootroot00000000000000# # Author:: Phil Dibowitz # Copyright:: Copyright (c) 2018 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Lsscsi) do depends "platform" provides "scsi" optional true require "mixlib/shellout" unless defined?(Mixlib::ShellOut::DEFAULT_READ_TIMEOUT) collect_data(:linux) do devices = Mash.new lsscsi = shell_out("lsscsi") lsscsi.stdout.each_line do |line| line_bits = line.split info = {} # The first three fields are consistent... info["scsi_addr"] = line_bits.shift[1..-2] info["type"] = line_bits.shift info["transport"] = line_bits.shift # After that the last two are consistent... info["device"] = line_bits.pop info["revision"] = line_bits.pop # What"s in the middle is the make and model... # which could have arbitrary spaces info["name"] = line_bits.join(" ") devices[info["scsi_addr"]] = info end scsi devices end end ohai-16.0.7/lib/ohai/plugins/shard.rb000066400000000000000000000064751362624620500173440ustar00rootroot00000000000000# # Author:: Phil Dibowitz # Copyright:: Copyright (c) 2016 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:ShardSeed) do depends "hostname", "dmi", "machine_id", "machinename", "fips", "hardware", "kernel" provides "shard_seed" def get_dmi_property(dmi, thing) %w{system base_board chassis}.each do |section| unless dmi[section][thing].strip.empty? return dmi[section][thing] end end end def default_sources case collect_os when "linux", "darwin", "windows" %i{machinename serial uuid} else [:machinename] end end def default_digest_algorithm if fips && fips["kernel"]["enabled"] # Even though it is being used safely, FIPS-mode will still blow up on # any use of MD5 so default to SHA2 instead. "sha256" else "md5" end end def digest_algorithm case Ohai.config[:plugin][:shard_seed][:digest_algorithm] || default_digest_algorithm when "md5" require "digest/md5" Digest::MD5 when "sha256" require "openssl/digest" OpenSSL::Digest::SHA256 end end # Common sources go here. Put sources that need to be different per-platform # under their collect_data block. def create_seed(&block) sources = Ohai.config[:plugin][:shard_seed][:sources] || default_sources data = "" sources.each do |src| data << case src when :fqdn fqdn when :hostname hostname when :machine_id machine_id when :machinename machinename else yield(src) end end shard_seed digest_algorithm.hexdigest(data)[0...7].to_i(16) end collect_data do create_seed do |src| raise "No such shard_seed source: #{src}" end end collect_data(:windows) do require "wmi-lite/wmi" wmi = WmiLite::Wmi.new create_seed do |src| case src when :serial wmi.first_of("Win32_BIOS")["SerialNumber"] when :os_serial kernel["os_info"]["serial_number"] when :uuid wmi.first_of("Win32_ComputerSystemProduct")["UUID"] else raise "No such shard_seed source: #{src}" end end end collect_data(:darwin) do create_seed do |src| case src when :serial hardware["serial_number"] when :uuid hardware["platform_UUID"] else raise "No such shard_seed source: #{src}" end end end collect_data(:linux) do create_seed do |src| case src when :serial get_dmi_property(dmi, :serial_number) when :uuid get_dmi_property(dmi, :uuid) else raise "No such shard_seed source: #{src}" end end end end ohai-16.0.7/lib/ohai/plugins/shells.rb000066400000000000000000000017461362624620500175310ustar00rootroot00000000000000# # Author:: Tim Smith () # Copyright:: Copyright (c) 2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Shells) do provides "shells" collect_data do if ::File.exist?("/etc/shells") shells [] ::File.readlines("/etc/shells").each do |line| # remove carriage returns and skip over comments / empty lines shells << line.chomp if line[0] == "/" end end end end ohai-16.0.7/lib/ohai/plugins/softlayer.rb000066400000000000000000000027371362624620500202500ustar00rootroot00000000000000# # Author:: Alexey Karpik # Author:: Peter Schroeter # Author:: Stas Turlo # Copyright:: Copyright (c) 2010-2014 RightScale Inc # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Softlayer) do require_relative "../mixin/softlayer_metadata" include ::Ohai::Mixin::SoftlayerMetadata provides "softlayer" # Identifies the softlayer cloud # # === Return # true:: If the softlayer cloud can be identified # false:: Otherwise def looks_like_softlayer? hint?("softlayer") end collect_data do # Adds softlayer Mash if looks_like_softlayer? logger.trace("Plugin Softlayer: looks_like_softlayer? == true") metadata = fetch_metadata softlayer Mash.new metadata.each { |k, v| softlayer[k] = v } if metadata else logger.trace("Plugin Softlayer: looks_like_softlayer? == false") end end end ohai-16.0.7/lib/ohai/plugins/solaris2/000077500000000000000000000000001362624620500174405ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/solaris2/dmi.rb000066400000000000000000000200331362624620500205340ustar00rootroot00000000000000# # Author:: Kurt Yoder (ktyopscode@yoderhome.com) # Copyright:: Copyright (c) 2010 Kurt Yoder # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:DMI) do provides "dmi" collect_data(:solaris2) do require_relative "../../common/dmi" # if we already have a "dmi" with keys (presumably from dmidecode), don't try smbios # note that a single key just means dmidecode exited with its version if dmi.is_a?(Mash) && dmi.keys.length > 1 logger.trace("Plugin DMI: skipping smbios output, since DMI information has already been provided") return end dmi Mash.new # bad Solaris shows strings defined by system instead of SMB IDs # this is what the *real* IDs are: # pulled from http://src.opensolaris.org/source/xref/nwam/nwam1/usr/src/uts/common/sys/smbios.h smb_to_id = { "SMB_TYPE_BIOS" => 0, # BIOS information (R) "SMB_TYPE_SYSTEM" => 1, # system information (R) "SMB_TYPE_BASEBOARD" => 2, # base board "SMB_TYPE_CHASSIS" => 3, # system enclosure or chassis (R) "SMB_TYPE_PROCESSOR" => 4, # processor (R) "SMB_TYPE_MEMCTL" => 5, # memory controller (O) "SMB_TYPE_MEMMOD" => 6, # memory module (O) "SMB_TYPE_CACHE" => 7, # processor cache (R) "SMB_TYPE_PORT" => 8, # port connector "SMB_TYPE_SLOT" => 9, # upgradeable system slot (R) "SMB_TYPE_OBDEVS" => 10, # on-board devices "SMB_TYPE_OEMSTR" => 11, # OEM string table "SMB_TYPE_SYSCONFSTR" => 12, # system configuration string table "SMB_TYPE_LANG" => 13, # BIOS language information "SMB_TYPE_GROUP" => 14, # group associations "SMB_TYPE_EVENTLOG" => 15, # system event log "SMB_TYPE_MEMARRAY" => 16, # physical memory array (R) "SMB_TYPE_MEMDEVICE" => 17, # memory device (R) "SMB_TYPE_MEMERR32" => 18, # 32-bit memory error information "SMB_TYPE_MEMARRAYMAP" => 19, # memory array mapped address (R) "SMB_TYPE_MEMDEVICEMAP" => 20, # memory device mapped address (R) "SMB_TYPE_POINTDEV" => 21, # built-in pointing device "SMB_TYPE_BATTERY" => 22, # portable battery "SMB_TYPE_RESET" => 23, # system reset settings "SMB_TYPE_SECURITY" => 24, # hardware security settings "SMB_TYPE_POWERCTL" => 25, # system power controls "SMB_TYPE_VPROBE" => 26, # voltage probe "SMB_TYPE_COOLDEV" => 27, # cooling device "SMB_TYPE_TPROBE" => 28, # temperature probe "SMB_TYPE_IPROBE" => 29, # current probe "SMB_TYPE_OOBRA" => 30, # out-of-band remote access facility "SMB_TYPE_BIS" => 31, # boot integrity services "SMB_TYPE_BOOT" => 32, # system boot status (R) "SMB_TYPE_MEMERR64" => 33, # 64-bit memory error information "SMB_TYPE_MGMTDEV" => 34, # management device "SMB_TYPE_MGMTDEVCP" => 35, # management device component "SMB_TYPE_MGMTDEVDATA" => 36, # management device threshold data "SMB_TYPE_MEMCHAN" => 37, # memory channel "SMB_TYPE_IPMIDEV" => 38, # IPMI device information "SMB_TYPE_POWERSUP" => 39, # system power supply "SMB_TYPE_ADDINFO" => 40, # additional information "SMB_TYPE_OBDEVEXT" => 41, # on-board device extended info "SMB_TYPE_MCHI" => 42, # mgmt controller host interface "SMB_TYPE_INACTIVE" => 126, # inactive table entry "SMB_TYPE_EOT" => 127, # end of table "SMB_TYPE_OEM_LO" => 128, # start of OEM-specific type range "SUN_OEM_EXT_PROCESSOR" => 132, # processor extended info "SUN_OEM_PCIEXRC" => 138, # PCIE RootComplex/RootPort info "SUN_OEM_EXT_MEMARRAY" => 144, # phys memory array extended info "SUN_OEM_EXT_MEMDEVICE" => 145, # memory device extended info "SMB_TYPE_OEM_HI" => 256, # end of OEM-specific type range } # all output lines should fall within one of these patterns header_type_line = /^ID\s+SIZE\s+TYPE/ header_information_line = /^(\d+)\s+(\d+)\s+(\S+)\s+\(([^\)]+)\)/ blank_line = /^\s*$/ data_key_value_line = /^ ([^:]+): (.*)/ data_key_only_line = /^ (\S.*)(:\s*)?$/ extended_data_line = /^\t(\S+) \((.+)\)/ dmi_record = nil field = nil so = shell_out("smbios") # ==== EXAMPLE: ==== # ID SIZE TYPE # 0 40 SMB_TYPE_BIOS (BIOS information) # # Vendor: HP # Version String: 2.16 # ... similar lines trimmed # Characteristics: 0x7fc9da80 # SMB_BIOSFL_PCI (PCI is supported) # ... similar lines trimmed # note the second level of indentation is via a *tab* so.stdout.lines do |raw_line| next if header_type_line.match(raw_line) next if blank_line.match(raw_line) # remove/replace any characters that don't fall inside permissible ASCII range, or whitespace line = raw_line.gsub(/[^\x20-\x7E\n\t\r]/, ".") if line != raw_line logger.trace("Plugin DMI: converted characters from line:\n#{raw_line}") end if ( header_information = header_information_line.match(line) ) dmi_record = {} # look up SMB ID if smb_to_id.key?(header_information[3]) id = smb_to_id[header_information[3]] # Don't overcapture for now (OHAI-260) unless Ohai::Common::DMI.whitelisted_ids.include?(id) dmi_record = nil next end dmi_record[:type] = Ohai::Common::DMI.id_lookup(id) else logger.trace("Plugin DMI: unrecognized header type; skipping") dmi_record = nil next end dmi[dmi_record[:type]] ||= Mash.new dmi[dmi_record[:type]][:all_records] = [] unless dmi[dmi_record[:type]].key?(:all_records) dmi_record[:position] = dmi[dmi_record[:type]][:all_records].length dmi[dmi_record[:type]][:all_records].push(Mash.new) dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:record_id] = header_information[1] dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:size] = header_information[2] dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:application_identifier] = header_information[4] field = nil elsif ( data = data_key_value_line.match(line) ) if dmi_record.nil? logger.trace("Plugin DMI: unexpected data line found before header; discarding:\n#{line}") next end dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = data[2] field = data[1] elsif ( data = data_key_only_line.match(line) ) if dmi_record.nil? logger.trace("Plugin DMI: unexpected data line found before header; discarding:\n#{line}") next end dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = "" field = data[1] elsif ( extended_data = extended_data_line.match(line) ) if dmi_record.nil? logger.trace("Plugin DMI: unexpected extended data line found before header; discarding:\n#{line}") next end if field.nil? logger.trace("Plugin DMI: unexpected extended data line found outside data section; discarding:\n#{line}") next end # overwrite "raw" value with a new Mash dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field] = Mash.new unless dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field].is_a?(Mash) dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field][extended_data[1]] = extended_data[2] else logger.trace("Plugin DMI: unrecognized output line; discarding:\n#{line}") end end Ohai::Common::DMI.convenience_keys(dmi) end end ohai-16.0.7/lib/ohai/plugins/solaris2/memory.rb000066400000000000000000000021231362624620500212730ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory" collect_data(:solaris2) do memory Mash.new memory[:swap] = Mash.new meminfo = shell_out("prtconf | grep Memory").stdout memory[:total] = "#{meminfo.split[2].to_i * 1024}kB" tokens = shell_out("swap -s").stdout.strip.split used_swap = tokens[8][0..-1].to_i # strip k from end free_swap = tokens[10][0..-1].to_i # strip k from end memory[:swap][:total] = "#{used_swap + free_swap}kB" memory[:swap][:free] = "#{free_swap}kB" end end ohai-16.0.7/lib/ohai/plugins/solaris2/network.rb000066400000000000000000000172251362624620500214650ustar00rootroot00000000000000# # Author:: Benjamin Black () # Copyright:: Copyright (c) 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # EXAMPLE SOLARIS IFCONFIG OUTPUT; CURRENTLY, ONLY SIMPLE STUFF IS SUPPORTED (E.G., NO TUNNELS) # DEAR SUN: YOU GET AN F FOR YOUR IFCONFIG # lo0:3: flags=2001000849 mtu 8232 index 1 # inet 127.0.0.1 netmask ff000000 # e1000g0:3: flags=201000843 mtu 1500 index 3 # inet 72.2.115.28 netmask ffffff80 broadcast 72.2.115.127 # e1000g2:1: flags=201000843 mtu 1500 index 4 # inet 10.2.115.28 netmask ffffff80 broadcast 10.2.115.127 # inet6 2001:0db8:3c4d:55:a00:20ff:fe8e:f3ad/64 # ip.tun0: flags=2200851 mtu 1480 index 3 # inet tunnel src 109.146.85.57 tunnel dst 109.146.85.212 # tunnel security settings --> use 'ipsecconf -ln -i ip.tun1' # tunnel hop limit 60 # inet6 fe80::6d92:5539/10 --> fe80::6d92:55d4 # ip.tun0:1: flags=2200851 mtu 1480 index 3 # inet6 2::45/128 --> 2::46 # lo0: flags=1000849 mtu 8232 index 1 # inet 127.0.0.1 netmask ff000000 # eri0: flags=1004843 mtu 1500 \ # index 2 # inet 172.17.128.208 netmask ffffff00 broadcast 172.17.128.255 # ip6.tun0: flags=10008d1 \ # mtu 1460 # index 3 # inet6 tunnel src fe80::1 tunnel dst fe80::2 # tunnel security settings --> use 'ipsecconf -ln -i ip.tun1' # tunnel hop limit 60 tunnel encapsulation limit 4 # inet 10.0.0.208 --> 10.0.0.210 netmask ff000000 # qfe1: flags=2000841 mtu 1500 index 3 # usesrc vni0 # inet6 fe80::203:baff:fe17:4be0/10 # ether 0:3:ba:17:4b:e0 # vni0: flags=2002210041 mtu 0 # index 5 # srcof qfe1 # inet6 fe80::203:baff:fe17:4444/128 # Extracted from http://illumos.org/hcl/ unless defined?(ETHERNET_ENCAPS) ETHERNET_ENCAPS = %w{ afe amd8111s arn atge ath bfe bge bnx bnxe ce cxgbe dmfe e1000g efe elxl emlxs eri hermon hme hxge igb iprb ipw iwh iwi iwk iwp ixgb ixgbe mwl mxfe myri10ge nge ntxn nxge pcn platform qfe qlc ral rge rtls rtw rwd rwn sfe tavor vr wpi xge yge aggr}.freeze end Ohai.plugin(:Network) do require_relative "../../mixin/network_helper" provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" include Ohai::Mixin::NetworkHelper def solaris_encaps_lookup(ifname) return "Ethernet" if ETHERNET_ENCAPS.include?(ifname) return "Ethernet" if ifname.eql?("net") return "Loopback" if ifname.eql?("lo") "Unknown" end def arpname_to_ifname(iface, arpname) iface.each_key do |ifn| return ifn if ifn.split(":")[0].eql?(arpname) end nil end def full_interface_name(iface, part_name, index) iface.each do |name, attrs| next unless attrs && attrs.respond_to?(:[]) return name if /^#{part_name}($|:)/.match(name) && attrs[:index] == index end nil end collect_data(:solaris2) do iface = Mash.new network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new so = shell_out("ifconfig -a") cint = nil so.stdout.lines do |line| # regex: https://rubular.com/r/ZiIHbsnfiWPW1p if line =~ /^([0-9a-zA-Z\.\:\-]+): \S+ mtu (\d+)(?: index (\d+))?/ cint = $1 iface[cint] ||= Mash.new iface[cint][:mtu] = $2 iface[cint][:index] = $3 if line =~ / flags\=\d+\<((ADDRCONF|ANYCAST|BROADCAST|CoS|DEPRECATED|DHCP|DUPLICATE|FAILED|FIXEDMTU|INACTIVE|L3PROTECT|LOOPBACK|MIP|MULTI_BCAST|MULTICAST|NOARP|NOFAILOVER|NOLOCAL|NONUD|NORTEXCH|NOXMIT|OFFLINE|PHYSRUNNING|POINTOPOINT|PREFERRED|PRIVATE|ROUTER|RUNNING|STANDBY|TEMPORARY|UNNUMBERED|UP|VIRTUAL|XRESOLV|IPv4|IPv6|,)+)\>\s/ flags = $1.split(",") else flags = [] end iface[cint][:flags] = flags.flatten if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 iface[cint][:encapsulation] = solaris_encaps_lookup($1) end end if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask (([0-9a-f]){1,8})\s*$/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => hex_to_dec_netmask($2) } end if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask (([0-9a-f]){1,8}) broadcast (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => hex_to_dec_netmask($2) , "broadcast" => $4 } end if line =~ %r{\s+inet6 ([a-f0-9\:]+)(\s*|(\%[a-z0-9]+)\s*)/(\d+)\s*$} iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $4 } end end # Device IP Address Mask Flags Phys Addr # bge1 172.16.0.129 255.255.255.255 SPLA 00:03:ba:xx:xx:xx so = shell_out("arp -an") so.stdout.lines do |line| if line =~ /([0-9a-zA-Z]+)\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\w+)?\s+([a-zA-Z0-9\.\:\-]+)/ next unless iface[arpname_to_ifname(iface, $1)] # this should never happen, except on solaris because sun hates you. iface[arpname_to_ifname(iface, $1)][:arp] ||= Mash.new iface[arpname_to_ifname(iface, $1)][:arp][$2] = $5 end end iface.each_key do |ifn| iaddr = nil if iface[ifn][:encapsulation].eql?("Ethernet") iface[ifn][:addresses].each_key do |addr| if iface[ifn][:addresses][addr]["family"].eql?("inet") iaddr = addr break end end if iface[ifn][:arp] iface[ifn][:arp].each_key do |addr| if addr.eql?(iaddr) iface[ifn][:addresses][iface[ifn][:arp][iaddr]] = { "family" => "lladdr" } break end end end end end network[:interfaces] = iface so = shell_out("route -v -n get default") so.stdout.lines do |line| matches = /interface: (?\S+)\s+index\s+(?\d+)/.match(line) if matches network[:default_interface] = case when iface[matches[:name]] matches[:name] when int_name = full_interface_name(iface, matches[:name], matches[:index]) int_name else matches[:name] end logger.trace("Plugin Network: found interface device: #{network[:default_interface]} #{matches[:name]}") end matches = /gateway: (\S+)/.match(line) if matches logger.trace("Plugin Network: found gateway: #{matches[1]}") network[:default_gateway] = matches[1] end end end end ohai-16.0.7/lib/ohai/plugins/solaris2/platform.rb000066400000000000000000000035621362624620500216170ustar00rootroot00000000000000# # Author:: Benjamin Black () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_build", "platform_family" collect_data(:solaris2) do if File.exist?("/sbin/uname") uname_exec = "/sbin/uname" else uname_exec = "uname" end so = shell_out("#{uname_exec} -X") so.stdout.lines do |line| case line when /^Release =\s+(.+)$/ platform_version $1 when /^KernelID =\s+(.+)$/ platform_build $1 end end File.open("/etc/release") do |file| while ( line = file.gets ) case line when /^.*(SmartOS).*$/ platform "smartos" when /^\s*(OmniOS).*r(\d+).*$/ platform "omnios" platform_version $2 when /^\s*(OpenIndiana).*oi_(\d+).*$/ platform "openindiana" platform_version $2 when /^\s*(OpenSolaris).*snv_(\d+).*$/ platform "opensolaris" platform_version $2 when /^\s*(Oracle Solaris)/ platform "solaris2" when /^\s*(Solaris)\s.*$/ platform "solaris2" when /^\s*(NexentaCore)\s.*$/ platform "nexentacore" end end end platform_family platform end end ohai-16.0.7/lib/ohai/plugins/solaris2/virtualization.rb000066400000000000000000000062061362624620500230550ustar00rootroot00000000000000# # Author:: Sean Walbran () # Author:: Kurt Yoder () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2010 Kurt Yoder # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualization) do require_relative "../../mixin/dmi_decode" include Ohai::Mixin::DmiDecode provides "virtualization" depends "dmi" def collect_solaris_guestid command = "/usr/sbin/zoneadm list -p" so = shell_out(command) so.stdout.split(":").first end collect_data(:solaris2) do virtualization Mash.new virtualization[:systems] = Mash.new # Detect paravirt KVM/QEMU from cpuinfo, report as KVM psrinfo_path = Ohai.abs_path( "/usr/sbin/psrinfo" ) if File.exist?(psrinfo_path) so = shell_out("#{psrinfo_path} -pv") if so.stdout =~ /QEMU Virtual CPU|Common KVM processor|Common 32-bit KVM processor/ virtualization[:system] = "kvm" virtualization[:role] = "guest" virtualization[:systems][:kvm] = "guest" end end # parse dmi to discover various virtualization guests guest = guest_from_dmi_data(get_attribute(:dmi, :system, :manufacturer), get_attribute(:dmi, :system, :product), get_attribute(:dmi, :system, :version)) if guest logger.trace("Plugin Virtualization: DMI data indicates #{guest} guest") virtualization[:system] = guest virtualization[:role] = "guest" virtualization[:systems][guest.to_sym] = "guest" end if File.executable?("/usr/sbin/zoneadm") zones = Mash.new so = shell_out("zoneadm list -pc") so.stdout.lines do |line| info = line.chomp.split(/:/) zones[info[1]] = { "id" => info[0], "state" => info[2], "root" => info[3], "uuid" => info[4], "brand" => info[5], "ip" => info[6], } end if zones.length == 1 first_zone = zones.keys[0] if first_zone == "global" virtualization[:system] = "zone" virtualization[:role] = "host" virtualization[:systems][:zone] = "host" else virtualization[:system] = "zone" virtualization[:role] = "guest" virtualization[:systems][:zone] = "guest" virtualization[:guest_uuid] = zones[first_zone]["uuid"] virtualization[:guest_id] = collect_solaris_guestid end elsif zones.length > 1 virtualization[:system] = "zone" virtualization[:role] = "host" virtualization[:systems][:zone] = "host" virtualization[:guests] = zones end end end end ohai-16.0.7/lib/ohai/plugins/ssh_host_key.rb000066400000000000000000000053671362624620500207440ustar00rootroot00000000000000# # Author:: Bryan McLellan # Copyright:: Copyright (c) 2012-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:SSHHostKey) do provides "keys/ssh" depends "keys" def extract_keytype?(content) case content[0] when "ssh-dss" [ "dsa", nil ] when "ssh-rsa" [ "rsa", nil ] when /^ecdsa/ [ "ecdsa", content[0] ] when "ssh-ed25519" [ "ed25519", nil ] else [ nil, nil ] end end collect_data do keys[:ssh] = Mash.new sshd_config = if File.exist?("/etc/ssh/sshd_config") "/etc/ssh/sshd_config" elsif File.exist?("/etc/sshd_config") # Darwin "/etc/sshd_config" else logger.trace("Plugin SSHHostKey: Failed to find sshd configuration file") nil end if sshd_config File.open(sshd_config) do |conf| conf.each_line do |line| if line =~ /^hostkey\s/i pub_file = "#{line.split[1]}.pub" content = IO.read(pub_file).split key_type, key_subtype = extract_keytype?(content) keys[:ssh]["host_#{key_type}_public"] = content[1] unless key_type.nil? keys[:ssh]["host_#{key_type}_type"] = key_subtype unless key_subtype.nil? end end end end if keys[:ssh][:host_dsa_public].nil? && File.exist?("/etc/ssh/ssh_host_dsa_key.pub") keys[:ssh][:host_dsa_public] = IO.read("/etc/ssh/ssh_host_dsa_key.pub").split[1] end if keys[:ssh][:host_rsa_public].nil? && File.exist?("/etc/ssh/ssh_host_rsa_key.pub") keys[:ssh][:host_rsa_public] = IO.read("/etc/ssh/ssh_host_rsa_key.pub").split[1] end if keys[:ssh][:host_ecdsa_public].nil? && File.exist?("/etc/ssh/ssh_host_ecdsa_key.pub") content = IO.read("/etc/ssh/ssh_host_ecdsa_key.pub") keys[:ssh][:host_ecdsa_public] = content.split[1] keys[:ssh][:host_ecdsa_type] = content.split[0] end if keys[:ssh][:host_ed25519_public].nil? && File.exist?("/etc/ssh/ssh_host_ed25519_key.pub") keys[:ssh][:host_ed25519_public] = IO.read("/etc/ssh/ssh_host_ed25519_key.pub").split[1] end end end ohai-16.0.7/lib/ohai/plugins/sysconf.rb000066400000000000000000000024441362624620500177170ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Sysconf) do provides "sysconf" collect_data(:aix, :linux, :solaris2) do getconf_path = which("getconf") if getconf_path getconf = shell_out("#{getconf_path} -a") if getconf.exitstatus == 0 sysconf Mash.new unless sysconf getconf.stdout.split("\n").each do |line| key, val = /^(\S+)\s*(.*)?$/.match(line).captures if val && !val.empty? begin sysconf[key] = Integer(val) rescue sysconf[key] = val end else sysconf[key] = nil end end end end end end ohai-16.0.7/lib/ohai/plugins/timezone.rb000066400000000000000000000014431362624620500200630ustar00rootroot00000000000000# # Author:: John Bellone () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Ohai.plugin(:Timezone) do provides "time/timezone" collect_data(:default) do time Mash.new unless time time[:timezone] = Time.now.getlocal.zone end end ohai-16.0.7/lib/ohai/plugins/uptime.rb000066400000000000000000000057601362624620500175420ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Bryan McLellan () # Author:: Claire McQuin () # Author:: Doug MacEachern () # Author:: Kurt Yoder () # Author:: Paul Mooring () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2009 Bryan McLellan # Copyright:: Copyright (c) 2010 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Uptime) do require_relative "../mixin/seconds_to_human" provides "uptime", "uptime_seconds" provides "idletime", "idletime_seconds" # linux only def collect_uptime(path) # kern.boottime: { sec = 1232765114, usec = 823118 } Fri Jan 23 18:45:14 2009 so = shell_out("#{Ohai.abs_path(path)} kern.boottime") so.stdout.lines do |line| if line =~ /kern.boottime:\D+(\d+)/ usec = Time.new.to_i - $1.to_i return [usec, seconds_to_human(usec)] end end [nil, nil] end collect_data(:darwin) do data = collect_uptime("/usr/sbin/sysctl") uptime_seconds data.first uptime data.last end collect_data(:freebsd, :netbsd, :dragonflybsd) do data = collect_uptime("/sbin/sysctl") uptime_seconds data.first uptime data.last end collect_data(:linux) do uptime, idletime = File.open("/proc/uptime").gets.split(" ") uptime_seconds uptime.to_i uptime seconds_to_human(uptime.to_i) idletime_seconds idletime.to_i idletime seconds_to_human(idletime.to_i) end collect_data(:openbsd) do # kern.boottime=Tue Nov 1 14:45:52 2011 so = shell_out("#{Ohai.abs_path( "/sbin/sysctl" )} #kern.boottime") so.stdout.lines do |line| if line =~ /kern.boottime=(.+)/ uptime_seconds Time.new.to_i - Time.parse($1).to_i uptime seconds_to_human(uptime_seconds) end end end collect_data(:solaris2) do so = shell_out("kstat -p unix:0:system_misc:boot_time") # unix:0:system_misc:boot_time 1343860543 so.stdout.lines do |line| if line =~ /unix:0:system_misc:boot_time\s+(\d+)/ uptime_seconds Time.new.to_i - $1.to_i uptime seconds_to_human(uptime_seconds) end end end collect_data(:windows) do require "wmi-lite/wmi" wmi = WmiLite::Wmi.new last_boot_up_time = wmi.first_of("Win32_OperatingSystem")["lastbootuptime"] uptime_seconds Time.new.to_i - Time.parse(last_boot_up_time).to_i uptime seconds_to_human(uptime_seconds) end end ohai-16.0.7/lib/ohai/plugins/virtualbox.rb000066400000000000000000000155361362624620500204400ustar00rootroot00000000000000# # Author:: Tim Smith # Author:: Joshua Colson # Copyright:: 2015-2019 Chef Software, Inc. # Copyright:: 2019 Joshua Colson # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualbox) do depends "virtualization" provides "virtualbox" # query virtualbox for each configured vm, as well as # each guest's individual configuration settings def vboxmanage_list_vms vms = Mash.new so_cmd = "VBoxManage list --sorted vms" logger.trace(so_cmd) so = shell_out(so_cmd) if so.exitstatus == 0 # parse the output so.stdout.lines.each do |line| case line when /^"(\S*)" \{(\S*)\}$/ name = Regexp.last_match(1) uuid = Regexp.last_match(2) vms[name] = vboxmanage_vminfo(uuid) end end end vms rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not run 'VBoxManage list --sorted vms'. Skipping data") end # query the vminfo for particular guest instance, normalizing # the fields so that they're not enclosed in double-quotes (") def vboxmanage_vminfo(machine_id) vm = Mash.new so_cmd = "VBoxManage showvminfo #{machine_id} --machinereadable" logger.trace(so_cmd) so = shell_out(so_cmd) if so.exitstatus == 0 so.stdout.lines.each do |line| line.chomp! left, right = line.split("=") # remove enclosing quotes, if needed key = left.delete_prefix('"').delete_suffix('"') # skip the name attribute since that is the parent key next if key == "name" vm[key.downcase] = right.delete_prefix('"').delete_suffix('"') end end vm rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not run '#{so_cmd}'. Skipping data") end # query virtualbox for a list of #{query_type} items # these queries return a result set that is delimited by # multiple successive newlines, with each block containing # key/value pairs delimited by a colon (:) and column aligned # # the keys of each k/v pair are normalized to lowercase def vboxmanage_list_blocks(query_type, name_key) # ignore unrecognized query type supported_queries = %w{ bridgedifs dhcpservers dvds hdds hostdvds hostfloppies hostonlyifs natnets } return nil unless supported_queries.include? query_type results = Mash.new so_cmd = "VBoxManage list --sorted #{query_type}" logger.trace(so_cmd) so = shell_out(so_cmd) # raise an exception if the command fails # so.error! if so.exitstatus == 0 # break the result into paragraph blocks, on successive newlines so.stdout.each_line("") do |blk| # remove the multiple newlines of each record blk.chomp!.chomp! # initialize a blank record hash record = Mash.new # parse the record block into key/value pairs blk.each_line do |line| next unless line.include? ":" # split the line into key/value pair key, right = line.split(":", 2) # strip the leading/trailing whitespace if the value is not nil value = right.nil? ? "" : right.strip record[key.downcase] = value end # insert the record into the list of results if record.key? name_key.downcase name = record.delete(name_key.downcase) results[name] = record end end end results rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not run '#{so_cmd}'. Skipping data") end collect_data(:default) do case virtualization.dig("systems", "vbox") when "guest" logger.trace("Plugin Virtualbox: Node detected as vbox guest. Collecting guest data.") begin so = shell_out("VBoxControl guestproperty enumerate") if so.exitstatus == 0 virtualbox Mash.new virtualbox[:host] = Mash.new virtualbox[:guest] = Mash.new so.stdout.lines.each do |line| case line when /LanguageID, value: (\S*),/ virtualbox[:host][:language] = Regexp.last_match(1) when /VBoxVer, value: (\S*),/ virtualbox[:host][:version] = Regexp.last_match(1) when /VBoxRev, value: (\S*),/ virtualbox[:host][:revision] = Regexp.last_match(1) when %r{GuestAdd/VersionExt, value: (\S*),} virtualbox[:guest][:guest_additions_version] = Regexp.last_match(1) when %r{GuestAdd/Revision, value: (\S*),} virtualbox[:guest][:guest_additions_revision] = Regexp.last_match(1) end end end rescue Ohai::Exceptions::Exec logger.trace('Plugin Virtualbox: Could not execute "VBoxControl guestproperty enumerate". Skipping data collection.') end when "host" logger.trace("Plugin Virtualbox: Node detected as vbox host. Collecting host data.") virtualbox Mash.new begin # get a list of virtualbox guest vms virtualbox["guests"] = vboxmanage_list_vms # get a list of virtualbox virtual hard disk drives virtualbox["hdds"] = vboxmanage_list_blocks("hdds", "Location") # get a list of virtualbox virtual dvd drives virtualbox["dvds"] = vboxmanage_list_blocks("dvds", "Location") # get a list of virtualbox host dvd drives virtualbox["hostdvds"] = vboxmanage_list_blocks("hostdvds", "Name") # get a list of virtualbox host floppy drives virtualbox["hostfloppies"] = vboxmanage_list_blocks("hostfloppies", "Name") # get a list of virtualbox hostonly network interfaces virtualbox["hostonlyifs"] = vboxmanage_list_blocks("hostonlyifs", "Name") # get a list of virtualbox bridged network interfaces virtualbox["bridgedifs"] = vboxmanage_list_blocks("bridgedifs", "Name") # get a list of virtualbox dhcp servers virtualbox["dhcpservers"] = vboxmanage_list_blocks("dhcpservers", "NetworkName") # get a list of virtualbox nat networks virtualbox["natnets"] = vboxmanage_list_blocks("natnets", "NetworkName") rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not collect data for VirtualBox host. Skipping data") end else logger.trace("Plugin Virtualbox: Not on a Virtualbox host or guest. Skipping plugin.") end end end ohai-16.0.7/lib/ohai/plugins/vmware.rb000066400000000000000000000047641362624620500175430ustar00rootroot00000000000000# # Author:: "Dan Robinson" # Author:: "Christopher M. Luciano" # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # Copyright (C) 2015 IBM Corp. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Provides a set of attributes for a VMware ESX virtual machine with results # obtained from vmware-toolbox-cmd. VMware Tools must be installed # on the virtual machine. # # Modify the path to vmware-toolbox-cmd in the call to get_vm_attributes for # your particular operating system and configuration # # Example: # # get_vm_attributes("/usr/bin/vmware-toolbox-cmd") # Ohai.plugin(:VMware) do provides "vmware" depends "virtualization" def from_cmd(cmd) so = shell_out(cmd) so.stdout.split($/)[0] end def get_vm_attributes(vmtools_path) if !File.exist?(vmtools_path) logger.trace("Plugin VMware: #{vmtools_path} not found") else vmware Mash.new begin # vmware-toolbox-cmd stat commands # Iterate through each parameter supported by the "vwware-toolbox-cmd stat" command, assign value # to attribute "vmware[:]" %w{hosttime speed sessionid balloon swap memlimit memres cpures cpulimit}.each do |param| vmware[param] = from_cmd("#{vmtools_path} stat #{param}") if vmware[param] =~ /UpdateInfo failed/ vmware[param] = nil end end # vmware-toolbox-cmd status commands # Iterate through each parameter supported by the "vwware-toolbox-cmd status" command, assign value # to attribute "vmware[:]" %w{upgrade timesync}.each do |param| vmware[param] = from_cmd("#{vmtools_path} #{param} status") end rescue logger.trace("Plugin VMware: Error while collecting VMware guest attributes") end end end collect_data(:linux) do get_vm_attributes("/usr/bin/vmware-toolbox-cmd") if virtualization[:systems][:vmware] end end ohai-16.0.7/lib/ohai/plugins/windows/000077500000000000000000000000001362624620500173745ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/plugins/windows/drivers.rb000066400000000000000000000032211362624620500213750ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2015 Chef Software # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Drivers) do provides "kernel/pnp_drivers", "kernel/modules" depends "kernel" collect_data(:windows) do if configuration(:enabled) require "wmi-lite/wmi" kext = Mash.new pnp_drivers = Mash.new wmi = WmiLite::Wmi.new drivers = wmi.instances_of("Win32_PnPSignedDriver") drivers.each do |driver| pnp_drivers[driver["deviceid"]] = Mash.new driver.wmi_ole_object.properties_.each do |p| pnp_drivers[driver["deviceid"]][p.name.wmi_underscore.to_sym] = driver[p.name.downcase] end if driver["devicename"] kext[driver["devicename"]] = pnp_drivers[driver["deviceid"]] kext[driver["devicename"]][:version] = pnp_drivers[driver["deviceid"]][:driver_version] kext[driver["devicename"]][:date] = pnp_drivers[driver["deviceid"]][:driver_date] ? pnp_drivers[driver["deviceid"]][:driver_date].to_s[0..7] : nil end end kernel[:pnp_drivers] = pnp_drivers kernel[:modules] = kext end end end ohai-16.0.7/lib/ohai/plugins/windows/fips.rb000066400000000000000000000024771362624620500206740ustar00rootroot00000000000000# # Author:: Matt Wrock () # Copyright:: Copyright (c) 2016-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # After long discussion in IRC the "powers that be" have come to a concensus # that there is no other Windows platforms exist that were not based on the # Windows_NT kernel, so we herby decree that "windows" will refer to all # platforms built upon the Windows_NT kernel and have access to win32 or win64 # subsystems. Ohai.plugin(:Fips) do provides "fips" collect_data(:windows) do fips Mash.new require "openssl" unless defined?(OpenSSL) if defined?(OpenSSL.fips_mode) && OpenSSL.fips_mode && !$FIPS_TEST_MODE fips["kernel"] = { "enabled" => true } else fips["kernel"] = { "enabled" => false } end end end ohai-16.0.7/lib/ohai/plugins/windows/memory.rb000066400000000000000000000021441362624620500212320ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Memory) do provides "memory" collect_data(:windows) do require "wmi-lite/wmi" memory Mash.new memory[:swap] = Mash.new wmi = WmiLite::Wmi.new os = wmi.first_of("Win32_OperatingSystem") # MemTotal memory[:total] = os["TotalVisibleMemorySize"] + "kB" # MemFree memory[:free] = os["FreePhysicalMemory"] + "kB" # SwapTotal memory[:swap][:total] = os["SizeStoredInPagingFiles"] + "kB" # SwapFree memory[:swap][:free] = os["FreeSpaceInPagingFiles"] + "kB" end end ohai-16.0.7/lib/ohai/plugins/windows/network.rb000066400000000000000000000175671362624620500214320ustar00rootroot00000000000000# # Author:: James Gartrell () # Copyright:: Copyright (c) 2008-2017, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do provides "network", "network/interfaces" provides "counters/network", "counters/network/interfaces" def windows_encaps_lookup(encap) return "Ethernet" if encap.eql?("Ethernet 802.3") encap end def mac_addresses(iface) prop = iface[:configuration][:mac_address] || iface[:instance][:network_addresses] [prop].flatten.map { |addr| addr.include?(":") ? addr : addr.scan(/.{1,2}/).join(":") } end def network_data @network_data ||= begin data = {} wmi = WmiLite::Wmi.new data[:addresses] = wmi.instances_of("Win32_NetworkAdapterConfiguration") # If we are running on windows nano or another operating system from the future # that does not populate the deprecated win32_* WMI classes, then we should # grab data from the newer MSFT_* classes return msft_adapter_data if data[:addresses].count == 0 data[:adapters] = wmi.instances_of("Win32_NetworkAdapter") data end end def msft_adapter_data data = {} wmi = WmiLite::Wmi.new("ROOT/StandardCimv2") data[:addresses] = wmi.instances_of("MSFT_NetIPAddress") data[:adapters] = wmi.instances_of("MSFT_NetAdapter") data end # Returns interface code for an interface # # Interface Index (if present, Index otherwise) will be converted in hexadecimal format # # @param int_idx [String or nil] the interface index of interface # @param idx [String] the index of interface # # @return [String] # # @example Interface Code when interface index is present # plugin.interface_code("1", "1") #=> "ox1" # @example Interface Code when interface index is not present # plugin.interface_code(nil, "2") #=> "ox2" # def interface_code(int_idx, idx) sprintf("0x%x", (int_idx || idx)).downcase end # Returns IPV4 address from list of addresses containing IPV4 and IPV6 formats # # @param addresses [Array] List of addresses # # @return [String] # # @example When list contains both IPV4 and IPV6 formats # plugin.prefer_ipv4([IPV4, IPV6]) #=> "IPV4" # @example When list contains only IPV6 format # plugin.prefer_ipv4([IPV6]) #=> "IPV6" # def prefer_ipv4(addresses) return nil unless addresses.is_a?(Array) addresses.find { |ip| IPAddress.valid_ipv4?(ip) } || addresses.find { |ip| IPAddress.valid_ipv6?(ip) } end # Selects default interface and returns its information # # @note Interface with least metric value should be prefered as default_route # # @param configuration [Mash] Configuration of interfaces as iface_config # [ => {}] # # @return [Hash<:index, :interface_index, :default_ip_gateway, :ip_connection_metric>] # def favored_default_route_windows(configuration) return nil unless configuration.is_a?(Hash) config = configuration.dup config.inject([]) do |arr, (k, v)| if v["default_ip_gateway"] arr << { index: v["index"], interface_index: v["interface_index"], default_ip_gateway: prefer_ipv4(v["default_ip_gateway"]), ip_connection_metric: v["ip_connection_metric"] } end arr end.min_by { |r| r[:ip_connection_metric] } end collect_data(:windows) do require "wmi-lite/wmi" iface = Mash.new iface_config = Mash.new iface_instance = Mash.new network Mash.new unless network network[:interfaces] ||= Mash.new counters Mash.new unless counters counters[:network] ||= Mash.new network_data[:addresses].each do |adapter| i = adapter["index"] || adapter["InterfaceIndex"] iface_config[i] ||= Mash.new iface_config[i][:ip_address] ||= [] iface_config[i][:ip_address] << adapter["IPAddress"] adapter.wmi_ole_object.properties_.each do |p| if iface_config[i][p.name.wmi_underscore.to_sym].nil? iface_config[i][p.name.wmi_underscore.to_sym] = adapter[p.name.downcase] end end end network_data[:adapters].each do |adapter| i = adapter["index"] || adapter["InterfaceIndex"] iface_instance[i] = Mash.new adapter.wmi_ole_object.properties_.each do |p| # skip wmi class name fields which make no sense in ohai next if %w{creation_class_name system_creation_class_name}.include?(p.name.wmi_underscore) iface_instance[i][p.name.wmi_underscore.to_sym] = adapter[p.name.downcase] end end iface_instance.each_key do |i| if iface_instance[i][:name] && iface_config[i] && iface_config[i][:ip_address][0] cint = interface_code(iface_instance[i][:interface_index], iface_instance[i][:index]) iface[cint] = Mash.new iface[cint][:configuration] = iface_config[i] iface[cint][:instance] = iface_instance[i] iface[cint][:counters] = Mash.new iface[cint][:addresses] = Mash.new iface[cint][:configuration][:ip_address] = iface[cint][:configuration][:ip_address].flatten iface[cint][:configuration][:ip_address].each_index do |ip_index| ip = iface[cint][:configuration][:ip_address][ip_index] ip_and_subnet = ip.dup ip_and_subnet << "/#{iface[cint][:configuration][:ip_subnet][ip_index]}" if iface[cint][:configuration][:ip_subnet] ip2 = IPAddress(ip_and_subnet) iface[cint][:addresses][ip] = Mash.new(prefixlen: ip2.prefix) if ip2.ipv6? iface[cint][:addresses][ip][:family] = "inet6" iface[cint][:addresses][ip][:scope] = "Link" if ip =~ /^fe80/i else if iface[cint][:configuration][:ip_subnet] iface[cint][:addresses][ip][:netmask] = ip2.netmask.to_s if iface[cint][:configuration][:ip_use_zero_broadcast] iface[cint][:addresses][ip][:broadcast] = ip2.network.to_s else iface[cint][:addresses][ip][:broadcast] = ip2.broadcast.to_s end end iface[cint][:addresses][ip][:family] = "inet" end end mac_addresses(iface[cint]).each do |mac_addr| iface[cint][:addresses][mac_addr] = { "family" => "lladdr", } end iface[cint][:mtu] = iface[cint][:configuration][:mtu] if iface[cint][:configuration].key?(:mtu) iface[cint][:type] = iface[cint][:instance][:adapter_type] if iface[cint][:instance][:adapter_type] iface[cint][:arp] = {} iface[cint][:encapsulation] = windows_encaps_lookup(iface[cint][:instance][:adapter_type]) if iface[cint][:instance][:adapter_type] end end if (route = favored_default_route_windows(iface_config)) network[:default_gateway] = route[:default_ip_gateway] network[:default_interface] = interface_code(route[:interface_index], route[:index]) end cint = nil so = shell_out("arp -a") if so.exitstatus == 0 so.stdout.lines do |line| if line =~ /^Interface:\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[-]+\s+(0x\S+)/ cint = $2.downcase end next unless iface[cint] if line =~ /^\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-fA-F0-9\:-]+)/ iface[cint][:arp][$1] = $2.tr("-", ":").downcase end end end network["interfaces"] = iface end end ohai-16.0.7/lib/ohai/plugins/windows/platform.rb000066400000000000000000000023151362624620500215460ustar00rootroot00000000000000# # Author:: James Gartrell () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # After long discussion in IRC the "powers that be" have come to a concensus # that there is no other Windows platforms exist that were not based on the # Windows_NT kernel, so we herby decree that "windows" will refer to all # platforms built upon the Windows_NT kernel and have access to win32 or win64 # subsystems. Ohai.plugin(:Platform) do provides "platform", "platform_version", "platform_family" collect_data(:windows) do platform os platform_version kernel["release"] platform_family "windows" end end ohai-16.0.7/lib/ohai/plugins/windows/system_enclosure.rb000066400000000000000000000021001362624620500233150ustar00rootroot00000000000000# # Author:: Stuart Preston () # Copyright:: Copyright (c) 2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin :SystemEnclosure do provides "system_enclosure" collect_data(:windows) do require "wmi-lite/wmi" system_enclosure Mash.new wmi = WmiLite::Wmi.new wmi_object = wmi.first_of("Win32_SystemEnclosure").wmi_ole_object system_enclosure[:manufacturer] = wmi_object.invoke("manufacturer") system_enclosure[:serialnumber] = wmi_object.invoke("serialnumber") end end ohai-16.0.7/lib/ohai/plugins/windows/virtualization.rb000066400000000000000000000030371362624620500230100ustar00rootroot00000000000000# # Author:: Pavel Yudin () # Author:: Tim Smith () # Copyright:: Copyright (c) 2015 Pavel Yudin # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Virtualization) do provides "virtualization" require_relative "../../mixin/dmi_decode" include Ohai::Mixin::DmiDecode collect_data(:windows) do require "wmi-lite/wmi" virtualization Mash.new unless virtualization virtualization[:systems] ||= Mash.new # Grab system DMI data from WMI to determine vendor information wmi = WmiLite::Wmi.new dmi = wmi.first_of("Win32_ComputerSystemProduct") guest = guest_from_dmi_data(dmi["vendor"], dmi["name"], dmi["version"]) if guest logger.trace("Plugin Virtualization: DMI data in Win32_ComputerSystemProduct indicates #{guest} guest") virtualization[:system] = guest virtualization[:role] = "guest" virtualization[:systems][guest.to_sym] = "guest" end end end ohai-16.0.7/lib/ohai/plugins/zpools.rb000066400000000000000000000066111362624620500175610ustar00rootroot00000000000000# # Author:: Jason J. W. Williams (williamsjj@digitar.com) # Copyright:: Copyright (c) 2011-2017 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Zpools) do provides "zpools" depends "platform_family" # If zpool status doesn't know about a field it returns '-'. # We don't want to fill a field with that def sanitize_value(value) value == "-" ? nil : value end def gather_pool_info pools = Mash.new begin # Grab ZFS zpools overall health and attributes so = shell_out("zpool list -H -o name,size,alloc,free,cap,dedup,health,version") so.stdout.lines do |line| case line when /^([-_0-9A-Za-z]*)\s+([.0-9]+[MGTPE])\s+([.0-9]+[MGTPE])\s+([.0-9]+[MGTPE])\s+(\d+%)\s+([.0-9]+x)\s+([-_0-9A-Za-z]+)\s+(\d+|-)$/ Ohai::Log.debug("Plugin Zpools: Parsing zpool list line: #{line.chomp}") pools[$1] = Mash.new pools[$1][:pool_size] = sanitize_value($2) pools[$1][:pool_allocated] = sanitize_value($3) pools[$1][:pool_free] = sanitize_value($4) pools[$1][:capacity_used] = sanitize_value($5) pools[$1][:dedup_factor] = sanitize_value($6) pools[$1][:health] = sanitize_value($7) pools[$1][:zpool_version] = sanitize_value($8) end end rescue Ohai::Exceptions::Exec Ohai::Log.debug('Plugin Zpools: Could not shell_out "zpool list -H -o name,size,alloc,free,cap,dedup,health,version". Skipping plugin.') end pools end collect_data(:solaris2, :linux, :freebsd, :openbsd, :netbsd, :dragonflybsd) do pools = gather_pool_info # Grab individual health for devices in the zpools pools.each_key do |pool| pools[pool][:devices] = Mash.new # Run "zpool status" as non-root user (adm) so that # the command won't try to open() each device which can # hang the command if any of the disks are bad. if platform_family == "solaris2" command = "su adm -c \"zpool status #{pool}\"" else command = "zpool status #{pool}" end so = shell_out(command) so.stdout.lines do |line| case line # linux: http://rubular.com/r/J3wQC6E2lH # solaris: http://rubular.com/r/FqOBzUQQ4p # freebsd: http://rubular.com/r/RYkMNlytXl when /^\s+((sd|c|ad|da)[-_a-zA-Z0-9]+)\s+([-_a-zA-Z0-9]+)\s+(\d+)\s+(\d+)\s+(\d+)$/ logger.trace("Plugin Zpools: Parsing zpool status line: #{line.chomp}") pools[pool][:devices][$1] = Mash.new pools[pool][:devices][$1][:state] = $3 pools[pool][:devices][$1][:errors] = Mash.new pools[pool][:devices][$1][:errors][:read] = $4 pools[pool][:devices][$1][:errors][:write] = $5 pools[pool][:devices][$1][:errors][:checksum] = $6 end end end # Set the zpools data zpools pools unless pools.empty? end end ohai-16.0.7/lib/ohai/provides_map.rb000066400000000000000000000151541362624620500172440ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Daniel DeLeo () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "mash" require_relative "exception" require_relative "mixin/os" require_relative "dsl" module Ohai class ProvidesMap attr_reader :map def initialize @map = Mash.new end # @param [Ohai::DSL::Plugin] plugin # @param [Array] provided_attributes # # @return void # def set_providers_for(plugin, provided_attributes) unless plugin.is_a?(Ohai::DSL::Plugin) raise ArgumentError, "set_providers_for only accepts Ohai Plugin classes (got: #{plugin})" end provided_attributes.each do |attribute| attrs = @map parts = normalize_and_validate(attribute) parts.each do |part| attrs[part] ||= Mash.new attrs = attrs[part] end attrs[:_plugins] ||= [] attrs[:_plugins] << plugin end end # # gather plugins providing exactly the attributes listed # # @param [Array] attributes # # @return [Array] plugin names # def find_providers_for(attributes) plugins = [] attributes.each do |attribute| attrs = select_subtree(@map, attribute) raise Ohai::Exceptions::AttributeNotFound, "No such attribute: \'#{attribute}\'" unless attrs raise Ohai::Exceptions::ProviderNotFound, "Cannot find plugin providing attribute: \'#{attribute}\'" unless attrs[:_plugins] plugins += attrs[:_plugins] end plugins.uniq end # This function is used to fetch the plugins for the attributes specified # in the CLI options to Ohai. # It first attempts to find the plugins for the attributes # or the sub attributes given. # If it can't find any, it looks for plugins that might # provide the parents of a given attribute and returns the # first parent found. # # @param [Array] attributes # # @return [Array] plugin names def deep_find_providers_for(attributes) plugins = [] attributes.each do |attribute| attrs = select_subtree(@map, attribute) unless attrs attrs = select_closest_subtree(@map, attribute) unless attrs raise Ohai::Exceptions::AttributeNotFound, "No such attribute: \'#{attribute}\'" end end collect_plugins_in(attrs, plugins) end plugins.uniq end # This function is used to fetch the plugins from # 'depends "languages"' statements in plugins. # It gathers plugins providing each of the attributes listed, or the # plugins providing the closest parent attribute # # @param [Array] attributes # # @return [Array] plugin names def find_closest_providers_for(attributes) plugins = [] attributes.each do |attribute| parts = normalize_and_validate(attribute) raise Ohai::Exceptions::AttributeNotFound, "No such attribute: \'#{attribute}\'" unless @map[parts[0]] attrs = select_closest_subtree(@map, attribute) raise Ohai::Exceptions::ProviderNotFound, "Cannot find plugin providing attribute: \'#{attribute}\'" unless attrs plugins += attrs[:_plugins] end plugins.uniq end def all_plugins(attribute_filter = nil) if attribute_filter.nil? collected = [] collect_plugins_in(map, collected).uniq else deep_find_providers_for(Array(attribute_filter)) end end private def normalize_and_validate(attribute) raise Ohai::Exceptions::AttributeSyntaxError, "Attribute contains duplicate '/' characters: #{attribute}" if attribute =~ %r{//+} raise Ohai::Exceptions::AttributeSyntaxError, "Attribute contains a trailing '/': #{attribute}" if attribute =~ %r{/$} parts = attribute.split("/") parts.shift if parts.length != 0 && parts[0].length == 0 # attribute begins with a '/' parts end def select_subtree(provides_map, attribute) subtree = provides_map parts = normalize_and_validate(attribute) parts.each do |part| return nil unless subtree[part] subtree = subtree[part] end subtree end def select_closest_subtree(provides_map, attribute) attr, *rest = normalize_and_validate(attribute) # return nil if the top-level part of the attribute is not a # top-level key in the provides_map (can't search any lower, and # no information to return from this level of the search) return nil unless provides_map[attr] # attr is a key in the provides_map, search for the sub # attribute under attr (if attribute = attr/sub1/sub2 then we # search provides_map[attr] for sub1/sub2) unless rest.empty? subtree = select_closest_subtree(provides_map[attr], rest.join("/")) end if subtree.nil? # no subtree of provides_map[attr] either 1) has a # subattribute, 2) has a plugin providing a subattribute. unless provides_map[attr][:_plugins] # no providers for this attribute, this subtree won't do. return nil # no providers for this attribute else # there are providers for this attribute, return its subtree # to indicate this is the closest subtree return provides_map[attr] end end # we've already found a closest subtree or we've search all # parent attributes of the original attribute and found no # providers (subtree is nil in this case) subtree end # Takes a section of the map, recursively searches for a `_plugins` key # to find all the plugins in that section of the map. If given the whole # map, it will find all of the plugins that have at least one provided # attribute. def collect_plugins_in(provides_map, collected) provides_map.each_key do |plugin| if plugin.eql?("_plugins") collected.concat(provides_map[plugin]) else collect_plugins_in(provides_map[plugin], collected) end end collected end end end ohai-16.0.7/lib/ohai/runner.rb000066400000000000000000000100761362624620500160630ustar00rootroot00000000000000# # Author:: Claire McQuin () # Copyright:: Copyright (c) 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); you # may not use this file except in compliance with the License. You may # obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or # implied. # See the License for the specific language governing permissions and # limitations under the License # require_relative "dsl" require "benchmark" module Ohai class Runner attr_reader :failed_plugins, :logger # safe_run: set to true if this runner will run plugins in # safe-mode. default false. def initialize(controller, safe_run = false) @provides_map = controller.provides_map @safe_run = safe_run @failed_plugins = [] @logger = controller.logger.with_child @logger.metadata = { subsystem: "runner" } end # Runs plugins and any un-run dependencies. # If force is set to true, then this plugin and its dependencies # will be run even if they have been run before. # # @param [Ohai::DSL::Plugin] plugin # # @return void # def run_plugin(plugin) elapsed = Benchmark.realtime do unless plugin.is_a?(Ohai::DSL::Plugin) raise Ohai::Exceptions::InvalidPlugin, "Invalid plugin #{plugin} (must be an Ohai::DSL::Plugin or subclass)" end begin if plugin.version == :version7 run_v7_plugin(plugin) else raise Ohai::Exceptions::InvalidPlugin, "Invalid plugin version #{plugin.version} for plugin #{plugin}" end rescue Ohai::Exceptions::Error # rubocop: disable Lint/ShadowedException raise rescue SystemExit # abort or exit from plug-in should exit Ohai with failure code raise rescue Exception => e logger.trace("Plugin #{plugin.name} threw exception #{e.inspect} #{e.backtrace.join("\n")}") end end logger.trace("Plugin #{plugin.name} took #{elapsed} seconds to run.") end # @param [Ohai::DSL::Plugin] plugin # # @return void # def run_v7_plugin(plugin) return true if plugin.optional? && !Ohai.config[:run_all_plugins] && !Ohai.config[:optional_plugins].include?(plugin.name) visited = [ plugin ] until visited.empty? next_plugin = visited.pop next if next_plugin.has_run? if visited.include?(next_plugin) raise Ohai::Exceptions::DependencyCycle, "Dependency cycle detected. Please refer to the following plugins: #{get_cycle(visited, plugin).join(", ")}" end dependency_providers = fetch_plugins(next_plugin.dependencies) # Remove the already ran plugins from dependencies if force is not set # Also remove the plugin that we are about to run from dependencies as well. dependency_providers.delete_if do |dep_plugin| dep_plugin.has_run? || dep_plugin.eql?(next_plugin) end if dependency_providers.empty? @safe_run ? next_plugin.safe_run : next_plugin.run if next_plugin.failed @failed_plugins << next_plugin.name end else visited << next_plugin << dependency_providers.first end end end # @param [Array] attributes # # @return [Array] # def fetch_plugins(attributes) @provides_map.find_closest_providers_for(attributes) end # Given a list of plugins and the first plugin in the cycle, # returns the list of plugin source files responsible for the # cycle. Does not include plugins that aren't a part of the cycle def get_cycle(plugins, cycle_start) cycle = plugins.drop_while { |plugin| !plugin.eql?(cycle_start) } names = [] cycle.each { |plugin| names << plugin.name } names end end end ohai-16.0.7/lib/ohai/system.rb000066400000000000000000000152751362624620500161040ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "version" require_relative "loader" require_relative "log" require_relative "mash" require_relative "runner" require_relative "dsl" require_relative "mixin/command" require_relative "mixin/os" require_relative "mixin/string" require_relative "mixin/constant_helper" require_relative "provides_map" require_relative "hints" require "mixlib/shellout" unless defined?(Mixlib::ShellOut::DEFAULT_READ_TIMEOUT) require_relative "config" require "ffi_yajl" unless defined?(FFI_Yajl) module Ohai # The class used by Ohai::Application and Chef to actually collect data class System include Ohai::Mixin::ConstantHelper attr_accessor :data attr_reader :config attr_reader :provides_map attr_reader :logger # the cli flag is used to determine if we're being constructed by # something like chef-client (which doesn't set this flag) and # which sets up its own loggers, or if we're coming from Ohai::Application # and therefore need to configure Ohai's own logger. def initialize(config = {}) @cli = config[:invoked_from_cli] @plugin_path = "" @config = config @failed_plugins = [] @logger = config[:logger] || Ohai::Log.with_child @logger.metadata = { system: "ohai", version: Ohai::VERSION } reset_system end # clears the current collected data, clears the provides map for plugins, # refreshes hints, and reconfigures ohai. In short this gets Ohai into a first run state # # @return [void] def reset_system @data = Mash.new @provides_map = ProvidesMap.new configure_ohai configure_logging if @cli @loader = Ohai::Loader.new(self) @runner = Ohai::Runner.new(self, true) Ohai::Hints.refresh_hints # Remove the previously defined plugins recursive_remove_constants(Ohai::NamedPlugin) end def [](key) @data[key] end # Resets the system and loads then runs the plugins. This is the primary method called # to run the system. # # @param [Array] attribute_filter the attributes to run. All will be run if not specified # # @return [void] def all_plugins(attribute_filter = nil) # Reset the system when all_plugins is called since this function # can be run multiple times in order to pick up any changes in the # config or plugins with Chef. reset_system load_plugins run_plugins(true, attribute_filter) end # load all plugins by calling Ohai::Loader.load_all # # @see Ohai::Loader.load_all def load_plugins @loader.load_all end # run all plugins or those that match the attribute filter is provided # # @param safe [Boolean] # @param [Array] attribute_filter the attributes to run. All will be run if not specified # # @return [Mash] def run_plugins(safe = false, attribute_filter = nil) begin @provides_map.all_plugins(attribute_filter).each do |plugin| @runner.run_plugin(plugin) end rescue Ohai::Exceptions::AttributeNotFound, Ohai::Exceptions::DependencyCycle => e logger.error("Encountered error while running plugins: #{e.inspect}") raise end critical_failed = Ohai::Config.ohai[:critical_plugins] & @runner.failed_plugins unless critical_failed.empty? msg = "The following Ohai plugins marked as critical failed: #{critical_failed}" if @cli logger.error(msg) exit(true) else raise Ohai::Exceptions::CriticalPluginFailure, "#{msg}. Failing Chef run." end end # Freeze all strings. freeze_strings! end # @param [String] plugin_path # # @return [void] # def run_additional_plugins(plugin_path) @loader.load_additional(plugin_path).each do |plugin| logger.trace "Running plugin #{plugin}" @runner.run_plugin(plugin) end freeze_strings! end # # Serialize this object as a hash # def to_json FFI_Yajl::Encoder.new.encode(@data) end # # Pretty Print this object as JSON # def json_pretty_print(item = nil) FFI_Yajl::Encoder.new(pretty: true, validate_utf8: false).encode(item || @data) end def attributes_print(a) data = @data a.split("/").each do |part| data = data[part] end raise ArgumentError, "I cannot find an attribute named #{a}!" if data.nil? case data when Hash, Mash, Array, Integer json_pretty_print(data) when String if data.respond_to?(:lines) json_pretty_print(data.lines.to_a) else json_pretty_print(data.to_a) end else raise ArgumentError, "I can only generate JSON for Hashes, Mashes, Arrays and Strings. You fed me a #{data.class}!" end end private def configure_ohai Ohai.config.merge!(@config) # add any additional CLI passed directories to the plugin path excluding duplicates unless Ohai.config[:directory].nil? # make sure the directory config is an array since it could be a string set in client.rb Array(Ohai.config[:directory]).each do |dir| next if Ohai.config[:plugin_path].include?(dir) Ohai.config[:plugin_path] << dir end end logger.debug("Running Ohai with the following configuration: #{Ohai.config.configuration}") end def configure_logging if Ohai.config[:log_level] == :auto Ohai::Log.level = :info else Ohai::Log.level = Ohai.config[:log_level] end end # Freeze all string values in @data. This makes them immutable and saves # a bit of RAM. # # @api private # @return [void] def freeze_strings! # Recursive visitor pattern helper. visitor = lambda do |val| case val when Hash val.each_value { |v| visitor.call(v) } when Array val.each { |v| visitor.call(v) } when String val.freeze end end visitor.call(@data) end end end ohai-16.0.7/lib/ohai/util/000077500000000000000000000000001362624620500151765ustar00rootroot00000000000000ohai-16.0.7/lib/ohai/util/file_helper.rb000066400000000000000000000023421362624620500200020ustar00rootroot00000000000000# Author:: Lamont Granquist () # # Copyright:: Copyright (c) 2013-14 Chef Software, Inc. # # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Copied from chef/lib/chef/util/selinux.rb module Ohai module Util module FileHelper def which(cmd) paths = ENV["PATH"].split(File::PATH_SEPARATOR) + [ "/bin", "/usr/bin", "/sbin", "/usr/sbin" ] paths.each do |path| filename = File.join(path, cmd) if File.executable?(filename) logger.trace("Plugin #{name}: found #{cmd} at #{filename}") return filename end end logger.trace("Plugin #{name}: did not find #{cmd}") false end end end end ohai-16.0.7/lib/ohai/util/ip_helper.rb000066400000000000000000000031051362624620500174710ustar00rootroot00000000000000# # Author:: Stafford Brunk () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "ipaddress" module Ohai module Util module IpHelper # Corresponding to RFC 4192 + RFC 4193 IPV6_LINK_LOCAL_UNICAST_BLOCK = IPAddress("fe80::/10") IPV6_PRIVATE_ADDRESS_BLOCK = IPAddress("fc00::/7") def private_address?(addr) ip = IPAddress(addr) if ip.respond_to? :private? ip.private? else IPV6_LINK_LOCAL_UNICAST_BLOCK.include?(ip) || IPV6_PRIVATE_ADDRESS_BLOCK.include?(ip) end end alias :unique_local_address? :private_address? def public_address?(addr) !private_address?(addr) end # The ipaddress gem doesn't implement loopback? # for IPv4 addresses # https://github.com/bluemonk/ipaddress/issues/25 def loopback?(addr) ip = IPAddress(addr) if ip.respond_to? :loopback? ip.loopback? else IPAddress("127.0.0.0/8").include? ip end end end end end ohai-16.0.7/lib/ohai/util/win32.rb000066400000000000000000000025111362624620500164640ustar00rootroot00000000000000# Author:: Adam Edwards () # # Copyright:: Copyright (c) 2013-14 Chef Software, Inc. # # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Ohai module Util module Win32 if RUBY_PLATFORM =~ /mswin|mingw|windows/ require "ffi" unless defined?(FFI) extend FFI::Library ffi_lib "advapi32" attach_function :lookup_account_sid, :LookupAccountSidA, %i{pointer pointer pointer pointer pointer pointer pointer}, :long attach_function :convert_string_sid_to_sid, :ConvertStringSidToSidA, %i{pointer pointer}, :long ffi_lib "kernel32" attach_function :local_free, :LocalFree, [ :pointer ], :long attach_function :get_last_error, :GetLastError, [], :long end end end end ohai-16.0.7/lib/ohai/version.rb000066400000000000000000000014231362624620500162330ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Ohai OHAI_ROOT = File.expand_path(File.dirname(__FILE__)) VERSION = "16.0.7".freeze end ohai-16.0.7/ohai.gemspec000066400000000000000000000024001362624620500150140ustar00rootroot00000000000000 $:.unshift File.expand_path("../lib", __FILE__) require "ohai/version" Gem::Specification.new do |s| s.name = "ohai" s.version = Ohai::VERSION s.summary = "Ohai profiles your system and emits JSON" s.description = s.summary s.license = "Apache-2.0" s.author = "Adam Jacob" s.email = "adam@chef.io" s.homepage = "https://github.com/chef/ohai/" s.required_ruby_version = ">= 2.5" s.add_dependency "systemu", "~> 2.6.4" s.add_dependency "ffi-yajl", "~> 2.2" s.add_dependency "mixlib-cli", ">= 1.7.0" # 1.7+ needed to support passing multiple options s.add_dependency "mixlib-config", ">= 2.0", "< 4.0" s.add_dependency "mixlib-log", ">= 2.0.1", "< 4.0" s.add_dependency "mixlib-shellout", ">= 2.0", "< 4.0" s.add_dependency "plist", "~> 3.1" s.add_dependency "ipaddress" s.add_dependency "wmi-lite", "~> 1.0" s.add_dependency "ffi", "~> 1.9" s.add_dependency "chef-config", ">= 12.8", "< 17" # Note for ohai developers: If chef-config causes you grief, try: # bundle install --with development # this should work as long as chef is a development dependency in Gemfile. # s.bindir = "bin" s.executables = %w{ohai} s.require_path = "lib" s.files = %w{LICENSE Gemfile} + Dir.glob("*.gemspec") + Dir.glob("lib/**/*") end ohai-16.0.7/spec/000077500000000000000000000000001362624620500134655ustar00rootroot00000000000000ohai-16.0.7/spec/data/000077500000000000000000000000001362624620500143765ustar00rootroot00000000000000ohai-16.0.7/spec/data/plugins/000077500000000000000000000000001362624620500160575ustar00rootroot00000000000000ohai-16.0.7/spec/data/plugins/dpkg-query.output000066400000000000000000000001521362624620500214270ustar00rootroot00000000000000adduser 3.113+nmu3 all libc-bin 2.19-18+deb8u3 amd64 libc6 2.19-18+deb8u3 amd64 tzdata 2015g-0+deb8u1 all ohai-16.0.7/spec/data/plugins/lslpp.output000066400000000000000000000125711362624620500205010ustar00rootroot00000000000000bos.sysmgt:bos.sysmgt.smit:7.1.1.15: : :C:F:System Management Interface Tool (SMIT): : : : : : :0:0:/:1216 bos.sysmgt:bos.sysmgt.sysbr:7.1.1.17: : :C:F:System Backup and BOS Install Utilities: : : : : : :0:0:/:1228 bos.sysmgt:bos.sysmgt.trace:7.1.1.15: : :C:F:Software Trace Service Aids: : : : : : :0:1:/:1216 bos.terminfo:bos.terminfo.ansi.data:7.1.0.0: : :C: :Amer National Stds Institute Terminal Defs: : : : : : :0:1:/:1036 bos.terminfo:bos.terminfo.com.data:7.1.0.0: : :C: :Common Terminal Definitions: : : : : : :0:1:/:1036 bos.terminfo:bos.terminfo.dec.data:7.1.0.0: : :C: :Digital Equipment Corp. Terminal Definitions: : : : : : :0:1:/:1036 bos.terminfo:bos.terminfo.ibm.data:7.1.0.0: : :C: :IBM Terminal Definitions: : : : : : :0:1:/:1036 bos.terminfo:bos.terminfo.pc.data:7.1.0.0: : :C: :Personal Computer Terminal Definitions: : : : : : :0:1:/:1036 bos.terminfo:bos.terminfo.print.data:7.1.0.0: : :C: :Generic Line Printer Terminal Definitions: : : : : : :0:1:/:1036 bos.terminfo:bos.terminfo.rte:7.1.0.0: : :C: :Run-time Environment for AIX Terminals: : : : : : :0:0:/:1036 bos.terminfo:bos.terminfo.svprint.data:7.1.0.0: : :C: :System V Printer Terminal Definitions: : : : : : :0:0:/:1036 bos.terminfo:bos.terminfo.televideo.data:7.1.0.0: : :C: :Televideo Terminal Definitions: : : : : : :0:0:/:1036 bos.terminfo:bos.terminfo.wyse.data:7.1.0.0: : :C: :Wyse Terminal Definitions: : : : : : :0:0:/:1036 bos.txt:bos.txt.hplj.fnt:7.1.0.0: : :C: :Fonts for Hewlett Packard Laser Jet Printers : : : : : : :0:0:/:1115 bos.txt:bos.txt.ibm3812.fnt:7.1.0.0: : :C: :Fonts for IBM 3812 Printer : : : : : : :0:0:/:1115 bos.txt:bos.txt.ibm3816.fnt:7.1.0.0: : :C: :Fonts for IBM 3816 Printer : : : : : : :0:0:/:1115 bos.txt:bos.txt.spell:7.1.0.0: : :C: :Writer's Tools Commands : : : : : : :0:0:/:1115 bos.txt:bos.txt.spell.data:7.1.0.0: : :C: :Writer's Tools Data: : : : : : :0:0:/:1036 bos.txt:bos.txt.tfs:7.1.1.15: : :C:F:Text Formatting Services Commands: : : : : : :0:0:/:1216 bos.txt:bos.txt.tfs.data:7.1.0.0: : :C: :Text Formatting Services Data: : : : : : :0:0:/:1036 bos.wpars:bos.wpars:7.1.1.15: : :C:F:AIX Workload Partitions: : : : : : :0:0:/:1216 cdrtools.base:cdrtools.base:1.9.0.9: : :C: :CD/DVD recorder: : : : : : :0:0:/: cdrtools.man.en_US:cdrtools.man.en_US:1.9.0.9: : :C: :CD/DVD recorder man page documentation: : : : : : :0:0:/: chef:chef:12.5.1.1: : :C: :The full stack of chef: : : : : : :0:0:/: clic.rte:clic.rte.kernext:4.7.0.1: : :C: :CryptoLite for C Kernel: : : : : : :0:0:/: clic.rte:clic.rte.lib:4.7.0.1: : :C: :CryptoLite for C Library: : : : : : :0:0:/: devices.artic960:devices.artic960.diag:7.1.0.0: : :C: :IBM ARTIC960 Adapter Diagnostics : : : : : : :0:0:/:1115 devices.artic960:devices.artic960.rte:7.1.1.15: : :C:F:IBM ARTIC960 Runtime Support: : : : : : :0:0:/:1216 devices.artic960:devices.artic960.ucode:7.1.0.0: : :C: :IBM ARTIC960 Adapter Software : : : : : : :0:0:/:1115 devices.chrp.AT97SC3201_r:devices.chrp.AT97SC3201_r.rte:7.1.0.0: : :C: :Trusted Platform Module Device Software: : : : : : :0:0:/:1036 devices.chrp.IBM.lhca:devices.chrp.IBM.lhca.rte:7.1.1.16: : :C:F:Infiniband Logical HCA Runtime Environment: : : : : : :0:0:/:1228 devices.chrp.IBM.lhea:devices.chrp.IBM.lhea.diag:7.1.0.0: : :C: :Host Ethernet Adapter Diagnostics : : : : : : :0:0:/:1115 devices.chrp.IBM.lhea:devices.chrp.IBM.lhea.rte:7.1.1.16: : :C:F:Host Ethernet Adapter (HEA) Runtime Environment: : : : : : :0:0:/:1228 devices.chrp.base:devices.chrp.base.ServiceRM:1.5.1.0: : :C:F:RSCT Service Resource Manager: : : : : : :0:0:/: devices.chrp.base:devices.chrp.base.diag:7.1.1.15: : :C:F:RISC CHRP Base System Device Diagnostics: : : : : : :0:0:/:1216 devices.chrp.base:devices.chrp.base.rte:7.1.1.16: : :C:F:RISC PC Base System Device Software (CHRP): : : : : : :0:0:/:1228 devices.chrp.pci:devices.chrp.pci.rte:7.1.1.16: : :C:F:PCI Bus Software (CHRP): : : : : : :0:0:/:1228 devices.chrp.pciex:devices.chrp.pciex.rte:7.1.0.0: : :C: :PCI Express Bus Software (CHRP): : : : : : :0:0:/:1036 devices.chrp.vdevice:devices.chrp.vdevice.rte:7.1.1.16: : :C:F:Virtual I/O Bus Support: : : : : : :0:0:/:1228 devices.chrp_lpar.base:devices.chrp_lpar.base.ras:7.1.0.15: : :C: :CHRP LPAR RAS Support : : : : : : :0:0:/:1115 devices.common.IBM.async:devices.common.IBM.async.diag:7.1.0.0: : :C: :Common Serial Adapter Diagnostics: : : : : : :0:0:/:1036 devices.common.IBM.atm:devices.common.IBM.atm.rte:7.1.1.16: : :C:F:Common ATM Software: : : : : : :0:0:/:1228 devices.common.IBM.crypt:devices.common.IBM.crypt.rte:7.1.0.0: : :C: :Cryptographic Common Runtime Environment: : : : : : :0:0:/:1036 devices.common.IBM.cx:devices.common.IBM.cx.rte:7.1.1.15: : :C:F:CX Common Adapter Software: : : : : : :0:0:/:1216 devices.common.IBM.disk:devices.common.IBM.disk.rte:7.1.1.15: : :C:F:Common IBM Disk Software: : : : : : :0:0:/:1216 devices.common.IBM.ethernet:devices.common.IBM.ethernet.rte:7.1.1.16: : :C:F:Common Ethernet Software: : : : : : :0:1:/:1228 devices.common.IBM.fc:devices.common.IBM.fc.hba-api:7.1.1.16: : :C:F:Common HBA API Library: : : : : : :0:0:/:1228 devices.common.IBM.fc:devices.common.IBM.fc.rte:7.1.1.16: : :C:F:Common IBM FC Software: : : : : : :0:0:/:1228 devices.common.IBM.fda:devices.common.IBM.fda.diag:7.1.0.0: : :C: :Common Diskette Adapter and Device Diagnostics: : : : : : :0:0:/:1036 wget:wget-1.9.1-3:1.9.1-3: : :C:R:A utility for retrieving files using the HTTP or FTP protocols.: :/bin/rpm -e wget: : : : :0: :/opt/freeware:Wed Nov 5 01:37:09 MST 2014 ohai-16.0.7/spec/data/plugins/pacman.output000066400000000000000000000040611362624620500206010ustar00rootroot00000000000000Name : acl Version : 2.2.52-3 Description : Access control list utilities, libraries and headers Architecture : x86_64 URL : http://savannah.nongnu.org/projects/acl Licenses : LGPL Groups : None Provides : xfsacl Depends On : attr>=2.4.46 Optional Deps : None Required By : coreutils gettext libarchive logrotate sed shadow systemd tar Optional For : None Conflicts With : xfsacl Replaces : xfsacl Installed Size : 290.00 KiB Packager : Bartlomiej Piotrowski Build Date : Sun Nov 6 14:03:46 2016 Install Date : Sun Jul 23 03:25:45 2017 Install Reason : Installed as a dependency for another package Install Script : No Validated By : Signature Name : abcde Version : 2.8.1-2 Description : Frontend command-line utility that grabs tracks off a CD, encodes them to ogg or mp3 format, and tags them, all in one go Architecture : any URL : https://abcde.einval.com/ Licenses : GPL Groups : None Provides : None Depends On : bash cd-discid wget vorbis-tools python2-eyed3 Optional Deps : cdparanoia: Paranoia ripping support [installed] cdrkit: icedax ripping support [installed] flac: FLAC encoding support [installed] id3: ID3 v1 tag support lame: MP3 encoding support [installed] mp3gain: MP3 normalization support [installed] perl-musicbrainz-discid: musicbrainz support (AUR) perl-webservice-musicbrainz: musicbrainz support (AUR) vorbisgain: Ogg Vorbis normalization support [installed] Required By : None Optional For : None Conflicts With : None Replaces : None Installed Size : 334.00 KiB Packager : Alexander RΓΈdseth Build Date : Wed Apr 26 02:04:21 2017 Install Date : Fri May 5 15:36:23 2017 Install Reason : Explicitly installed Install Script : No Validated By : Signature ohai-16.0.7/spec/data/plugins/pkg-query.output000066400000000000000000000026251362624620500212720ustar00rootroot00000000000000rubygem-chef 12.6.0_1 rubygem-chef-config 12.6.0_1 rubygem-chef-zero 4.4.2_1 rubygem-coderay 1.1.1 rubygem-diff-lcs 1.2.5_1 rubygem-domain_name 0.5.24 rubygem-erubis 2.7.0_1 rubygem-ffi 1.9.10 rubygem-ffi-yajl 2.2.3 rubygem-hashie 3.4.3 rubygem-hashie2 2.1.2 rubygem-highline 1.7.8 rubygem-http-cookie 1.0.2 rubygem-ipaddress 0.8.3 rubygem-json 1.8.3 rubygem-json_pure 1.8.3 rubygem-libyajl2 1.2.0 rubygem-method_source 0.8.2 rubygem-mime-types 2.99 rubygem-mime-types1 1.25.1 rubygem-mixlib-authentication 1.3.0 rubygem-mixlib-cli 1.4.0 rubygem-mixlib-config 2.1.0 rubygem-mixlib-log 1.6.0 rubygem-mixlib-shellout 2.2.5_1 rubygem-multi_json 1.11.2 rubygem-net-scp 1.2.1 rubygem-net-ssh 3.0.2,2 rubygem-net-ssh-gateway 1.2.0 rubygem-net-ssh-multi 1.2.1 rubygem-net-ssh2 2.9.2,1 rubygem-net-telnet 0.1.1 rubygem-netrc 0.7.7 rubygem-ohai 8.8.1 rubygem-plist 3.1.0 rubygem-proxifier 1.0.3 rubygem-pry 0.10.3_2 rubygem-rack 1.4.7,3 rubygem-rake 10.5.0 rubygem-rest-client 1.8.0 rubygem-rspec 3.4.0 rubygem-rspec-core 3.4.4 rubygem-rspec-expectations 3.4.0 rubygem-rspec-its 1.2.0_1 rubygem-rspec-mocks 3.4.1 rubygem-rspec-support 3.4.1 rubygem-rspec_junit_formatter 0.2.3_1 rubygem-ruby-termios 0.9.6 rubygem-serverspec 2.29.1_1 rubygem-sfl 2.2_1 rubygem-slop3 3.6.0 rubygem-specinfra 2.50.2_1 rubygem-syslog-logger 1.6.8 rubygem-systemu 2.6.4 rubygem-unf 0.1.4 rubygem-unf_ext 0.0.7.1 rubygem-uuidtools 2.1.5 rubygem-wmi-lite 1.0.0 ohai-16.0.7/spec/data/plugins/pkginfo.output000066400000000000000000000030721362624620500210000ustar00rootroot00000000000000 PKGINST: mqm NAME: WebSphere MQ Client for Sun Solaris CATEGORY: application ARCH: sparcv9 VERSION: 7.0.1.4 BASEDIR: / VENDOR: IBM PSTAMP: src (packaged: January 14, 2011 - 11:44:27 PM) INSTDATE: Dec 22 2015 17:10 VSTOCK: 5724-H72 STATUS: completely installed FILES: 3303 installed pathnames 88 directories 158 executables 20 setuid/setgid executables 327903 blocks used (approx) PKGINST: vasclnt NAME: vasclnt 4.1.0.21853 CATEGORY: application ARCH: sparcv9 VERSION: 4.1.0.21853 BASEDIR: / VENDOR: Quest Software, Inc. DESC: Quest Authentication System (QAS) provides centralized user and PSTAMP: vassol8sparc20150701013812 INSTDATE: Dec 22 2015 16:58 STATUS: completely installed FILES: 174 installed pathnames 9 shared pathnames 32 directories 101 executables 60402 blocks used (approx) PKGINST: vasgp NAME: vasgp 4.1.0.21853 CATEGORY: application ARCH: sparcv9 VERSION: 4.1.0.21853 BASEDIR: / VENDOR: Quest Software, Inc. DESC: Quest Group Policy (QGP) provides Active Directory Group Policy PSTAMP: vassol8sparc20150701013859 INSTDATE: Dec 22 2015 17:06 STATUS: completely installed FILES: 50 installed pathnames 9 shared pathnames 18 directories 25 executables 11999 blocks used (approx) ohai-16.0.7/spec/data/plugins/pkglist.output000066400000000000000000000036301362624620500210200ustar00rootroot00000000000000chef 12.5.1 i-- compatibility/ucb 0.5.11-0.175.2.0.0.42.2 i-- compress/bzip2 1.0.6-0.175.2.0.0.42.1 i-- compress/gzip 1.5-0.175.2.4.0.3.0 i-- compress/p7zip 9.20.1-0.175.2.0.0.42.1 i-- compress/pbzip2 1.1.6-0.175.2.0.0.42.1 i-- compress/pixz 1.0-0.175.2.0.0.42.1 i-- compress/unzip 6.0-0.175.2.3.0.4.0 i-- compress/xz 5.0.1-0.175.2.0.0.42.1 i-- compress/zip 3.0-0.175.2.0.0.42.1 i-- consolidation/SunVTS/SunVTS-incorporation 7.18.2-0.175.2.1.0.5.1 i-- consolidation/X/X-incorporation 0.5.11-0.175.2.1.0.3.1413 i-- consolidation/admin/admin-incorporation 0.5.11-0.175.1.0.0.5.0 i-- consolidation/cacao/cacao-incorporation 0.5.11-0.175.2.0.0.38.0 i-- consolidation/cde/cde-incorporation 0.5.11-0.175.2.0.0.23.0 i-- consolidation/cns/cns-incorporation 0.5.11-0.175.2.0.0.39.0 i-- consolidation/dbtg/dbtg-incorporation 0.5.11-0.175.2.0.0.38.0 i-- consolidation/ddt/ddt-incorporation 8.10.15.11.23 i-- consolidation/desktop/desktop-incorporation 0.5.11-0.175.2.4.0.5.0 i-- consolidation/desktop/gnome-incorporation 0.5.11-0.175.2.0.0.42.0 i-- consolidation/gfx/gfx-incorporation 0.5.11-0.175.1.0.0.5.0 i-- consolidation/ips/ips-incorporation 0.5.11-0.175.2.3.0.3.0 i-- consolidation/java-7/java-7-incorporation 1.7.0.72.14-0 i-- system/EMCpower (emc.com) 6.0.0.1.0-3 i-- ohai-16.0.7/spec/data/plugins/rpmquery.output000066400000000000000000000005511362624620500212260ustar00rootroot00000000000000centos-release 0 7 2.1511.el7.centos.2.10 1463486612 x86_64 tzdata 0 2016d 1.el7 1463486618 noarch nss-softokn-freebl 0 3.16.2.3 14.2.el7_2 1463486619 x86_64 glibc 0 2.17 106.el7_2.6 1463486666 x86_64 libstdc++ 0 4.8.5 4.el7 1463486669 x86_64 kernel 0 3.10.0 862.2.3.el7 1526310781 x86_64 kernel 0 3.10.0 862.el7 1521745632 x86_64 ohai-16.0.7/spec/functional/000077500000000000000000000000001362624620500156275ustar00rootroot00000000000000ohai-16.0.7/spec/functional/application_spec.rb000066400000000000000000000064231362624620500214760ustar00rootroot00000000000000# # Author:: Claire McQuin # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/application" RSpec.describe "Ohai::Application" do let(:app) { Ohai::Application.new } let(:argv) { [] } let(:stderr) { StringIO.new } before do @original_argv = ARGV.dup ARGV.replace(argv) end after do ARGV.replace(@original_argv) end describe "#configure_ohai" do let(:config_content) { "" } let(:config_dir) { Dir.mktmpdir(".chef") } let(:config_location) { File.join(config_dir, "config.rb") } before do File.open(config_location, "w+") do |f| f.write(config_content) end end after do FileUtils.rm_rf(config_dir) end context "when a configuration file is provided as a command line option" do let(:argv) { [ "-c", config_location + ".oops" ] } context "and the configuration file does not exist" do it "logs an error and terminates the application" do expect(STDERR).to receive(:puts).with(/FATAL:/) expect(Ohai::Log).to receive(:fatal) .with(/Specified config file #{argv[1]} does not exist/) expect { app.configure_ohai }.to raise_error(SystemExit) end end end context "when a workstation configuration file exists" do let(:config_content) { "ohai.disabled_plugins = [ :Foo, :Baz ]" } # env['KNIFE_HOME']/config.rb is the first config file the workstation # config loader looks for: # https://github.com/chef/chef/blob/master/chef-config/lib/chef-config/workstation_config_loader.rb#L102 let(:env) { { "KNIFE_HOME" => config_dir } } before do allow_any_instance_of(ChefConfig::WorkstationConfigLoader) .to receive(:env).and_return(env) end it "loads the workstation configuration file" do app.configure_ohai expect(Ohai.config[:disabled_plugins]).to eq(%i{Foo Baz}) end end context "when the configuration file has a syntax error" do # For the purpose of these tests it doesn't matter if the configuration # file was specified via command line or discovered on the local # workstation. It's easier if we pass the configuration file as a cli # argument (there's less to stub). let(:argv) { [ "-c", config_location ] } let(:config_content) { 'config_location "blaaaaa' } it "logs an error and terminates the application" do expect(STDERR).to receive(:puts).with(/FATAL:/) expect(Ohai::Log).to receive(:fatal) .with(/You have invalid ruby syntax in your config file/) expect { app.configure_ohai }.to raise_error(SystemExit) end end end end ohai-16.0.7/spec/functional/loader_spec.rb000066400000000000000000000031661362624620500204420ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" RSpec.describe "Ohai::Loader" do let(:loader) { Ohai::Loader.new(Ohai::System.new) } describe "#load_all" do context "when the plugin path contains backslash characters", :windows_only do let(:plugin_directory) { Dir.mktmpdir("plugins") } let(:plugin_path) { plugin_directory.tr("/", "\\") } before do Ohai.config[:plugin_path] = plugin_path plugin_content = <<~EOF Ohai.plugin(:Foo) do provides 'foo' end EOF File.open(File.join(plugin_directory, "foo.rb"), "w+") do |f| f.write(plugin_content) end end after do FileUtils.rm_rf(plugin_directory) end it "loads all the plugins" do loader.load_all loaded_plugins = loader.instance_variable_get(:@v7_plugin_classes) loaded_plugins_names = loaded_plugins.map(&:name) expect(loaded_plugins_names).to eq(["Ohai::NamedPlugin::Foo"]) end end end end ohai-16.0.7/spec/functional/plugins/000077500000000000000000000000001362624620500173105ustar00rootroot00000000000000ohai-16.0.7/spec/functional/plugins/powershell_spec.rb000066400000000000000000000047651362624620500230470ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "languages plugin" do VERSION_MATCHING_REGEX = /^(?:[\d]+\.)+[\d]+$/.freeze describe "powershell plugin", :windows_only do RSpec.shared_examples "a version looking thing" do it "is present" do expect(subject).not_to be_nil end it "looks like a version" do expect(subject).to match(VERSION_MATCHING_REGEX) end end subject { @plugin[:languages][:powershell] } before(:all) do @plugin = get_plugin("powershell") @plugin[:languages] = Mash.new @plugin.run end it "has information about powershell" do expect(subject).not_to be_nil end describe :version do subject { @plugin.languages[:powershell][described_class] } it_behaves_like "a version looking thing" end describe :ws_man_stack_version do subject { @plugin.languages[:powershell][described_class] } it_behaves_like "a version looking thing" end describe :serialization_version do subject { @plugin.languages[:powershell][described_class] } it_behaves_like "a version looking thing" end describe :clr_version do subject { @plugin.languages[:powershell][described_class] } it_behaves_like "a version looking thing" end describe :build_version do subject { @plugin.languages[:powershell][described_class] } it_behaves_like "a version looking thing" end describe :remoting_protocol_version do subject { @plugin.languages[:powershell][described_class] } it_behaves_like "a version looking thing" end describe :compatible_versions do it "has compatible_versions that look like versions" do @plugin.languages[:powershell][described_class].each do |version| expect(version).to match(VERSION_MATCHING_REGEX) end end end end end ohai-16.0.7/spec/functional/plugins/root_group_spec.rb000066400000000000000000000027471362624620500230600ustar00rootroot00000000000000# # Author:: Adam Edwards () # # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "root_group plugin" do let(:plugin) { get_plugin("root_group") } describe "windows platform", :windows_only do let(:wmi) { WmiLite::Wmi.new } it "returns the system's administrators (root) group" do # Notethat the Win32_Group WMI provider can be slow if your # system is domain-joined and has hundreds of thousands of # groups in Active Directory -- not a typical test scenario, but # something to watch if you run this test in such an environment. groups = wmi.query("select * from Win32_Group where sid = 'S-1-5-32-544'") expect(groups.length).to eq(1) administrators_group = groups[0]["name"].downcase plugin.run expect(plugin[:root_group].downcase).to be == administrators_group end end end ohai-16.0.7/spec/functional/plugins/windows/000077500000000000000000000000001362624620500210025ustar00rootroot00000000000000ohai-16.0.7/spec/functional/plugins/windows/uptime_spec.rb000066400000000000000000000031421362624620500236440ustar00rootroot00000000000000# # Author:: Aliasgar Batterywala () # Copyright:: Copyright (c) 2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Windows plugin uptime" do context "for newer version of Windows" do let(:uptime_plugin) do get_plugin("uptime").tap do |plugin| plugin[:platform_version] = "6.3.9600" end end let(:wmi) do double("wmi", { first_of: { "lastbootuptime" => "20160912103128.597219+0000" }, }) end before do allow(uptime_plugin).to receive(:collect_os).and_return(:windows) allow(WmiLite::Wmi).to receive(:new).and_return(wmi) allow(Time).to receive_message_chain(:new, :to_i).and_return(1473756619) end it "sets uptime_seconds to uptime" do uptime_plugin.run expect(uptime_plugin[:uptime_seconds]).to be == 80331 end it "sets uptime to a human readable value" do uptime_plugin.run expect(uptime_plugin[:uptime]).to eq("22 hours 18 minutes 51 seconds") end end end ohai-16.0.7/spec/ohai_spec.rb000066400000000000000000000014771362624620500157550ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai do it "has a version constant defined" do expect(Ohai::VERSION).to be_a_kind_of(String) end end ohai-16.0.7/spec/rcov.opts000066400000000000000000000000411362624620500153400ustar00rootroot00000000000000--exclude spec,bin,/Library/Ruby ohai-16.0.7/spec/spec.opts000066400000000000000000000000321362624620500153210ustar00rootroot00000000000000--format specdoc --colour ohai-16.0.7/spec/spec_helper.rb000066400000000000000000000074341362624620500163130ustar00rootroot00000000000000require "rspec/collection_matchers" # require 'pry-debugger' # require 'pry-stack_explorer' $:.unshift(File.expand_path("../..", __FILE__)) $:.unshift(File.dirname(__FILE__) + "/../lib") require "spec/support/platform_helpers" require "spec/support/integration_helper" require "wmi-lite" require "ohai" Ohai.config[:log_level] = :error PLUGIN_PATH = File.expand_path("../../lib/ohai/plugins", __FILE__) SPEC_PLUGIN_PATH = File.expand_path("../data/plugins", __FILE__) RSpec.configure do |config| config.before { @object_pristine = Object.clone } config.after { remove_constants } end include Ohai::Mixin::ConstantHelper if Ohai::Mixin::OS.collect_os == /mswin|mingw32|windows/ ENV["PATH"] = "" end def get_plugin(plugin, ohai = Ohai::System.new, path = PLUGIN_PATH) loader = Ohai::Loader.new(ohai) loader.load_plugin(File.join(path, "#{plugin}.rb")) end def convert_windows_output(stdout) stdout.gsub("\n", "\r\n") end def it_should_check_from(plugin, attribute, from, value) it "sets the #{attribute} to the value from '#{from}'" do @plugin.run expect(@plugin[attribute]).to eq(value) end end def it_should_check_from_mash(plugin, attribute, from, value) it "gets the #{plugin}[:#{attribute}] value from '#{from}'" do expect(@plugin).to receive(:shell_out).with(from).and_return(mock_shell_out(value[0], value[1], value[2])) @plugin.run end it "sets the #{plugin}[:#{attribute}] to the value from '#{from}'" do @plugin.run expect(@plugin[plugin][attribute]).to eq(value[1].split($/)[0]) end end def mock_shell_out(exitstatus, stdout, stderr) shell_out = double("mixlib_shell_out") allow(shell_out).to receive(:exitstatus).and_return(exitstatus) allow(shell_out).to receive(:stdout).and_return(stdout) allow(shell_out).to receive(:stderr).and_return(stderr) shell_out end # the mash variable may be an array listing multiple levels of Mash hierarchy def it_should_check_from_deep_mash(plugin, mash, attribute, from, value) it "gets the #{mash.inspect}[:#{attribute}] value from '#{from}'" do expect(@plugin).to receive(:shell_out).with(from).and_return(mock_shell_out(value[0], value[1], value[2])) @plugin.run end it "sets the #{mash.inspect}[:#{attribute}] to the value from '#{from}'" do @plugin.run value = value[1].split($/)[0] if mash.is_a?(String) expect(@plugin[mash][attribute]).to eq(value) elsif mash.is_a?(Array) if mash.length == 2 expect(@plugin[mash[0]][mash[1]][attribute]).to eq value elsif mash.length == 3 expect(@plugin[mash[0]][mash[1]][mash[2]][attribute]).to eq value else return nil end else return nil end end end RSpec.configure do |config| # Not worth addressing warnings in Ohai until upstream ones in ffi-yajl are # fixed. # config.warnings = true config.raise_errors_for_deprecations! # `expect` should be preferred for new tests or when refactoring old tests, # but we're not going to do a "big bang" change at this time. config.expect_with :rspec do |c| c.syntax = :expect end config.mock_with :rspec do |c| c.syntax = :expect end config.filter_run focus: true config.filter_run_excluding windows_only: true unless windows? config.filter_run_excluding unix_only: true unless unix? config.filter_run_excluding requires_root: true unless ENV["USER"] == "root" config.filter_run_excluding requires_unprivileged_user: true if ENV["USER"] == "root" config.run_all_when_everything_filtered = true config.before do # TODO: Change to Ohai.config once Ohai::Config is deprecated fully. Needs # to stay Ohai::Config for now so that top-level attributes will get cleared # out between tests (config_spec should be the only place where top-level # config attributes are set). Ohai::Config.reset end end ohai-16.0.7/spec/support/000077500000000000000000000000001362624620500152015ustar00rootroot00000000000000ohai-16.0.7/spec/support/integration_helper.rb000066400000000000000000000033101362624620500214050ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); you # may not use this file except in compliance with the License. You may # obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or # implied. # See the License for the specific language governing permissions and # limitations under the License # require "tmpdir" module IntegrationSupport def when_plugins_directory(description, &block) context "When the plugins directory #{description}" do before do @plugins_directory = Dir.mktmpdir("ohai-plugins") end after do if @plugins_directory begin FileUtils.remove_entry_secure(@plugins_directory) ensure @plugins_directory = nil end end end def with_plugin(plugin_path, contents) # rubocop:disable Lint/NestedMethodDefinition filename = path_to(plugin_path) dir = File.dirname(filename) FileUtils.mkdir_p(dir) unless dir == "." File.open(filename, "w") do |file| file.write(contents) end end def path_to(plugin_path) # rubocop:disable Lint/NestedMethodDefinition File.expand_path(plugin_path, @plugins_directory) end def self.with_plugin(plugin_path, contents) # rubocop:disable Lint/NestedMethodDefinition before do with_plugin(plugin_path, contents) end end instance_eval(&block) end end end ohai-16.0.7/spec/support/platform_helpers.rb000066400000000000000000000015531362624620500211000ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); you # may not use this file except in compliance with the License. You may # obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or # implied. # See the License for the specific language governing permissions and # limitations under the License # def windows? !!(RUBY_PLATFORM =~ /mswin|mingw|windows/) end def unix? !windows? end def os_x? !!(RUBY_PLATFORM =~ /darwin/) end def solaris? !!(RUBY_PLATFORM =~ /solaris/) end def freebsd? !!(RUBY_PLATFORM =~ /freebsd/) end DEV_NULL = windows? ? "NUL" : "/dev/null" ohai-16.0.7/spec/unit/000077500000000000000000000000001362624620500144445ustar00rootroot00000000000000ohai-16.0.7/spec/unit/application_spec.rb000066400000000000000000000055531362624620500203160ustar00rootroot00000000000000# # Author:: Claire McQuin # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/application" RSpec.describe "Ohai::Application" do let(:argv) { [] } let(:app) { Ohai::Application.new } before do @original_argv = ARGV ARGV.replace(argv) end after do ARGV.replace(@original_argv) end describe "#configure_ohai" do describe "loading configuration from a file" do let(:config_file) { "/local/workstation/config" } let(:config_loader) { instance_double("ChefConfig::WorkstationConfigLoader") } context "when specified on the command line" do let(:argv) { [ "-c", config_file ] } before do if windows? expect(ChefConfig::WorkstationConfigLoader).to receive(:new) .with("C:#{config_file}", Ohai::Log) .and_return(config_loader) else expect(ChefConfig::WorkstationConfigLoader).to receive(:new) .with(config_file, Ohai::Log) .and_return(config_loader) end end it "loads the configuration file" do expect(config_loader).to receive(:load) app.configure_ohai end context "when the configuration file does not exist" do it "terminates the application" do expect(config_loader).to receive(:load).and_raise(ChefConfig::ConfigurationError) expect(Ohai::Application).to receive(:fatal!) app.configure_ohai end end end context "when a local workstation config exists" do before do expect(ChefConfig::WorkstationConfigLoader).to receive(:new) .with(nil, Ohai::Log) .and_return(config_loader) end it "loads the configuration file" do expect(config_loader).to receive(:load) app.configure_ohai end end end context "when CLI options are provided" do let(:argv) { [ "-d", directory ] } let(:directory) { "/some/fantastic/plugins" } it "does not generate deprecated config warnings for cli options" do expect(Ohai::Log).not_to receive(:warn) .with(/Ohai::Config\[:directory\] is deprecated/) app.configure_ohai end end end end ohai-16.0.7/spec/unit/config_spec.rb000066400000000000000000000042761362624620500172610ustar00rootroot00000000000000# # Author:: Claire McQuin () # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/config" RSpec.describe Ohai::Config do describe "config_context :ohai" do describe "option :plugin" do it "gets configured with a value" do described_class.ohai[:plugin][:foo] = true expect(described_class.ohai[:plugin]).to have_key(:foo) expect(described_class.ohai[:plugin][:foo]).to be true end it "gets configured with a Hash" do value = { bar: true, baz: true } described_class.ohai[:plugin][:foo] = value expect(described_class.ohai[:plugin]).to have_key(:foo) expect(described_class.ohai[:plugin][:foo]).to eq(value) end it "raises an error if the plugin name is not a symbol" do expect { described_class.ohai[:plugin]["foo"] = false } .to raise_error(Ohai::Exceptions::PluginConfigError, /Expected Symbol/) end it "raises an error if the value Hash has non-Symbol key" do value = { :bar => true, "baz" => true } expect { described_class.ohai[:plugin][:foo] = value } .to raise_error(Ohai::Exceptions::PluginConfigError, /Expected Symbol/) end end describe "option :optional_plugins" do it "Converts string values to symbols" do described_class.ohai[:optional_plugins] = [ "Foo" ] expect(described_class.ohai[:optional_plugins]).to eq([:Foo]) end end end describe "Ohai.config" do it "returns the ohai config context" do expect(Ohai.config).to eq(described_class.ohai) end end end ohai-16.0.7/spec/unit/dsl/000077500000000000000000000000001362624620500152265ustar00rootroot00000000000000ohai-16.0.7/spec/unit/dsl/plugin_spec.rb000066400000000000000000000477041362624620500200770ustar00rootroot00000000000000# # Author:: Claire McQuin () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); you # may not use this file except in compliance with the License. You may # obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or # implied. # See the License for the specific language governing permissions and # limitations under the License # require "spec_helper" shared_examples "Ohai::DSL::Plugin" do describe "#initialize" do it "sets has_run? to false" do expect(plugin.has_run?).to be false end it "sets the correct plugin version" do expect(plugin.version).to eql(version) end end describe "#run" do before do allow(plugin).to receive(:run_plugin).and_return(true) allow(plugin).to receive(:name).and_return(:TestPlugin) end describe "when plugin is enabled" do before do allow(Ohai.config).to receive(:[]).with(:disabled_plugins).and_return([ ]) end it "runs the plugin" do expect(plugin).to receive(:run_plugin) plugin.run end it "sets has_run? to true" do plugin.run expect(plugin.has_run?).to be true end end describe "if the plugin is disabled" do before do allow(Ohai.config).to receive(:[]).with(:disabled_plugins).and_return([ :TestPlugin ]) end it "does not run the plugin" do expect(plugin).not_to receive(:run_plugin) plugin.run end it "logs a message to trace" do expect(plugin.logger).to receive(:trace).with(/Skipping disabled plugin TestPlugin/) plugin.run end it "sets has_run? to true" do plugin.run expect(plugin.has_run?).to be true end end end context "when accessing data via method_missing" do it "takes a missing method and store the method name as a key, with its arguments as values" do plugin.guns_n_roses("chinese democracy") expect(plugin.data["guns_n_roses"]).to eql("chinese democracy") end it "returns the current value of the method name" do expect(plugin.guns_n_roses("chinese democracy")).to eql("chinese democracy") end it "allows you to get the value of a key by calling method_missing with no arguments" do plugin.guns_n_roses("chinese democracy") expect(plugin.guns_n_roses).to eql("chinese democracy") end end describe "set_attribute" do it "raises an ArgumentError when given one argument" do expect { plugin.set_attribute(:tea) }.to raise_error(ArgumentError) end it "lets you set an attribute" do plugin.set_attribute(:tea, "is soothing") expect(plugin.data["tea"]).to eql("is soothing") end it "lets you set an attribute to an empty array" do plugin.set_attribute(:tea, []) expect(plugin.data["tea"]).to eql([]) end it "lets you set an attribute to an empty Mash" do plugin.set_attribute(:tea, {}) expect(plugin.data["tea"]).to eql({}) end it "lets you modify an attribute" do plugin.data["tea"] = "is soothing" plugin.set_attribute(:tea, "tastes like plants") expect(plugin.data["tea"]).to eql("tastes like plants") end it "lets you set a subattribute" do plugin.data["tea"] = Mash.new plugin.set_attribute(:tea, :green, "tastes like green") expect(plugin.data["tea"]["green"]).to eql("tastes like green") end it "lets you set a subattribute to an empty array" do plugin.set_attribute(:tea, :green, []) expect(plugin.data["tea"]["green"]).to eql([]) end it "lets you set a subattribute to an empty Mash" do plugin.set_attribute(:tea, :green, {}) expect(plugin.data["tea"]["green"]).to eql({}) end it "lets you modify a subattribute" do plugin.data["tea"] = Mash.new plugin.data["tea"]["green"] = "tastes like green" plugin.set_attribute(:tea, :green, "made from leaves") expect(plugin.data["tea"]["green"]).to eql("made from leaves") end it "raises a TypeError when modifying an attribute that is not a Mash" do plugin.data["tea"] = Mash.new plugin.data["tea"] = "is soothing" expect { plugin.set_attribute(:tea, :green, "tastes like green") }.to raise_error(TypeError) end it "lets you modify a subattribute with an array" do green = { flavor: "tastes like green" } black = { flavor: "tastes like black" } plugin.data[:tea] = [green, black] plugin.set_attribute(:tea, 0, :source, "made from leaves") expect(plugin.data[:tea][0][:source]).to eq("made from leaves") end end context "when getting attributes" do before do plugin.set_attribute(:tea, "is soothing") end it "lets you get an attribute" do expect(plugin.get_attribute("tea")).to eql("is soothing") end end describe "get_attribute" do it "requires at least one argument" do expect { plugin.get_attribute }.to raise_error(ArgumentError) end describe "a top-level attribute" do before do plugin.set_attribute(:tea, "is soothing") end describe "as a string" do it "returns nil when the attribute does not exist" do expect(plugin.get_attribute("coffee")).to be nil end it "returns the attribute when it exists" do expect(plugin.get_attribute("tea")).to eql("is soothing") end end describe "as a symbol" do it "returns false when the attribute does not exist" do expect(plugin.get_attribute(:coffee)).to be nil end it "returns true when the attribute exists" do expect(plugin.get_attribute(:tea)).to eql("is soothing") end end end describe "a nested attribute" do before do plugin.set_attribute(:the_monarch, { arch_rival: "dr_venture" }) end describe "as a list" do describe "of strings" do it "returns true when the attribute exists" do expect(plugin.get_attribute("the_monarch", "arch_rival")) .to eql("dr_venture") end describe "when the attribute does not exist" do describe "and the subkey is missing" do it "returns nil" do expect( plugin.get_attribute("the_monarch", "henchmen") ).to be nil end end describe "and an intermediate key is missing" do it "returns nil" do expect( plugin.get_attribute("the_monarch", "henchmen", "corky_knightrider") ).to be nil end end describe "and an intermediate key is not a hash" do it "raises a TypeError" do expect do plugin.get_attribute("the_monarch", "arch_rival", "dr_venture", "since") end.to raise_error(TypeError, "Expected Hash but got String.") end end end end describe "of symbols" do it "returns true when the attribute exists" do expect(plugin.get_attribute(:the_monarch, :arch_rival)) .to eql("dr_venture") end describe "when the attribute does not exist" do describe "and the subkey is missing" do it "returns nil" do expect(plugin.get_attribute(:the_monarch, :henchmen)).to be nil end end describe "and an intermediate key is missing" do it "returns nil" do expect( plugin.get_attribute(:the_monarch, :henchmen, :corky_knightrider) ).to be nil end end describe "and an intermediate key is not a hash" do it "raises a TypeError" do expect do plugin.get_attribute(:the_monarch, :arch_rival, :dr_venture, :since) end.to raise_error(TypeError, "Expected Hash but got String.") end end end end end end end describe "attribute?" do it "requires at least one argument" do expect { plugin.attribute? }.to raise_error(ArgumentError) end describe "a top-level attribute" do describe "as a string" do it "returns false when the attribute does not exist" do expect(plugin.attribute?("alice in chains")).to be(false) end it "returns true if an attribute exists with the given name" do plugin.metallica("death magnetic") expect(plugin.attribute?("metallica")).to be(true) end end describe "as a symbol" do it "returns false when the attribute does not exist" do expect(plugin.attribute?(:sparkle_dream)).to be false end it "returns true when the attribute exists" do plugin.set_attribute("sparkle_dream", { version: 256 }) expect(plugin.attribute?(:sparkle_dream)).to be true end end end describe "a nested attribute" do before do plugin.set_attribute(:the_monarch, { arch_rival: "dr_venture" }) end describe "as a list" do describe "of strings" do it "returns true when the attribute exists" do expect(plugin.attribute?("the_monarch", "arch_rival")).to be true end describe "when the attribute does not exist" do describe "and the subkey is missing" do it "returns false" do expect( plugin.attribute?("the_monarch", "henchmen") ).to be false end end describe "and an intermediate key is missing" do it "returns false" do expect( plugin.attribute?("the_monarch", "henchmen", "corky_knightrider") ).to be false end end describe "and an intermediate key is not a hash" do it "raises a TypeError" do expect do plugin.attribute?("the_monarch", "arch_rival", "dr_venture", "since") end.to raise_error(TypeError, "Expected Hash but got String.") end end end end describe "of symbols" do it "returns true when the attribute exists" do expect(plugin.attribute?(:the_monarch, :arch_rival)).to be true end describe "when the attribute does not exist" do describe "and the subkey is missing" do it "returns false" do expect(plugin.attribute?(:the_monarch, :henchmen)).to be false end end describe "and an intermediate key is missing" do it "returns false" do expect( plugin.attribute?(:the_monarch, :henchmen, :corky_knightrider) ).to be false end end describe "and an intermediate key is not a hash" do it "raises a TypeError" do expect do plugin.attribute?(:the_monarch, :arch_rival, :dr_venture, :since) end.to raise_error(TypeError, "Expected Hash but got String.") end end end end end end end end describe Ohai::DSL::Plugin::VersionVII do let(:logger) { Ohai::Log } it "does not modify the plugin name when the plugin is named correctly" do plugin = Ohai.plugin(:FunkyVALIDpluginName) {}.new({}, logger) expect(plugin.name).to be(:FunkyVALIDpluginName) end describe "when the plugin is named incorrectly" do context "because the plugin name doesn't start with a capital letter" do it "raises an Ohai::Exceptions::InvalidPluginName exception" do expect { Ohai.plugin(:badName) {} }.to raise_error(Ohai::Exceptions::InvalidPluginName, /badName is not a valid plugin name/) end end context "because the plugin name contains an underscore" do it "raises an Ohai::Exceptions::InvalidPluginName exception" do expect { Ohai.plugin(:Bad_Name) {} }.to raise_error(Ohai::Exceptions::InvalidPluginName, /Bad_Name is not a valid plugin name/) end end context "because the plugin name isn't a symbol" do it "raises an Ohai::Exceptions::InvalidPluginName exception" do expect { Ohai.plugin(1138) {} }.to raise_error(Ohai::Exceptions::InvalidPluginName, /1138 is not a valid plugin name/) end end end describe "#version" do it "saves the plugin version as :version7" do plugin = Ohai.plugin(:Test) {} expect(plugin.version).to be(:version7) end end describe "#provides" do it "collects a single attribute" do plugin = Ohai.plugin(:Test) { provides("one") } expect(plugin.provides_attrs).to eql(["one"]) end it "collects a list of attributes" do plugin = Ohai.plugin(:Test) { provides("one", "two", "three") } expect(plugin.provides_attrs).to eql(%w{one two three}) end it "collects from multiple provides statements" do plugin = Ohai.plugin(:Test) do provides("one") provides("two", "three") provides("four") end expect(plugin.provides_attrs).to eql(%w{one two three four}) end it "collects attributes across multiple plugin files" do plugin = Ohai.plugin(:Test) { provides("one") } # rubocop: disable Lint/UselessAssignment plugin = Ohai.plugin(:Test) { provides("two", "three") } expect(plugin.provides_attrs).to eql(%w{one two three}) end it "collects unique attributes" do plugin = Ohai.plugin(:Test) { provides("one") } # rubocop: disable Lint/UselessAssignment plugin = Ohai.plugin(:Test) { provides("one", "two") } expect(plugin.provides_attrs).to eql(%w{one two}) end end describe "#depends" do it "collects a single dependency" do plugin = Ohai.plugin(:Test) { depends("one") } expect(plugin.depends_attrs).to eql(["one"]) end it "collects a list of dependencies" do plugin = Ohai.plugin(:Test) { depends("one", "two", "three") } expect(plugin.depends_attrs).to eql(%w{one two three}) end it "collects from multiple depends statements" do plugin = Ohai.plugin(:Test) do depends("one") depends("two", "three") depends("four") end expect(plugin.depends_attrs).to eql(%w{one two three four}) end it "collects dependencies across multiple plugin files" do plugin = Ohai.plugin(:Test) { depends("one") } # rubocop: disable Lint/UselessAssignment plugin = Ohai.plugin(:Test) { depends("two", "three") } expect(plugin.depends_attrs).to eql(%w{one two three}) end it "collects unique attributes" do plugin = Ohai.plugin(:Test) { depends("one") } # rubocop: disable Lint/UselessAssignment plugin = Ohai.plugin(:Test) { depends("one", "two") } expect(plugin.depends_attrs).to eql(%w{one two}) end end describe "#collect_data" do it "saves as :default if no platform is given" do plugin = Ohai.plugin(:Test) { collect_data {} } expect(plugin.data_collector).to have_key(:default) end it "saves a single given platform" do plugin = Ohai.plugin(:Test) { collect_data(:ubuntu) {} } expect(plugin.data_collector).to have_key(:ubuntu) end it "saves a list of platforms" do plugin = Ohai.plugin(:Test) { collect_data(:freebsd, :netbsd, :openbsd) {} } %i{freebsd netbsd openbsd}.each do |platform| expect(plugin.data_collector).to have_key(platform) end end it "saves multiple collect_data blocks" do plugin = Ohai.plugin(:Test) do collect_data {} collect_data(:windows) {} collect_data(:darwin) {} end %i{darwin default windows}.each do |platform| expect(plugin.data_collector).to have_key(platform) end end it "saves platforms across multiple plugins" do plugin = Ohai.plugin(:Test) { collect_data {} } plugin = Ohai.plugin(:Test) { collect_data(:aix, :sigar) {} } %i{aix default sigar}.each do |platform| expect(plugin.data_collector).to have_key(platform) end end it "fails a platform has already been defined in the same plugin" do Ohai.plugin(:Test) { collect_data {} } expect(Ohai::Log).to receive(:warn).with(/collect_data already defined on platform/).twice Ohai.plugin(:Test) do collect_data {} collect_data {} end end it "fails if a platform has already been defined in another plugin file" do Ohai.plugin(:Test) { collect_data {} } expect(Ohai::Log).to receive(:warn).with(/collect_data already defined on platform/) Ohai.plugin(:Test) do collect_data {} end end end describe "#provides (deprecated)" do it "logs a warning" do plugin = Ohai.plugin(:Test).new(Mash.new, logger) expect_any_instance_of(Mixlib::Log::Child).to receive(:warn).with(/\[UNSUPPORTED OPERATION\]/) plugin.provides("attribute") end end describe "#require_plugin (deprecated)" do it "logs a warning" do plugin = Ohai.plugin(:Test).new(Mash.new, logger) expect_any_instance_of(Mixlib::Log::Child).to receive(:warn).with(/\[UNSUPPORTED OPERATION\]/) plugin.require_plugin("plugin") end end describe "#configuration" do let(:plugin) do klass = Ohai.plugin(camel_name) {} klass.new({}, logger) end shared_examples_for "plugin config lookup" do it "returns the configuration option value" do Ohai.config[:plugin][snake_name][:foo] = true expect(plugin.configuration(:foo)).to eq(true) end end describe "a plugin named Abc" do let(:camel_name) { :Abc } let(:snake_name) { :abc } it "returns nil when the plugin is not configured" do expect(plugin.configuration(:foo)).to eq(nil) end it "does not auto-vivify an un-configured plugin" do plugin.configuration(:foo) expect(Ohai.config[:plugin]).not_to have_key(:test) end it "returns nil when the option is not configured" do Ohai.config[:plugin][snake_name][:foo] = true expect(plugin.configuration(:bar)).to eq(nil) end it "returns nil when the suboption is not configured" do Ohai.config[:plugin][snake_name][:foo] = {} expect(plugin.configuration(:foo, :bar)).to eq(nil) end include_examples "plugin config lookup" it "returns the configuration sub-option value" do Ohai.config[:plugin][snake_name][:foo] = { bar: true } expect(plugin.configuration(:foo, :bar)).to eq(true) end end describe "a plugin named ABC" do let(:camel_name) { :ABC } let(:snake_name) { :abc } include_examples "plugin config lookup" end describe "a plugin named Abc2" do let(:camel_name) { :Abc2 } let(:snake_name) { :abc_2 } include_examples "plugin config lookup" end describe "a plugin named AbcAbc" do let(:camel_name) { :AbcXyz } let(:snake_name) { :abc_xyz } include_examples "plugin config lookup" end describe "a plugin named ABCLmnoXyz" do let(:camel_name) { :ABCLmnoXyz } let(:snake_name) { :abc_lmno_xyz } include_examples "plugin config lookup" end end it_behaves_like "Ohai::DSL::Plugin" do let(:ohai) { Ohai::System.new } let(:plugin) { Ohai.plugin(:Test).new(ohai.data, ohai.logger) } let(:version) { :version7 } end end ohai-16.0.7/spec/unit/hints_spec.rb000066400000000000000000000032751362624620500171370ustar00rootroot00000000000000# # Author:: Serdar Sutay () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe "Ohai::Hints" do # We are using the plugins directory infrastructure to test hints extend IntegrationSupport before do @original_hints = Ohai.config[:hints_path] end after do Ohai.config[:hints_path] = @original_hints end when_plugins_directory "doesn't contain any hints" do before do Ohai.config[:hints_path] = [ path_to(".") ] end it "hint? should return nil" do expect(Ohai::Hints.hint?("cloud")).to be_nil end end when_plugins_directory "contains empty and full hints" do with_plugin("cloud.json", <<~EOF) {"name":"circus"} EOF with_plugin("cloud_empty.json", < "circus" }) end it "hint? should return empty hash for empty hints" do expect(Ohai::Hints.hint?("cloud_empty")).to eq({}) end end end ohai-16.0.7/spec/unit/loader_spec.rb000066400000000000000000000142261362624620500172560ustar00rootroot00000000000000# # Author:: Claire McQuin () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::Loader do extend IntegrationSupport let(:loader) { described_class.new(ohai) } let(:ohai) { double("Ohai::System", data: Mash.new, provides_map: provides_map, logger: Ohai::Log) } let(:provides_map) { Ohai::ProvidesMap.new } describe "#initialize" do it "returns an Ohai::Loader object" do loader = described_class.new(ohai) expect(loader).to be_a_kind_of(described_class) end end when_plugins_directory "is an additional plugin path" do with_plugin("cookbook_a/alpha.rb", <<~EOF) Ohai.plugin(:Alpha) do provides "alpha" end EOF with_plugin("cookbook_b/beta.rb", <<~EOF) Ohai.plugin(:Beta) do provides "beta" end EOF describe "#load_additional" do it "adds the plugins to the map" do loader.load_additional(@plugins_directory) expect(provides_map.map.keys).to include("alpha") end it "returns a set of plugins" do expect(loader.load_additional(@plugins_directory)).to include(Ohai::NamedPlugin::Alpha) end end end when_plugins_directory "contains invalid plugins" do with_plugin("extra_s.rb", <<~EOF) Ohai.plugins(:ExtraS) do provides "the_letter_s" end EOF with_plugin("no_method.rb", <<~EOF) Ohai.plugin(:NoMethod) do really_wants "this_attribute" end EOF with_plugin("illegal_def.rb", <<~EOF) Ohai.plugin(:Zoo) do collect_data(:darwin) do end collect_data(:darwin) do end end EOF with_plugin("unexpected_error.rb", <<~EOF) Ohai.plugin(:Zoo) do raise "You aren't expecting this." end EOF with_plugin("bad_symbol.rb", <<~EOF) Ohai.plugin(:1nval!d) do provides "not_a_symbol" end EOF with_plugin("no_end.rb", <<~EOF) Ohai.plugin(:NoEnd) do provides "fish_oil" collect_data do end EOF with_plugin("bad_name.rb", <<~EOF) Ohai.plugin(:you_give_plugins_a_bad_name) do provides "that/one/song" end EOF describe "load_plugin() method" do describe "when the plugin uses Ohai.plugin instead of Ohai.plugins" do it "logs an unsupported operation warning" do expect(loader.logger).to receive(:warn).with(/Plugin Method Error: <#{path_to("extra_s.rb")}>:/) loader.load_plugin(path_to("extra_s.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("extra_s.rb")) }.not_to raise_error end end describe "when the plugin tries to call an unexisting method" do it "shoud log an unsupported operation warning" do expect(loader.logger).to receive(:warn).with(/Plugin Method Error: <#{path_to("no_method.rb")}>:/) loader.load_plugin(path_to("no_method.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("no_method.rb")) }.not_to raise_error end end describe "when the plugin defines collect_data on the same platform more than once" do it "shoud log an illegal plugin definition warning" do expect(Ohai::Log).to receive(:warn).with(/collect_data already defined on platform/) loader.load_plugin(path_to("illegal_def.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("illegal_def.rb")) }.not_to raise_error end end describe "when an unexpected error is encountered" do it "logs a warning" do expect(loader.logger).to receive(:warn).with(/Plugin Error: <#{path_to("unexpected_error.rb")}>:/) loader.load_plugin(path_to("unexpected_error.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("unexpected_error.rb")) }.not_to raise_error end end describe "when the plugin name symbol has bad syntax" do it "logs a syntax error warning" do expect(loader.logger).to receive(:warn).with(/Plugin Syntax Error: <#{path_to("bad_symbol.rb")}>:/) loader.load_plugin(path_to("bad_symbol.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("bad_symbol.rb")) }.not_to raise_error end end describe "when the plugin forgets an 'end'" do it "logs a syntax error warning" do expect(loader.logger).to receive(:warn).with(/Plugin Syntax Error: <#{path_to("no_end.rb")}>:/) loader.load_plugin(path_to("no_end.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("no_end.rb")) }.not_to raise_error end end describe "when the plugin has an invalid name" do it "logs an invalid plugin name warning" do expect(loader.logger).to receive(:warn).with(/Plugin Name Error: <#{path_to("bad_name.rb")}>:/) loader.load_plugin(path_to("bad_name.rb")) end it "does not raise an error" do expect { loader.load_plugin(path_to("bad_name.rb")) }.not_to raise_error end end describe "when plugin directory does not exist" do it "logs an invalid plugin path warning" do expect(Ohai::Log).to receive(:debug).with(/The plugin path.*does not exist/) allow(Dir).to receive(:exist?).with("/bogus/dir").and_return(false) loader.plugin_files_by_dir("/bogus/dir") end end end end end ohai-16.0.7/spec/unit/mixin/000077500000000000000000000000001362624620500155705ustar00rootroot00000000000000ohai-16.0.7/spec/unit/mixin/azure_metadata_spec.rb000066400000000000000000000045521362624620500221230ustar00rootroot00000000000000# # Author:: Tim Smith # Copyright:: 2017 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDIT"Net::HTTP Response"NS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/mixin/azure_metadata" describe Ohai::Mixin::AzureMetadata do let(:mixin) do mixin = Object.new.extend(::Ohai::Mixin::AzureMetadata) mixin end before do logger = instance_double("Mixlib::Log::Child", trace: nil, debug: nil, warn: nil) allow(mixin).to receive(:logger).and_return(logger) end describe "#http_get" do it "gets the passed URI" do http_mock = double("http") allow(http_mock).to receive(:read_timeout=) allow(Net::HTTP).to receive(:start).with("169.254.169.254").and_return(http_mock) expect(http_mock).to receive(:get).with("http://www.chef.io", { "Metadata" => "true" }) mixin.http_get("http://www.chef.io") end end describe "#fetch_metadata" do it "returns an empty hash given a non-200 response" do http_mock = double("http", { code: "500" }) allow(mixin).to receive(:http_get).and_return(http_mock) expect(mixin.logger).to receive(:warn) vals = mixin.fetch_metadata expect(vals).to eq(nil) end it "returns an empty hash given invalid JSON response" do http_mock = double("http", { code: "200", body: '{ "foo" "bar"}' }) allow(mixin).to receive(:http_get).and_return(http_mock) expect(mixin.logger).to receive(:warn) vals = mixin.fetch_metadata expect(vals).to eq(nil) end it "returns a populated hash given valid JSON response" do http_mock = double("http", { code: "200", body: '{ "foo": "bar"}' }) allow(mixin).to receive(:http_get).and_return(http_mock) expect(mixin.logger).not_to receive(:warn) vals = mixin.fetch_metadata expect(vals).to eq({ "foo" => "bar" }) end end end ohai-16.0.7/spec/unit/mixin/command_spec.rb000066400000000000000000000106651362624620500205550ustar00rootroot00000000000000# encoding: utf-8 # # Author:: Diego Algorta (diego@oboxodo.com) # Copyright:: Copyright (c) 2009 Diego Algorta # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::Mixin::Command, "shell_out" do let(:cmd) { "sparkle-dream --version" } let(:shell_out) { double("Mixlib::ShellOut") } let(:plugin_name) { :OSSparkleDream } let(:options) { windows? ? { timeout: 30 } : { timeout: 30, env: { "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" } } } let(:logger) { instance_double("Mixlib::Log::Child", trace: nil, debug: nil, warn: nil) } before do allow(described_class).to receive(:logger).and_return(logger) allow(described_class).to receive(:name).and_return(plugin_name) @original_env = ENV.to_hash ENV.clear end after do ENV.clear ENV.update(@original_env) end describe "when the command runs" do it "logs the command and exitstatus" do expect(Mixlib::ShellOut) .to receive(:new) .with(cmd, options) .and_return(shell_out) expect(shell_out) .to receive(:run_command) expect(shell_out) .to receive(:exitstatus) .and_return(256) expect(logger).to receive(:trace) .with("Plugin OSSparkleDream: ran 'sparkle-dream --version' and returned 256") described_class.shell_out(cmd) end end describe "when the command does not exist" do it "logs the command and error message" do expect(Mixlib::ShellOut) .to receive(:new) .with(cmd, options) .and_return(shell_out) expect(shell_out) .to receive(:run_command) .and_raise(Errno::ENOENT, "sparkle-dream") expect(logger) .to receive(:trace) .with("Plugin OSSparkleDream: ran 'sparkle-dream --version' and failed " \ "#") expect { described_class.shell_out(cmd) } .to raise_error(Ohai::Exceptions::Exec) end end describe "when the command times out" do it "logs the command an timeout error message" do expect(Mixlib::ShellOut) .to receive(:new) .with(cmd, options) .and_return(shell_out) expect(shell_out) .to receive(:run_command) .and_raise(Mixlib::ShellOut::CommandTimeout) expect(logger) .to receive(:trace) .with("Plugin OSSparkleDream: ran 'sparkle-dream --version' and timed " \ "out after 30 seconds") expect { described_class.shell_out(cmd) } .to raise_error(Ohai::Exceptions::Exec) end end describe "when a timeout option is provided" do let(:options) { windows? ? { timeout: 10 } : { timeout: 10, env: { "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" } } } it "runs the command with the provided timeout" do expect(Mixlib::ShellOut) .to receive(:new) .with(cmd, options) .and_return(shell_out) expect(shell_out) .to receive(:run_command) expect(shell_out) .to receive(:exitstatus) .and_return(256) expect(logger).to receive(:trace) .with("Plugin OSSparkleDream: ran 'sparkle-dream --version' and returned 256") described_class.shell_out(cmd, options) end describe "when the command times out" do it "logs the command an timeout error message" do expect(Mixlib::ShellOut) .to receive(:new) .with(cmd, options) .and_return(shell_out) expect(shell_out) .to receive(:run_command) .and_raise(Mixlib::ShellOut::CommandTimeout) expect(logger) .to receive(:trace) .with("Plugin OSSparkleDream: ran 'sparkle-dream --version' and timed " \ "out after 10 seconds") expect { described_class.shell_out(cmd, options) } .to raise_error(Ohai::Exceptions::Exec) end end end end ohai-16.0.7/spec/unit/mixin/dmi_decode_spec.rb000066400000000000000000000054211362624620500212050ustar00rootroot00000000000000# # Author:: Tim Smith (tsmith@chef.io) # Copyright:: Copyright (c) 2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/mixin/dmi_decode" describe Ohai::Mixin::DmiDecode, "guest_from_dmi_data" do let(:mixin) { Object.new.extend(described_class) } # for the full DMI data used in these tests see https://github.com/chef/dmidecode_collection # the fields here are manufacturer, product, and version as passed to #guest_from_dmi_data { xen: ["Xen", "HVM domU", "4.2.amazon"], vmware: ["VMware, Inc.", "VMware Virtual Platform", "None"], hyperv: ["Microsoft", "Virtual Machine", "7.0"], amazonec2: ["Amazon EC2", "c5n.large", "Not Specified"], veertu: ["Veertu", "Veertu", "Not Specified"], parallels: ["Parallels Software International Inc.", "Parallels Virtual Platform", "None"], vbox: ["Oracle Corporation", "VirtualBox", "1.2"], openstack: ["OpenStack Foundation", "", "15.1.5"], kvm: ["Red Hat", "KVM", "RHEL 7.0.0 PC (i440FX + PIIX, 1996"], bhyve: ["", "BHYVE", "1.0"], }.each_pair do |hypervisor, values| describe "when passed #{hypervisor} dmi data" do it "returns '#{hypervisor}'" do expect(mixin.guest_from_dmi_data(values[0], values[1], values[2])).to eq("#{hypervisor}") end end end describe "when passed Redhat's Openstack varient dmi data" do it "returns 'openstack'" do expect(mixin.guest_from_dmi_data("Red Hat Inc.", "OpenStack Nova", "2014.1.2-1.el6")).to eq("openstack") end end describe "When running on RHEV Hypervisor" do it "returns 'kvm'" do expect(mixin.guest_from_dmi_data("Red Hat", "RHEV Hypervisor", "6.7-20150911.0.el6ev")).to eq("kvm") end end describe "When the manufactuer is 'QEMU'" do it "return kvm" do expect(mixin.guest_from_dmi_data("QEMU", "", "")).to eq("kvm") end end describe "returns nil if manufactuer is 'Microsoft', but product is not 'Virtual Machine'" do it "returns nil" do expect(mixin.guest_from_dmi_data("Microsot", "Zune", "2018")).to be_nil end end describe "When running on an unkown system" do it "returns nil" do expect(mixin.guest_from_dmi_data("TimCorp", "SuperServer", "2018")).to be_nil end end end ohai-16.0.7/spec/unit/mixin/ec2_metadata_spec.rb000066400000000000000000000060501362624620500214410ustar00rootroot00000000000000# # Author:: Bryan McLellan # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDIT"Net::HTTP Response"NS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/mixin/ec2_metadata" describe Ohai::Mixin::Ec2Metadata do let(:mixin) do metadata_object = Object.new.extend(described_class) http_client = double("Net::HTTP client") allow(http_client).to receive(:get).and_return(response) allow(metadata_object).to receive(:http_client).and_return(http_client) metadata_object end before do logger = instance_double("Mixlib::Log::Child", trace: nil, debug: nil, warn: nil) allow(mixin).to receive(:logger).and_return(logger) end describe "#best_api_version" do context "with a sorted list of metadata versions" do let(:response) { double("Net::HTTP Response", body: "1.0\n2011-05-01\n2012-01-12\nUnsupported", code: "200") } it "returns the most recent version" do expect(mixin.best_api_version).to eq("2012-01-12") end end context "with an unsorted list of metadata versions" do let(:response) { double("Net::HTTP Response", body: "1.0\n2009-04-04\n2007-03-01\n2011-05-01\n2008-09-01\nUnsupported", code: "200") } it "returns the most recent version (using string sort)" do expect(mixin.best_api_version).to eq("2011-05-01") end end context "when no supported versions are found" do let(:response) { double("Net::HTTP Response", body: "2020-01-01\nUnsupported", code: "200") } it "raises an error" do expect { mixin.best_api_version }.to raise_error(RuntimeError) end end # Presume 'latest' when we get a 404 for Eucalyptus back-compat context "when the response code is 404" do let(:response) { double("Net::HTTP Response", code: "404") } it "returns 'latest' as the version" do expect(mixin.best_api_version).to eq("latest") end end context "when the response code is unexpected" do let(:response) { double("Net::HTTP Response", body: "1.0\n2011-05-01\n2012-01-12\nUnsupported", code: "418") } it "raises an error" do expect { mixin.best_api_version }.to raise_error(RuntimeError) end end end describe "#metadata_get" do context "when the response code is unexpected" do let(:response) { double("Net::HTTP Response", body: "", code: "418") } it "raises an error" do expect { mixin.metadata_get("", "2012-01-12") }.to raise_error(RuntimeError) end end end end ohai-16.0.7/spec/unit/mixin/network_helper_spec.rb000066400000000000000000000020571362624620500221630ustar00rootroot00000000000000# # Author:: Kris Shannon # Copyright:: Copyright (c) 2019 Amaze Communication. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/mixin/network_helper" describe Ohai::Mixin::NetworkHelper, "Network Helper Mixin" do let(:mixin) { Object.new.extend(described_class) } describe "hex_to_dec_netmask method" do it "converts a netmask from hexadecimal form to decimal form" do expect(mixin.hex_to_dec_netmask("ffff0000")).to eq("255.255.0.0") end end end ohai-16.0.7/spec/unit/mixin/softlayer_metadata_spec.rb000066400000000000000000000060051362624620500230000ustar00rootroot00000000000000# # Author:: Alexey Karpik # Author:: Peter Schroeter # Author:: Stas Turlo # Copyright:: Copyright (c) 2010-2014 RightScale Inc # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" require "ohai/mixin/softlayer_metadata" describe ::Ohai::Mixin::SoftlayerMetadata do let(:mixin) do mixin = Object.new.extend(described_class) mixin end before do logger = instance_double("Mixlib::Log::Child", trace: nil, debug: nil, warn: nil) allow(mixin).to receive(:logger).and_return(logger) end def make_request(item) "/rest/v3.1/SoftLayer_Resource_Metadata/#{item}" end def make_res(body) double("response", { body: body, code: "200" }) end context "fetch_metadata" do it "raises error if softlayer api query results with error" do http_mock = double("http", { :ssl_version= => true, :use_ssl= => true, :ca_file= => true }) allow(http_mock).to receive(:get).and_raise(StandardError.new("API return fake error")) allow(::Net::HTTP).to receive(:new).with("api.service.softlayer.com", 443).and_return(http_mock) expect(mixin.logger).to receive(:error).at_least(:once) expect { mixin.fetch_metadata }.to raise_error(StandardError) end it "query api service" do http_mock = double("http", { :ssl_version= => true, :use_ssl= => true, :ca_file= => true }) allow(::Net::HTTP).to receive(:new).with("api.service.softlayer.com", 443).and_return(http_mock) expect(http_mock).to receive(:get).with(make_request("getFullyQualifiedDomainName.txt")).and_return(make_res("abc.host.org")).once expect(http_mock).to receive(:get).with(make_request("getPrimaryBackendIpAddress.txt")).and_return(make_res("10.0.1.10")).once expect(http_mock).to receive(:get).with(make_request("getPrimaryIpAddress.txt")).and_return(make_res("8.8.8.8")).once expect(http_mock).to receive(:get).with(make_request("getId.txt")).and_return(make_res("1111")).once expect(http_mock).to receive(:get).with(make_request("getDatacenter.txt")).and_return(make_res("dal05")).once metadata = mixin.fetch_metadata expect(metadata).not_to be_nil expect(metadata["public_fqdn"]).to eq("abc.host.org") expect(metadata["local_ipv4"]).to eq("10.0.1.10") expect(metadata["instance_id"]).to eq("1111") expect(metadata["region"]).to eq("dal05") expect(metadata["public_ipv4"]).to eq("8.8.8.8") end end end ohai-16.0.7/spec/unit/plugin_config_spec.rb000066400000000000000000000050101362624620500206220ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/plugin_config" describe "Ohai::PluginConfig" do describe "#[]=" do let(:plugin_config) { Ohai::PluginConfig.new } shared_examples_for "success" do it "sets the value" do plugin_config[key] = value expect(plugin_config).to have_key(key) expect(plugin_config[key]).to eq(value) end end shared_examples_for "failure" do it "raises an error" do expect { plugin_config[key] = value } .to raise_error(Ohai::Exceptions::PluginConfigError, /Expected Symbol/) end end describe "when the key is a Symbol" do let(:key) { :foo } describe "when the value is a Hash" do describe "when all Hash keys are symbols" do let(:value) do { bar0: true, bar1: %i{baz0 baz1 baz2}, bar2: { qux0: true, qux1: false }, } end include_examples "success" end describe "when some top-level Hash key is not a symbol" do let(:value) do { :bar0 => true, "bar1" => %i{baz0 baz1 baz2}, :bar2 => { qux0: true, qux1: false }, } end include_examples "failure" end describe "when some nested Hash key is not a symbol" do let(:value) do { bar0: true, bar1: %i{baz0 baz1 baz2}, bar2: { :qux0 => true, "qux1" => false }, } end include_examples "failure" end end describe "when the value is not a Hash" do let(:value) { true } include_examples "success" end end describe "when the key is not a Symbol" do let(:key) { "foo" } let(:value) { false } include_examples "failure" end end end ohai-16.0.7/spec/unit/plugins/000077500000000000000000000000001362624620500161255ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/abort_spec.rb000066400000000000000000000030701362624620500205730ustar00rootroot00000000000000# # Author:: Salim Alam (salam@chef.io) # Copyright:: Copyright (c) 2015 Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" tmp = ENV["TMPDIR"] || ENV["TMP"] || ENV["TEMP"] || "/tmp" abortstr = <<~EOF Ohai.plugin(:Abort) do provides "abort_test" collect_data do abort end end EOF describe "a plug-in that aborts execution" do before(:all) do Dir.mkdir("#{tmp}/plugins") rescue Errno::EEXIST # ignore end before do fail_file = File.open("#{tmp}/plugins/abort.rb", "w+") fail_file.write(abortstr) fail_file.close end after do File.delete("#{tmp}/plugins/abort.rb") end after(:all) do Dir.delete("#{tmp}/plugins") rescue # ignore end before do @ohai = Ohai::System.new @loader = Ohai::Loader.new(@ohai) @runner = Ohai::Runner.new(@ohai) end it "raises SystemExit" do @plugin = @loader.load_plugin("#{tmp}/plugins/abort.rb") expect { @runner.run_plugin(@plugin) }.to raise_error(SystemExit) end end ohai-16.0.7/spec/unit/plugins/aix/000077500000000000000000000000001362624620500167065ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/aix/cpu_spec.rb000066400000000000000000000102101362624620500210260ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "AIX cpu plugin" do before do @lsdev_cc_processor = <<~LSDEV_CC_PROCESSOR proc0 Available 00-00 Processor proc4 Defined 00-04 Processor LSDEV_CC_PROCESSOR @lsattr_el_proc0 = <<~LSATTR_EL frequency 1654344000 Processor Speed False smt_enabled true Processor SMT enabled False smt_threads 2 Processor SMT threads False state enable Processor state False type PowerPC_POWER5 Processor type False LSATTR_EL @pmcycles_m = <<~PMCYCLES_M CPU 0 runs at 1654 MHz CPU 1 runs at 1654 MHz CPU 2 runs at 1654 MHz CPU 3 runs at 1654 MHz PMCYCLES_M @plugin = get_plugin("cpu") allow(@plugin).to receive(:collect_os).and_return(:aix) allow(@plugin).to receive(:shell_out).with("lsdev -Cc processor").and_return(mock_shell_out(0, @lsdev_cc_processor, nil)) allow(@plugin).to receive(:shell_out).with("lsattr -El proc0").and_return(mock_shell_out(0, @lsattr_el_proc0, nil)) allow(@plugin).to receive(:shell_out).with("pmcycles -m").and_return(mock_shell_out(0, @pmcycles_m, nil)) end context "when run on an LPAR" do before do allow(@plugin).to receive(:shell_out).with("uname -W").and_return(mock_shell_out(0, "0", nil)) @plugin.run end it "sets the vendor id to IBM" do expect(@plugin[:cpu]["0"][:vendor_id]).to eq("IBM") end it "sets the available attribute" do expect(@plugin[:cpu][:available]).to eq(1) end it "sets the total number of processors" do expect(@plugin[:cpu][:total]).to eq(4) end it "sets the real number of processors" do expect(@plugin[:cpu][:real]).to eq(2) end it "sets the number of cores" do # from http://www-01.ibm.com/software/passportadvantage/pvu_terminology_for_customers.html # on AIX number of cores and processors are considered same expect(@plugin[:cpu][:cores]).to eq(@plugin[:cpu][:real]) end it "detects the model" do expect(@plugin[:cpu]["0"][:model_name]).to eq("PowerPC_POWER5") end it "detects the mhz" do expect(@plugin[:cpu]["0"][:mhz]).to eq(1654) end it "detects the status of the device" do expect(@plugin[:cpu]["0"][:status]).to eq("Available") end it "detects the location of the device" do expect(@plugin[:cpu]["0"][:location]).to eq("00-00") end context "lsattr -El device_name" do it "detects all the attributes of the device" do expect(@plugin[:cpu]["0"][:mhz]).to eq(1654) expect(@plugin[:cpu]["0"][:smt_enabled]).to eq("true") expect(@plugin[:cpu]["0"][:smt_threads]).to eq("2") expect(@plugin[:cpu]["0"][:state]).to eq("enable") expect(@plugin[:cpu]["0"][:model_name]).to eq("PowerPC_POWER5") end end end context "when run on a WPAR" do before do allow(@plugin).to receive(:shell_out).with("uname -W").and_return(mock_shell_out(0, "120", nil)) @plugin.run end it "sets the total number of processors" do expect(@plugin[:cpu][:total]).to eq(4) end it "doesn't set the real number of CPUs" do expect(@plugin[:cpu][:real]).to be_nil end it "doesn't set mhz of a processor it can't see" do # I'm so sorry expect do expect(@plugin[:cpu]["0"][:mhz]).to eq(1654) end.to raise_error(NoMethodError) end end end ohai-16.0.7/spec/unit/plugins/aix/filesystem_spec.rb000066400000000000000000000303701362624620500224340ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2020 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "AIX filesystem plugin" do before do @df_pk_lpar = <<~DF_PK Filesystem 1024-blocks Used Available Capacity Mounted on /dev/hd4 2097152 219796 1877356 11% / /dev/hd2 5242880 2416828 2826052 47% /usr /dev/hd9var 5242880 395540 4847340 8% /var /dev/hd3 5242880 1539508 3703372 30% /tmp /dev/hd1 10485760 1972 10483788 1% /home /dev/hd11admin 131072 380 130692 1% /admin /proc - - - - /proc /dev/hd10opt 5242880 1286720 3956160 25% /opt /dev/livedump 262144 368 261776 1% /var/adm/ras/livedump /dev/fslv00 524288 45076 479212 9% /wpars/sink-thinker-541ba3 /dev/fslv01 2097152 8956 2088196 1% /wpars/sink-thinker-541ba3/home /dev/fslv02 5242880 1307352 3935528 25% /wpars/sink-thinker-541ba3/opt /proc - - - - /wpars/sink-thinker-541ba3/proc /dev/fslv03 1048576 168840 879736 17% /wpars/sink-thinker-541ba3/tmp /dev/fslv04 5242880 2725040 2517840 52% /wpars/sink-thinker-541ba3/usr /dev/fslv05 524288 76000 448288 15% /wpars/sink-thinker-541ba3/var /dev/fslv07 10485760 130872 10354888 2% /wpars/toolchain-tester-5c969f /dev/fslv08 5242880 39572 5203308 1% /wpars/toolchain-tester-5c969f/home /dev/fslv09 5242880 1477164 3765716 29% /wpars/toolchain-tester-5c969f/opt /proc - - - - /wpars/toolchain-tester-5c969f/proc /dev/fslv10 5242880 42884 5199996 1% /wpars/toolchain-tester-5c969f/tmp /dev/fslv11 5242880 2725048 2517832 52% /wpars/toolchain-tester-5c969f/usr /dev/fslv12 10485760 272376 10213384 3% /wpars/toolchain-tester-5c969f/var DF_PK @df_pk_wpar = <<~DF_PK Filesystem 1024-blocks Used Available Capacity Mounted on Global 10485760 130872 10354888 2% / Global 5242880 39572 5203308 1% /home Global 5242880 1477164 3765716 29% /opt Global - - - - /proc Global 5242880 42884 5199996 1% /tmp Global 5242880 2725048 2517832 52% /usr Global 10485760 272376 10213384 3% /var DF_PK @mount_lpar = <<~MOUNT node mounted mounted over vfs date options -------- --------------- --------------- ------ ------------ --------------- /dev/hd4 / jfs2 Jul 17 13:22 rw,log=/dev/hd8 /dev/hd2 /usr jfs2 Jul 17 13:22 rw,log=/dev/hd8 /dev/hd9var /var jfs2 Jul 17 13:22 rw,log=/dev/hd8 /dev/hd3 /tmp jfs2 Jul 17 13:22 rw,log=/dev/hd8 /dev/hd1 /home jfs2 Jul 17 13:22 rw,log=/dev/hd8 /dev/hd11admin /admin jfs2 Jul 17 13:22 rw,log=/dev/hd8 /proc /proc procfs Jul 17 13:22 rw /dev/hd10opt /opt jfs2 Jul 17 13:22 rw,log=/dev/hd8 192.168.1.11 /stage/middleware1 /stage/middleware2 nfs3 Jul 17 13:24 ro,bg,hard,intr,sec=sys MOUNT @mount_wpar = <<~MOUNT node mounted mounted over vfs date options -------- --------------- --------------- ------ ------------ --------------- Global / jfs2 Nov 23 21:03 rw,log=NULL Global /home jfs2 Nov 23 21:03 rw,log=NULL Global /opt jfs2 Nov 23 21:03 rw,log=NULL Global /proc namefs Nov 23 21:03 rw Global /tmp jfs2 Nov 23 21:03 rw,log=NULL Global /usr jfs2 Nov 23 21:03 rw,log=NULL Global /var jfs2 Nov 23 21:03 rw,log=NULL 192.168.1.11 /stage/middleware3 /stage/middleware4 nfs3 Jul 17 13:24 ro,bg,hard,intr,sec=sys MOUNT @plugin = get_plugin("filesystem") allow(@plugin).to receive(:collect_os).and_return(:aix) @plugin[:filesystem] = Mash.new end context "when run within an LPAR" do before do allow(@plugin).to receive(:shell_out).with("df -Pk").and_return(mock_shell_out(0, @df_pk_lpar, nil)) allow(@plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @mount_lpar, nil)) @plugin.run end describe "df -Pk" do it "returns the filesystem block size" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["kb_size"]).to eq("2097152") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["kb_size"]).to eq("2097152") end it "returns the filesystem used space in kb" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["kb_used"]).to eq("219796") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["kb_used"]).to eq("219796") end it "returns the filesystem available space in kb" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["kb_available"]).to eq("1877356") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["kb_available"]).to eq("1877356") end it "returns the filesystem capacity in percentage" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["percent_used"]).to eq("11%") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["percent_used"]).to eq("11%") end it "returns the filesystem mounted location" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["mount"]).to eq("/") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["mount"]).to eq("/") end end describe "mount" do it "returns the filesystem mount location" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["mount"]).to eq("/") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["mount"]).to eq("/") end it "returns the filesystem type" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["fs_type"]).to eq("jfs2") expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["fs_type"]).to eq("jfs2") end it "returns the filesystem mount options" do expect(@plugin[:filesystem]["by_pair"]["/dev/hd4,/"]["mount_options"]).to eq(["rw", "log=/dev/hd8"]) expect(@plugin[:filesystem2]["by_pair"]["/dev/hd4,/"]["mount_options"]).to eq(["rw", "log=/dev/hd8"]) end # For entries like 192.168.1.11 /stage/middleware1 /stage/middleware2 nfs3 Jul 17 13:24 ro,bg,hard,intr,sec=sys context "having node values" do it "returns the filesystem mount location" do expect(@plugin[:filesystem]["by_pair"]["192.168.1.11:/stage/middleware1,/stage/middleware2"]["mount"]).to eq("/stage/middleware2") expect(@plugin[:filesystem2]["by_pair"]["192.168.1.11:/stage/middleware1,/stage/middleware2"]["mount"]).to eq("/stage/middleware2") end it "returns the filesystem type" do expect(@plugin[:filesystem]["by_pair"]["192.168.1.11:/stage/middleware1,/stage/middleware2"]["fs_type"]).to eq("nfs3") expect(@plugin[:filesystem2]["by_pair"]["192.168.1.11:/stage/middleware1,/stage/middleware2"]["fs_type"]).to eq("nfs3") end it "returns the filesystem mount options" do expect(@plugin[:filesystem]["by_pair"]["192.168.1.11:/stage/middleware1,/stage/middleware2"]["mount_options"]).to eq(["ro", "bg", "hard", "intr", "sec=sys"]) expect(@plugin[:filesystem2]["by_pair"]["192.168.1.11:/stage/middleware1,/stage/middleware2"]["mount_options"]).to eq(["ro", "bg", "hard", "intr", "sec=sys"]) end end end end context "when run within a WPAR" do before do allow(@plugin).to receive(:shell_out).with("df -Pk").and_return(mock_shell_out(0, @df_pk_wpar, nil)) allow(@plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @mount_wpar, nil)) @plugin.run end describe "df -Pk" do it "returns the filesystem block size" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["kb_size"]).to eq("10485760") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["kb_size"]).to eq("10485760") end it "returns the filesystem used space in kb" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["kb_used"]).to eq("130872") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["kb_used"]).to eq("130872") end it "returns the filesystem available space in kb" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["kb_available"]).to eq("10354888") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["kb_available"]).to eq("10354888") end it "returns the filesystem capacity in percentage" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["percent_used"]).to eq("2%") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["percent_used"]).to eq("2%") end it "returns the filesystem mounted location" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["mount"]).to eq("/") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["mount"]).to eq("/") end end describe "mount" do it "returns the filesystem mount location" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["mount"]).to eq("/") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["mount"]).to eq("/") end it "returns the filesystem type" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["fs_type"]).to eq("jfs2") expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["fs_type"]).to eq("jfs2") end it "returns the filesystem mount options" do expect(@plugin[:filesystem]["by_pair"]["Global:/,/"]["mount_options"]).to eq(["rw", "log=NULL"]) expect(@plugin[:filesystem2]["by_pair"]["Global:/,/"]["mount_options"]).to eq(["rw", "log=NULL"]) end # For entries like 192.168.1.11 /stage/middleware3 /stage/middleware4 nfs3 Jul 17 13:24 ro,bg,hard,intr,sec=sys context "having node values" do it "returns the filesystem mount location" do expect(@plugin[:filesystem]["by_pair"]["192.168.1.11:/stage/middleware3,/stage/middleware4"]["mount"]).to eq("/stage/middleware4") expect(@plugin[:filesystem2]["by_pair"]["192.168.1.11:/stage/middleware3,/stage/middleware4"]["mount"]).to eq("/stage/middleware4") end it "returns the filesystem type" do expect(@plugin[:filesystem]["by_pair"]["192.168.1.11:/stage/middleware3,/stage/middleware4"]["fs_type"]).to eq("nfs3") expect(@plugin[:filesystem2]["by_pair"]["192.168.1.11:/stage/middleware3,/stage/middleware4"]["fs_type"]).to eq("nfs3") end it "returns the filesystem mount options" do expect(@plugin[:filesystem]["by_pair"]["192.168.1.11:/stage/middleware3,/stage/middleware4"]["mount_options"]).to eq(["ro", "bg", "hard", "intr", "sec=sys"]) expect(@plugin[:filesystem2]["by_pair"]["192.168.1.11:/stage/middleware3,/stage/middleware4"]["mount_options"]).to eq(["ro", "bg", "hard", "intr", "sec=sys"]) end end end end end ohai-16.0.7/spec/unit/plugins/aix/hostname_spec.rb000066400000000000000000000022751362624620500220710ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "AIX hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:aix) allow(@plugin).to receive(:from_cmd).with("hostname -s").and_return("aix_admin") allow(@plugin).to receive(:from_cmd).with("hostname").and_return("aix_admin.ponyville.com") @plugin.run end it "sets the machinename" do expect(@plugin[:machinename]).to eql("aix_admin") end end ohai-16.0.7/spec/unit/plugins/aix/kernel_spec.rb000066400000000000000000000054221362624620500215300ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "AIX kernel plugin" do before do @plugin = get_plugin("aix/kernel") allow(@plugin).to receive(:collect_os).and_return(:aix) allow(@plugin).to receive(:shell_out).with("uname -s").and_return(mock_shell_out(0, "AIX", nil)) allow(@plugin).to receive(:shell_out).with("uname -r").and_return(mock_shell_out(0, "1", nil)) allow(@plugin).to receive(:shell_out).with("uname -v").and_return(mock_shell_out(0, "6", nil)) allow(@plugin).to receive(:shell_out).with("uname -p").and_return(mock_shell_out(0, "powerpc", nil)) allow(@plugin).to receive(:shell_out).with("genkex -d").and_return(mock_shell_out(0, " Text address Size Data address Size File\nf1000000c0338000 77000 f1000000c0390000 1ec8c /usr/lib/drivers/cluster\n 6390000 20000 63a0000 ba8 /usr/lib/drivers/if_en", nil)) allow(@plugin).to receive(:shell_out).with("getconf KERNEL_BITMODE").and_return(mock_shell_out(0, "64", nil)) @plugin.run end it "uname -s detects the name" do expect(@plugin[:kernel][:name]).to eq("aix") end it "uname -r detects the release" do expect(@plugin[:kernel][:release]).to eq("1") end it "uname -v detects the version" do expect(@plugin[:kernel][:version]).to eq("6") end it "uname -p detects the machine" do expect(@plugin[:kernel][:machine]).to eq("powerpc") end it "getconf KERNEL_BITMODE detects the kernel's bittiness" do expect(@plugin[:kernel][:bits]).to eq("64") end it "detects the modules" do expect(@plugin[:kernel][:modules]["/usr/lib/drivers/cluster"]["text"]).to eq({ "address" => "f1000000c0338000", "size" => "77000" }) expect(@plugin[:kernel][:modules]["/usr/lib/drivers/cluster"]["data"]).to eq({ "address" => "f1000000c0390000", "size" => "1ec8c" }) expect(@plugin[:kernel][:modules]["/usr/lib/drivers/if_en"]["text"]).to eq({ "address" => "6390000", "size" => "20000" }) expect(@plugin[:kernel][:modules]["/usr/lib/drivers/if_en"]["data"]).to eq({ "address" => "63a0000", "size" => "ba8" }) end end ohai-16.0.7/spec/unit/plugins/aix/memory_spec.rb000066400000000000000000000034021362624620500215540ustar00rootroot00000000000000# # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "AIX memory plugin" do before do @plugin = get_plugin("aix/memory") allow(@plugin).to receive(:collect_os).and_return(:aix) allow(@plugin).to receive(:shell_out).with("svmon -G -O unit=MB,summary=longreal | grep '[0-9]'").and_return(mock_shell_out(0, " 513280.00 340034.17 173245.83 62535.17 230400.05 276950.14 70176.00\n", nil)) @swap_s = "allocated = 23887872 blocks used = 288912 blocks free = 23598960 blocks\n" allow(@plugin).to receive(:shell_out).with("swap -s").and_return(mock_shell_out(0, @swap_s, nil)) end it "gets total memory" do @plugin.run expect(@plugin["memory"]["total"]).to eql("#{513280 * 1024}kB") end it "gets free memory" do @plugin.run expect(@plugin["memory"]["free"]).to eql("#{173245.83.to_i * 1024}kB") end it "gets total swap" do @plugin.run expect(@plugin["memory"]["swap"]["total"]).to eql( "#{23887872 * 4}kB") end it "gets free swap" do @plugin.run expect(@plugin["memory"]["swap"]["free"]).to eql( "#{23598960 * 4}kB") end end ohai-16.0.7/spec/unit/plugins/aix/network_spec.rb000066400000000000000000000253141362624620500217430ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "AIX network plugin" do before do @netstat_rn_grep_default = <<~NETSTAT_RN_GREP_DEFAULT default 172.31.8.1 UG 2 121789 en0 - - NETSTAT_RN_GREP_DEFAULT @ifconfig = <<~IFCONFIG en0: flags=1e080863,480 metric 1 inet 172.29.174.58 netmask 0xffffc000 broadcast 172.29.191.255 inet 172.29.174.59 broadcast 172.29.191.255 inet 172.29.174.60 netmask 0xffffc000 broadcast 172.29.191.255 inet6 ::1%1/0 tcp_sendspace 262144 tcp_recvspace 262144 rfc1323 1 en1: flags=1e084863,480 inet 172.31.10.211 netmask 0xfffffc00 broadcast 172.31.11.255 tcp_sendspace 262144 tcp_recvspace 262144 rfc1323 1 lo0: flags=e08084b,c0 inet 127.0.0.1 netmask 0xff000000 broadcast 127.255.255.255 inet6 ::1%1/0 tcp_sendspace 131072 tcp_recvspace 131072 rfc1323 1 IFCONFIG @netstat_nrf_inet = <<~NETSTAT_NRF_INET Destination Gateway Flags Refs Use If Exp Groups Route Tree for Protocol Family 2 (Internet): default 172.29.128.13 UG 0 587683 en0 - - 172.29.128.0 172.29.174.58 UHSb 0 0 en0 - - => 172.29.128/18 172.29.174.58 U 7 1035485 en0 - - 172.29.191.255 172.29.174.58 UHSb 0 1 en0 - - NETSTAT_NRF_INET @entstat_err = <<~ENSTAT_ERR entstat: 0909-002 Unable to open device en0, errno = 13 grep: 0652-033 Cannot open Address". ENSTAT_ERR @aix_arp_an = <<~ARP_AN ? (172.29.131.16) at 6e:87:70:0:40:3 [ethernet] stored in bucket 16 ? (10.153.50.202) at 34:40:b5:ab:fb:5a [ethernet] stored in bucket 40 ? (10.153.1.99) at 52:54:0:8e:f2:fb [ethernet] stored in bucket 58 ? (172.29.132.250) at 34:40:b5:a5:d7:1e [ethernet] stored in bucket 59 ? (172.29.132.253) at 34:40:b5:a5:d7:2a [ethernet] stored in bucket 62 ? (172.29.128.13) at 60:73:5c:69:42:44 [ethernet] stored in bucket 139 bucket: 0 contains: 0 entries There are 6 entries in the arp table. ARP_AN @plugin = get_plugin("aix/network") allow(@plugin).to receive(:collect_os).and_return(:aix) @plugin[:network] = Mash.new allow(@plugin).to receive(:shell_out).with("uname -W").and_return(mock_shell_out(0, "0", nil)) allow(@plugin).to receive(:shell_out).with("netstat -rn |grep default").and_return(mock_shell_out(0, @netstat_rn_grep_default, nil)) allow(@plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, @ifconfig, nil)) allow(@plugin).to receive(:shell_out).with("entstat -d en0 | grep \"Hardware Address\"").and_return(mock_shell_out(0, "Hardware Address: be:42:80:00:b0:05", nil)) allow(@plugin).to receive(:shell_out).with("entstat -d en1 | grep \"Hardware Address\"").and_return(mock_shell_out(0, @entstat_err, nil)) allow(@plugin).to receive(:shell_out).with("entstat -d lo0 | grep \"Hardware Address\"").and_return(mock_shell_out(0, @entstat_err, nil)) allow(@plugin).to receive(:shell_out).with("netstat -nrf inet").and_return(mock_shell_out(0, @netstat_nrf_inet, nil)) allow(@plugin).to receive(:shell_out).with("netstat -nrf inet6").and_return(mock_shell_out(0, "::1%1 ::1%1 UH 1 109392 en0 - -", nil)) allow(@plugin).to receive(:shell_out).with("arp -an").and_return(mock_shell_out(0, @aix_arp_an, nil)) end describe "run" do before do @plugin.run end it "detects network information" do expect(@plugin["network"]).not_to be_nil end it "detects the interfaces" do expect(@plugin["network"]["interfaces"].keys.sort).to eq(%w{en0 en1 lo0}) end it "detects the ip addresses of the interfaces" do expect(@plugin["network"]["interfaces"]["en0"]["addresses"].keys).to include("172.29.174.58") end end describe "when running on an LPAR" do describe "sets the top-level attribute correctly" do before do @plugin.run end it "for 'macaddress'" do expect(@plugin[:macaddress]).to eq("BE:42:80:00:B0:05") end end describe "netstat -rn |grep default" do before do @plugin.run end it "returns the default gateway of the system's network" do expect(@plugin[:network][:default_gateway]).to eq("172.31.8.1") end it "returns the default interface of the system's network" do expect(@plugin[:network][:default_interface]).to eq("en0") end end end describe "when running on a WPAR" do before do allow(@plugin).to receive(:shell_out).with("uname -W").and_return(mock_shell_out(0, "6", nil)) @plugin.run end it "avoids collecting routing information" do expect(@plugin[:network][:default_gateway]).to be_nil end it "avoids collecting default interface" do expect(@plugin[:network][:default_gateway]).to be_nil end it "avoids collecting a macaddress" do expect(@plugin[:macaddress]).to be_nil end end describe "lsdev -Cc if" do it "detects the state of the interfaces in the system" do @plugin.run expect(@plugin["network"]["interfaces"]["en0"][:state]).to eq("up") end describe "ifconfig interface" do it "detects the CHAIN network flag" do @plugin.run expect(@plugin["network"]["interfaces"]["en0"][:flags]).to include("CHAIN") end it "detects the metric network flag" do @plugin.run expect(@plugin["network"]["interfaces"]["en0"][:metric]).to eq("1") end context "inet entries" do before do @plugin.run @inet_entry = @plugin["network"]["interfaces"]["en0"][:addresses]["172.29.174.58"] end it "detects the family" do expect(@inet_entry[:family]).to eq("inet") end it "detects the netmask" do expect(@inet_entry[:netmask]).to eq("255.255.192.0") end it "detects the broadcast" do expect(@inet_entry[:broadcast]).to eq("172.29.191.255") end it "detects all key-values" do expect(@plugin["network"]["interfaces"]["en0"][:tcp_sendspace]).to eq("262144") expect(@plugin["network"]["interfaces"]["en0"][:tcp_recvspace]).to eq("262144") expect(@plugin["network"]["interfaces"]["en0"][:rfc1323]).to eq("1") end # For an output with no netmask like inet 172.29.174.59 broadcast 172.29.191.255 context "with no netmask in the output" do before do allow(@plugin).to receive(:shell_out).with("ifconfig en0").and_return(mock_shell_out(0, "inet 172.29.174.59 broadcast 172.29.191.255", nil)) end it "detects the default prefixlen" do @inet_entry = @plugin["network"]["interfaces"]["en0"][:addresses]["172.29.174.59"] expect(@inet_entry[:prefixlen]).to eq("32") end it "detects the default netmask" do @inet_entry = @plugin["network"]["interfaces"]["en0"][:addresses]["172.29.174.59"] expect(@inet_entry[:netmask]).to eq("255.255.255.255") end end end context "inet6 entries" do before do @plugin.run @inet_entry = @plugin["network"]["interfaces"]["en0"][:addresses]["::1"] end it "detects the prefixlen" do expect(@inet_entry[:prefixlen]).to eq("0") end it "detects the family" do expect(@inet_entry[:family]).to eq("inet6") end end end context "entstat -d interface" do before do @plugin.run @inet_interface_addresses = @plugin["network"]["interfaces"]["en0"][:addresses]["BE:42:80:00:B0:05"] end it "detects the family" do expect(@inet_interface_addresses[:family]).to eq("lladdr") end end end describe "netstat -nrf family" do before do @plugin.run end context "inet" do it "detects the route destinations" do expect(@plugin["network"]["interfaces"]["en0"][:routes][0][:destination]).to eq("default") expect(@plugin["network"]["interfaces"]["en0"][:routes][1][:destination]).to eq("172.29.128.0") end it "detects the route family" do expect(@plugin["network"]["interfaces"]["en0"][:routes][0][:family]).to eq("inet") end it "detects the route gateway" do expect(@plugin["network"]["interfaces"]["en0"][:routes][0][:via]).to eq("172.29.128.13") end it "detects the route flags" do expect(@plugin["network"]["interfaces"]["en0"][:routes][0][:flags]).to eq("UG") end end context "inet6" do it "detects the route destinations" do expect(@plugin["network"]["interfaces"]["en0"][:routes][4][:destination]).to eq("::1%1") end it "detects the route family" do expect(@plugin["network"]["interfaces"]["en0"][:routes][4][:family]).to eq("inet6") end it "detects the route gateway" do expect(@plugin["network"]["interfaces"]["en0"][:routes][4][:via]).to eq("::1%1") end it "detects the route flags" do expect(@plugin["network"]["interfaces"]["en0"][:routes][4][:flags]).to eq("UH") end end end describe "arp -an" do before do @plugin.run end it "supresses the hostname entries" do expect(@plugin["network"]["arp"][0][:remote_host]).to eq("?") end it "detects the remote ip entry" do expect(@plugin["network"]["arp"][0][:remote_ip]).to eq("172.29.131.16") end it "detects the remote mac entry" do expect(@plugin["network"]["arp"][0][:remote_mac]).to eq("6e:87:70:0:40:3") end end end ohai-16.0.7/spec/unit/plugins/aix/platform_spec.rb000066400000000000000000000025471362624620500221010ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "Aix plugin platform" do before do @plugin = get_plugin("aix/platform") allow(@plugin).to receive(:collect_os).and_return(:aix) kernel = Mash.new kernel[:name] = "aix" kernel[:version] = "7" kernel[:release] = "1" allow(@plugin).to receive(:kernel).and_return(kernel) @plugin.run end it "sets platform to aix" do expect(@plugin[:platform]).to eq("aix") end it "sets the platform_version" do expect(@plugin[:platform_version]).to eq("7.1") end it "sets platform_family" do expect(@plugin[:platform_family]).to eq(@plugin[:platform]) end end ohai-16.0.7/spec/unit/plugins/aix/uptime_spec.rb000066400000000000000000000032121362624620500215460ustar00rootroot00000000000000# # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Aix plugin uptime" do before do @plugin = get_plugin("aix/uptime") allow(@plugin).to receive(:collect_os).and_return(:aix) allow(@plugin).to receive(:shell_out).and_call_original end it "sets uptime_seconds and uptime standard case" do allow(@plugin).to receive(:shell_out).with("LC_ALL=POSIX ps -o etime= -p 1").and_return(mock_shell_out(0, "1148-20:54:50", nil)) @plugin.run expect(@plugin[:uptime_seconds]).to eq(99262490) expect(@plugin[:uptime]).to eq("1148 days 20 hours 54 minutes 50 seconds") end it "sets uptime_seconds and uptime in the whitespace case" do allow(@plugin).to receive(:shell_out).with("LC_ALL=POSIX ps -o etime= -p 1").and_return(mock_shell_out(0, " 2-20:54:50", nil)) @plugin.run expect(@plugin[:uptime_seconds]).to eq(248090) expect(@plugin[:uptime]).to eq("2 days 20 hours 54 minutes 50 seconds") end end ohai-16.0.7/spec/unit/plugins/aix/virtualization_spec.rb000066400000000000000000000352661362624620500233450ustar00rootroot00000000000000# # Author:: Julian C. Dunn () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "AIX virtualization plugin" do context "when inside an LPAR" do let(:plugin) do p = get_plugin("aix/virtualization") allow(p).to receive(:collect_os).and_return(:aix) allow(p).to receive(:shell_out).with("uname -L").and_return(mock_shell_out(0, "29 l273pp027", nil)) allow(p).to receive(:shell_out).with("uname -W").and_return(mock_shell_out(0, "0", nil)) allow(p).to receive(:shell_out).with("lswpar -L").and_return(mock_shell_out(0, @lswpar_l, nil)) p end before do @lswpar_l = <<~LSWPAR_L ================================================================= applejack-541ba3 - Active ================================================================= GENERAL Type: S RootVG WPAR: no Owner: root Hostname: applejack-pony-541ba3.ponyville.com WPAR-Specific Routing: yes Virtual IP WPAR: Directory: /wpars/applejack-541ba3 Start/Stop Script: Auto: no Private /usr: yes Checkpointable: no Application: UUID: 541ba314-c7ca-4f67-bc6e-a10d5eaa8541 NETWORK Interface Address(6) Mask/Prefix Broadcast ----------------------------------------------------------------- en0 192.168.0.231 255.255.252.0 192.168.0.255 lo0 127.0.0.1 255.0.0.0 127.255.255.255 USER-SPECIFIED ROUTES Type Destination Gateway Interface ----------------------------------------------------------------- default 192.168.0.1 en0 FILE SYSTEMS MountPoint Device Vfs Nodename Options ----------------------------------------------------------------- /wpars/sink-thinker-5... /dev/fslv00 jfs2 log=NULL /wpars/sink-thinker-5... /dev/fslv01 jfs2 log=NULL /wpars/sink-thinker-5... /dev/fslv02 jfs2 log=NULL /wpars/sink-thinker-5... /proc namefs rw /wpars/sink-thinker-5... /dev/fslv03 jfs2 log=NULL /wpars/sink-thinker-5... /dev/fslv04 jfs2 log=NULL /wpars/sink-thinker-5... /dev/fslv05 jfs2 log=NULL RESOURCE CONTROLS Active: yes Resource Set: CPU Shares: unlimited CPU Limits: 0%-100%,100% Memory Shares: unlimited Memory Limits: 0%-100%,100% Per-Process Virtual Memory Limit: unlimited Total Virtual Memory Limit: unlimited Total Processes: unlimited Total Threads: unlimited Total PTYs: unlimited Total Large Pages: unlimited Max Message Queue IDs: 100% Max Semaphore IDs: 100% Max Shared Memory IDs: 100% Max Pinned Memory: 100% OPERATION Operation: none Process ID: Start Time: SECURITY SETTINGS Privileges: PV_AU_,PV_AU_ADD,PV_AU_ADMIN,PV_AU_PROC,PV_AU_READ, PV_AU_WRITE,PV_AZ_ADMIN,PV_AZ_CHECK,PV_AZ_READ,PV_AZ_ROOT, PV_DAC_,PV_DAC_GID,PV_DAC_O,PV_DAC_R,PV_DAC_RID,PV_DAC_UID, PV_DAC_W,PV_DAC_X,PV_DEV_CONFIG,PV_DEV_QUERY,PV_FS_CHOWN, PV_FS_CHROOT,PV_FS_CNTL,PV_FS_LINKDIR,PV_FS_MKNOD, PV_FS_MOUNT,PV_FS_PDMODE,PV_FS_QUOTA,PV_KER_ACCT, PV_KER_CONF,PV_KER_DR,PV_KER_EWLM,PV_KER_EXTCONF, PV_KER_IPC,PV_KER_IPC_O,PV_KER_IPC_R,PV_KER_IPC_W, PV_KER_NFS,PV_KER_RAC,PV_KER_RAS_ERR,PV_KER_REBOOT, PV_NET_PORT,PV_PROC_CKPT,PV_PROC_CORE,PV_PROC_CRED, PV_PROC_ENV,PV_PROC_PRIO,PV_PROC_PDMODE,PV_PROC_RAC, PV_PROC_RTCLK,PV_PROC_SIG,PV_PROC_TIMER,PV_PROC_VARS, PV_PROC_PRIV,PV_SU_UID,PV_TCB,PV_TP,PV_TP_SET,PV_MIC, PV_MIC_CL,PV_LAB_,PV_LAB_CL,PV_LAB_CLTL,PV_LAB_LEF, PV_LAB_SLDG,PV_LAB_SLDG_STR,PV_LAB_SL_FILE,PV_LAB_SL_PROC, PV_LAB_SL_SELF,PV_LAB_SLUG,PV_LAB_SLUG_STR,PV_LAB_TL, PV_MAC_,PV_MAC_CL,PV_MAC_R,PV_MAC_R_CL,PV_MAC_R_STR, PV_MAC_R_PROC,PV_MAC_W,PV_MAC_W_CL,PV_MAC_W_DN,PV_MAC_W_UP, PV_MAC_W_PROC,PV_MAC_OVRRD,PV_KER_SECCONFIG, PV_PROBEVUE_TRC_USER,PV_PROBEVUE_TRC_USER_SELF,PV_KER_LVM DEVICE EXPORTS Name Type Virtual Device RootVG Status ----------------------------------------------------------------- /dev/null pseudo EXPORTED /dev/tty pseudo EXPORTED /dev/console pseudo EXPORTED /dev/zero pseudo EXPORTED /dev/clone pseudo EXPORTED /dev/sad clone EXPORTED /dev/xti/tcp clone EXPORTED /dev/xti/tcp6 clone EXPORTED /dev/xti/udp clone EXPORTED /dev/xti/udp6 clone EXPORTED /dev/xti/unixdg clone EXPORTED /dev/xti/unixst clone EXPORTED /dev/error pseudo EXPORTED /dev/errorctl pseudo EXPORTED /dev/audit pseudo EXPORTED /dev/nvram pseudo EXPORTED ================================================================= fluttershy-5c969f - Active ================================================================= GENERAL Type: S RootVG WPAR: no Owner: root Hostname: fluttershy-pony-5c969f.ponyville.com WPAR-Specific Routing: yes Virtual IP WPAR: Directory: /wpars/fluttershy-5c969f Start/Stop Script: Auto: no Private /usr: yes Checkpointable: no Application: UUID: 6f1fd4be-8be5-4627-8ec0-3a8739cbd9e2 NETWORK Interface Address(6) Mask/Prefix Broadcast ----------------------------------------------------------------- en0 192.168.0.18 255.255.252.0 192.168.0.255 lo0 127.0.0.1 255.0.0.0 127.255.255.255 USER-SPECIFIED ROUTES Type Destination Gateway Interface ----------------------------------------------------------------- default 192.168.0.1 en0 FILE SYSTEMS MountPoint Device Vfs Nodename Options ----------------------------------------------------------------- /wpars/toolchain-test... /dev/fslv07 jfs2 log=NULL /wpars/toolchain-test... /dev/fslv08 jfs2 log=NULL /wpars/toolchain-test... /dev/fslv09 jfs2 log=NULL /wpars/toolchain-test... /proc namefs rw /wpars/toolchain-test... /dev/fslv10 jfs2 log=NULL /wpars/toolchain-test... /dev/fslv11 jfs2 log=NULL /wpars/toolchain-test... /dev/fslv12 jfs2 log=NULL RESOURCE CONTROLS Active: yes Resource Set: CPU Shares: unlimited CPU Limits: 0%-100%,100% Memory Shares: unlimited Memory Limits: 0%-100%,100% Per-Process Virtual Memory Limit: unlimited Total Virtual Memory Limit: unlimited Total Processes: unlimited Total Threads: unlimited Total PTYs: unlimited Total Large Pages: unlimited Max Message Queue IDs: 100% Max Semaphore IDs: 100% Max Shared Memory IDs: 100% Max Pinned Memory: 100% OPERATION Operation: none Process ID: Start Time: SECURITY SETTINGS Privileges: PV_AU_,PV_AU_ADD,PV_AU_ADMIN,PV_AU_PROC,PV_AU_READ, PV_AU_WRITE,PV_AZ_ADMIN,PV_AZ_CHECK,PV_AZ_READ,PV_AZ_ROOT, PV_DAC_,PV_DAC_GID,PV_DAC_O,PV_DAC_R,PV_DAC_RID,PV_DAC_UID, PV_DAC_W,PV_DAC_X,PV_DEV_CONFIG,PV_DEV_QUERY,PV_FS_CHOWN, PV_FS_CHROOT,PV_FS_CNTL,PV_FS_LINKDIR,PV_FS_MKNOD, PV_FS_MOUNT,PV_FS_PDMODE,PV_FS_QUOTA,PV_KER_ACCT, PV_KER_CONF,PV_KER_DR,PV_KER_EWLM,PV_KER_EXTCONF, PV_KER_IPC,PV_KER_IPC_O,PV_KER_IPC_R,PV_KER_IPC_W, PV_KER_NFS,PV_KER_RAC,PV_KER_RAS_ERR,PV_KER_REBOOT, PV_NET_PORT,PV_PROC_CKPT,PV_PROC_CORE,PV_PROC_CRED, PV_PROC_ENV,PV_PROC_PRIO,PV_PROC_PDMODE,PV_PROC_RAC, PV_PROC_RTCLK,PV_PROC_SIG,PV_PROC_TIMER,PV_PROC_VARS, PV_PROC_PRIV,PV_SU_UID,PV_TCB,PV_TP,PV_TP_SET,PV_MIC, PV_MIC_CL,PV_LAB_,PV_LAB_CL,PV_LAB_CLTL,PV_LAB_LEF, PV_LAB_SLDG,PV_LAB_SLDG_STR,PV_LAB_SL_FILE,PV_LAB_SL_PROC, PV_LAB_SL_SELF,PV_LAB_SLUG,PV_LAB_SLUG_STR,PV_LAB_TL, PV_MAC_,PV_MAC_CL,PV_MAC_R,PV_MAC_R_CL,PV_MAC_R_STR, PV_MAC_R_PROC,PV_MAC_W,PV_MAC_W_CL,PV_MAC_W_DN,PV_MAC_W_UP, PV_MAC_W_PROC,PV_MAC_OVRRD,PV_KER_SECCONFIG, PV_PROBEVUE_TRC_USER,PV_PROBEVUE_TRC_USER_SELF,PV_KER_LVM DEVICE EXPORTS Name Type Virtual Device RootVG Status ----------------------------------------------------------------- /dev/null pseudo EXPORTED /dev/tty pseudo EXPORTED /dev/console pseudo EXPORTED /dev/zero pseudo EXPORTED /dev/clone pseudo EXPORTED /dev/sad clone EXPORTED /dev/xti/tcp clone EXPORTED /dev/xti/tcp6 clone EXPORTED /dev/xti/udp clone EXPORTED /dev/xti/udp6 clone EXPORTED /dev/xti/unixdg clone EXPORTED /dev/xti/unixst clone EXPORTED /dev/error pseudo EXPORTED /dev/errorctl pseudo EXPORTED /dev/audit pseudo EXPORTED /dev/nvram pseudo EXPORTED LSWPAR_L end it "uname -L detects the LPAR number and name" do plugin.run expect(plugin[:virtualization][:lpar_no]).to eq("29") expect(plugin[:virtualization][:lpar_name]).to eq("l273pp027") end context "when WPARs exist on the LPAR" do before do plugin.run end let(:wpar1) do plugin[:virtualization][:wpars]["applejack-541ba3"] end let(:wpar2) do plugin[:virtualization][:wpars]["fluttershy-5c969f"] end it "detects all WPARs present (2)" do expect(plugin[:virtualization][:wpars].length).to eq(2) end context "when collecting WPAR info" do it "finds the WPAR's hostname correctly" do expect(wpar1[:hostname]).to eq("applejack-pony-541ba3.ponyville.com") expect(wpar2[:hostname]).to eq("fluttershy-pony-5c969f.ponyville.com") end it "finds the WPAR's IP correctly" do expect(wpar1[:address]).to eq("192.168.0.231") expect(wpar2[:address]).to eq("192.168.0.18") end it "parses device exports properly" do expect(wpar1["device exports"]["/dev/nvram"]["type"]).to eq("pseudo") expect(wpar1["device exports"]["/dev/nvram"]["status"]).to eq("EXPORTED") end end end context "when WPARs don't exist on the LPAR" do before do allow(plugin).to receive(:shell_out).with("lswpar -L").and_return(mock_shell_out(0, "", nil)) plugin.run end it "detects all WPARs present (0)" do expect(plugin[:virtualization][:wpars]).to be_nil end end end context "when inside a WPAR" do let(:plugin) do p = get_plugin("aix/virtualization") allow(p).to receive(:collect_os).and_return(:aix) allow(p).to receive(:shell_out).with("uname -L").and_return(mock_shell_out(0, "43 l33t", nil)) allow(p).to receive(:shell_out).with("uname -W").and_return(mock_shell_out(0, "42", nil)) p.run p end it "uname -W detects the WPAR number" do expect(plugin[:virtualization][:wpar_no]).to eq("42") end end end ohai-16.0.7/spec/unit/plugins/azure_spec.rb000066400000000000000000000247061362624620500206230ustar00rootroot00000000000000# # Author:: Kaustubh Deorukhkar () # Copyright:: Copyright (c) 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "open-uri" describe Ohai::System, "plugin azure" do let(:plugin) { get_plugin("azure") } let(:hint) do { "public_ip" => "137.135.46.202", "vm_name" => "test-vm", "public_fqdn" => "service.cloudapp.net", "public_ssh_port" => "22", "public_winrm_port" => "5985", } end let(:response_data) do { "compute" => { "location" => "westus", "name" => "timtest", "offer" => "UbuntuServer", "osType" => "Linux", "platformFaultDomain" => "0", "platformUpdateDomain" => "0", "publisher" => "Canonical", "sku" => "16.04-LTS", "version" => "16.04.201707270", "vmId" => "f78151b3-da8b-4bd8-a592-d9ce8a57ea65", "vmSize" => "Standard_DS2_v2" }, "network" => { "interface" => [ { "ipv4" => { "ipAddress" => [{ "privateIpAddress" => "10.0.1.6", "publicIpAddress" => "40.118.212.225" }], "subnet" => [{ "address" => "10.0.1.0", "prefix" => "24" }] }, "ipv6" => { "ipAddress" => [] }, "macAddress" => "000D3A37F080" }] } } end before do # skips all the metadata logic unless we want to test it allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::AzureMetadata::AZURE_METADATA_ADDR, 80) .and_return(false) end shared_examples_for "!azure" do it "does not set the azure attribute" do plugin.run expect(plugin[:azure]).to be_nil end end shared_examples_for "azure" do it "sets the azure attribute" do plugin.run expect(plugin[:azure]).to be_truthy expect(plugin[:azure]).to have_key(:metadata) end end describe "with azure hint file" do before do allow(plugin).to receive(:hint?).with("azure").and_return(hint) end it "sets the azure cloud attributes" do plugin.run expect(plugin[:azure]["public_ip"]).to eq("137.135.46.202") expect(plugin[:azure]["vm_name"]).to eq("test-vm") expect(plugin[:azure]["public_fqdn"]).to eq("service.cloudapp.net") expect(plugin[:azure]["public_ssh_port"]).to eq("22") expect(plugin[:azure]["public_winrm_port"]).to eq("5985") end end describe "without azure hint file or agent or dhcp options" do before do allow(plugin).to receive(:hint?).with("azure").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/waagent").and_return(false) allow(Dir).to receive(:exist?).with('C:\WindowsAzure').and_return(false) allow(File).to receive(:exist?).with("/var/lib/dhcp/dhclient.eth0.leases").and_return(true) @double_file = double("/var/lib/dhcp/dhclient.eth0.leases") allow(@double_file).to receive(:each) .and_yield("lease {") .and_yield(' interface "eth0";') .and_yield(" fixed-address 192.168.1.194;") .and_yield(" option subnet-mask 255.255.255.0;") .and_yield(" option routers 192.168.1.1;") .and_yield(" option dhcp-lease-time 86400;") .and_yield(" option dhcp-message-type 5;") .and_yield(" option domain-name-servers 8.8.8.8;") .and_yield(" option dhcp-server-identifier 192.168.1.2;") .and_yield(" option interface-mtu 1454;") .and_yield(" option dhcp-renewal-time 42071;") .and_yield(" option broadcast-address 192.168.1.255;") .and_yield(" option dhcp-rebinding-time 74471;") .and_yield(' option host-name "host-192-168-1-194";') .and_yield(' option domain-name "openstacklocal";') .and_yield(" renew 2 2016/03/01 01:49:41;") .and_yield(" rebind 2 2016/03/01 13:22:07;") .and_yield(" expire 2 2016/03/01 16:40:56;") .and_yield("}") allow(File).to receive(:open).with("/var/lib/dhcp/dhclient.eth0.leases").and_return(@double_file) end it_behaves_like "!azure" end describe "with rackspace hint file, no agent, and no dhcp lease" do before do allow(plugin).to receive(:hint?).with("rackspace").and_return(true) allow(plugin).to receive(:hint?).with("azure").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/waagent").and_return(false) allow(Dir).to receive(:exist?).with('C:\WindowsAzure').and_return(false) allow(File).to receive(:exist?).with("/var/lib/dhcp/dhclient.eth0.leases").and_return(false) end it_behaves_like "!azure" end describe "without azure hint file but with agent on linux" do before do allow(plugin).to receive(:hint?).with("azure").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/waagent").and_return(true) allow(Dir).to receive(:exist?).with('C:\WindowsAzure').and_return(false) end it_behaves_like "azure" end describe "without azure hint file but with agent on windows" do before do allow(plugin).to receive(:hint?).with("azure").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/waagent").and_return(false) allow(Dir).to receive(:exist?).with('C:\WindowsAzure').and_return(true) end it_behaves_like "azure" end describe "without azure hint or agent but with dhcp option" do before do allow(plugin).to receive(:hint?).with("azure").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/waagent").and_return(false) allow(Dir).to receive(:exist?).with('C:\WindowsAzure').and_return(false) allow(File).to receive(:exist?).with("/var/lib/dhcp/dhclient.eth0.leases").and_return(true) @double_file = double("/var/lib/dhcp/dhclient.eth0.leases") allow(@double_file).to receive(:each) .and_yield("lease {") .and_yield(' interface "eth0";') .and_yield(" fixed-address 10.1.0.5;") .and_yield(' server-name "RD24BE05C6F140";') .and_yield(" option subnet-mask 255.255.255.0;") .and_yield(" option dhcp-lease-time 4294967295;") .and_yield(" option routers 10.1.0.1;") .and_yield(" option dhcp-message-type 5;") .and_yield(" option dhcp-server-identifier 168.63.129.16;") .and_yield(" option domain-name-servers 168.63.129.16;") .and_yield(" option dhcp-renewal-time 4294967295;") .and_yield(" option rfc3442-classless-static-routes 0,10,1,0,1,32,168,63,129,16,10,1,0,1;") .and_yield(" option unknown-245 a8:3f:81:10;") .and_yield(" option dhcp-rebinding-time 4294967295;") .and_yield(' option domain-name "v4wvfurds4relghweduc4zqjmd.dx.internal.cloudapp.net";') .and_yield(" renew 5 2152/03/10 09:03:39;") .and_yield(" rebind 5 2152/03/10 09:03:39;") .and_yield(" expire 5 2152/03/10 09:03:39;") .and_yield("}") allow(File).to receive(:open).with("/var/lib/dhcp/dhclient.eth0.leases").and_return(@double_file) end it_behaves_like "azure" end describe "with non-responsive metadata endpoint" do before do allow(plugin).to receive(:hint?).with("azure").and_return({}) end it "does not return metadata information" do allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::AzureMetadata::AZURE_METADATA_ADDR, 80) .and_return(true) allow(plugin).to receive(:fetch_metadata).and_return(nil) plugin.run expect(plugin[:azure]).to have_key(:metadata) expect(plugin[:azure][:metadata]).to be_nil end end describe "with responsive metadata endpoint" do before do allow(plugin).to receive(:hint?).with("azure").and_return({}) allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::AzureMetadata::AZURE_METADATA_ADDR, 80) .and_return(true) allow(plugin).to receive(:fetch_metadata).and_return(response_data) plugin.run end it "returns metadata compute information" do expect(plugin[:azure][:metadata][:compute][:location]).to eq("westus") expect(plugin[:azure][:metadata][:compute][:name]).to eq("timtest") expect(plugin[:azure][:metadata][:compute][:offer]).to eq("UbuntuServer") expect(plugin[:azure][:metadata][:compute][:osType]).to eq("Linux") expect(plugin[:azure][:metadata][:compute][:platformFaultDomain]).to eq("0") expect(plugin[:azure][:metadata][:compute][:platformUpdateDomain]).to eq("0") expect(plugin[:azure][:metadata][:compute][:publisher]).to eq("Canonical") expect(plugin[:azure][:metadata][:compute][:sku]).to eq("16.04-LTS") expect(plugin[:azure][:metadata][:compute][:version]).to eq("16.04.201707270") expect(plugin[:azure][:metadata][:compute][:vmId]).to eq("f78151b3-da8b-4bd8-a592-d9ce8a57ea65") expect(plugin[:azure][:metadata][:compute][:vmSize]).to eq("Standard_DS2_v2") end it "returns metadata network information" do expect(plugin[:azure][:metadata][:network][:interfaces]["000D3A37F080"][:mac]).to eq("000D3A37F080") expect(plugin[:azure][:metadata][:network][:interfaces]["000D3A37F080"][:public_ipv6]).to eq([]) expect(plugin[:azure][:metadata][:network][:interfaces]["000D3A37F080"][:public_ipv4]).to eq(["40.118.212.225"]) expect(plugin[:azure][:metadata][:network][:interfaces]["000D3A37F080"][:local_ipv6]).to eq([]) expect(plugin[:azure][:metadata][:network][:interfaces]["000D3A37F080"][:local_ipv4]).to eq(["10.0.1.6"]) expect(plugin[:azure][:metadata][:network][:public_ipv6]).to eq([]) expect(plugin[:azure][:metadata][:network][:public_ipv4]).to eq(["40.118.212.225"]) expect(plugin[:azure][:metadata][:network][:local_ipv6]).to eq([]) expect(plugin[:azure][:metadata][:network][:local_ipv4]).to eq(["10.0.1.6"]) end end end ohai-16.0.7/spec/unit/plugins/bsd/000077500000000000000000000000001362624620500166755ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/bsd/filesystem_spec.rb000066400000000000000000000130201362624620500224140ustar00rootroot00000000000000# # Author:: Matthew Kent () # Author:: Tim Smith () # Copyright:: Copyright (c) 2011-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "BSD filesystem plugin" do let(:plugin) { get_plugin("filesystem") } before do allow(plugin).to receive(:collect_os).and_return(:freebsd) allow(plugin).to receive(:shell_out).with("df").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("mount -l").and_return(mock_shell_out(0, "", "")) end describe "when gathering filesystem usage data from df" do before do @stdout = <<~DF Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ada0p2 9637788 3313504 5553264 37% / devfs 1 1 0 100% /dev DF allow(plugin).to receive(:shell_out).with("df").and_return(mock_shell_out(0, @stdout, "")) @inode_stdout = <<~DFI Filesystem 512-blocks Used Avail Capacity iused ifree %iused Mounted on /dev/ada0p2 15411832 5109256 9069632 36% 252576 790750 24% / devfs 2 2 0 100% 0 0 100% /dev DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) end it "runs df and df -iP" do expect(plugin).to receive(:shell_out).ordered.with("df").and_return(mock_shell_out(0, @stdout, "")) expect(plugin).to receive(:shell_out).ordered.with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) plugin.run end it "sets kb_size to value from df" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:kb_size]).to eq("9637788") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:kb_size]).to eq("9637788") end it "sets kb_used to value from df" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:kb_used]).to eq("3313504") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:kb_used]).to eq("3313504") end it "sets kb_available to value from df" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:kb_available]).to eq("5553264") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:kb_available]).to eq("5553264") end it "sets percent_used to value from df" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:percent_used]).to eq("37%") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:percent_used]).to eq("37%") end it "sets mount to value from df" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:mount]).to eq("/") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:mount]).to eq("/") end it "sets total_inodes to value from df -iP" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:total_inodes]).to eq("1043326") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:total_inodes]).to eq("1043326") end it "sets inodes_used to value from df -iP" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:inodes_used]).to eq("252576") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:inodes_used]).to eq("252576") end it "sets inodes_available to value from df -iP" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:inodes_available]).to eq("790750") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:inodes_available]).to eq("790750") end end describe "when gathering mounted filesystem data from mount" do before do @stdout = <<~MOUNT /dev/ada0p2 on / (ufs, local, journaled soft-updates) devfs on /dev (devfs, local, multilabel) MOUNT allow(plugin).to receive(:shell_out).with("mount -l").and_return(mock_shell_out(0, @stdout, "")) end it "runs mount" do expect(plugin).to receive(:shell_out).with("mount -l").and_return(mock_shell_out(0, @stdout, "")) plugin.run end it "sets mount to value from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:mount]).to eq("/") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:mount]).to eq("/") end it "sets fs_type to value from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:fs_type]).to eq("ufs") expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:fs_type]).to eq("ufs") end it "sets mount_options to an array of values from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/ada0p2,/"][:mount_options]).to eq(["local", "journaled soft-updates"]) expect(plugin[:filesystem2]["by_pair"]["/dev/ada0p2,/"][:mount_options]).to eq(["local", "journaled soft-updates"]) end end end ohai-16.0.7/spec/unit/plugins/bsd/virtualization_spec.rb000066400000000000000000000144471362624620500233320ustar00rootroot00000000000000# # Author:: Bryan McLellan # Copyright:: Copyright (c) 2012-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "BSD virtualization plugin" do let(:plugin) { get_plugin("bsd/virtualization") } before do allow(plugin).to receive(:collect_os).and_return(:freebsd) allow(plugin).to receive(:shell_out).with("sysctl -n security.jail.jailed").and_return(mock_shell_out(0, "0", "")) allow(plugin).to receive(:shell_out).with((Ohai.abs_path( "/sbin/kldstat" )).to_s).and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("jls -nd").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("sysctl -n hw.model").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("sysctl -n kern.hostuuid").and_return(mock_shell_out(0, "", "")) allow(File).to receive(:exist?).and_return false end context "when on a bhyve host" do it "detects we are a host" do allow(File).to receive(:exist?).with("/dev/vmm").and_return true plugin.run expect(plugin[:virtualization][:system]).to eq("bhyve") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:bhyve]).to eq("host") end end context "when on a bhyve guest" do it "detects we are a guest" do allow(plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "bhyve", "")) plugin.run expect(plugin[:virtualization][:system]).to eq("bhyve") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:bhyve]).to eq("guest") end end context "jails" do it "detects we are in a jail" do allow(plugin).to receive(:shell_out).with("sysctl -n security.jail.jailed").and_return(mock_shell_out(0, "1", "")) plugin.run expect(plugin[:virtualization][:system]).to eq("jail") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:jail]).to eq("guest") end it "detects we are hosting jails" do # from http://www.freebsd.org/doc/handbook/jails-application.html @jails = "JID IP Address Hostname Path\n 3 192.168.3.17 ns.example.org /home/j/ns\n 2 192.168.3.18 mail.example.org /home/j/mail\n 1 62.123.43.14 www.example.org /home/j/www" allow(plugin).to receive(:shell_out).with("jls -nd").and_return(mock_shell_out(0, @jails, "")) plugin.run expect(plugin[:virtualization][:system]).to eq("jail") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:jail]).to eq("host") end end context "when on a virtualbox guest" do before do @vbox_guest = <<~OUT Id Refs Address Size Name 1 40 0xffffffff80100000 d20428 kernel 7 3 0xffffffff81055000 41e88 vboxguest.ko OUT allow(plugin).to receive(:shell_out).with((Ohai.abs_path("/sbin/kldstat")).to_s).and_return(mock_shell_out(0, @vbox_guest, "")) end it "detects we are a guest" do plugin.run expect(plugin[:virtualization][:system]).to eq("vbox") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:vbox]).to eq("guest") end end context "when on a virtualbox host" do before do @stdout = <<~OUT Id Refs Address Size Name 1 40 0xffffffff80100000 d20428 kernel 7 3 0xffffffff81055000 41e88 vboxdrv.ko OUT allow(plugin).to receive(:shell_out).with("/sbin/kldstat").and_return(mock_shell_out(0, @stdout, "")) end it "detects we are a host" do plugin.run expect(plugin[:virtualization][:system]).to eq("vbox") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:vbox]).to eq("host") end end context "when on a QEMU guest" do it "detects we are a guest" do [ "Common KVM processor", 'QEMU Virtual CPU version (cpu64-rhel6) ("GenuineIntel" 686-class)', "Common 32-bit KVM processor"].each do |kvm_string| allow(plugin).to receive(:shell_out).with("sysctl -n hw.model").and_return(mock_shell_out(0, kvm_string, "")) plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:kvm]).to eq("guest") end end end { xen: "xen", vmware: "vmware", hyperv: "hv", kvm: "kvm", bhyve: "bhyve" }.each_pair do |hypervisor, val| context "when on a #{hypervisor} guest" do it "detects we are a guest" do allow(plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, val, "")) plugin.run expect(plugin[:virtualization][:system]).to eq(hypervisor.to_s) expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][hypervisor]).to eq("guest") end end end context "when on an amazonec2 guest" do it "detects we are a guest" do allow(plugin).to receive(:shell_out).with("sysctl -n kern.vm_guest").and_return(mock_shell_out(0, "kvm", "")) allow(plugin).to receive(:shell_out).with("sysctl -n kern.hostuuid").and_return(mock_shell_out(0, "ec2fb75c-7a36-7938-4efa-8e40b4ac634b", "")) plugin.run expect(plugin[:virtualization][:system]).to eq("amazonec2") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:amazonec2]).to eq("guest") end end end ohai-16.0.7/spec/unit/plugins/c_spec.rb000066400000000000000000000354701362624620500177170ustar00rootroot00000000000000 # Author:: Doug MacEachern # Copyright:: Copyright (c) 2010 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" C_GCC = <<~EOF.freeze Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) EOF C_GLIBC = <<~EOF.freeze GNU C Library stable release version 2.5, by Roland McGrath et al. Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-44). Compiled on a Linux 2.6.9 system on 2009-09-02. Available extensions: The C stubs add-on version 2.1.2. crypt add-on version 2.1 by Michael Glad and others GNU Libidn by Simon Josefsson GNU libio by Per Bothner NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk Native POSIX Threads Library by Ulrich Drepper et al BIND-8.2.3-T5B RT using linux kernel aio Thread-local storage support included. For bug reporting instructions, please see: . EOF C_CL = <<~EOF.freeze Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. EOF C_VS = <<~EOF.freeze Microsoft (R) Visual Studio Version 8.0.50727.762. Copyright (C) Microsoft Corp 1984-2005. All rights reserved. EOF C_XLC = <<~EOF.freeze IBM XL C/C++ Enterprise Edition for AIX, V9.0 Version: 09.00.0000.0000 EOF C_SUN = <<~EOF.freeze cc: Sun C 5.8 Patch 121016-06 2007/08/01 EOF describe Ohai::System, "plugin c" do let(:plugin) { get_plugin("c") } before do plugin[:languages] = Mash.new # gcc allow(plugin).to receive(:shell_out).with("gcc -v").and_return(mock_shell_out(0, "", C_GCC)) end context "when on AIX" do before do allow(plugin).to receive(:collect_os).and_return(:aix) allow(plugin).to receive(:shell_out).with("xlc -qversion").and_return(mock_shell_out(0, C_XLC, "")) end # ibm xlc it "gets the xlc version from running xlc -qversion" do expect(plugin).to receive(:shell_out).with("xlc -qversion").and_return(mock_shell_out(0, C_XLC, "")) plugin.run end it "sets languages[:c][:xlc][:version]" do plugin.run expect(plugin.languages[:c][:xlc][:version]).to eql("9.0") end it "sets languages[:c][:xlc][:description]" do plugin.run expect(plugin.languages[:c][:xlc][:description]).to eql("IBM XL C/C++ Enterprise Edition for AIX, V9.0") end it "does not set the languages[:c][:xlc] tree up if xlc command exits nonzero" do allow(plugin).to receive(:shell_out).with("xlc -qversion").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:xlc) end it "does not set the languages[:c][:xlc] tree up if xlc command fails" do allow(plugin).to receive(:shell_out).with("xlc -qversion").and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages][:c]).not_to have_key(:xlc) expect(plugin[:languages][:c]).not_to be_empty # expect other attributes end it "sets the languages[:c][:xlc] tree up if xlc exit status is 249" do allow(plugin).to receive(:shell_out).with("xlc -qversion").and_return(mock_shell_out(63744, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:xlc) end end context "when on Darwin" do before do allow(plugin).to receive(:shell_out).with("/usr/bin/xcode-select -p").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:collect_os).and_return(:darwin) end it "shells out to see if xcode is installed" do expect(plugin).to receive(:shell_out).with("/usr/bin/xcode-select -p") plugin.run end it "doesnt shellout to gcc if xcode isn't installed" do allow(plugin).to receive(:shell_out).with("/usr/bin/xcode-select -p").and_return(mock_shell_out(1, "", "")) expect(plugin).not_to receive(:shell_out).with("gcc -v") plugin.run end end context "when on Windows" do before do allow(plugin).to receive(:collect_os).and_return(:windows) allow(plugin).to receive(:shell_out).with("cl /\?").and_return(mock_shell_out(0, "", C_CL)) allow(plugin).to receive(:shell_out).with("devenv.com /\?").and_return(mock_shell_out(0, C_VS, "")) end # ms cl it "gets the cl version from running cl /?" do expect(plugin).to receive(:shell_out).with("cl /\?") plugin.run end it "sets languages[:c][:cl][:version]" do plugin.run expect(plugin.languages[:c][:cl][:version]).to eql("14.00.50727.762") end it "sets languages[:c][:cl][:description]" do plugin.run expect(plugin.languages[:c][:cl][:description]).to eql("Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86") end it "does not set the languages[:c][:cl] tree up if cl command exits nonzero" do allow(plugin).to receive(:shell_out).with("cl /\?").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:cl) end it "does not set the languages[:c][:cl] tree up if cl command fails" do allow(plugin).to receive(:shell_out).with("cl /\?").and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages][:c]).not_to have_key(:cl) expect(plugin[:languages][:c]).not_to be_empty # expect other attributes end # ms vs it "gets the vs version from running devenv.com /?" do expect(plugin).to receive(:shell_out).with("devenv.com /\?").and_return(mock_shell_out(0, C_VS, "")) plugin.run end it "sets languages[:c][:vs][:version]" do plugin.run expect(plugin.languages[:c][:vs][:version]).to eql("8.0.50727.762") end it "sets languages[:c][:vs][:description]" do plugin.run expect(plugin.languages[:c][:vs][:description]).to eql("Microsoft (R) Visual Studio Version 8.0.50727.762.") end it "does not set the languages[:c][:vs] tree up if devenv command exits nonzero" do allow(plugin).to receive(:shell_out).with("devenv.com /\?").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:vs) end it "does not set the languages[:c][:vs] tree up if devenv command fails" do allow(plugin).to receive(:shell_out).with("devenv.com /\?").and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages][:c]).not_to have_key(:vs) expect(plugin[:languages][:c]).not_to be_empty # expect other attributes end end context "when on Linux" do before do allow(plugin).to receive(:collect_os).and_return(:linux) # glibc allow(plugin).to receive(:shell_out).with("/lib/libc.so.6").and_return(mock_shell_out(0, C_GLIBC, "")) allow(plugin).to receive(:shell_out).with("/lib64/libc.so.6").and_return(mock_shell_out(0, C_GLIBC, "")) # sun pro allow(plugin).to receive(:shell_out).with("cc -V -flags").and_return(mock_shell_out(0, "", C_SUN)) end # gcc it "gets the gcc version from running gcc -v" do expect(plugin).to receive(:shell_out).with("gcc -v") plugin.run end it "sets languages[:c][:gcc][:version]" do plugin.run expect(plugin.languages[:c][:gcc][:version]).to eql("5.4.0") end it "sets languages[:c][:gcc][:description]" do plugin.run expect(plugin.languages[:c][:gcc][:description]).to eql("gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)") end it "sets languages[:c][:gcc][:configured_with]" do plugin.run expect(plugin.languages[:c][:gcc][:configured_with]).to eql("../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu") end it "sets languages[:c][:gcc][:target]" do plugin.run expect(plugin.languages[:c][:gcc][:target]).to eql("x86_64-linux-gnu") end it "sets languages[:c][:gcc][:thread_model]" do plugin.run expect(plugin.languages[:c][:gcc][:thread_model]).to eql("posix") end it "does not set the languages[:c][:gcc] tree up if gcc command exits nonzero" do allow(plugin).to receive(:shell_out).with("gcc -v").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:gcc) end it "does not set the languages[:c][:gcc] tree up if gcc command fails" do allow(plugin).to receive(:shell_out).with("gcc -v").and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages][:c]).not_to have_key(:gcc) expect(plugin[:languages][:c]).not_to be_empty # expect other attributes end # glibc it "gets the glibc x.x.x version from running /lib/libc.so.6" do expect(plugin).to receive(:shell_out).with("/lib/libc.so.6") plugin.run end it "sets languages[:c][:glibc][:version]", :unix_only do plugin.run expect(plugin.languages[:c][:glibc][:version]).to eql("2.5") end it "sets languages[:c][:glibc][:description]" do plugin.run expect(plugin.languages[:c][:glibc][:description]).to eql("GNU C Library stable release version 2.5, by Roland McGrath et al.") end it "does not set the languages[:c][:glibc] tree up if glibc exits nonzero" do allow(plugin).to receive(:shell_out).with("/lib/libc.so.6").and_return(mock_shell_out(1, "", "")) allow(plugin).to receive(:shell_out).with("/lib64/libc.so.6").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:glibc) end it "does not set the languages[:c][:glibc] tree up if glibc fails" do allow(plugin).to receive(:shell_out).with("/lib/libc.so.6").and_raise(Ohai::Exceptions::Exec) allow(plugin).to receive(:shell_out).with("/lib64/libc.so.6").and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages][:c]).not_to have_key(:glibc) expect(plugin[:languages][:c]).not_to be_empty # expect other attributes end it "gets the glibc x.x version from running /lib/libc.so.6" do allow(plugin).to receive(:shell_out).with("/lib/libc.so.6").and_return(mock_shell_out(0, C_GLIBC, "")) expect(plugin).to receive(:shell_out).with("/lib/libc.so.6") plugin.run expect(plugin.languages[:c][:glibc][:version]).to eql("2.5") end # sun pro it "gets the cc version from running cc -V -flags" do expect(plugin).to receive(:shell_out).with("cc -V -flags").and_return(mock_shell_out(0, "", C_SUN)) plugin.run end it "sets languages[:c][:sunpro][:version]" do plugin.run expect(plugin.languages[:c][:sunpro][:version]).to eql("5.8") end it "sets languages[:c][:sunpro][:description]" do plugin.run expect(plugin.languages[:c][:sunpro][:description]).to eql("cc: Sun C 5.8 Patch 121016-06 2007/08/01") end it "does not set the languages[:c][:sunpro] tree up if cc command exits nonzero" do allow(plugin).to receive(:shell_out).with("cc -V -flags").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin[:languages][:c]).not_to have_key(:sunpro) end it "does not set the languages[:c][:sunpro] tree up if cc command fails" do allow(plugin).to receive(:shell_out).with("cc -V -flags").and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages][:c]).not_to have_key(:sunpro) expect(plugin[:languages][:c]).not_to be_empty # expect other attributes end it "does not set the languages[:c][:sunpro] tree if the corresponding cc command fails on linux" do fedora_error_message = "cc: error trying to exec 'i686-redhat-linux-gcc--flags': execvp: No such file or directory" allow(plugin).to receive(:shell_out).with("cc -V -flags").and_return(mock_shell_out(0, "", fedora_error_message)) plugin.run expect(plugin[:languages][:c]).not_to have_key(:sunpro) end end end ohai-16.0.7/spec/unit/plugins/chef_spec.rb000066400000000000000000000027171362624620500204000ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Tollef Fog Heen # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2010 Tollef Fog Heen # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # begin require "spec_helper" require "chef/version" describe Ohai::System, "plugin chef" do before do @plugin = get_plugin("chef") end it "sets [:chef_packages][:chef][:version] to the current chef version", if: defined?(Chef) do @plugin.run expect(@plugin[:chef_packages][:chef][:version]).to eq(Chef::VERSION) end pending "would set [:chef_packages][:chef][:version] if chef was available", unless: defined?(Chef) end rescue LoadError # the chef module is not available, ignoring. describe Ohai::System, "plugin chef" do pending "would set [:chef_packages][:chef][:version] if chef was available", unless: defined?(Chef) end end ohai-16.0.7/spec/unit/plugins/cloud_spec.rb000066400000000000000000000343771362624620500206100ustar00rootroot00000000000000# # Author:: Cary Penniman () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ipaddr" describe "CloudAttrs object" do before do @plugin = get_plugin("cloud") end let(:cloud_node) do { "public_ipv4_addrs" => ["1.2.3.1"], "local_ipv4_addrs" => ["1.2.4.1"], "public_ipv6_addrs" => ["3ffe:505:2::1"], "local_ipv6_addrs" => ["3ffe:506:2::1"], "public_ipv4" => "1.2.3.1", "local_ipv4" => "1.2.4.1", "public_ipv6" => "3ffe:505:2::1", "local_ipv6" => "3ffe:506:2::1", "public_hostname" => "myhost.somewhere.com", "local_hostname" => "my-localhost", "provider" => "my_awesome_cloud", } end it "populates cloud mash" do @cloud_attr_obj = ::CloudAttrs.new @cloud_attr_obj.add_ipv4_addr("1.2.3.1", :public) @cloud_attr_obj.add_ipv4_addr("1.2.4.1", :private) @cloud_attr_obj.add_ipv6_addr("3ffe:505:2::1", :public) @cloud_attr_obj.add_ipv6_addr("3ffe:506:2::1", :private) @cloud_attr_obj.public_hostname = "myhost.somewhere.com" @cloud_attr_obj.local_hostname = "my-localhost" @cloud_attr_obj.provider = "my_awesome_cloud" expect(@cloud_attr_obj.cloud_mash).to eq(cloud_node) end it "throws exception with a bad ipv4 address" do @cloud_attr_obj = ::CloudAttrs.new expect { @cloud_attr_obj.add_ipv6_addr("somebogusstring", :public) }.to raise_error(RuntimeError) end it "throws exception with a bad ipv6 address" do @cloud_attr_obj = ::CloudAttrs.new expect { @cloud_attr_obj.add_ipv6_addr("FEED:B0B:DEAD:BEEF", :public) }.to raise_error(RuntimeError) end it "throws exception with ipv6 address passed to ipv4" do @cloud_attr_obj = ::CloudAttrs.new expect { @cloud_attr_obj.add_ipv4_addr("3ffe:506:2::1", :public) }.to raise_error(RuntimeError) end it "throws exception with ipv4 address passed to ipv6" do @cloud_attr_obj = ::CloudAttrs.new expect { @cloud_attr_obj.add_ipv6_addr("1.2.3.4", :public) }.to raise_error(RuntimeError) end end describe Ohai::System, "plugin cloud" do before do @plugin = get_plugin("cloud") end describe "with no cloud mashes" do it "doesn't populate the cloud data" do @plugin[:ec2] = nil @plugin[:rackspace] = nil @plugin[:eucalyptus] = nil @plugin[:linode] = nil @plugin[:azure] = nil @plugin[:gce] = nil @plugin[:digital_ocean] = nil @plugin[:softlayer] = nil @plugin.run expect(@plugin[:cloud]).to be_nil end end describe "with EC2 mash" do before do @plugin[:ec2] = Mash.new end it "populates cloud public ip" do @plugin[:ec2]["public_ipv4"] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs][0]).to eq(@plugin[:ec2]["public_ipv4"]) end it "populates cloud private ip" do @plugin[:ec2]["local_ipv4"] = "10.252.42.149" @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs][0]).to eq(@plugin[:ec2]["local_ipv4"]) end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("ec2") end end describe "with GCE mash" do describe "with a public IP" do before do @plugin[:gce] = Mash.new @plugin[:gce]["instance"] = Mash.new @plugin[:gce]["instance"]["networkInterfaces"] = [ { "accessConfigs" => [ { "externalIp" => "8.35.198.173", "type" => "ONE_TO_ONE_NAT" } ], "ip" => "10.240.0.102", "network" => "projects/foo/networks/default", }, ] end it "populates cloud public ip" do @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs][0]).to eq("8.35.198.173") end it "populates cloud private ip" do @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs][0]).to eq("10.240.0.102") end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("gce") end end describe "with no public IP" do before do @plugin[:gce] = Mash.new @plugin[:gce]["instance"] = Mash.new @plugin[:gce]["instance"]["networkInterfaces"] = [ { "accessConfigs" => [ { "externalIp" => "", "type" => "ONE_TO_ONE_NAT" } ], "ip" => "10.240.0.102", "network" => "projects/foo/networks/default", }, ] end it "does not populate cloud public ip" do @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs]).to be_nil end it "populates cloud private ip" do @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs][0]).to eq("10.240.0.102") end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("gce") end end end describe "with rackspace" do before do @plugin[:rackspace] = Mash.new end it "populates cloud public ip" do @plugin[:rackspace][:public_ipv4] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:public_ipv4]).to eq(@plugin[:rackspace][:public_ipv4]) end it "populates cloud public ipv6" do @plugin[:rackspace][:public_ipv6] = "2a00:1a48:7805:111:e875:efaf:ff08:75" @plugin.run expect(@plugin[:cloud][:public_ipv6]).to eq(@plugin[:rackspace][:public_ipv6]) end it "populates cloud private ip" do @plugin[:rackspace][:local_ipv4] = "10.252.42.149" @plugin.run expect(@plugin[:cloud][:local_ipv4]).to eq(@plugin[:rackspace][:local_ipv4]) end it "populates cloud private ipv6" do @plugin[:rackspace][:local_ipv6] = "2a00:1a48:7805:111:e875:efaf:ff08:75" @plugin.run expect(@plugin[:cloud][:local_ipv6]).to eq(@plugin[:rackspace][:local_ipv6]) end it "populates first cloud public ip" do @plugin[:rackspace][:public_ipv4] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs].first).to eq(@plugin[:rackspace][:public_ipv4]) end it "populates first cloud public ip" do @plugin[:rackspace][:local_ipv4] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs].first).to eq(@plugin[:rackspace][:local_ipv4]) end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("rackspace") end end describe "with linode mash" do before do @plugin[:linode] = Mash.new end it "populates cloud public ip" do @plugin[:linode]["public_ip"] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs][0]).to eq(@plugin[:linode][:public_ip]) end it "populates cloud private ip" do @plugin[:linode]["private_ip"] = "10.252.42.149" @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs][0]).to eq(@plugin[:linode][:private_ip]) end it "populates first cloud public ip" do @plugin[:linode]["public_ip"] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs].first).to eq(@plugin[:linode][:public_ip]) end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("linode") end end describe "with eucalyptus mash" do before do @plugin[:eucalyptus] = Mash.new end it "populates cloud public ip" do @plugin[:eucalyptus]["public_ipv4"] = "174.129.150.8" @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs][0]).to eq(@plugin[:eucalyptus]["public_ipv4"]) end it "populates cloud private ip" do @plugin[:eucalyptus]["local_ipv4"] = "10.252.42.149" @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs][0]).to eq(@plugin[:eucalyptus]["local_ipv4"]) end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("eucalyptus") end end describe "with Azure mash" do before do @plugin[:azure] = Mash.new @plugin[:azure][:metadata] = { "compute" => { "location" => "westus", "name" => "timtest", "offer" => "UbuntuServer", "osType" => "Linux", "platformFaultDomain" => "0", "platformUpdateDomain" => "0", "publisher" => "Canonical", "sku" => "16.04-LTS", "version" => "16.04.201707270", "vmId" => "f78151b3-da8b-4bd8-a592-d9ce8357e365", "vmSize" => "Standard_DS2_v2", }, "network" => { "interfaces" => { "000D3A37F080" => { "mac" => "000D3A37F080", "public_ipv6" => [], "public_ipv4" => ["40.118.212.225"], "local_ipv6" => [], "local_ipv4" => ["10.0.1.6"], }, }, "public_ipv4" => ["40.118.212.225"], "local_ipv4" => ["10.0.1.6"], "public_ipv6" => [], "local_ipv6" => [], }, } end it "populates cloud public ip" do @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs][0]).to eq("40.118.212.225") end it "doesn't populates cloud vm_name" do @plugin.run expect(@plugin[:cloud][:vm_name]).not_to eq("timtest") end it "populates cloud public_hostname" do @plugin[:azure]["public_fqdn"] = "linux-vm-svc.cloudapp.net" @plugin.run expect(@plugin[:cloud][:public_hostname]).to eq("linux-vm-svc.cloudapp.net") end it "doesn't populate cloud public_ssh_port" do @plugin[:azure]["public_ssh_port"] = "22" @plugin.run expect(@plugin[:cloud][:public_ssh_port]).to be_nil end it "does not populate cloud public_ssh_port when winrm is used" do @plugin[:azure]["public_winrm_port"] = "5985" @plugin.run expect(@plugin[:cloud][:public_ssh_port]).to be_nil end it "populates cloud public_winrm_port" do @plugin[:azure]["public_winrm_port"] = "5985" @plugin.run expect(@plugin[:cloud][:public_winrm_port]).to be_nil end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("azure") end end describe "with digital_ocean mash" do before do @plugin[:digital_ocean] = Mash.new @plugin[:digital_ocean][:interfaces] = Mash.new @plugin[:digital_ocean][:interfaces] = { "private" => [ { "ipv4" => { "ip_address" => "10.135.32.4", "netmask" => "255.255.0.0", "gateway" => "10.135.0.1", }, "mac" => "36:9e:23:65:c1:fe", "type" => "private", }, ], "public" => [ { "ipv4" => { "ip_address" => "207.154.221.42", "netmask" => "255.255.240.0", "gateway" => "207.154.208.1", }, "ipv6" => { "ip_address" => "2A03:B0C0:0003:00D0:0000:0000:3B15:B001", "cidr" => 64, "gateway" => "2A03:B0C0:0003:00D0:0000:0000:0000:0001", }, "anchor_ipv4" => { "ip_address" => "10.19.0.5", "netmask" => "255.255.0.0", "gateway" => "10.19.0.1", }, "mac" => "9a:80:15:02:7a:c1", "type" => "public", }, ], } end before do @plugin.run end it "populates cloud local hostname" do expect(@plugin[:cloud][:local_hostname]).to be_nil end it "populates cloud public_ipv4_addrs" do expect(@plugin[:cloud][:public_ipv4_addrs]).to eq(["207.154.221.42"]) end it "populates cloud local_ipv4_addrs" do expect(@plugin[:cloud][:local_ipv4_addrs]).to eq(["10.135.32.4"]) end it "populates cloud public_ipv4" do expect(@plugin[:cloud][:public_ipv4]).to eq("207.154.221.42") end it "populates cloud local_ipv4" do expect(@plugin[:cloud][:local_ipv4]).to eq("10.135.32.4") end it "populates cloud public_ipv6_addrs" do expect(@plugin[:cloud][:public_ipv6_addrs]).to eq(["2a03:b0c0:3:d0::3b15:b001"]) end it "populates cloud local_ipv6_addrs" do expect(@plugin[:cloud][:local_ipv6_addrs]).to be_nil end it "populates cloud public_ipv6" do expect(@plugin[:cloud][:public_ipv6]).to eq("2a03:b0c0:3:d0::3b15:b001") end it "populates cloud local_ipv6" do expect(@plugin[:cloud][:local_ipv6]).to be_nil end it "populates cloud provider" do expect(@plugin[:cloud][:provider]).to eq("digital_ocean") end end describe "with softlayer mash" do before do @plugin[:softlayer] = Mash.new @plugin[:softlayer] = { "local_ipv4" => "192.168.0.1", "public_ipv4" => "8.8.8.8", "public_fqdn" => "abc1234.public.com", } end it "populates cloud public ip" do @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs][0]).to eq(@plugin[:softlayer][:public_ipv4]) end it "populates cloud private ip" do @plugin.run expect(@plugin[:cloud][:local_ipv4_addrs][0]).to eq(@plugin[:softlayer][:local_ipv4]) end it "populates first cloud public ip" do @plugin.run expect(@plugin[:cloud][:public_ipv4_addrs].first).to eq(@plugin[:softlayer][:public_ipv4]) end it "populates cloud public_hostname" do @plugin.run expect(@plugin[:cloud][:public_hostname]).to eq(@plugin[:softlayer][:public_fqdn]) end it "populates cloud provider" do @plugin.run expect(@plugin[:cloud][:provider]).to eq("softlayer") end end end ohai-16.0.7/spec/unit/plugins/darwin/000077500000000000000000000000001362624620500174115ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/darwin/cpu_spec.rb000066400000000000000000000107461362624620500215470ustar00rootroot00000000000000# # Author:: Nathan L Smith () # Copyright:: Copyright (c) 2013-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin cpu plugin" do before do @plugin = get_plugin("cpu") @stdout = <<~CTL hw.ncpu: 8 hw.byteorder: 1234 hw.memsize: 17179869184 hw.activecpu: 8 hw.packages: 1 hw.tbfrequency: 1000000000 hw.l3cachesize: 6291456 hw.l2cachesize: 262144 hw.l1dcachesize: 32768 hw.l1icachesize: 32768 hw.cachelinesize: 64 hw.cpufrequency: 2800000000 hw.busfrequency: 100000000 hw.pagesize32: 4096 hw.pagesize: 4096 hw.cpufamily: 280134364 hw.cpu64bit_capable: 1 hw.cpusubtype: 8 hw.cputype: 7 hw.logicalcpu_max: 8 hw.logicalcpu: 8 hw.physicalcpu_max: 4 hw.physicalcpu: 4 hw.targettype: Mac hw.cputhreadtype: 1 machdep.cpu.thread_count: 8 machdep.cpu.core_count: 4 machdep.cpu.address_bits.virtual: 48 machdep.cpu.address_bits.physical: 39 machdep.cpu.cache.size: 256 machdep.cpu.cache.L2_associativity: 8 machdep.cpu.cache.linesize: 64 machdep.cpu.processor_flag: 5 machdep.cpu.microcode_version: 15 machdep.cpu.cores_per_package: 8 machdep.cpu.logical_per_package: 16 machdep.cpu.extfeatures: SYSCALL XD 1GBPAGE EM64T LAHF LZCNT RDTSCP TSCI machdep.cpu.leaf7_features: SMEP ERMS RDWRFSGS TSC_THREAD_OFFSET BMI1 HLE AVX2 BMI2 INVPCID RTM FPU_CSDS machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 PCLMULQDQ DTES64 MON DSCPL VMX SMX EST TM2 SSSE3 FMA CX16 TPR PDCM SSE4.1 SSE4.2 x2APIC MOVBE POPCNT AES PCID XSAVE OSXSAVE SEGLIM64 TSCTMR AVX1.0 RDRAND F16C machdep.cpu.brand: 0 machdep.cpu.signature: 263777 machdep.cpu.extfeature_bits: 142473169152 machdep.cpu.leaf7_feature_bits: 12219 machdep.cpu.feature_bits: 9221960262849657855 machdep.cpu.stepping: 1 machdep.cpu.extfamily: 0 machdep.cpu.extmodel: 4 machdep.cpu.model: 70 machdep.cpu.family: 6 machdep.cpu.brand_string: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz machdep.cpu.vendor: GenuineIntel machdep.cpu.max_ext: 2147483656 machdep.cpu.max_basic: 13 CTL allow(@plugin).to receive(:collect_os).and_return(:darwin) allow(@plugin).to receive(:shell_out).with("sysctl hw machdep").and_return(mock_shell_out(0, @stdout, "")) @plugin.run end it "sets cpu[:cores] to 4" do expect(@plugin[:cpu][:cores]).to eq(4) end it "sets cpu[:total] to 8" do expect(@plugin[:cpu][:total]).to eq(8) end it "sets cpu[:real] to 1" do expect(@plugin[:cpu][:real]).to eq(1) end it "sets cpu[:mhz] to 2800" do expect(@plugin[:cpu][:mhz]).to eq(2800) end it "sets cpu[:vendor_id] to GenuineIntel" do expect(@plugin[:cpu][:vendor_id]).to eq("GenuineIntel") end it "sets cpu[:model_name] to Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz" do expect(@plugin[:cpu][:model_name]).to eq("Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz") end it "sets cpu[:model] to 70" do expect(@plugin[:cpu][:model]).to eq(70) end it "sets cpu[:family] to 6" do expect(@plugin[:cpu][:family]).to eq(6) end it "sets cpu[:stepping] to 1" do expect(@plugin[:cpu][:stepping]).to eq(1) end it "sets cpu[:flags] to array of flags" do expect(@plugin[:cpu][:flags]).to eq(["fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "clfsh", "ds", "acpi", "mmx", "fxsr", "sse", "sse2", "ss", "htt", "tm", "pbe", "sse3", "pclmulqdq", "dtes64", "mon", "dscpl", "vmx", "smx", "est", "tm2", "ssse3", "fma", "cx16", "tpr", "pdcm", "sse4.1", "sse4.2", "x2apic", "movbe", "popcnt", "aes", "pcid", "xsave", "osxsave", "seglim64", "tsctmr", "avx1.0", "rdrand", "f16c"]) end end ohai-16.0.7/spec/unit/plugins/darwin/filesystem_spec.rb000066400000000000000000000153541362624620500231440ustar00rootroot00000000000000# # Author:: Phil Dibowitz () # Copyright:: Copyright (c) 2015 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "darwin filesystem plugin" do let(:plugin) { get_plugin("filesystem") } before do allow(plugin).to receive(:collect_os).and_return(:darwin) allow(plugin).to receive(:shell_out).with("df -i").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, "", "")) end describe "when gathering filesystem usage data from df" do before do @stdout = <<~DF Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on /dev/disk0s2 488555536 313696448 174347088 65% 39276054 21793386 64% / devfs 385 385 0 100% 666 0 100% /dev map /etc/auto.direct 0 0 0 100% 0 0 100% /mnt/vol map -hosts 0 0 0 100% 0 0 100% /net map -static 0 0 0 100% 0 0 100% /mobile_symbol deweyfs@osxfuse0 0 0 0 100% 0 0 100% /mnt/dewey DF allow(plugin).to receive(:shell_out).with("df -i").and_return(mock_shell_out(0, @stdout, "")) end it "runs df -i" do expect(plugin).to receive(:shell_out).ordered.with("df -i").and_return(mock_shell_out(0, @stdout, "")) plugin.run end it "sets size to value from df -i" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:kb_size]).to eq("244277768") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:kb_used]).to eq("156848224") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:kb_available]).to eq("87173544") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:percent_used]).to eq("65%") end it "sets device and mount to value from df -i" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:mount]).to eq("/") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:device]).to eq("/dev/disk0s2") end it "sets inode info to value from df -i" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:total_inodes]).to eq("61069440") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:inodes_used]).to eq("39276054") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:inodes_available]).to eq("21793386") end end describe "when gathering mounted filesystem data from mount" do before do @stdout = <<~MOUNT /dev/disk0s2 on / (hfs, local, journaled) devfs on /dev (devfs, local, nobrowse) map /etc/auto.direct on /mnt/vol (autofs, automounted, nobrowse) map -hosts on /net (autofs, nosuid, automounted, nobrowse) map -static on /mobile_symbol (autofs, automounted, nobrowse) deweyfs@osxfuse0 on /mnt/dewey (osxfusefs, synchronous, nobrowse) MOUNT allow(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @stdout, "")) end it "runs mount" do expect(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @stdout, "")) plugin.run end it "sets values from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:mount]).to eq("/") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:fs_type]).to eq("hfs") expect(plugin[:filesystem]["by_pair"]["/dev/disk0s2,/"][:mount_options]).to eq(%w{local journaled}) end end describe "when gathering filesystem data with devices mounted more than once" do before do @dfstdout = <<~DF Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on /dev/disk0s2 488555536 313696448 174347088 65% 39276054 21793386 64% / devfs 385 385 0 100% 666 0 100% /dev map /etc/auto.direct 0 0 0 100% 0 0 100% /mnt/vol map -hosts 0 0 0 100% 0 0 100% /net map -static 0 0 0 100% 0 0 100% /mobile_symbol deweyfs@osxfuse0 0 0 0 100% 0 0 100% /mnt/dewey /dev/disk0s2 488555536 313696448 174347088 65% 39276054 21793386 64% /another/mountpoint DF allow(plugin).to receive(:shell_out).with("df -i").and_return(mock_shell_out(0, @dfstdout, "")) end it "provides a devices view with all mountpoints" do plugin.run expect(plugin[:filesystem]["by_device"]["/dev/disk0s2"][:mounts]).to eq(["/", "/another/mountpoint"]) end end describe "when gathering filesystem data with double-mounts" do before do @dfstdout = <<~DF Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on /dev/disk0s2 488555536 313696448 174347088 65% 39276054 21793386 64% / devfs 385 385 0 100% 666 0 100% /dev map /etc/auto.direct 0 0 0 100% 0 0 100% /mnt/vol map -hosts 0 0 0 100% 0 0 100% /net map -static 0 0 0 100% 0 0 100% /mobile_symbol deweyfs@osxfuse0 0 0 0 100% 0 0 100% /mnt/dewey /dev/disk0s3 488555536 313696448 174347088 65% 39276054 21793386 64% /mnt /dev/disk0s4 488555536 313696448 174347088 65% 39276054 21793386 64% /mnt DF allow(plugin).to receive(:shell_out).with("df -i").and_return(mock_shell_out(0, @dfstdout, "")) end it "provides a mounts view with all devices" do plugin.run expect(plugin[:filesystem]["by_mountpoint"]["/mnt"][:devices]).to eq(["/dev/disk0s3", "/dev/disk0s4"]) end end end ohai-16.0.7/spec/unit/plugins/darwin/hardware_spec.rb000066400000000000000000000103751362624620500225530ustar00rootroot00000000000000# # Author:: Nate Walck () # Copyright:: Copyright (c) 2016-present Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require_relative "hardware_system_profiler_output" describe Ohai::System, "Darwin hardware plugin", :unix_only do let(:plugin) { get_plugin("darwin/hardware") } before do allow(plugin).to receive(:collect_os).and_return(:darwin) # Make sure it always runs correct commands and mock the data as it calls them allow(plugin).to receive(:shell_out).with( "system_profiler SPHardwareDataType -xml" ).and_return( mock_shell_out(0, HardwareSystemProfilerOutput::HARDWARE, "") ) allow(plugin).to receive(:shell_out).with( "sw_vers" ).and_return( mock_shell_out(0, "ProductName: Mac OS X\nProductVersion: 10.12\nBuildVersion: 16A239j", "") ) allow(plugin).to receive(:shell_out).with( "uname -m" ).and_return( mock_shell_out(0, "x86_64", "") ) allow(plugin).to receive(:shell_out).with( "system_profiler SPStorageDataType -xml" ).and_return( mock_shell_out(0, HardwareSystemProfilerOutput::STORAGE, "") ) allow(plugin).to receive(:shell_out).with( "system_profiler SPPowerDataType -xml" ).and_return( mock_shell_out(0, HardwareSystemProfilerOutput::POWER, "") ) end it "parses hardware data correctly" do plugin.run expect(plugin["hardware"]["SMC_version_system"]).to eq("2.16f68") expect(plugin["hardware"]["boot_rom_version"]).to eq("MBP111.0138.B17") expect(plugin["hardware"]["cpu_type"]).to eq("Intel Core i7") expect(plugin["hardware"]["current_processor_speed"]).to eq("3 GHz") expect(plugin["hardware"]["l2_cache_core"]).to eq("256 KB") expect(plugin["hardware"]["l3_cache"]).to eq("4 MB") expect(plugin["hardware"]["machine_model"]).to eq("MacBookPro11,1") expect(plugin["hardware"]["machine_name"]).to eq("MacBook Pro") expect(plugin["hardware"]["number_processors"]).to eq(2) expect(plugin["hardware"]["packages"]).to eq(1) expect(plugin["hardware"]["physical_memory"]).to eq("16 GB") expect(plugin["hardware"]["platform_UUID"]).to eq("F1A4AE0F-84A8-45D8-83C7-F3F904464FC5") expect(plugin["hardware"]["serial_number"]).to eq("ABCDEFG12345") end it "parses sw_vers and uname data correctly" do plugin.run expect(plugin["hardware"]["operating_system"]).to eq("Mac OS X") expect(plugin["hardware"]["operating_system_version"]).to eq("10.12") expect(plugin["hardware"]["build_version"]).to eq("16A239j") expect(plugin["hardware"]["architecture"]).to eq("x86_64") end it "parses storage data correctly" do plugin.run expect(plugin["hardware"]["storage"][0]["name"]).to eq("Macintosh HD") expect(plugin["hardware"]["storage"][0]["bsd_name"]).to eq("disk1") expect(plugin["hardware"]["storage"][0]["capacity"]).to eq(249661751296) expect(plugin["hardware"]["storage"][0]["drive_type"]).to eq("ssd") expect(plugin["hardware"]["storage"][0]["smart_status"]).to eq("Verified") expect(plugin["hardware"]["storage"][0]["partitions"]).to eq(1) end it "parses storage data correctly" do plugin.run expect(plugin["hardware"]["battery"]["current_capacity"]).to eq(5841) expect(plugin["hardware"]["battery"]["max_capacity"]).to eq(5841) expect(plugin["hardware"]["battery"]["fully_charged"]).to eq(true) expect(plugin["hardware"]["battery"]["is_charging"]).to eq(false) expect(plugin["hardware"]["battery"]["charge_cycle_count"]).to eq(201) expect(plugin["hardware"]["battery"]["health"]).to eq("Good") expect(plugin["hardware"]["battery"]["serial"]).to eq("D123456789ABCDEFG") expect(plugin["hardware"]["battery"]["remaining"]).to eq(100) end end ohai-16.0.7/spec/unit/plugins/darwin/hardware_system_profiler_output.rb000066400000000000000000001036001362624620500264610ustar00rootroot00000000000000module HardwareSystemProfilerOutput HARDWARE = <<~HARDWARE_OUTPUT.freeze _SPCommandLineArguments /usr/sbin/system_profiler -nospawn -xml SPHardwareDataType -detailLevel full _SPCompletionInterval 0.095997989177703857 _SPResponseTime 0.21922904253005981 _dataType SPHardwareDataType _detailLevel -2 _items SMC_version_system 2.16f68 _name hardware_overview boot_rom_version MBP111.0138.B17 cpu_type Intel Core i7 current_processor_speed 3 GHz l2_cache_core 256 KB l3_cache 4 MB machine_model MacBookPro11,1 machine_name MacBook Pro number_processors 2 packages 1 physical_memory 16 GB platform_UUID F1A4AE0F-84A8-45D8-83C7-F3F904464FC5 serial_number ABCDEFG12345 _parentDataType SPRootDataType _properties LOM_revision _order 85 Lightshow_version _order 83 _suppressLocalization YES MMM_state _order 70 SMC_version_other _order 82 SMC_version_riser _order 81 SMC_version_system _order 80 _suppressLocalization YES apple_rom_info _order 53 boot_rom_release_date _order 52 boot_rom_vendor _order 50 boot_rom_version _order 51 bus_speed _order 45 cores_per_package _order 24 cpu_interconnect_speed _order 46 cpu_type _order 15 current_processor_speed _order 17 l2_cache _order 26 l2_cache_core _order 26 l2_cache_share _order 26 l2_cache_size _order 26 l3_cache _order 27 l3_cache_processor _order 27 l3_cache_size _order 27 machine_model _order 11 machine_name _order 10 maximum_processor_speed _order 19 minimum_processor_speed _order 18 number_cpus _order 20 number_processors _order 22 packages _order 20 physical_memory _order 40 platform_UUID _detailLevel 0 _order 98 platform_cpu_features _order 30 platform_cpu_htt _order 28 platform_cpu_vendor _order 12 platform_manufacturer _order 4 platform_product_name _order 2 platform_version _order 6 riser_serial_number _detailLevel 0 _order 92 sales_order_number _detailLevel 0 _order 95 serial_number _detailLevel 0 _order 90 volumes _detailLevel 0 _timeStamp 2016-07-08T19:44:04Z _versionInfo com.apple.SystemProfiler.SPPlatformReporter 1445 HARDWARE_OUTPUT STORAGE = <<~STORAGE_OUTPUT.freeze _SPCommandLineArguments /usr/sbin/system_profiler -nospawn -xml SPStorageDataType -detailLevel full _SPCompletionInterval 0.35913503170013428 _SPResponseTime 0.46972799301147461 _dataType SPStorageDataType _items _name Macintosh HD bsd_name disk1 com.apple.corestorage.lv com.apple.corestorage.lv.encrypted yes com.apple.corestorage.lv.encryptionType AES-XTS com.apple.corestorage.lv.locked no com.apple.corestorage.lv.revertible kCoreStorageDecryptRevert com.apple.corestorage.lv.uuid 1CD892E5-60BC-4339-AEF9-8C2818735617 com.apple.corestorage.lvg com.apple.corestorage.lvg.freeSpace 0 com.apple.corestorage.lvg.name Macintosh HD com.apple.corestorage.lvg.size 250006216704 com.apple.corestorage.lvg.uuid 949A3F85-1B19-4930-8EE0-B1565D66F2C5 com.apple.corestorage.pv _name disk0s2 com.apple.corestorage.pv.size 250006216704 com.apple.corestorage.pv.status Online com.apple.corestorage.pv.uuid D26DACEB-E661-4621-9BE3-355FAE611398 device_name APPLE SSD SM0256F is_internal_disk yes media_name APPLE SSD SM0256F Media medium_type ssd partition_map_type guid_partition_map_type protocol PCI smart_status Verified file_system Journaled HFS+ free_space_in_bytes 23864803328 ignore_ownership no mount_point / size_in_bytes 249661751296 volume_uuid 06A53A23-1675-31BF-93BF-E78C149C61E9 writable yes _parentDataType SPHardwareDataType _properties _name _isColumn YES _order 100 bsd_name _isColumn _order 180 com.apple.corestorage.lv _order 200 com.apple.corestorage.lv.bytesConverted _isByteSize _order 250 com.apple.corestorage.lv.conversionState _order 240 com.apple.corestorage.lv.encrypted _order 220 com.apple.corestorage.lv.encryptionType _order 225 com.apple.corestorage.lv.locked _order 230 com.apple.corestorage.lv.revertible _order 210 com.apple.corestorage.lv.uuid _order 290 com.apple.corestorage.lvg _order 400 com.apple.corestorage.lvg.freeSpace _isByteSize _order 430 com.apple.corestorage.lvg.name _order 410 com.apple.corestorage.lvg.size _isByteSize _order 420 com.apple.corestorage.lvg.uuid _order 440 com.apple.corestorage.pv _order 500 com.apple.corestorage.pv.size _isByteSize _order 520 com.apple.corestorage.pv.status _order 565 com.apple.corestorage.pv.uuid _order 590 device_name _order 505 file_system _isColumn _order 140 free_space_in_bytes _isByteSize _isColumn _order 110 ignore_ownership _order 160 is_internal_disk _order 550 media_name _order 510 medium_type _order 530 mount_point _isColumn _order 130 optical_media_type _order 535 partition_map_type _order 560 protocol _order 540 size_in_bytes _isByteSize YES _isColumn _order 120 smart_status _order 570 volume_uuid _order 190 volumes _detailLevel 0 writable _order 150 _timeStamp 2016-07-08T19:45:57Z _versionInfo com.apple.SystemProfiler.SPStorageReporter 900 STORAGE_OUTPUT POWER = <<~POWER_OUTPUT.freeze _SPCommandLineArguments /usr/sbin/system_profiler -nospawn -xml SPPowerDataType -detailLevel full _SPCompletionInterval 0.061106979846954346 _SPResponseTime 0.16731500625610352 _dataType SPPowerDataType _detailLevel 0 _items _name spbattery_information sppower_battery_charge_info sppower_battery_current_capacity 5841 sppower_battery_fully_charged TRUE sppower_battery_is_charging FALSE sppower_battery_max_capacity 5841 sppower_battery_health_info sppower_battery_cycle_count 201 sppower_battery_health Good sppower_battery_installed TRUE sppower_battery_model_info PCB Lot Code 0000 Pack Lot Code 0000 sppower_battery_cell_revision 0389 sppower_battery_device_name bq20z451 sppower_battery_firmware_version 0702 sppower_battery_hardware_revision 000a sppower_battery_manufacturer SMP sppower_battery_serial_number D123456789ABCDEFG sppower_current_amperage 0 sppower_current_voltage 12788 AC Power AutoPowerOff Delay 14400 AutoPowerOff Enabled 1 Current Power Source TRUE DarkWakeBackgroundTasks Disk Sleep Timer 10 Display Sleep Timer 10 Display Sleep Uses Dim Yes Hibernate Mode 3 PrioritizeNetworkReachabilityOverSleep 0 Standby Delay 10800 Standby Enabled 1 System Sleep Timer 1 Wake On AC Change No Wake On Clamshell Open Yes Wake On LAN Yes Battery Power AutoPowerOff Delay 14400 AutoPowerOff Enabled 1 DarkWakeBackgroundTasks Disk Sleep Timer 10 Display Sleep Timer 2 Display Sleep Uses Dim Yes Hibernate Mode 3 ReduceBrightness Yes Standby Delay 10800 Standby Enabled 1 System Sleep Timer 1 Wake On AC Change No Wake On Clamshell Open Yes _name sppower_information _name sppower_hwconfig_information sppower_ups_installed FALSE _name sppower_ac_charger_information sppower_ac_charger_ID 0x0100 sppower_ac_charger_family 0x0085 sppower_ac_charger_revision 0x0000 sppower_ac_charger_serial_number 0x00a1dab7 sppower_ac_charger_watts 85 sppower_battery_charger_connected TRUE sppower_battery_is_charging FALSE _parentDataType SPHardwareDataType _properties Automatic Restart On Power Loss _isColumn NO _order 107 Disk Sleep Timer _isColumn NO _order 102 Display Sleep Timer _isColumn NO _order 103 Dynamic Power Step _isColumn NO _order 104 PCB Lot Code _isColumn NO _order 404 Pack Lot Code _isColumn NO _order 403 Reduce Processor Speed _isColumn NO _order 105 Sleep On Power Button _isColumn NO _order 106 System Sleep Timer _isColumn NO _order 101 Wake On AC Change _isColumn NO _order 108 Wake On Clamshell Open _isColumn NO _order 109 Wake On LAN _isColumn NO _order 110 Wake On Modem Ring _isColumn NO _order 111 spbattery_information _isColumn NO _order 200 sppower_ac_charger_ID _isColumn NO _order 310 sppower_ac_charger_family _isColumn NO _order 313 sppower_ac_charger_firmware_version _isColumn NO _order 318 sppower_ac_charger_hardware_version _isColumn NO _order 317 sppower_ac_charger_information _isColumn NO _order 300 sppower_ac_charger_manufacturer _isColumn NO _order 316 sppower_ac_charger_name _isColumn NO _order 315 sppower_ac_charger_revision _isColumn NO _order 312 sppower_ac_charger_serial_number _isColumn NO _order 314 sppower_ac_charger_watts _isColumn NO _order 311 sppower_battery_cannot_charge _isColumn NO _order 401 sppower_battery_cell_revision _isColumn NO _order 407 sppower_battery_charge_info _isColumn NO _order 2 sppower_battery_charger_connected _isColumn NO _order 302 sppower_battery_depleted _isColumn NO _order 203 sppower_battery_device_name _isColumn NO _order 402 sppower_battery_firmware_version _isColumn NO _order 405 sppower_battery_hardware_revision _isColumn NO _order 406 sppower_battery_health_info _isColumn NO _order 3 sppower_battery_installed _isColumn NO _order 201 sppower_battery_manufacturer _isColumn NO _order 401 sppower_battery_model_info _isColumn NO _order 1 sppower_battery_serial_number _isColumn NO _order 400 sppower_clamshell_closed _isColumn NO _order 401 sppower_current_amperage _isColumn NO _order 206 sppower_current_voltage _isColumn NO _order 207 sppower_events_info _isColumn NO _order 500 sppower_hwconfig_information _isColumn NO _order 400 sppower_information _isColumn NO _order 100 sppower_repeating_events_info _isColumn NO _order 520 sppower_scheduled_events_info _isColumn NO _order 510 sppower_watts _isColumn NO _order 301 volumes _detailLevel 0 _timeStamp 2016-07-08T19:46:23Z _versionInfo com.apple.SystemProfiler.SPPowerReporter 150 POWER_OUTPUT end ohai-16.0.7/spec/unit/plugins/darwin/hostname_spec.rb000066400000000000000000000030731362624620500225710ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:darwin) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return(mock_shell_out(0, "katie", "")) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie.local", "")) allow(@plugin).to receive(:resolve_fqdn).and_return("katie.bethell") end it_should_check_from("darwin::hostname", "hostname", "hostname -s", "katie") it_should_check_from("linux::hostname", "machinename", "hostname", "katie.local") it "uses #resolve_fqdn to find the fqdn" do @plugin.run expect(@plugin[:fqdn]).to eq("katie.bethell") end it "sets the domain to everything after the first dot of the fqdn" do @plugin.run expect(@plugin[:domain]).to eq("bethell") end end ohai-16.0.7/spec/unit/plugins/darwin/kernel_spec.rb000066400000000000000000000057101362624620500222330ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin kernel plugin" do before do @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:darwin) allow(@plugin).to receive(:init_kernel).and_return({}) end it "populates kernel[:modules] from `kextstat -k -l`" do allow(@plugin).to receive(:shell_out).with("sysctl -n hw.optional.x86_64").and_return(mock_shell_out(0, "0", "")) allow(@plugin).to receive(:shell_out).with("kextstat -k -l").and_return(mock_shell_out(0, < 9 22 0xffffff7f807f3000 0x9000 0x9000 com.apple.iokit.IOACPIFamily (1.4) <7 6 4 3> 10 30 0xffffff7f80875000 0x29000 0x29000 com.apple.iokit.IOPCIFamily (2.8) <7 6 5 4 3> EOF modules = { "com.apple.kec.corecrypto" => { "version" => "1.0", "size" => 266240, "index" => "8", "refcount" => "0" }, "com.apple.iokit.IOACPIFamily" => { "version" => "1.4", "size" => 36864, "index" => "9", "refcount" => "22" }, "com.apple.iokit.IOPCIFamily" => { "version" => "2.8", "size" => 167936, "index" => "10", "refcount" => "30" } } @plugin.run expect(@plugin[:kernel][:modules]).to eql(modules) end it "does not set kernel_machine to x86_64" do allow(@plugin).to receive(:shell_out).with("sysctl -n hw.optional.x86_64").and_return(mock_shell_out(0, "0", "")) allow(@plugin).to receive(:shell_out).with("kextstat -k -l").and_return(mock_shell_out(0, "", "")) @plugin.run expect(@plugin[:kernel][:machine]).not_to eq("x86_64") end it "sets kernel_machine to x86_64" do allow(@plugin).to receive(:shell_out).with("sysctl -n hw.optional.x86_64").and_return(mock_shell_out(0, "1", "")) allow(@plugin).to receive(:shell_out).with("kextstat -k -l").and_return(mock_shell_out(0, "", "")) @plugin.run expect(@plugin[:kernel][:machine]).to eq("x86_64") end it "sets the kernel_os to the kernel_name value" do allow(@plugin).to receive(:shell_out).with("sysctl -n hw.optional.x86_64").and_return(mock_shell_out(0, "1", "")) allow(@plugin).to receive(:shell_out).with("kextstat -k -l").and_return(mock_shell_out(0, "", "")) @plugin.run expect(@plugin[:kernel][:os]).to eq(@plugin[:kernel][:name]) end end ohai-16.0.7/spec/unit/plugins/darwin/memory_spec.rb000066400000000000000000000044641362624620500222700ustar00rootroot00000000000000# # Author:: Patrick Collins () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin Memory Plugin" do before do darwin_memsize = <<~DARWIN_MEMSIZE 17179869184 DARWIN_MEMSIZE darwin_vm_stat = <<~DARWIN_VM_STAT Mach Virtual Memory Statistics: (page size of 4096 bytes) Pages free: 2155305. Pages active: 924164. Pages inactive: 189127. Pages speculative: 531321. Pages wired down: 391749. "Translation faults": 14107520. Pages copy-on-write: 810071. Pages zero filled: 6981505. Pages reactivated: 1397. Pageins: 630064. Pageouts: 0. Object cache: 12 hits of 139872 lookups (0% hit rate) DARWIN_VM_STAT @plugin = get_plugin("darwin/memory") allow(@plugin).to receive(:collect_os).and_return(:darwin) allow(@plugin).to receive(:shell_out).with("sysctl -n hw.memsize").and_return(mock_shell_out(0, darwin_memsize, "")) allow(@plugin).to receive(:shell_out).with("vm_stat").and_return(mock_shell_out(0, darwin_vm_stat, "")) @plugin.run end it "sets memory[:total] to 16384MB" do expect(@plugin[:memory][:total]).to eq("16384MB") end it "sets memory[:active] to 5140MB" do expect(@plugin[:memory][:active]).to eq("5140MB") end it "sets memory[:inactive] to 738MB" do expect(@plugin[:memory][:inactive]).to eq("738MB") end it "sets memory[:free] to 10504MB" do expect(@plugin[:memory][:free]).to eq("10504MB") end end ohai-16.0.7/spec/unit/plugins/darwin/network_spec.rb000066400000000000000000001436511362624620500224530ustar00rootroot00000000000000# # Author:: Alan Harper # Copyright:: Copyright (c) 2012-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin Network Plugin" do before do @darwin_ifconfig = <<~DARWIN_IFCONFIG lo0: flags=8049 mtu 16384 options=3 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fd54:185f:37df:cad2:ba8d:12ff:fe3a:32de prefixlen 128 gif0: flags=8010 mtu 1280 stf0: flags=0<> mtu 1280 en1: flags=8863 mtu 1500 ether b8:8d:12:3a:32:de inet6 fe80::ba8d:12ff:fe3a:32de%en1 prefixlen 64 scopeid 0x4 inet 10.20.10.144 netmask 0xffffff00 broadcast 10.20.10.255 inet6 2001:44b8:4186:1100:ba8d:12ff:fe3a:32de prefixlen 64 autoconf inet6 2001:44b8:4186:1100:7dba:7a60:97a:e14a prefixlen 64 autoconf temporary media: autoselect status: active p2p0: flags=8843 mtu 2304 ether 0a:8d:12:3a:32:de media: autoselect status: inactive en0: flags=8863 mtu 1500 options=2b ether 3c:07:54:4e:0e:35 media: autoselect (none) status: inactive fw0: flags=8822 mtu 4078 lladdr a4:b1:97:ff:fe:b9:3a:d4 media: autoselect status: inactive utun0: flags=8051 mtu 1380 inet6 fe80::ba8d:12ff:fe3a:32de%utun0 prefixlen 64 scopeid 0x8 inet6 fd00:6587:52d7:c87:ba8d:12ff:fe3a:32de prefixlen 64 DARWIN_IFCONFIG @darwin_arp = <<~DARWIN_ARP ? (10.20.10.1) at 0:4:ed:de:41:bf on en1 ifscope [ethernet] ? (10.20.10.2) at 0:1e:c9:55:7e:ee on en1 ifscope [ethernet] ? (10.20.10.6) at 34:15:9e:18:a1:20 on en1 ifscope [ethernet] ? (10.20.10.57) at cc:8:e0:e0:8a:2 on en1 ifscope [ethernet] ? (10.20.10.61) at 28:37:37:12:5:77 on en1 ifscope [ethernet] ? (10.20.10.73) at e0:f8:47:8:86:2 on en1 ifscope [ethernet] ? (10.20.10.130) at 68:a8:6d:da:2b:24 on en1 ifscope [ethernet] ? (10.20.10.138) at 8:0:37:8c:d2:23 on en1 ifscope [ethernet] ? (10.20.10.141) at b8:8d:12:28:c5:90 on en1 ifscope [ethernet] ? (10.20.10.166) at 0:1b:63:a0:1:3a on en1 ifscope [ethernet] ? (10.20.10.174) at 98:d6:bb:bd:37:ad on en1 ifscope [ethernet] ? (10.20.10.178) at 24:ab:81:2d:a3:c5 on en1 ifscope [ethernet] ? (10.20.10.181) at 78:a3:e4:e4:16:32 on en1 ifscope [ethernet] ? (10.20.10.185) at 0:26:8:9a:e8:a3 on en1 ifscope [ethernet] ? (10.20.10.200) at b8:8d:12:55:7f:7f on en1 ifscope [ethernet] ? (10.20.10.255) at ff:ff:ff:ff:ff:ff on en1 ifscope [ethernet] DARWIN_ARP @darwin_route = <<~DARWIN_ROUTE route to: default destination: default mask: default gateway: 10.20.10.1 interface: en1 flags: recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire 0 0 0 0 0 0 1500 0 DARWIN_ROUTE @darwin_netstat = <<~DARWIN_NETSTAT Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop lo0 16384 174982 0 25774844 174982 0 25774844 0 lo0 16384 fe80::1%lo0 fe80:1::1 174982 - 25774844 174982 - 25774844 - - lo0 16384 127 127.0.0.1 174982 - 25774844 174982 - 25774844 - - lo0 16384 ::1/128 ::1 174982 - 25774844 174982 - 25774844 - - lo0 16384 fd54:185f:3 fd54:185f:37df:ca 174982 - 25774844 174982 - 25774844 - - gif0* 1280 0 0 0 0 0 0 0 stf0* 1280 0 0 0 0 0 0 0 en1 1500 b8:8d:12:3a:32:de 5921903 0 2530556736 14314573 0 18228234970 0 en1 1500 fe80::ba8d: fe80:4::ba8d:12ff 5921903 - 2530556736 14314573 - 18228234970 - - en1 1500 10.20.10/24 10.20.10.144 5921903 - 2530556736 14314573 - 18228234970 - - en1 1500 2001:44b8:4 2001:44b8:4186:11 5921903 - 2530556736 14314573 - 18228234970 - - en1 1500 2001:44b8:4 2001:44b8:4186:11 5921903 - 2530556736 14314573 - 18228234970 - - p2p0 2304 0a:8d:12:3a:32:de 0 0 0 0 0 0 0 en0 1500 3c:07:54:4e:0e:35 0 0 0 0 0 2394 0 fw0* 4078 a4:b1:97:ff:fe:b9:3a:d4 0 0 0 0 0 1038 0 utun0 1380 5 0 324 13 0 740 0 utun0 1380 fe80::ba8d: fe80:8::ba8d:12ff 5 - 324 13 - 740 - - utun0 1380 fd00:6587:5 fd00:6587:52d7:c8 5 - 324 13 - 740 - - DARWIN_NETSTAT @darwin_sysctl = <<~DARWIN_SYSCTL net.local.stream.sendspace: 8192 net.local.stream.recvspace: 8192 net.local.stream.tracemdns: 0 net.local.dgram.maxdgram: 2048 net.local.dgram.recvspace: 4096 net.local.inflight: 0 net.inet.ip.portrange.lowfirst: 1023 net.inet.ip.portrange.lowlast: 600 net.inet.ip.portrange.first: 49152 net.inet.ip.portrange.last: 65535 net.inet.ip.portrange.hifirst: 49152 net.inet.ip.portrange.hilast: 65535 net.inet.ip.forwarding: 1 net.inet.ip.redirect: 1 net.inet.ip.ttl: 64 net.inet.ip.rtexpire: 12 net.inet.ip.rtminexpire: 10 net.inet.ip.rtmaxcache: 128 net.inet.ip.sourceroute: 0 net.inet.ip.intr_queue_maxlen: 50 net.inet.ip.intr_queue_drops: 0 net.inet.ip.accept_sourceroute: 0 net.inet.ip.keepfaith: 0 net.inet.ip.gifttl: 30 net.inet.ip.subnets_are_local: 0 net.inet.ip.mcast.maxgrpsrc: 512 net.inet.ip.mcast.maxsocksrc: 128 net.inet.ip.mcast.loop: 1 net.inet.ip.check_route_selfref: 1 net.inet.ip.use_route_genid: 1 net.inet.ip.dummynet.hash_size: 64 net.inet.ip.dummynet.curr_time: 0 net.inet.ip.dummynet.ready_heap: 0 net.inet.ip.dummynet.extract_heap: 0 net.inet.ip.dummynet.searches: 0 net.inet.ip.dummynet.search_steps: 0 net.inet.ip.dummynet.expire: 1 net.inet.ip.dummynet.max_chain_len: 16 net.inet.ip.dummynet.red_lookup_depth: 256 net.inet.ip.dummynet.red_avg_pkt_size: 512 net.inet.ip.dummynet.red_max_pkt_size: 1500 net.inet.ip.dummynet.debug: 0 net.inet.ip.fw.enable: 1 net.inet.ip.fw.autoinc_step: 100 net.inet.ip.fw.one_pass: 0 net.inet.ip.fw.debug: 0 net.inet.ip.fw.verbose: 0 net.inet.ip.fw.verbose_limit: 0 net.inet.ip.fw.dyn_buckets: 256 net.inet.ip.fw.curr_dyn_buckets: 256 net.inet.ip.fw.dyn_count: 0 net.inet.ip.fw.dyn_max: 4096 net.inet.ip.fw.static_count: 2 net.inet.ip.fw.dyn_ack_lifetime: 300 net.inet.ip.fw.dyn_syn_lifetime: 20 net.inet.ip.fw.dyn_fin_lifetime: 1 net.inet.ip.fw.dyn_rst_lifetime: 1 net.inet.ip.fw.dyn_udp_lifetime: 10 net.inet.ip.fw.dyn_short_lifetime: 5 net.inet.ip.fw.dyn_keepalive: 1 net.inet.ip.maxfragpackets: 1536 net.inet.ip.maxfragsperpacket: 128 net.inet.ip.maxfrags: 3072 net.inet.ip.scopedroute: 1 net.inet.ip.check_interface: 0 net.inet.ip.linklocal.in.allowbadttl: 1 net.inet.ip.random_id: 1 net.inet.ip.maxchainsent: 0 net.inet.ip.select_srcif_debug: 0 net.inet.icmp.maskrepl: 0 net.inet.icmp.icmplim: 250 net.inet.icmp.timestamp: 0 net.inet.icmp.drop_redirect: 0 net.inet.icmp.log_redirect: 0 net.inet.icmp.bmcastecho: 1 net.inet.igmp.recvifkludge: 1 net.inet.igmp.sendra: 1 net.inet.igmp.sendlocal: 1 net.inet.igmp.v1enable: 1 net.inet.igmp.v2enable: 1 net.inet.igmp.legacysupp: 0 net.inet.igmp.default_version: 3 net.inet.igmp.gsrdelay: 10 net.inet.igmp.debug: 0 net.inet.tcp.rfc1323: 1 net.inet.tcp.rfc1644: 0 net.inet.tcp.mssdflt: 512 net.inet.tcp.keepidle: 7200000 net.inet.tcp.keepintvl: 75000 net.inet.tcp.sendspace: 65536 net.inet.tcp.recvspace: 65536 net.inet.tcp.keepinit: 75000 net.inet.tcp.v6mssdflt: 1024 net.inet.tcp.log_in_vain: 0 net.inet.tcp.blackhole: 0 net.inet.tcp.delayed_ack: 3 net.inet.tcp.tcp_lq_overflow: 1 net.inet.tcp.recvbg: 0 net.inet.tcp.drop_synfin: 1 net.inet.tcp.reass.maxsegments: 3072 net.inet.tcp.reass.cursegments: 0 net.inet.tcp.reass.overflows: 0 net.inet.tcp.slowlink_wsize: 8192 net.inet.tcp.maxseg_unacked: 8 net.inet.tcp.rfc3465: 1 net.inet.tcp.rfc3465_lim2: 1 net.inet.tcp.rtt_samples_per_slot: 20 net.inet.tcp.recv_allowed_iaj: 5 net.inet.tcp.acc_iaj_high_thresh: 100 net.inet.tcp.rexmt_thresh: 2 net.inet.tcp.path_mtu_discovery: 1 net.inet.tcp.slowstart_flightsize: 1 net.inet.tcp.local_slowstart_flightsize: 8 net.inet.tcp.tso: 1 net.inet.tcp.ecn_initiate_out: 0 net.inet.tcp.ecn_negotiate_in: 0 net.inet.tcp.packetchain: 50 net.inet.tcp.socket_unlocked_on_output: 1 net.inet.tcp.rfc3390: 1 net.inet.tcp.min_iaj_win: 4 net.inet.tcp.acc_iaj_react_limit: 200 net.inet.tcp.sack: 1 net.inet.tcp.sack_maxholes: 128 net.inet.tcp.sack_globalmaxholes: 65536 net.inet.tcp.sack_globalholes: 0 net.inet.tcp.minmss: 216 net.inet.tcp.minmssoverload: 0 net.inet.tcp.do_tcpdrain: 0 net.inet.tcp.pcbcount: 86 net.inet.tcp.icmp_may_rst: 1 net.inet.tcp.strict_rfc1948: 0 net.inet.tcp.isn_reseed_interval: 0 net.inet.tcp.background_io_enabled: 1 net.inet.tcp.rtt_min: 100 net.inet.tcp.rexmt_slop: 200 net.inet.tcp.randomize_ports: 0 net.inet.tcp.newreno_sockets: 81 net.inet.tcp.background_sockets: -1 net.inet.tcp.tcbhashsize: 4096 net.inet.tcp.background_io_trigger: 5 net.inet.tcp.msl: 15000 net.inet.tcp.max_persist_timeout: 0 net.inet.tcp.always_keepalive: 0 net.inet.tcp.timer_fastmode_idlemax: 20 net.inet.tcp.broken_peer_syn_rxmit_thres: 7 net.inet.tcp.tcp_timer_advanced: 5 net.inet.tcp.tcp_resched_timerlist: 12209 net.inet.tcp.pmtud_blackhole_detection: 1 net.inet.tcp.pmtud_blackhole_mss: 1200 net.inet.tcp.timer_fastquantum: 100 net.inet.tcp.timer_slowquantum: 500 net.inet.tcp.win_scale_factor: 3 net.inet.tcp.in_sw_cksum: 5658081 net.inet.tcp.in_sw_cksum_bytes: 2198681467 net.inet.tcp.out_sw_cksum: 14166053 net.inet.tcp.out_sw_cksum_bytes: 17732561863 net.inet.tcp.sockthreshold: 64 net.inet.tcp.bg_target_qdelay: 100 net.inet.tcp.bg_allowed_increase: 2 net.inet.tcp.bg_tether_shift: 1 net.inet.tcp.bg_ss_fltsz: 2 net.inet.udp.checksum: 1 net.inet.udp.maxdgram: 9216 net.inet.udp.recvspace: 42080 net.inet.udp.in_sw_cksum: 19639 net.inet.udp.in_sw_cksum_bytes: 3928092 net.inet.udp.out_sw_cksum: 17436 net.inet.udp.out_sw_cksum_bytes: 2495444 net.inet.udp.log_in_vain: 0 net.inet.udp.blackhole: 0 net.inet.udp.pcbcount: 72 net.inet.udp.randomize_ports: 1 net.inet.ipsec.def_policy: 1 net.inet.ipsec.esp_trans_deflev: 1 net.inet.ipsec.esp_net_deflev: 1 net.inet.ipsec.ah_trans_deflev: 1 net.inet.ipsec.ah_net_deflev: 1 net.inet.ipsec.ah_cleartos: 1 net.inet.ipsec.ah_offsetmask: 0 net.inet.ipsec.dfbit: 0 net.inet.ipsec.ecn: 0 net.inet.ipsec.debug: 0 net.inet.ipsec.esp_randpad: -1 net.inet.ipsec.bypass: 0 net.inet.ipsec.esp_port: 4500 net.inet.raw.maxdgram: 8192 net.inet.raw.recvspace: 8192 net.link.generic.system.ifcount: 10 net.link.generic.system.dlil_verbose: 0 net.link.generic.system.multi_threaded_input: 1 net.link.generic.system.dlil_input_sanity_check: 0 net.link.ether.inet.prune_intvl: 300 net.link.ether.inet.max_age: 1200 net.link.ether.inet.host_down_time: 20 net.link.ether.inet.apple_hwcksum_tx: 1 net.link.ether.inet.apple_hwcksum_rx: 1 net.link.ether.inet.arp_llreach_base: 30 net.link.ether.inet.maxtries: 5 net.link.ether.inet.useloopback: 1 net.link.ether.inet.proxyall: 0 net.link.ether.inet.sendllconflict: 0 net.link.ether.inet.log_arp_warnings: 0 net.link.ether.inet.keep_announcements: 1 net.link.ether.inet.send_conflicting_probes: 1 net.link.bridge.log_stp: 0 net.link.bridge.debug: 0 net.key.debug: 0 net.key.spi_trycnt: 1000 net.key.spi_minval: 256 net.key.spi_maxval: 268435455 net.key.int_random: 60 net.key.larval_lifetime: 30 net.key.blockacq_count: 10 net.key.blockacq_lifetime: 20 net.key.esp_keymin: 256 net.key.esp_auth: 0 net.key.ah_keymin: 128 net.key.prefered_oldsa: 0 net.key.natt_keepalive_interval: 20 net.inet6.ip6.forwarding: 0 net.inet6.ip6.redirect: 1 net.inet6.ip6.hlim: 64 net.inet6.ip6.maxfragpackets: 1536 net.inet6.ip6.accept_rtadv: 0 net.inet6.ip6.keepfaith: 0 net.inet6.ip6.log_interval: 5 net.inet6.ip6.hdrnestlimit: 15 net.inet6.ip6.dad_count: 1 net.inet6.ip6.auto_flowlabel: 1 net.inet6.ip6.defmcasthlim: 1 net.inet6.ip6.gifhlim: 0 net.inet6.ip6.kame_version: 2009/apple-darwin net.inet6.ip6.use_deprecated: 1 net.inet6.ip6.rr_prune: 5 net.inet6.ip6.v6only: 0 net.inet6.ip6.rtexpire: 3600 net.inet6.ip6.rtminexpire: 10 net.inet6.ip6.rtmaxcache: 128 net.inet6.ip6.use_tempaddr: 1 net.inet6.ip6.temppltime: 86400 net.inet6.ip6.tempvltime: 604800 net.inet6.ip6.auto_linklocal: 1 net.inet6.ip6.prefer_tempaddr: 1 net.inet6.ip6.use_defaultzone: 0 net.inet6.ip6.maxfrags: 12288 net.inet6.ip6.mcast_pmtu: 0 net.inet6.ip6.neighborgcthresh: 1024 net.inet6.ip6.maxifprefixes: 16 net.inet6.ip6.maxifdefrouters: 16 net.inet6.ip6.maxdynroutes: 1024 net.inet6.ip6.fw.enable: 1 net.inet6.ip6.fw.debug: 0 net.inet6.ip6.fw.verbose: 0 net.inet6.ip6.fw.verbose_limit: 0 net.inet6.ip6.scopedroute: 1 net.inet6.ip6.select_srcif_debug: 0 net.inet6.ip6.mcast.maxgrpsrc: 512 net.inet6.ip6.mcast.maxsocksrc: 128 net.inet6.ip6.mcast.loop: 1 net.inet6.ip6.only_allow_rfc4193_prefixes: 0 net.inet6.ipsec6.def_policy: 1 net.inet6.ipsec6.esp_trans_deflev: 1 net.inet6.ipsec6.esp_net_deflev: 1 net.inet6.ipsec6.ah_trans_deflev: 1 net.inet6.ipsec6.ah_net_deflev: 1 net.inet6.ipsec6.ecn: 0 net.inet6.ipsec6.debug: 0 net.inet6.ipsec6.esp_randpad: -1 net.inet6.icmp6.rediraccept: 1 net.inet6.icmp6.redirtimeout: 600 net.inet6.icmp6.nd6_prune: 1 net.inet6.icmp6.nd6_delay: 5 net.inet6.icmp6.nd6_umaxtries: 3 net.inet6.icmp6.nd6_mmaxtries: 3 net.inet6.icmp6.nd6_useloopback: 1 net.inet6.icmp6.nodeinfo: 3 net.inet6.icmp6.errppslimit: 500 net.inet6.icmp6.nd6_maxnudhint: 0 net.inet6.icmp6.nd6_debug: 0 net.inet6.icmp6.nd6_accept_6to4: 1 net.inet6.icmp6.nd6_onlink_ns_rfc4861: 0 net.inet6.icmp6.nd6_llreach_base: 30 net.inet6.mld.gsrdelay: 10 net.inet6.mld.v1enable: 1 net.inet6.mld.use_allow: 1 net.inet6.mld.debug: 0 net.idle.route.expire_timeout: 30 net.idle.route.drain_interval: 10 net.statistics: 1 net.alf.loglevel: 55 net.alf.perm: 0 net.alf.defaultaction: 1 net.alf.mqcount: 0 net.smb.fs.version: 107000 net.smb.fs.loglevel: 0 net.smb.fs.kern_ntlmssp: 0 net.smb.fs.kern_deprecatePreXPServers: 1 net.smb.fs.kern_deadtimer: 60 net.smb.fs.kern_hard_deadtimer: 600 net.smb.fs.kern_soft_deadtimer: 30 net.smb.fs.tcpsndbuf: 261120 net.smb.fs.tcprcvbuf: 261120 DARWIN_SYSCTL @plugin = get_plugin("darwin/network") allow(@plugin).to receive(:collect_os).and_return(:darwin) # @stdin_ifconfig = StringIO.new # @stdin_arp = StringIO.new # @stdin_sysctl = StringIO.new # @stdin_netstat = StringIO.new # @ifconfig_lines = darwin_ifconfig.split("\n") # @arp_lines = darwin_arp.split("\n") # @netstat_lines = darwin_netstat.split("\n") # @sysctl_lines = darwin_sysctl.split("\n") allow(@plugin).to receive(:shell_out).with("route -n get default").and_return(mock_shell_out(0, @darwin_route, "")) allow(@plugin).to receive(:shell_out).with("netstat -i -d -l -b -n") end describe "gathering IP layer address info" do before do allow(@plugin).to receive(:shell_out).with("arp -an").and_return(mock_shell_out(0, @darwin_arp, "")) allow(@plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, @darwin_ifconfig, "")) allow(@plugin).to receive(:shell_out).with("netstat -i -d -l -b -n").and_return(mock_shell_out(0, @darwin_netstat, "")) allow(@plugin).to receive(:shell_out).with("sysctl net").and_return(mock_shell_out(0, @darwin_sysctl, "")) @plugin.run end it "completes the run" do expect(@plugin["network"]).not_to be_nil end it "detects the interfaces" do expect(@plugin["network"]["interfaces"].keys.sort).to eq(%w{en0 en1 fw0 gif0 lo0 p2p0 stf0 utun0}) end it "detects the ipv4 addresses of the ethernet interface" do expect(@plugin["network"]["interfaces"]["en1"]["addresses"].keys).to include("10.20.10.144") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["10.20.10.144"]["netmask"]).to eq("255.255.255.0") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["10.20.10.144"]["broadcast"]).to eq("10.20.10.255") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["10.20.10.144"]["family"]).to eq("inet") end it "detects the ipv6 addresses of the ethernet interface" do expect(@plugin["network"]["interfaces"]["en1"]["addresses"].keys).to include("fe80::ba8d:12ff:fe3a:32de") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["fe80::ba8d:12ff:fe3a:32de"]["scope"]).to eq("Link") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["fe80::ba8d:12ff:fe3a:32de"]["prefixlen"]).to eq("64") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["fe80::ba8d:12ff:fe3a:32de"]["family"]).to eq("inet6") expect(@plugin["network"]["interfaces"]["en1"]["addresses"].keys).to include("2001:44b8:4186:1100:ba8d:12ff:fe3a:32de") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["2001:44b8:4186:1100:ba8d:12ff:fe3a:32de"]["scope"]).to eq("Global") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["2001:44b8:4186:1100:ba8d:12ff:fe3a:32de"]["prefixlen"]).to eq("64") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["2001:44b8:4186:1100:ba8d:12ff:fe3a:32de"]["family"]).to eq("inet6") end it "detects the mac addresses of the ethernet interface" do expect(@plugin["network"]["interfaces"]["en1"]["addresses"].keys).to include("b8:8d:12:3a:32:de") expect(@plugin["network"]["interfaces"]["en1"]["addresses"]["b8:8d:12:3a:32:de"]["family"]).to eq("lladdr") end it "detects the encapsulation type of the ethernet interface" do expect(@plugin["network"]["interfaces"]["en1"]["encapsulation"]).to eq("Ethernet") end it "detects the flags of the ethernet interface" do expect(@plugin["network"]["interfaces"]["en1"]["flags"].sort).to eq(%w{BROADCAST MULTICAST RUNNING SIMPLEX SMART UP}) end it "detects the mtu of the ethernet interface" do expect(@plugin["network"]["interfaces"]["en1"]["mtu"]).to eq("1500") end it "detects the ipv4 addresses of the loopback interface" do expect(@plugin["network"]["interfaces"]["lo0"]["addresses"].keys).to include("127.0.0.1") expect(@plugin["network"]["interfaces"]["lo0"]["addresses"]["127.0.0.1"]["netmask"]).to eq("255.0.0.0") expect(@plugin["network"]["interfaces"]["lo0"]["addresses"]["127.0.0.1"]["family"]).to eq("inet") end it "detects the ipv6 addresses of the loopback interface" do expect(@plugin["network"]["interfaces"]["lo0"]["addresses"].keys).to include("::1") expect(@plugin["network"]["interfaces"]["lo0"]["addresses"]["::1"]["scope"]).to eq("Node") expect(@plugin["network"]["interfaces"]["lo0"]["addresses"]["::1"]["prefixlen"]).to eq("128") expect(@plugin["network"]["interfaces"]["lo0"]["addresses"]["::1"]["family"]).to eq("inet6") end it "detects the encapsulation type of the loopback interface" do expect(@plugin["network"]["interfaces"]["lo0"]["encapsulation"]).to eq("Loopback") end it "detects the flags of the ethernet interface" do expect(@plugin["network"]["interfaces"]["lo0"]["flags"].sort).to eq(%w{LOOPBACK MULTICAST RUNNING UP}) end it "detects the mtu of the loopback interface" do expect(@plugin["network"]["interfaces"]["lo0"]["mtu"]).to eq("16384") end it "detects the arp entries" do expect(@plugin["network"]["interfaces"]["en1"]["arp"]["10.20.10.1"]).to eq("0:4:ed:de:41:bf") end it "detects the ethernet counters" do expect(@plugin["counters"]["network"]["interfaces"]["en1"]["tx"]["bytes"]).to eq("18228234970") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["tx"]["packets"]).to eq("14314573") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["tx"]["collisions"]).to eq("0") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["tx"]["errors"]).to eq("0") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["tx"]["carrier"]).to eq(0) expect(@plugin["counters"]["network"]["interfaces"]["en1"]["tx"]["drop"]).to eq(0) expect(@plugin["counters"]["network"]["interfaces"]["en1"]["rx"]["bytes"]).to eq("2530556736") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["rx"]["packets"]).to eq("5921903") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["rx"]["errors"]).to eq("0") expect(@plugin["counters"]["network"]["interfaces"]["en1"]["rx"]["overrun"]).to eq(0) expect(@plugin["counters"]["network"]["interfaces"]["en1"]["rx"]["drop"]).to eq(0) end it "detects the loopback counters" do expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["tx"]["bytes"]).to eq("25774844") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["tx"]["packets"]).to eq("174982") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["tx"]["collisions"]).to eq("0") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["tx"]["errors"]).to eq("0") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["tx"]["carrier"]).to eq(0) expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["tx"]["drop"]).to eq(0) expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["rx"]["bytes"]).to eq("25774844") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["rx"]["packets"]).to eq("174982") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["rx"]["errors"]).to eq("0") expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["rx"]["overrun"]).to eq(0) expect(@plugin["counters"]["network"]["interfaces"]["lo0"]["rx"]["drop"]).to eq(0) end it "finds the default interface by asking which iface has the default route" do expect(@plugin["network"][:default_interface]).to eq("en1") end it "finds the default interface by asking which iface has the default route" do expect(@plugin["network"][:default_gateway]).to eq("10.20.10.1") end it "detects network settings" do expect(@plugin["network"]["settings"]["net.local.stream.sendspace"]).to eq("8192") expect(@plugin["network"]["settings"]["net.local.stream.recvspace"]).to eq("8192") expect(@plugin["network"]["settings"]["net.local.stream.tracemdns"]).to eq("0") expect(@plugin["network"]["settings"]["net.local.dgram.maxdgram"]).to eq("2048") expect(@plugin["network"]["settings"]["net.local.dgram.recvspace"]).to eq("4096") expect(@plugin["network"]["settings"]["net.local.inflight"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.portrange.lowfirst"]).to eq("1023") expect(@plugin["network"]["settings"]["net.inet.ip.portrange.lowlast"]).to eq("600") expect(@plugin["network"]["settings"]["net.inet.ip.portrange.first"]).to eq("49152") expect(@plugin["network"]["settings"]["net.inet.ip.portrange.last"]).to eq("65535") expect(@plugin["network"]["settings"]["net.inet.ip.portrange.hifirst"]).to eq("49152") expect(@plugin["network"]["settings"]["net.inet.ip.portrange.hilast"]).to eq("65535") expect(@plugin["network"]["settings"]["net.inet.ip.forwarding"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.redirect"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.ttl"]).to eq("64") expect(@plugin["network"]["settings"]["net.inet.ip.rtexpire"]).to eq("12") expect(@plugin["network"]["settings"]["net.inet.ip.rtminexpire"]).to eq("10") expect(@plugin["network"]["settings"]["net.inet.ip.rtmaxcache"]).to eq("128") expect(@plugin["network"]["settings"]["net.inet.ip.sourceroute"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.intr_queue_maxlen"]).to eq("50") expect(@plugin["network"]["settings"]["net.inet.ip.intr_queue_drops"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.accept_sourceroute"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.keepfaith"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.gifttl"]).to eq("30") expect(@plugin["network"]["settings"]["net.inet.ip.subnets_are_local"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.mcast.maxgrpsrc"]).to eq("512") expect(@plugin["network"]["settings"]["net.inet.ip.mcast.maxsocksrc"]).to eq("128") expect(@plugin["network"]["settings"]["net.inet.ip.mcast.loop"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.check_route_selfref"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.use_route_genid"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.hash_size"]).to eq("64") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.curr_time"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.ready_heap"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.extract_heap"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.searches"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.search_steps"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.expire"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.max_chain_len"]).to eq("16") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.red_lookup_depth"]).to eq("256") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.red_avg_pkt_size"]).to eq("512") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.red_max_pkt_size"]).to eq("1500") expect(@plugin["network"]["settings"]["net.inet.ip.dummynet.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.fw.enable"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.fw.autoinc_step"]).to eq("100") expect(@plugin["network"]["settings"]["net.inet.ip.fw.one_pass"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.fw.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.fw.verbose"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.fw.verbose_limit"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_buckets"]).to eq("256") expect(@plugin["network"]["settings"]["net.inet.ip.fw.curr_dyn_buckets"]).to eq("256") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_count"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_max"]).to eq("4096") expect(@plugin["network"]["settings"]["net.inet.ip.fw.static_count"]).to eq("2") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_ack_lifetime"]).to eq("300") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_syn_lifetime"]).to eq("20") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_fin_lifetime"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_rst_lifetime"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_udp_lifetime"]).to eq("10") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_short_lifetime"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet.ip.fw.dyn_keepalive"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.maxfragpackets"]).to eq("1536") expect(@plugin["network"]["settings"]["net.inet.ip.maxfragsperpacket"]).to eq("128") expect(@plugin["network"]["settings"]["net.inet.ip.maxfrags"]).to eq("3072") expect(@plugin["network"]["settings"]["net.inet.ip.scopedroute"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.check_interface"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.linklocal.in.allowbadttl"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.random_id"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ip.maxchainsent"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ip.select_srcif_debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.icmp.maskrepl"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.icmp.icmplim"]).to eq("250") expect(@plugin["network"]["settings"]["net.inet.icmp.timestamp"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.icmp.drop_redirect"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.icmp.log_redirect"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.icmp.bmcastecho"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.igmp.recvifkludge"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.igmp.sendra"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.igmp.sendlocal"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.igmp.v1enable"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.igmp.v2enable"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.igmp.legacysupp"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.igmp.default_version"]).to eq("3") expect(@plugin["network"]["settings"]["net.inet.igmp.gsrdelay"]).to eq("10") expect(@plugin["network"]["settings"]["net.inet.igmp.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.rfc1323"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.rfc1644"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.mssdflt"]).to eq("512") expect(@plugin["network"]["settings"]["net.inet.tcp.keepidle"]).to eq("7200000") expect(@plugin["network"]["settings"]["net.inet.tcp.keepintvl"]).to eq("75000") expect(@plugin["network"]["settings"]["net.inet.tcp.sendspace"]).to eq("65536") expect(@plugin["network"]["settings"]["net.inet.tcp.recvspace"]).to eq("65536") expect(@plugin["network"]["settings"]["net.inet.tcp.keepinit"]).to eq("75000") expect(@plugin["network"]["settings"]["net.inet.tcp.v6mssdflt"]).to eq("1024") expect(@plugin["network"]["settings"]["net.inet.tcp.log_in_vain"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.blackhole"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.delayed_ack"]).to eq("3") expect(@plugin["network"]["settings"]["net.inet.tcp.tcp_lq_overflow"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.recvbg"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.drop_synfin"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.reass.maxsegments"]).to eq("3072") expect(@plugin["network"]["settings"]["net.inet.tcp.reass.cursegments"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.reass.overflows"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.slowlink_wsize"]).to eq("8192") expect(@plugin["network"]["settings"]["net.inet.tcp.maxseg_unacked"]).to eq("8") expect(@plugin["network"]["settings"]["net.inet.tcp.rfc3465"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.rfc3465_lim2"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.rtt_samples_per_slot"]).to eq("20") expect(@plugin["network"]["settings"]["net.inet.tcp.recv_allowed_iaj"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet.tcp.acc_iaj_high_thresh"]).to eq("100") expect(@plugin["network"]["settings"]["net.inet.tcp.rexmt_thresh"]).to eq("2") expect(@plugin["network"]["settings"]["net.inet.tcp.path_mtu_discovery"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.slowstart_flightsize"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.local_slowstart_flightsize"]).to eq("8") expect(@plugin["network"]["settings"]["net.inet.tcp.tso"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.ecn_initiate_out"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.ecn_negotiate_in"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.packetchain"]).to eq("50") expect(@plugin["network"]["settings"]["net.inet.tcp.socket_unlocked_on_output"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.rfc3390"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.min_iaj_win"]).to eq("4") expect(@plugin["network"]["settings"]["net.inet.tcp.acc_iaj_react_limit"]).to eq("200") expect(@plugin["network"]["settings"]["net.inet.tcp.sack"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.sack_maxholes"]).to eq("128") expect(@plugin["network"]["settings"]["net.inet.tcp.sack_globalmaxholes"]).to eq("65536") expect(@plugin["network"]["settings"]["net.inet.tcp.sack_globalholes"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.minmss"]).to eq("216") expect(@plugin["network"]["settings"]["net.inet.tcp.minmssoverload"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.do_tcpdrain"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.pcbcount"]).to eq("86") expect(@plugin["network"]["settings"]["net.inet.tcp.icmp_may_rst"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.strict_rfc1948"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.isn_reseed_interval"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.background_io_enabled"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.rtt_min"]).to eq("100") expect(@plugin["network"]["settings"]["net.inet.tcp.rexmt_slop"]).to eq("200") expect(@plugin["network"]["settings"]["net.inet.tcp.randomize_ports"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.newreno_sockets"]).to eq("81") expect(@plugin["network"]["settings"]["net.inet.tcp.background_sockets"]).to eq("-1") expect(@plugin["network"]["settings"]["net.inet.tcp.tcbhashsize"]).to eq("4096") expect(@plugin["network"]["settings"]["net.inet.tcp.background_io_trigger"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet.tcp.msl"]).to eq("15000") expect(@plugin["network"]["settings"]["net.inet.tcp.max_persist_timeout"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.always_keepalive"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.tcp.timer_fastmode_idlemax"]).to eq("20") expect(@plugin["network"]["settings"]["net.inet.tcp.broken_peer_syn_rxmit_thres"]).to eq("7") expect(@plugin["network"]["settings"]["net.inet.tcp.tcp_timer_advanced"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet.tcp.tcp_resched_timerlist"]).to eq("12209") expect(@plugin["network"]["settings"]["net.inet.tcp.pmtud_blackhole_detection"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.pmtud_blackhole_mss"]).to eq("1200") expect(@plugin["network"]["settings"]["net.inet.tcp.timer_fastquantum"]).to eq("100") expect(@plugin["network"]["settings"]["net.inet.tcp.timer_slowquantum"]).to eq("500") expect(@plugin["network"]["settings"]["net.inet.tcp.win_scale_factor"]).to eq("3") expect(@plugin["network"]["settings"]["net.inet.tcp.sockthreshold"]).to eq("64") expect(@plugin["network"]["settings"]["net.inet.tcp.bg_target_qdelay"]).to eq("100") expect(@plugin["network"]["settings"]["net.inet.tcp.bg_allowed_increase"]).to eq("2") expect(@plugin["network"]["settings"]["net.inet.tcp.bg_tether_shift"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.tcp.bg_ss_fltsz"]).to eq("2") expect(@plugin["network"]["settings"]["net.inet.udp.checksum"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.udp.maxdgram"]).to eq("9216") expect(@plugin["network"]["settings"]["net.inet.udp.recvspace"]).to eq("42080") expect(@plugin["network"]["settings"]["net.inet.udp.log_in_vain"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.udp.blackhole"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.udp.pcbcount"]).to eq("72") expect(@plugin["network"]["settings"]["net.inet.udp.randomize_ports"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.def_policy"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.esp_trans_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.esp_net_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.ah_trans_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.ah_net_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.ah_cleartos"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet.ipsec.ah_offsetmask"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ipsec.dfbit"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ipsec.ecn"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ipsec.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ipsec.esp_randpad"]).to eq("-1") expect(@plugin["network"]["settings"]["net.inet.ipsec.bypass"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet.ipsec.esp_port"]).to eq("4500") expect(@plugin["network"]["settings"]["net.inet.raw.maxdgram"]).to eq("8192") expect(@plugin["network"]["settings"]["net.inet.raw.recvspace"]).to eq("8192") expect(@plugin["network"]["settings"]["net.link.generic.system.ifcount"]).to eq("10") expect(@plugin["network"]["settings"]["net.link.generic.system.dlil_verbose"]).to eq("0") expect(@plugin["network"]["settings"]["net.link.generic.system.multi_threaded_input"]).to eq("1") expect(@plugin["network"]["settings"]["net.link.generic.system.dlil_input_sanity_check"]).to eq("0") expect(@plugin["network"]["settings"]["net.link.ether.inet.prune_intvl"]).to eq("300") expect(@plugin["network"]["settings"]["net.link.ether.inet.max_age"]).to eq("1200") expect(@plugin["network"]["settings"]["net.link.ether.inet.host_down_time"]).to eq("20") expect(@plugin["network"]["settings"]["net.link.ether.inet.apple_hwcksum_tx"]).to eq("1") expect(@plugin["network"]["settings"]["net.link.ether.inet.apple_hwcksum_rx"]).to eq("1") expect(@plugin["network"]["settings"]["net.link.ether.inet.arp_llreach_base"]).to eq("30") expect(@plugin["network"]["settings"]["net.link.ether.inet.maxtries"]).to eq("5") expect(@plugin["network"]["settings"]["net.link.ether.inet.useloopback"]).to eq("1") expect(@plugin["network"]["settings"]["net.link.ether.inet.proxyall"]).to eq("0") expect(@plugin["network"]["settings"]["net.link.ether.inet.sendllconflict"]).to eq("0") expect(@plugin["network"]["settings"]["net.link.ether.inet.log_arp_warnings"]).to eq("0") expect(@plugin["network"]["settings"]["net.link.ether.inet.keep_announcements"]).to eq("1") expect(@plugin["network"]["settings"]["net.link.ether.inet.send_conflicting_probes"]).to eq("1") expect(@plugin["network"]["settings"]["net.link.bridge.log_stp"]).to eq("0") expect(@plugin["network"]["settings"]["net.link.bridge.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.key.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.key.spi_trycnt"]).to eq("1000") expect(@plugin["network"]["settings"]["net.key.spi_minval"]).to eq("256") expect(@plugin["network"]["settings"]["net.key.spi_maxval"]).to eq("268435455") expect(@plugin["network"]["settings"]["net.key.int_random"]).to eq("60") expect(@plugin["network"]["settings"]["net.key.larval_lifetime"]).to eq("30") expect(@plugin["network"]["settings"]["net.key.blockacq_count"]).to eq("10") expect(@plugin["network"]["settings"]["net.key.blockacq_lifetime"]).to eq("20") expect(@plugin["network"]["settings"]["net.key.esp_keymin"]).to eq("256") expect(@plugin["network"]["settings"]["net.key.esp_auth"]).to eq("0") expect(@plugin["network"]["settings"]["net.key.ah_keymin"]).to eq("128") expect(@plugin["network"]["settings"]["net.key.prefered_oldsa"]).to eq("0") expect(@plugin["network"]["settings"]["net.key.natt_keepalive_interval"]).to eq("20") expect(@plugin["network"]["settings"]["net.inet6.ip6.forwarding"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.redirect"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.hlim"]).to eq("64") expect(@plugin["network"]["settings"]["net.inet6.ip6.maxfragpackets"]).to eq("1536") expect(@plugin["network"]["settings"]["net.inet6.ip6.accept_rtadv"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.keepfaith"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.log_interval"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet6.ip6.hdrnestlimit"]).to eq("15") expect(@plugin["network"]["settings"]["net.inet6.ip6.dad_count"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.auto_flowlabel"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.defmcasthlim"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.gifhlim"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.kame_version"]).to eq("2009/apple-darwin") expect(@plugin["network"]["settings"]["net.inet6.ip6.use_deprecated"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.rr_prune"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet6.ip6.v6only"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.rtexpire"]).to eq("3600") expect(@plugin["network"]["settings"]["net.inet6.ip6.rtminexpire"]).to eq("10") expect(@plugin["network"]["settings"]["net.inet6.ip6.rtmaxcache"]).to eq("128") expect(@plugin["network"]["settings"]["net.inet6.ip6.use_tempaddr"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.temppltime"]).to eq("86400") expect(@plugin["network"]["settings"]["net.inet6.ip6.tempvltime"]).to eq("604800") expect(@plugin["network"]["settings"]["net.inet6.ip6.auto_linklocal"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.prefer_tempaddr"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.use_defaultzone"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.maxfrags"]).to eq("12288") expect(@plugin["network"]["settings"]["net.inet6.ip6.mcast_pmtu"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.neighborgcthresh"]).to eq("1024") expect(@plugin["network"]["settings"]["net.inet6.ip6.maxifprefixes"]).to eq("16") expect(@plugin["network"]["settings"]["net.inet6.ip6.maxifdefrouters"]).to eq("16") expect(@plugin["network"]["settings"]["net.inet6.ip6.maxdynroutes"]).to eq("1024") expect(@plugin["network"]["settings"]["net.inet6.ip6.fw.enable"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.fw.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.fw.verbose"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.fw.verbose_limit"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.scopedroute"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.select_srcif_debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ip6.mcast.maxgrpsrc"]).to eq("512") expect(@plugin["network"]["settings"]["net.inet6.ip6.mcast.maxsocksrc"]).to eq("128") expect(@plugin["network"]["settings"]["net.inet6.ip6.mcast.loop"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ip6.only_allow_rfc4193_prefixes"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.def_policy"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.esp_trans_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.esp_net_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.ah_trans_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.ah_net_deflev"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.ecn"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.ipsec6.esp_randpad"]).to eq("-1") expect(@plugin["network"]["settings"]["net.inet6.icmp6.rediraccept"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.icmp6.redirtimeout"]).to eq("600") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_prune"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_delay"]).to eq("5") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_umaxtries"]).to eq("3") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_mmaxtries"]).to eq("3") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_useloopback"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nodeinfo"]).to eq("3") expect(@plugin["network"]["settings"]["net.inet6.icmp6.errppslimit"]).to eq("500") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_maxnudhint"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_accept_6to4"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_onlink_ns_rfc4861"]).to eq("0") expect(@plugin["network"]["settings"]["net.inet6.icmp6.nd6_llreach_base"]).to eq("30") expect(@plugin["network"]["settings"]["net.inet6.mld.gsrdelay"]).to eq("10") expect(@plugin["network"]["settings"]["net.inet6.mld.v1enable"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.mld.use_allow"]).to eq("1") expect(@plugin["network"]["settings"]["net.inet6.mld.debug"]).to eq("0") expect(@plugin["network"]["settings"]["net.idle.route.expire_timeout"]).to eq("30") expect(@plugin["network"]["settings"]["net.idle.route.drain_interval"]).to eq("10") expect(@plugin["network"]["settings"]["net.statistics"]).to eq("1") expect(@plugin["network"]["settings"]["net.alf.loglevel"]).to eq("55") expect(@plugin["network"]["settings"]["net.alf.perm"]).to eq("0") expect(@plugin["network"]["settings"]["net.alf.defaultaction"]).to eq("1") expect(@plugin["network"]["settings"]["net.alf.mqcount"]).to eq("0") expect(@plugin["network"]["settings"]["net.smb.fs.version"]).to eq("107000") expect(@plugin["network"]["settings"]["net.smb.fs.loglevel"]).to eq("0") expect(@plugin["network"]["settings"]["net.smb.fs.kern_ntlmssp"]).to eq("0") expect(@plugin["network"]["settings"]["net.smb.fs.kern_deprecatePreXPServers"]).to eq("1") expect(@plugin["network"]["settings"]["net.smb.fs.kern_deadtimer"]).to eq("60") expect(@plugin["network"]["settings"]["net.smb.fs.kern_hard_deadtimer"]).to eq("600") expect(@plugin["network"]["settings"]["net.smb.fs.kern_soft_deadtimer"]).to eq("30") expect(@plugin["network"]["settings"]["net.smb.fs.tcpsndbuf"]).to eq("261120") expect(@plugin["network"]["settings"]["net.smb.fs.tcprcvbuf"]).to eq("261120") end end end ohai-16.0.7/spec/unit/plugins/darwin/platform_spec.rb000066400000000000000000000043761362624620500226060ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin plugin platform" do before do @plugin = get_plugin("darwin/platform") allow(@plugin).to receive(:collect_os).and_return(:darwin) @stdout = "ProductName: Mac OS X\nProductVersion: 10.5.5\nBuildVersion: 9F33" allow(@plugin).to receive(:shell_out).with("/usr/bin/sw_vers").and_return(mock_shell_out(0, @stdout, "")) end it "runs sw_vers" do expect(@plugin).to receive(:shell_out).with("/usr/bin/sw_vers").and_return(mock_shell_out(0, @stdout, "")) @plugin.run end it "sets platform to ProductName, downcased with _ for \\s" do @plugin.run expect(@plugin[:platform]).to eq("mac_os_x") end it "sets platform_version to ProductVersion" do @plugin.run expect(@plugin[:platform_version]).to eq("10.5.5") end it "sets platform_build to BuildVersion" do @plugin.run expect(@plugin[:platform_build]).to eq("9F33") end it "sets platform_family to mac_os_x" do @plugin.run expect(@plugin[:platform_family]).to eq("mac_os_x") end describe "on os x server" do before do @plugin[:os] = "darwin" @stdout = "ProductName: Mac OS X Server\nProductVersion: 10.6.8\nBuildVersion: 10K549" allow(@plugin).to receive(:shell_out).with("/usr/bin/sw_vers").and_return(mock_shell_out(0, @stdout, "")) end it "sets platform to mac_os_x_server" do @plugin.run expect(@plugin[:platform]).to eq("mac_os_x_server") end it "sets platform_family to mac_os_x" do @plugin.run expect(@plugin[:platform_family]).to eq("mac_os_x") end end end ohai-16.0.7/spec/unit/plugins/darwin/virtualization_spec.rb000066400000000000000000000162601362624620500240410ustar00rootroot00000000000000# # Author:: Pavel Yudin () # Author:: Tim Smith () # Copyright:: Copyright (c) 2015 Pavel Yudin # Copyright:: Copyright (c) 2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Darwin virtualization platform" do let(:plugin) { get_plugin("darwin/virtualization") } before do allow(plugin).to receive(:collect_os).and_return(:darwin) allow(plugin).to receive(:prlctl_exists?).and_return(false) allow(plugin).to receive(:ioreg_exists?).and_return(false) allow(plugin).to receive(:vboxmanage_exists?).and_return(false) allow(plugin).to receive(:fusion_exists?).and_return(false) allow(plugin).to receive(:docker_exists?).and_return(false) plugin[:hardware] = Mash.new plugin[:hardware][:boot_rom_version] = "not_a_vm" end describe "when detecting OS X virtualization" do it "does not set virtualization keys if no binaries are found" do plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end it "sets docker host if docker exists" do allow(plugin).to receive(:docker_exists?).and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:docker]).to eq("host") end it "sets vmware host if /Applications/VMware\ Fusion.app exists" do allow(plugin).to receive(:fusion_exists?).and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("vmware") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:vmware]).to eq("host") end it "sets vmware guest if hardware attributes mention vmware" do plugin[:hardware][:boot_rom_version] = "VMW71.00V.6997262.B64.1710270607" plugin.run expect(plugin[:virtualization][:system]).to eq("vmware") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:vmware]).to eq("guest") end it "sets vbox host if /usr/local/bin/VBoxManage exists" do allow(plugin).to receive(:vboxmanage_exists?).and_return("/usr/local/bin/VBoxManage") plugin.run expect(plugin[:virtualization][:system]).to eq("vbox") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:vbox]).to eq("host") end it "sets vbox guest if hardware attributes mention virtualbox" do plugin[:hardware][:boot_rom_version] = "VirtualBox" plugin.run expect(plugin[:virtualization][:system]).to eq("vbox") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:vbox]).to eq("guest") end it "sets parallels host if /usr/bin/prlctl exists" do allow(plugin).to receive(:prlctl_exists?).and_return("/usr/bin/prlctl") plugin.run expect(plugin[:virtualization][:system]).to eq("parallels") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:parallels]).to eq("host") end it "sets parallels guest if /usr/sbin/ioreg exists and its output contains pci1ab8,4000" do allow(plugin).to receive(:ioreg_exists?).and_return(true) ioreg = <<-IOREG | | +-o pci1ab8,4000@3 | | | | { | | | | "compatible" = <"pci1ab8,400","pci1ab8,4000","pciclass,ff0000"> | | | | "subsystem-vendor-id" = | | | | "IOName" = "pci1ab8,4000" | | | | "reg" = <00180000000000000000000000000000000000001018000100000000000000000000000020000000> | | | | "device-id" = <00400000> | | | | "assigned-addresses" = <101800810000000040d200000000000020000000> | | | | "IOPowerManagement" = {"MaxPowerState"=3,"ChildProxyPowerState"=2,"CurrentPowerState"=2} | | | | "IOPCIResourced" = Yes | | | | "IODeviceMemory" = ("IOSubMemoryDescriptor is not serializable") | | | | "revision-id" = <00000000> | | | | "IOInterruptControllers" = ("IOPCIMessagedInterruptController") | | | | "vendor-id" = | | | | "pcidebug" = "0:3:0" | | | | "class-code" = <0000ff00> | | | | "IOInterruptSpecifiers" = (<0000000000000100>) | | | | "IOPCIMSIMode" = Yes | | | | "subsystem-id" = <00040000> | | | | "name" = <"pci1ab8,4000"> | | | | } IOREG shellout = double("shellout") allow(shellout).to receive(:stdout).and_return(ioreg) allow(plugin).to receive(:shell_out).with("ioreg -l").and_return(shellout) plugin.run expect(plugin[:virtualization][:system]).to eq("parallels") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:parallels]).to eq("guest") end it "does not set parallels guest if /usr/sbin/ioreg exists and its output not contain pci1ab8,4000" do allow(plugin).to receive(:ioreg_exists?).and_return(true) ioreg = <<-IOREG | | +-o pci8086,2445@1F,4 | | | { | | | "compatible" = <"pci1ab8,400","pci8086,2445","pciclass,040100"> | | | "subsystem-vendor-id" = | | | "IOName" = "pci8086,2445" | | | "reg" = <00fc00000000000000000000000000000000000010fc00010000000000000000000000000001000014fc000100000000000000000000000000010000> | | | "device-id" = <45240000> | | | "assigned-addresses" = <10fc00810000000000d10000000000000001000014fc00810000000000d000000000000000010000> | | | "IOPowerManagement" = {"ChildrenPowerState"=2,"CurrentPowerState"=2,"ChildProxyPowerState"=2,"MaxPowerState"=3} | | | "IOPCIResourced" = Yes | | | "IODeviceMemory" = ("IOSubMemoryDescriptor is not serializable","IOSubMemoryDescriptor is not serializable") | | | "revision-id" = <02000000> | | | "IOInterruptControllers" = ("io-apic-0") | | | "vendor-id" = <86800000> | | | "pcidebug" = "0:31:4" | | | "class-code" = <00010400> | | | "IOInterruptSpecifiers" = (<1100000007000000>) | | | "subsystem-id" = <00040000> | | | "name" = <"pci8086,2445"> | | | } IOREG shellout = double("shellout") allow(shellout).to receive(:stdout).and_return(ioreg) allow(plugin).to receive(:shell_out).with("ioreg -l").and_return(shellout) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end end ohai-16.0.7/spec/unit/plugins/digital_ocean_spec.rb000066400000000000000000000125331362624620500222520ustar00rootroot00000000000000# # Author:: Dylan Page () # Author:: Stafford Brunk () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin digital_ocean" do let(:plugin) { get_plugin("digital_ocean") } let(:hint) do { "droplet_id" => 12345678, "name" => "example.com", "image_id" => 3240036, "size_id" => 66, "region_id" => 4, "ip_addresses" => { "public" => "1.2.3.4", "private" => "5.6.7.8", }, } end before do allow(plugin).to receive(:hint?).with("digital_ocean").and_return(false) end shared_examples_for "!digital_ocean" do it "does not attempt to fetch the digital_ocean metadata" do expect(plugin).not_to receive(:http_client) expect(plugin[:digital_ocean]).to be_nil plugin.run end end shared_examples_for "digital_ocean" do before do @http_client = double("Net::HTTP client") allow(plugin).to receive(:http_client).and_return(@http_client) allow(IO).to receive(:select).and_return([[], [1], []]) t = double("connection") allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS) allow(Socket).to receive(:new).and_return(t) allow(Socket).to receive(:pack_sockaddr_in).and_return(nil) end let(:body) do '{"droplet_id":2756924,"hostname":"sample-droplet","vendor_data":"#cloud-config\ndisable_root: false\nmanage_etc_hosts: true\n\n# The modules that run in the \'init\' stage\ncloud_init_modules:\n - migrator\n - ubuntu-init-switch\n - seed_random\n - bootcmd\n - write-files\n - growpart\n - resizefs\n - set_hostname\n - update_hostname\n - [ update_etc_hosts, once-per-instance ]\n - ca-certs\n - rsyslog\n - users-groups\n - ssh\n\n# The modules that run in the \'config\' stage\ncloud_config_modules:\n - disk_setup\n - mounts\n - ssh-import-id\n - locale\n - set-passwords\n - grub-dpkg\n - apt-pipelining\n - apt-configure\n - package-update-upgrade-install\n - landscape\n - timezone\n - puppet\n - chef\n - salt-minion\n - mcollective\n - disable-ec2-metadata\n - runcmd\n - byobu\n\n# The modules that run in the \'final\' stage\ncloud_final_modules:\n - rightscale_userdata\n - scripts-vendor\n - scripts-per-once\n - scripts-per-boot\n - scripts-per-instance\n - scripts-user\n - ssh-authkey-fingerprints\n - keys-to-console\n - phone-home\n - final-message\n - power-state-change\n","public_keys":["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDAkMD3PYKHaH0KbDiXrRE6KCBo/OKcFqhM+fmnnb0+LUh4RalJWX4edeJmnT5bxLeqmLV/Yggjlpfq73R+Dy7JB4pbBLuM959mSM9ohBCSnByAGoT2iUPev4aZFZZ/ahUzTCylNxXrhZV/bopD399CvYREt7Q+FlauBv0O8MMuMGR8aC69Z3jNL+r+fGWNq98JVHGFO/UgoNL15wGCaidMhzfRqkt1u+m1nY77SFM5qWJz2R0CEC4fMlOiCg8mWBklnryV4yDEPgiXp2I8Rli1Eu2GHwuY1YX9elMeQS7n3Pzq7l6aIQmSgvcEWx6TgMD2V7nQUWpfcud/8dpp/t7z9UyfzLmNwnULHNmUeEp52sejcH5lYzISnkkWa1LzlKSeIrhF3y45m9AyxIfjEqyh/mlKQtUaW3NVXXLPwrNitxHtMIZPU5b16BODn0wb8bqPxpDNpUYrQd/BS7mWDxNpICP2ObLPhd9LW9KIYRNTzryE+uKwxm9NkMlhRku2fu415fH0G0+7aURsHviNN9SO4zct3Pj6QE5rnbVHqxt3biplUTOScdWxSk2Nv3V2dGdt/lBfu6iRPAV9IAS31s7Po3qK1t2jpEPCJwstaCBOM80kmoi3zAgotiAW50X8CelaWsHNrq5jBBgeHUZWgn/c8BkcI61pUE9l34Q6gsiEMQ== tsmith84@gmail.com"],"region":"nyc3","interfaces":{"public":[{"ipv4":{"ip_address":"159.203.92.161","netmask":"255.255.240.0","gateway":"159.203.80.1"},"ipv6":{"ip_address":"2604:A880:0800:00A1:0000:0000:0201:0001","cidr":64,"gateway":"2604:A880:0800:00A1:0000:0000:0000:0001"},"anchor_ipv4":{"ip_address":"10.17.0.5","netmask":"255.255.0.0","gateway":"10.17.0.1"},"mac":"04:01:e5:14:03:01","type":"public"}]},"floating_ip":{"ipv4":{"active":false}},"dns":{"nameservers":["2001:4860:4860::8844","2001:4860:4860::8888","8.8.8.8"]}}' end it "fetches and properly parse json metadata" do expect(@http_client).to receive(:get) .with("/metadata/v1.json") .and_return(double("Net::HTTP Response", body: body, code: "200")) plugin.run expect(plugin[:digital_ocean]).not_to be_nil expect(plugin[:digital_ocean]["droplet_id"]).to eq(2756924) expect(plugin[:digital_ocean]["hostname"]).to eq("sample-droplet") end it "completes the run despite unavailable metadata" do expect(@http_client).to receive(:get) .with("/metadata/v1.json") .and_return(double("Net::HTTP Response", body: "", code: "404")) plugin.run expect(plugin[:digitalocean]).to be_nil end end describe "without hint or dmi data" do it_behaves_like "!digital_ocean" end describe "with digital_ocean hint file" do before do allow(plugin).to receive(:hint?).with("digital_ocean").and_return(true) end it_behaves_like "digital_ocean" end describe "with digital_ocean DMI data" do before do plugin[:dmi] = { bios: { all_records: [ { Vendor: "DigitalOcean" } ] } } end it_behaves_like "digital_ocean" end end ohai-16.0.7/spec/unit/plugins/dmi_spec.rb000066400000000000000000000106731362624620500202440ustar00rootroot00000000000000# # Author:: Bryan McLellan () # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" # NOTE: These data lines must be prefixed with one or two tabs, not spaces. DMI_OUT = <<~EOS.freeze # dmidecode 2.9 SMBIOS 2.4 present. 98 structures occupying 3699 bytes. Table at 0x000E0010. Handle 0x0000, DMI type 0, 24 bytes BIOS Information Vendor: Phoenix Technologies LTD Version: 6.00 Release Date: 12/31/2009 Address: 0xEA2E0 Runtime Size: 89376 bytes ROM Size: 64 kB Characteristics: ISA is supported PCI is supported PC Card (PCMCIA) is supported PNP is supported APM is supported BIOS is upgradeable BIOS shadowing is allowed ESCD support is available USB legacy is supported Smart battery is supported BIOS boot specification is supported Targeted content distribution is supported BIOS Revision: 4.6 Firmware Revision: 0.0 Handle 0x0001, DMI type 1, 27 bytes System Information Manufacturer: VMware, Inc. Product Name: VMware Virtual Platform Version: None Serial Number: VMware-56 4d 71 d1 65 70 83 a8-df c8 14 12 19 41 71 45 UUID: 564D71D1-6570-83A8-DFC8-141219417145 Wake-up Type: Power Switch SKU Number: Not Specified Family: Not Specified Handle 0x0002, DMI type 2, 15 bytes Base Board Information Manufacturer: Intel Corporation Product Name: 440BX Desktop Reference Platform Version: None Serial Number: None Asset Tag: Not Specified Features: None Location In Chassis: Not Specified Chassis Handle: 0x0000 Type: Unknown Contained Object Handles: 0 Handle 0x1000, DMI type 16, 15 bytes Physical Memory Array Location: Other Use: System Memory Error Correction Type: Multi-bit ECC Maximum Capacity: 2 GB Error Information Handle: Not Provided Number Of Devices: 1 Handle 0x0003, DMI type 3, 21 bytes Chassis Information Manufacturer: No Enclosure Type: Other Lock: Not Present Version: N/A Serial Number: None Asset Tag: No Asset Tag Boot-up State: Safe Power Supply State: Safe Thermal State: Safe Security Status: None OEM Information: 0x00001234 Height: Unspecified Number Of Power Cords: Unspecified Contained Elements: 0 EOS describe Ohai::System, "plugin dmi" do let(:plugin) { get_plugin("dmi") } let(:stdout) { DMI_OUT } before do allow(plugin).to receive(:shell_out).with("dmidecode").and_return(mock_shell_out(0, stdout, "")) end it "runs dmidecode" do expect(plugin).to receive(:shell_out).with("dmidecode").and_return(mock_shell_out(0, stdout, "")) plugin.run end # Test some simple sample data { bios: { vendor: "Phoenix Technologies LTD", release_date: "12/31/2009", }, system: { manufacturer: "VMware, Inc.", product_name: "VMware Virtual Platform", }, chassis: { lock: "Not Present", asset_tag: "No Asset Tag", }, }.each do |id, data| data.each do |attribute, value| it "attribute [:dmi][:#{id}][:#{attribute}] is set" do plugin.run expect(plugin[:dmi][id][attribute]).to eql(value) end it "attribute [:dmi][:#{id}][:#{attribute}] set for windows output" do stdout = convert_windows_output(DMI_OUT) expect(plugin).to receive(:shell_out).with("dmidecode").and_return(mock_shell_out(0, stdout, "")) plugin.run expect(plugin[:dmi][id][attribute]).to eql(value) end end end it "allows capturing additional DMI data" do Ohai.config[:additional_dmi_ids] = [ 16 ] plugin.run expect(plugin[:dmi]).to have_key(:physical_memory_array) end it "correctly ignores data in excluded DMI IDs" do expect(plugin).to receive(:shell_out).with("dmidecode").and_return(mock_shell_out(0, stdout, "")) plugin.run expect(plugin[:dmi]).not_to have_key(:physical_memory_array) end end ohai-16.0.7/spec/unit/plugins/docker_spec.rb000066400000000000000000000111311362624620500207300ustar00rootroot00000000000000# # Copyright:: 2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" docker_output = <<~EOF {"ID":"KZET:VDFN:2V2G:JS5Z:HAKO:SOGI:AFSZ:HDMT:GVEM:V2NT:DUSW:J3Z6","Containers":11,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":11,"Images":30,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"SystemStatus":null,"Plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":true,"KernelMemory":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":true,"NFd":21,"OomKillDisable":true,"NGoroutines":39,"SystemTime":"2018-02-15T19:12:40.214106068Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","NEventsListener":2,"KernelVersion":"4.9.60-linuxkit-aufs","OperatingSystem":"Docker for Mac","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":[],"AllowNondistributableArtifactsHostnames":[],"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":[],"Secure":true,"Official":true}},"Mirrors":[]},"NCPU":4,"MemTotal":2095816704,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"docker.for.mac.http.internal:3128","HttpsProxy":"docker.for.mac.http.internal:3129","NoProxy":"","Name":"linuxkit-025000000001","Labels":[],"ExperimentalBuild":true,"ServerVersion":"17.12.0-ce","ClusterStore":"","ClusterAdvertise":"","Runtimes":{"runc":{"path":"docker-runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"89623f28b87a6004d4b785663257362d1658a729","Expected":"89623f28b87a6004d4b785663257362d1658a729"},"RuncCommit":{"ID":"b2567b37d7b75eb4cf325b77297b140ea686ce8f","Expected":"b2567b37d7b75eb4cf325b77297b140ea686ce8f"},"InitCommit":{"ID":"949e6fa","Expected":"949e6fa"},"SecurityOptions":["name=seccomp,profile=default"]} EOF expected_output = { "version_string" => "17.12.0-ce", "version" => "17.12.0", "runtimes" => { "runc" => { "path" => "docker-runc", }, }, "root_dir" => "/var/lib/docker", "containers" => { "total" => 11, "running" => 0, "paused" => 0, "stopped" => 11, }, "plugins" => { "Volume" => [ "local", ], "Network" => %w{ bridge host ipvlan macvlan null overlay}, "Authorization" => nil, "Log" => %w{ awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog }, }, "networking" => { "ipv4_forwarding" => true, "bridge_nf_iptables" => true, "bridge_nf_ipv6_iptables" => true, }, "swarm" => { "NodeID" => "", "NodeAddr" => "", "LocalNodeState" => "inactive", "ControlAvailable" => false, "Error" => "", "RemoteManagers" => nil, }, } describe Ohai::System, "plugin docker" do let(:plugin) { get_plugin("docker") } context "without docker installed" do it "does not create a docker attribute" do plugin[:virtualization] = Mash.new plugin[:virtualization][:systems] = Mash.new plugin.run expect(plugin).not_to have_key(:docker) end end context "with docker installed" do it "creates a docker attribute with correct data" do plugin[:virtualization] = Mash.new plugin[:virtualization][:systems] = Mash.new plugin[:virtualization][:systems][:docker] = "host" allow(plugin).to receive(:shell_out).with("docker info --format '{{json .}}'").and_return(mock_shell_out(0, docker_output, "")) plugin.run expect(plugin).to have_key(:docker) expect(plugin[:docker]).to eq(expected_output) end end end ohai-16.0.7/spec/unit/plugins/ec2_spec.rb000066400000000000000000000460271362624620500201460ustar00rootroot00000000000000# # Author:: Tim Dysinger () # Author:: Christopher Brown (cb@chef.io) # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "open-uri" require "base64" describe Ohai::System, "plugin ec2" do let(:plugin) { get_plugin("ec2") } before do allow(plugin).to receive(:hint?).with("ec2").and_return(false) allow(File).to receive(:exist?).with("/sys/hypervisor/uuid").and_return(false) allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_vendor").and_return(false) allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_version").and_return(false) end shared_examples_for "!ec2" do it "DOESN'T attempt to fetch the ec2 metadata or set ec2 attribute" do expect(plugin).not_to receive(:http_client) expect(plugin[:ec2]).to be_nil plugin.run end end shared_examples_for "ec2" do before do @http_client = double("Net::HTTP client") allow(plugin).to receive(:http_client).and_return(@http_client) allow(IO).to receive(:select).and_return([[], [1], []]) t = double("connection") allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS) allow(Socket).to receive(:new).and_return(t) expect(@http_client).to receive(:get) .with("/") .and_return(double("Net::HTTP Response", body: "2012-01-12", code: "200")) end context "with common metadata paths" do let(:paths) do { "meta-data/" => "instance_type\nami_id\nsecurity-groups", "meta-data/instance_type" => "c1.medium", "meta-data/ami_id" => "ami-5d2dc934", "meta-data/security-groups" => "group1\ngroup2", } end it "recursively fetches all the ec2 metadata" do paths.each do |name, body| expect(@http_client).to receive(:get) .with("/2012-01-12/#{name}") .and_return(double("Net::HTTP Response", body: body, code: "200")) end expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["instance_type"]).to eq("c1.medium") expect(plugin[:ec2]["ami_id"]).to eq("ami-5d2dc934") expect(plugin[:ec2]["security_groups"]).to eql %w{group1 group2} end it "fetches binary userdata opaquely" do paths.each do |name, body| expect(@http_client).to receive(:get) .with("/2012-01-12/#{name}") .and_return(double("Net::HTTP Response", body: body, code: "200")) end expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "^_<8B>^H^HU^@^Csomething^@KT,)IU(I-.II^B^@^Qz^R^@^@^@", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["instance_type"]).to eq("c1.medium") expect(plugin[:ec2]["ami_id"]).to eq("ami-5d2dc934") expect(plugin[:ec2]["security_groups"]).to eql %w{group1 group2} expect(plugin[:ec2]["userdata"]).to eq(Base64.decode64("Xl88OEI+XkheSDxDNz5VXkBeQ3NvbWV0aGluZ15AS1Q8Qzg+PEM5PiwpPEM5\nPklVKEktLkk8Q0I+PENDPkk8RTU+XkJeQF5RejxCRj48QjA+XlJeQF5AXkA=")) end it "fetches AWS account id" do paths.each do |name, body| expect(@http_client).to receive(:get) .with("/2012-01-12/#{name}") .and_return(double("Net::HTTP Response", body: body, code: "200")) end expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "^_<8B>^H^HU^@^Csomething^@KT,)IU(I-.II^B^@^Qz^R^@^@^@", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["instance_type"]).to eq("c1.medium") expect(plugin[:ec2]["ami_id"]).to eq("ami-5d2dc934") expect(plugin[:ec2]["security_groups"]).to eql %w{group1 group2} expect(plugin[:ec2]["account_id"]).to eq("4815162342") end it "fetches AWS region" do paths.each do |name, body| expect(@http_client).to receive(:get) .with("/2012-01-12/#{name}") .and_return(double("Net::HTTP Response", body: body, code: "200")) end expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "^_<8B>^H^HU^@^Csomething^@KT,)IU(I-.II^B^@^Qz^R^@^@^@", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"region\":\"us-east-1\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["instance_type"]).to eq("c1.medium") expect(plugin[:ec2]["ami_id"]).to eq("ami-5d2dc934") expect(plugin[:ec2]["security_groups"]).to eql %w{group1 group2} expect(plugin[:ec2]["region"]).to eq("us-east-1") end it "fetches AWS availability zone" do paths.each do |name, body| expect(@http_client).to receive(:get) .with("/2012-01-12/#{name}") .and_return(double("Net::HTTP Response", body: body, code: "200")) end expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "^_<8B>^H^HU^@^Csomething^@KT,)IU(I-.II^B^@^Qz^R^@^@^@", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"availabilityZone\":\"us-east-1d\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["instance_type"]).to eq("c1.medium") expect(plugin[:ec2]["ami_id"]).to eq("ami-5d2dc934") expect(plugin[:ec2]["security_groups"]).to eql %w{group1 group2} expect(plugin[:ec2]["availability_zone"]).to eq("us-east-1d") end end it "parses ec2 network/ directory as a multi-level hash" do expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/") .and_return(double("Net::HTTP Response", body: "network/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/network/") .and_return(double("Net::HTTP Response", body: "interfaces/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/network/interfaces/") .and_return(double("Net::HTTP Response", body: "macs/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/network/interfaces/macs/") .and_return(double("Net::HTTP Response", body: "12:34:56:78:9a:bc/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/network/interfaces/macs/12:34:56:78:9a:bc/") .and_return(double("Net::HTTP Response", body: "public_hostname", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/network/interfaces/macs/12:34:56:78:9a:bc/public_hostname") .and_return(double("Net::HTTP Response", body: "server17.opscode.com", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["network_interfaces_macs"]["12:34:56:78:9a:bc"]["public_hostname"]).to eql("server17.opscode.com") end # context with common metadata paths context "with ec2_iam hint file" do before do allow(plugin).to receive(:hint?).with("iam").and_return(true) end it "parses ec2 iam/ directory and collect iam/security-credentials/" do expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/") .and_return(double("Net::HTTP Response", body: "iam/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/iam/") .and_return(double("Net::HTTP Response", body: "security-credentials/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/iam/security-credentials/") .and_return(double("Net::HTTP Response", body: "MyRole", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/iam/security-credentials/MyRole") .and_return(double("Net::HTTP Response", body: "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2012-08-22T07:47:22Z\",\n \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"AAAAAAAA\",\n \"SecretAccessKey\" : \"SSSSSSSS\",\n \"Token\" : \"12345678\",\n \"Expiration\" : \"2012-08-22T11:25:52Z\"\n}", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["iam"]["security-credentials"]["MyRole"]["Code"]).to eql "Success" expect(plugin[:ec2]["iam"]["security-credentials"]["MyRole"]["Token"]).to eql "12345678" end end context "without ec2_iam hint file" do before do allow(plugin).to receive(:hint?).with("iam").and_return(false) end it "parses ec2 iam/ directory and NOT collect iam/security-credentials/" do expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/") .and_return(double("Net::HTTP Response", body: "iam/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/iam/") .and_return(double("Net::HTTP Response", body: "security-credentials/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/iam/security-credentials/") .and_return(double("Net::HTTP Response", body: "MyRole", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/iam/security-credentials/MyRole") .and_return(double("Net::HTTP Response", body: "{\n \"Code\" : \"Success\",\n \"LastUpdated\" : \"2012-08-22T07:47:22Z\",\n \"Type\" : \"AWS-HMAC\",\n \"AccessKeyId\" : \"AAAAAAAA\",\n \"SecretAccessKey\" : \"SSSSSSSS\",\n \"Token\" : \"12345678\",\n \"Expiration\" : \"2012-08-22T11:25:52Z\"\n}", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["iam"]).to be_nil end end it "ignores \"./\" and \"../\" on ec2 metadata paths to avoid infinity loops" do expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/") .and_return(double("Net::HTTP Response", body: ".\n./\n..\n../\npath1/.\npath2/./\npath3/..\npath4/../", code: "200")) expect(@http_client).not_to receive(:get) .with("/2012-01-12/meta-data/.") expect(@http_client).not_to receive(:get) .with("/2012-01-12/meta-data/./") expect(@http_client).not_to receive(:get) .with("/2012-01-12/meta-data/..") expect(@http_client).not_to receive(:get) .with("/2012-01-12/meta-data/../") expect(@http_client).not_to receive(:get) .with("/2012-01-12/meta-data/path1/..") expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/path1/") .and_return(double("Net::HTTP Response", body: "", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/path2/") .and_return(double("Net::HTTP Response", body: "", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/path3/") .and_return(double("Net::HTTP Response", body: "", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/path4/") .and_return(double("Net::HTTP Response", body: "", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil end it "completes the run despite unavailable metadata" do expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/") .and_return(double("Net::HTTP Response", body: "metrics/", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/metrics/") .and_return(double("Net::HTTP Response", body: "vhostmd", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/metrics/vhostmd") .and_return(double("Net::HTTP Response", body: "", code: "404")) expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/dynamic/instance-identity/document/") .and_return(double("Net::HTTP Response", body: "{\"accountId\":\"4815162342\"}", code: "200")) plugin.run expect(plugin[:ec2]).not_to be_nil expect(plugin[:ec2]["metrics"]).to be_nil expect(plugin[:ec2]["metrics_vhostmd"]).to be_nil end end # shared examples for ec2 describe "with amazon dmi bios version data" do before do allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_version").and_return(true) allow(File).to receive(:read).with("/sys/class/dmi/id/bios_version").and_return("4.2.amazon\n") end it_behaves_like "ec2" end describe "with non-amazon dmi bios version data" do before do allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_version").and_return(true) allow(File).to receive(:read).with("/sys/class/dmi/id/bios_version").and_return("1.0\n") end it_behaves_like "!ec2" end describe "with amazon dmi bios vendor data" do before do allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_vendor").and_return(true) allow(File).to receive(:read).with("/sys/class/dmi/id/bios_vendor").and_return("Amazon EC2\n") end it_behaves_like "ec2" end describe "with non-amazon dmi bios vendor data" do before do allow(File).to receive(:exist?).with("/sys/class/dmi/id/bios_vendor").and_return(true) allow(File).to receive(:read).with("/sys/class/dmi/id/bios_vendor").and_return("Xen\n") end it_behaves_like "!ec2" end describe "with EC2 Xen UUID" do before do allow(File).to receive(:exist?).with("/sys/hypervisor/uuid").and_return(true) allow(File).to receive(:read).with("/sys/hypervisor/uuid").and_return("ec2a0561-e4d6-8e15-d9c8-2e0e03adcde8\n") end it_behaves_like "ec2" end describe "with non-EC2 Xen UUID" do before do allow(File).to receive(:exist?).with("/sys/hypervisor/uuid").and_return(true) allow(File).to receive(:read).with("/sys/hypervisor/uuid").and_return("123a0561-e4d6-8e15-d9c8-2e0e03adcde8\n") end it_behaves_like "!ec2" end describe "with EC2 Identifying Number", :windows_only do before do allow_any_instance_of(WmiLite::Wmi).to receive(:first_of).and_return( { "caption" => "Computer System Product", "description" => "Computer System Product", "identifyingnumber" => "ec2a355a-91cd-5fe8-bbfc-cc891d0bf9d6", "name" => "HVM domU", "skunumber" => nil, "uuid" => "5A352AEC-CD91-E85F-BBFC-CC891D0BF9D6", "vendor" => "Xen", "version" => "4.2.amazon" } ) end it_behaves_like "ec2" end describe "without EC2 Identifying Number", :windows_only do before do allow_any_instance_of(WmiLite::Wmi).to receive(:first_of).and_return( { "caption" => "Computer System Product", "description" => "Computer System Product", "identifyingnumber" => "1234", "name" => "HVM domU", "skunumber" => nil, "uuid" => "5A352AEC-CD91-E85F-BBFC-CC891D0BF9D6", "vendor" => "Xen", "version" => "1.2.3" } ) end it_behaves_like "!ec2" end describe "with ec2 hint file" do before do allow(plugin).to receive(:hint?).with("ec2").and_return({}) end it_behaves_like "ec2" end describe "without any hints that it is an ec2 system" do before do allow(plugin).to receive(:hint?).with("ec2").and_return(false) plugin[:dmi] = nil end it_behaves_like "!ec2" end end ohai-16.0.7/spec/unit/plugins/elixir_spec.rb000066400000000000000000000040501362624620500207570ustar00rootroot00000000000000# Author:: Christopher M Luciano () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language elixirverning permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin elixir" do let(:plugin) { get_plugin("elixir") } before do plugin[:languages] = Mash.new end it "shellouts to elixir -v" do expect(plugin).to receive(:shell_out).with("elixir -v").and_return(mock_shell_out(0, "Elixir 1.0.2", "")) plugin.run end it "sets languages[:elixir][:version] on older elixir" do allow(plugin).to receive(:shell_out).with("elixir -v").and_return(mock_shell_out(0, "Elixir 1.0.2", "")) plugin.run expect(plugin.languages[:elixir][:version]).to eql("1.0.2") end it "sets languages[:elixir][:version] on newer elixir" do new_stdout = "Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]\n\nElixir 1.2.4\n" allow(plugin).to receive(:shell_out).with("elixir -v").and_return(mock_shell_out(0, new_stdout, "")) plugin.run expect(plugin.languages[:elixir][:version]).to eql("1.2.4") end it "does not set languages[:elixir] if elixir command fails" do allow(plugin).to receive(:shell_out).with("elixir -v").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:elixir) end it "does not set languages[:elixir] if elixir command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:elixir) end end ohai-16.0.7/spec/unit/plugins/erlang_spec.rb000066400000000000000000000051761362624620500207450ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin erlang" do let(:plugin) { get_plugin("erlang") } before do plugin[:languages] = Mash.new erl_v_output = "Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 7.3\n" erl_systeminfo_output = "19.1,8.1,2.11" allow(plugin).to receive(:shell_out).with("erl +V") .and_return(mock_shell_out(0, "", erl_v_output)) allow(plugin).to receive(:shell_out).with("erl -eval '{ok, Ver} = file:read_file(filename:join([code:root_dir(), \"releases\", erlang:system_info(otp_release), \"OTP_VERSION\"])), Vsn = binary:bin_to_list(Ver, {0, byte_size(Ver) - 1}), io:format(\"~s,~s,~s\", [Vsn, erlang:system_info(version), erlang:system_info(nif_version)]), halt().' -noshell") .and_return(mock_shell_out(0, erl_systeminfo_output, "")) end it "sets languages[:erlang][:options]" do plugin.run expect(plugin.languages[:erlang][:options]).to eql(%w{SMP ASYNC_THREADS HIPE}) end it "sets languages[:erlang][:emulator]" do plugin.run expect(plugin.languages[:erlang][:emulator]).to eql("BEAM") end it "sets languages[:erlang][:version]" do plugin.run expect(plugin.languages[:erlang][:version]).to eql("19.1") end it "sets languages[:erlang][:erts_version]" do plugin.run expect(plugin.languages[:erlang][:erts_version]).to eql("8.1") end it "sets languages[:erlang][:nif_version]" do plugin.run expect(plugin.languages[:erlang][:nif_version]).to eql("2.11") end it "does not set languages[:erlang] if the erl commands fails" do allow(plugin).to receive(:shell_out).and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:erlang) end it "does not set languages[:erlang] if the erl command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:erlang) end end ohai-16.0.7/spec/unit/plugins/eucalyptus_spec.rb000066400000000000000000000074231362624620500216700ustar00rootroot00000000000000# # Author:: Tim Dysinger () # Author:: Christopher Brown (cb@chef.io) # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "open-uri" describe Ohai::System, "plugin eucalyptus" do let(:plugin) { get_plugin("eucalyptus") } shared_examples_for "!eucalyptus" do it "does NOT attempt to fetch the eucalyptus metadata" do expect(OpenURI).not_to receive(:open) plugin.run end end shared_examples_for "eucalyptus" do before do @http_client = double("Net::HTTP client") allow(plugin).to receive(:http_client).and_return(@http_client) expect(@http_client).to receive(:get) .with("/") .and_return(double("Net::HTTP Response", body: "2012-01-12", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/") .and_return(double("Net::HTTP Response", body: "instance_type\nami_id\nsecurity-groups", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/instance_type") .and_return(double("Net::HTTP Response", body: "c1.medium", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/ami_id") .and_return(double("Net::HTTP Response", body: "ami-5d2dc934", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/meta-data/security-groups") .and_return(double("Net::HTTP Response", body: "group1\ngroup2", code: "200")) expect(@http_client).to receive(:get) .with("/2012-01-12/user-data/") .and_return(double("Net::HTTP Response", body: "By the pricking of my thumb...", code: "200")) end it "recursively fetches all the eucalyptus metadata" do allow(IO).to receive(:select).and_return([[], [1], []]) t = double("connection") allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS) allow(Socket).to receive(:new).and_return(t) plugin.run expect(plugin[:eucalyptus]).not_to be_nil expect(plugin[:eucalyptus]["instance_type"]).to eq("c1.medium") expect(plugin[:eucalyptus]["ami_id"]).to eq("ami-5d2dc934") expect(plugin[:eucalyptus]["security_groups"]).to eql %w{group1 group2} end end describe "with eucalyptus mac and metadata address connected" do before do allow(IO).to receive(:select).and_return([[], [1], []]) plugin[:network] = { "interfaces" => { "eth0" => { "addresses" => { "d0:0d:95:47:6E:ED" => { "family" => "lladdr" } } } } } end it_behaves_like "eucalyptus" end describe "without eucalyptus mac and metadata address connected" do before do plugin[:network] = { "interfaces" => { "eth0" => { "addresses" => { "ff:ff:95:47:6E:ED" => { "family" => "lladdr" } } } } } end it_behaves_like "!eucalyptus" end describe "with eucalyptus hint file" do before do allow(plugin).to receive(:hint?).with("eucalyptus").and_return(true) end it_behaves_like "eucalyptus" end describe "without hint file" do before do plugin[:network] = { interfaces: {} } allow(plugin).to receive(:hint?).with("eucalyptus").and_return(false) end it_behaves_like "!eucalyptus" end end ohai-16.0.7/spec/unit/plugins/fail_spec.rb000066400000000000000000000121351362624620500204010ustar00rootroot00000000000000# # Author:: Toomas Pelberg (toomas.pelberg@playtech.com>) # Author:: Claire McQuin (claire@chef.io) # Copyright:: Copyright (c) 2011, 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" tmp = ENV["TMPDIR"] || ENV["TMP"] || ENV["TEMP"] || "/tmp" shared_examples "a v7 loading failure" do before(:all) do Dir.mkdir("#{tmp}/plugins") rescue Errno::EEXIST # ignore end before do fail_file = File.open("#{tmp}/plugins/fail.rb", "w+") fail_file.write(failstr) fail_file.close end after do File.delete("#{tmp}/plugins/fail.rb") end after(:all) do Dir.delete("#{tmp}/plugins") rescue # ignore end before do @ohai = Ohai::System.new @loader = Ohai::Loader.new(@ohai) end it "does not have attribute keys" do @loader.load_plugin("#{tmp}/plugins/fail.rb") # @ohai.attributes.should_not have_key("fail") expect { @ohai.provides_map.find_providers_for(["fail"]) }.to raise_error(Ohai::Exceptions::AttributeNotFound) end it "writes to Ohai::Log" do expect(@loader.logger).to receive(:warn).once @loader.load_plugin("#{tmp}/plugins/fail.rb") end end shared_examples "a v7 loading success" do before(:all) do Dir.mkdir("#{tmp}/plugins") rescue Errno::EEXIST # ignore end before do fail_file = File.open("#{tmp}/plugins/fail.rb", "w+") fail_file.write(failstr) fail_file.close end after do File.delete("#{tmp}/plugins/fail.rb") end after(:all) do Dir.delete("#{tmp}/plugins") rescue # ignore end before do @ohai = Ohai::System.new @loader = Ohai::Loader.new(@ohai) end it "has attribute keys" do @loader.load_plugin("#{tmp}/plugins/fail.rb") expect(@ohai.provides_map).to have_key("fail") end it "does not write to Ohai::Log" do expect(@loader.logger).not_to receive(:warn) @loader.load_plugin("#{tmp}/plugins/fail.rb") end end shared_examples "a v7 run failure" do before(:all) do Dir.mkdir("#{tmp}/plugins") rescue Errno::EEXIST # ignore end before do fail_file = File.open("#{tmp}/plugins/fail.rb", "w+") fail_file.write(failstr) fail_file.close end after do File.delete("#{tmp}/plugins/fail.rb") end after(:all) do Dir.delete("#{tmp}/plugins") rescue # ignore end before do @ohai = Ohai::System.new @loader = Ohai::Loader.new(@ohai) end it "does not have new attribute keys" do @loader.load_plugin("#{tmp}/plugins/fail.rb").new(@ohai).run expect(@ohai.provides_map).not_to have_key("other") end it "writes to Ohai::Log" do expect(@loader.logger).to receive(:warn).once @loader.load_plugin("#{tmp}/plugins/fail.rb").new(@ohai).run end end describe "when using DSL commands outside Ohai.plugin block" do failstr1 = <<~EOF provides "fail" Ohai.plugin do end EOF failstr2 = <<~EOF depends "fail" Ohai.plugin do end EOF failstr3 = <<~EOF collect_data do end Ohai.plugin do end EOF it_behaves_like "a v7 loading failure" do let(:failstr) { failstr1 } end it_behaves_like "a v7 loading failure" do let(:failstr) { failstr2 } end it_behaves_like "a v7 loading failure" do let(:failstr) { failstr3 } end end describe "when using nonexistent DSL commands in Ohai.plugin block" do failstr = "Ohai.plugin do\n\tcreates \"fail\"\nend\n" it_behaves_like "a v7 loading failure" do let(:failstr) { failstr } end end =begin describe "when using DSL commands in collect_data block" do failstr1 = < # Copyright:: Copyright (c) 2014 Limelight Networks, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "FreeBSD cpu plugin on FreeBSD >=10.2" do before do @plugin = get_plugin("cpu") allow(@plugin).to receive(:collect_os).and_return(:freebsd) @double_file = double("/var/run/dmesg.boot") allow(@double_file).to receive(:each) .and_yield("CPU: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz (2793.59-MHz K8-class CPU)") .and_yield(' Origin="GenuineIntel" Id=0x40661 Family=0x6 Model=0x46 Stepping=1') .and_yield(" Features=0x783fbff") .and_yield(" Features2=0x5ed8220b") .and_yield(" AMD Features=0x28100800") .and_yield(" AMD Features2=0x21") .and_yield(" Structured Extended Features=0x2000") .and_yield(" TSC: P-state invariant") .and_yield("real memory = 1073676288 (1023 MB)") .and_yield("avail memory = 1010253824 (963 MB)") .and_yield('Event timer "LAPIC" quality 400') .and_yield("ACPI APIC Table: ") .and_yield("FreeBSD/SMP: Multiprocessor System Detected: 16 CPUs") .and_yield("FreeBSD/SMP: 2 package(s) x 4 core(s) x 2 SMT threads") allow(File).to receive(:open).with("/var/run/dmesg.boot").and_return(@double_file) end it "detects all CPU flags" do @plugin.run expect(@plugin[:cpu][:flags]).to eq(%w{fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse sse2 sse3 pclmulqdq mon ssse3 cx16 sse4.1 sse4.2 movbe popcnt aesni xsave osxsave avx rdrand syscall nx rdtscp lm lahf abm nfpusg}) end it "detects CPU model_name" do @plugin.run expect(@plugin[:cpu][:model_name]).to eq("Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz") end it "detects CPU mhz" do @plugin.run expect(@plugin[:cpu][:mhz]).to eq("2793.59") end it "detects CPU vendor_id" do @plugin.run expect(@plugin[:cpu][:vendor_id]).to eq("GenuineIntel") end it "detects CPU family" do @plugin.run expect(@plugin[:cpu][:family]).to eq("6") end it "detects CPU model" do @plugin.run expect(@plugin[:cpu][:model]).to eq("70") end it "detects CPU stepping" do @plugin.run expect(@plugin[:cpu][:stepping]).to eq("1") end it "detects real CPUs" do @plugin.run expect(@plugin[:cpu][:real]).to eq(2) end it "detects total real CPU cores" do @plugin.run expect(@plugin[:cpu][:cores]).to eq(8) end it "detects total HT CPU cores" do @plugin.run expect(@plugin[:cpu][:total]).to eq(16) end end describe Ohai::System, "FreeBSD cpu plugin on FreeBSD <=10.1" do before do @plugin = get_plugin("cpu") allow(@plugin).to receive(:collect_os).and_return(:freebsd) allow(@plugin).to receive(:shell_out).with("sysctl -n hw.ncpu").and_return(mock_shell_out(0, "2", "")) @double_file = double("/var/run/dmesg.boot") allow(@double_file).to receive(:each) .and_yield("CPU: Intel(R) Atom(TM) CPU N270 @ 1.60GHz (1596.03-MHz 686-class CPU)") .and_yield(' Origin = "GenuineIntel" Id = 0x106c2 Family = 0x6 Model = 0x1c Stepping = 2') allow(File).to receive(:open).with("/var/run/dmesg.boot").and_return(@double_file) end it "detects CPU vendor_id" do @plugin.run expect(@plugin[:cpu][:vendor_id]).to eq("GenuineIntel") end it "detects CPU family" do @plugin.run expect(@plugin[:cpu][:family]).to eq("6") end it "detects CPU model" do @plugin.run expect(@plugin[:cpu][:model]).to eq("28") end it "detects CPU stepping" do @plugin.run expect(@plugin[:cpu][:stepping]).to eq("2") end end ohai-16.0.7/spec/unit/plugins/freebsd/hostname_spec.rb000066400000000000000000000026711362624620500227220ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "FreeBSD hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:freebsd) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return(mock_shell_out(0, "katie", "")) allow(@plugin).to receive(:shell_out).with("hostname -f").and_return(mock_shell_out(0, "katie.bethell", "")) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie.local", "")) end it_should_check_from("freebsd::hostname", "hostname", "hostname -s", "katie") it_should_check_from("freebsd::hostname", "fqdn", "hostname -f", "katie.bethell") it_should_check_from("freebsd::hostname", "machinename", "hostname", "katie.local") end ohai-16.0.7/spec/unit/plugins/freebsd/kernel_spec.rb000066400000000000000000000027211362624620500223600ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "FreeBSD kernel plugin" do before do @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:freebsd) allow(@plugin).to receive(:init_kernel).and_return({ name: "freebsd" }) allow(@plugin).to receive(:shell_out).with("uname -i").and_return(mock_shell_out(0, "foo\n", "")) allow(@plugin).to receive(:shell_out).with("sysctl kern.securelevel").and_return(mock_shell_out(0, "kern.securelevel: 1", "")) allow(@plugin).to receive(:shell_out).with( Ohai.abs_path( "/sbin/kldstat" )).and_return(mock_shell_out(0, " 1 7 0xc0400000 97f830 kernel", "")) end it "sets the kernel_os to the kernel_name value" do @plugin.run expect(@plugin[:kernel][:os]).to eq(@plugin[:kernel][:name]) end end ohai-16.0.7/spec/unit/plugins/freebsd/platform_spec.rb000066400000000000000000000025001362624620500227170ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "FreeBSD plugin platform" do before do @plugin = get_plugin("freebsd/platform") allow(@plugin).to receive(:shell_out).with("uname -s").and_return(mock_shell_out(0, "FreeBSD\n", "")) allow(@plugin).to receive(:shell_out).with("uname -r").and_return(mock_shell_out(0, "7.1\n", "")) allow(@plugin).to receive(:collect_os).and_return(:freebsd) end it "sets platform to lowercased lsb[:id]" do @plugin.run expect(@plugin[:platform]).to eq("freebsd") end it "sets platform_version to lsb[:release]" do @plugin.run expect(@plugin[:platform_version]).to eq("7.1") end end ohai-16.0.7/spec/unit/plugins/gce_spec.rb000066400000000000000000000046701362624620500202310ustar00rootroot00000000000000# # Author:: Ranjib Dey (dey.ranjib@gmail.com) # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDIT"Net::HTTP Response"NS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "open-uri" describe Ohai::System, "plugin gce" do let(:plugin) { get_plugin("gce") } shared_examples_for "!gce" do it "does NOT attempt to fetch the gce metadata" do expect(plugin).not_to receive(:http_get) plugin.run end it "does NOT set gce attributes" do expect(plugin[:gce]).to be_nil plugin.run end end shared_examples_for "gce" do before do @http_get = double("Net::HTTP client") allow(plugin).to receive(:http_get).and_return(double("Net::HTTP Response", body: '{"instance":{"hostname":"test-host"}}', code: "200")) allow(IO).to receive(:select).and_return([[], [1], []]) t = double("connection") allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS) allow(Socket).to receive(:new).and_return(t) allow(Socket).to receive(:pack_sockaddr_in).and_return(nil) end it "recursively fetches and properly parses json metadata" do plugin.run expect(plugin[:gce]).not_to be_nil expect(plugin[:gce]["instance"]).to eq("hostname" => "test-host") end end describe "with hint file and with metadata connection" do before do allow(plugin).to receive(:hint?).with("gce").and_return({}) end it_behaves_like "gce" end describe "without hint file and without metadata connection" do before do allow(plugin).to receive(:hint?).with("gce").and_return(false) # Raise Errno::ENOENT to simulate the scenario in which metadata server # can not be connected t = double("connection") allow(t).to receive(:connect_nonblock).and_raise(Errno::ENOENT) allow(Socket).to receive(:new).and_return(t) allow(Socket).to receive(:pack_sockaddr_in).and_return(nil) end it_behaves_like "!gce" end end ohai-16.0.7/spec/unit/plugins/go_spec.rb000066400000000000000000000031411362624620500200700ustar00rootroot00000000000000# Author:: Christian Vozar () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "plugin go" do let(:plugin) { get_plugin("go") } before do plugin[:languages] = Mash.new stdout = "go version go1.6.1 darwin/amd64\n" allow(plugin).to receive(:shell_out).with("go version").and_return(mock_shell_out(0, stdout, "")) end it "shells out to get the go version" do expect(plugin).to receive(:shell_out).with("go version") plugin.run end it "sets languages[:go][:version]" do plugin.run expect(plugin.languages[:go][:version]).to eql("1.6.1") end it "does not set languages[:go] if go command fails" do allow(plugin).to receive(:shell_out).with("go version").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:go) end it "does not set languages[:go] if go command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:go) end end ohai-16.0.7/spec/unit/plugins/groovy_spec.rb000066400000000000000000000047321362624620500210170ustar00rootroot00000000000000# # Author:: Doug MacEachern # Copyright:: Copyright (c) 2009 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin groovy" do let(:plugin) { get_plugin("groovy") } before do plugin[:languages] = Mash.new end it "shells out to groovy -v" do allow(plugin).to receive(:shell_out).with("groovy -v").and_return(mock_shell_out(0, "", "")) expect(plugin).to receive(:shell_out).with("groovy -v") plugin.run end it "sets languages[:groovy][:version] on newer groovy versions" do new_stdout = "Groovy Version: 2.4.6 JVM: 1.8.0_60 Vendor: Oracle Corporation OS: Mac OS X\n" allow(plugin).to receive(:shell_out).with("groovy -v").and_return(mock_shell_out(0, new_stdout, "")) plugin.run expect(plugin.languages[:groovy][:version]).to eql("2.4.6") end it "sets languages[:groovy][:version] on older groovy versions" do old_stdout = "Groovy Version: 1.6.3 JVM: 1.6.0_0\n" allow(plugin).to receive(:shell_out).with("groovy -v").and_return(mock_shell_out(0, old_stdout, "")) plugin.run expect(plugin.languages[:groovy][:version]).to eql("1.6.3") end it "sets languages[:groovy][:jvm]" do new_stdout = "Groovy Version: 2.4.6 JVM: 1.8.0_60 Vendor: Oracle Corporation OS: Mac OS X\n" allow(plugin).to receive(:shell_out).with("groovy -v").and_return(mock_shell_out(0, new_stdout, "")) plugin.run expect(plugin.languages[:groovy][:jvm]).to eql("1.8.0_60") end it "does not set languages[:groovy] if groovy command fails" do allow(plugin).to receive(:shell_out).with("groovy -v").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:groovy) end it "does not set languages[:groovy] if groovy command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:groovy) end end ohai-16.0.7/spec/unit/plugins/haskell_spec.rb000066400000000000000000000160441362624620500211140ustar00rootroot00000000000000# Author:: Chris Dituri () # Copyright:: Copyright (c) 2016 Chris Dituri # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "plugin haskell" do let(:plugin) do get_plugin("haskell").tap do |plugin| plugin[:languages] = Mash.new end end let(:ghc_out) { "The Glorious Glasgow Haskell Compilation System, version 7.6.3" } let(:ghci_out) { "The Glorious Glasgow Haskell Compilation System, version 7.6.3" } let(:cabal_out) { "cabal-install version 1.16.0.2\nusing version 1.16.0 of the Cabal library" } let(:stack_out) { "Version 1.2.0 x86_64 hpack-0.14.0" } let(:stack_out_git) { "Version 1.1.0, Git revision 0e9430aad55841b5ff2c6c2851f0548c16bce7cf (3540 commits) x86_64 hpack-0.13.0" } def setup_plugin allow(plugin).to receive(:shell_out) .with("ghc --version") .and_return(mock_shell_out(0, ghc_out, "")) allow(plugin).to receive(:shell_out) .with("ghci --version") .and_return(mock_shell_out(0, ghci_out, "")) allow(plugin).to receive(:shell_out) .with("cabal --version") .and_return(mock_shell_out(0, cabal_out, "")) allow(plugin).to receive(:shell_out) .with("stack --version") .and_return(mock_shell_out(0, stack_out, "")) end context "when haskell/ghc is installed" do before do setup_plugin plugin.run end it "set languages[:haskell][:ghc][:version]" do expect(plugin[:languages][:haskell][:ghc][:version]).to eql("7.6.3") end it "set languages[:haskell][:ghc][:description]" do expect(plugin[:languages][:haskell][:ghc][:description]).to eql(ghc_out) end end context "when haskell/ghci is installed" do before do setup_plugin plugin.run end it "set languages[:haskell][:ghci][:version]" do expect(plugin[:languages][:haskell][:ghci][:version]).to eql("7.6.3") end it "set languages[:haskell][:ghci][:description]" do expect(plugin[:languages][:haskell][:ghci][:description]).to eql(ghci_out) end end context "when haskell/cabal is installed" do before do setup_plugin plugin.run end it "set languages[:haskell][:cabal][:version]" do expect(plugin[:languages][:haskell][:cabal][:version]).to eql("1.16.0.2") end it "set languages[:haskell][:cabal][:description]" do expect(plugin[:languages][:haskell][:cabal][:description]).to eql(cabal_out.split("\n")[0].chomp) end end context "when haskell/stack is installed" do before do setup_plugin plugin.run end it "set languages[:haskell][:stack][:version]" do expect(plugin[:languages][:haskell][:stack][:version]).to eql("1.2.0") end it "set languages[:haskell][:stack][:description]" do expect(plugin[:languages][:haskell][:stack][:description]).to eql(stack_out) end end context "when haskell/stack prerelease is installed" do before do setup_plugin allow(plugin).to receive(:shell_out) .with("stack --version") .and_return(mock_shell_out(0, stack_out_git, "")) plugin.run end it "set languages[:haskell][:stack][:version]" do expect(plugin[:languages][:haskell][:stack][:version]).to eql("1.1.0") end it "set languages[:haskell][:stack][:description]" do expect(plugin[:languages][:haskell][:stack][:description]).to eql(stack_out_git) end end context "when haskell is NOT installed" do before do allow(plugin).to receive(:shell_out) .and_raise( Ohai::Exceptions::Exec ) plugin.run end it "do NOT set languages[:haskell]" do expect(plugin[:languages]).not_to have_key(:haskell) end end context "when haskell/ghc is NOT installed" do before do allow(plugin).to receive(:shell_out) .with("ghc --version") .and_raise( Ohai::Exceptions::Exec ) allow(plugin).to receive(:shell_out) .with("ghci --version") .and_return(mock_shell_out(0, ghci_out, "")) allow(plugin).to receive(:shell_out) .with("cabal --version") .and_return(mock_shell_out(0, cabal_out, "")) allow(plugin).to receive(:shell_out) .with("stack --version") .and_return(mock_shell_out(0, stack_out, "")) plugin.run end it "do NOT set languages[:haskell][:ghc]" do expect(plugin[:languages][:haskell]).not_to have_key(:ghc) end end context "when haskell/ghci is NOT installed" do before do allow(plugin).to receive(:shell_out) .with("ghc --version") .and_return(mock_shell_out(0, ghc_out, "")) allow(plugin).to receive(:shell_out) .with("ghci --version") .and_raise( Ohai::Exceptions::Exec ) allow(plugin).to receive(:shell_out) .with("cabal --version") .and_return(mock_shell_out(0, cabal_out, "")) allow(plugin).to receive(:shell_out) .with("stack --version") .and_return(mock_shell_out(0, stack_out, "")) plugin.run end it "do NOT set languages[:haskell][:ghci]" do expect(plugin[:languages][:haskell]).not_to have_key(:ghci) end end context "when haskell/cabal is NOT installed" do before do allow(plugin).to receive(:shell_out) .with("ghc --version") .and_return(mock_shell_out(0, ghc_out, "")) allow(plugin).to receive(:shell_out) .with("ghci --version") .and_return(mock_shell_out(0, ghci_out, "")) allow(plugin).to receive(:shell_out) .with("cabal --version") .and_raise( Ohai::Exceptions::Exec ) allow(plugin).to receive(:shell_out) .with("stack --version") .and_return(mock_shell_out(0, stack_out, "")) plugin.run end it "do NOT set languages[:haskell][:cabal]" do expect(plugin[:languages][:haskell]).not_to have_key(:cabal) end end context "when haskell/stack is NOT installed" do before do allow(plugin).to receive(:shell_out) .with("ghc --version") .and_return(mock_shell_out(0, ghc_out, "")) allow(plugin).to receive(:shell_out) .with("ghci --version") .and_return(mock_shell_out(0, ghci_out, "")) allow(plugin).to receive(:shell_out) .with("cabal --version") .and_return(mock_shell_out(0, cabal_out, "")) allow(plugin).to receive(:shell_out) .with("stack --version") .and_raise( Ohai::Exceptions::Exec ) plugin.run end it "do NOT set languages[:haskell][:stack]" do expect(plugin[:languages][:haskell]).not_to have_key(:stack) end end end ohai-16.0.7/spec/unit/plugins/hostname_spec.rb000066400000000000000000000106461362624620500213110ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "wmi-lite/wmi" require "socket" describe Ohai::System, "hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:default) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie.local", "")) end context "default behavior" before do allow(@plugin).to receive(:resolve_fqdn).and_return("katie.bethell") end it_should_check_from("linux::hostname", "machinename", "hostname", "katie.local") it "uses #resolve_fqdn to find the fqdn" do @plugin.run expect(@plugin[:fqdn]).to eq("katie.bethell") end it "sets the domain to everything after the first dot of the fqdn" do @plugin.run expect(@plugin[:domain]).to eq("bethell") end it "sets the [short] hostname to everything before the first dot of the fqdn" do @plugin.run expect(@plugin[:hostname]).to eq("katie") end context "when a system has a bare hostname without a FQDN" do before do allow(@plugin).to receive(:collect_os).and_return(:default) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie", "")) end it "correctlies set the [short] hostname" do @plugin.run expect(@plugin[:hostname]).to eq("katie") end end context "hostname --fqdn when it returns empty string" do before do allow(@plugin).to receive(:collect_os).and_return(:linux) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return( mock_shell_out(0, "katie", "") ) allow(@plugin).to receive(:shell_out).with("hostname --fqdn").and_return( mock_shell_out(0, "", ""), mock_shell_out(0, "katie.local", "") ) end it "is called twice" do @plugin.run expect(@plugin[:fqdn]).to eq("katie.local") end end context "hostname --fqdn when it works" do before do allow(@plugin).to receive(:collect_os).and_return(:linux) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return( mock_shell_out(0, "katie", "") ) allow(@plugin).to receive(:shell_out).with("hostname --fqdn").and_return( mock_shell_out(0, "katie.local", "") ) end it "is not be called twice" do @plugin.run expect(@plugin[:fqdn]).to eq("katie.local") end end end describe Ohai::System, "hostname plugin for windows", :windows_only do let(:success) { true } let(:host) do { "name" => "local", "dnshostname" => "local", } end let(:info) do [ "local", [], 23, "address1", "address2", "address3", "address4", ] end let(:local_hostent) do [ "local", [], 23, "address", ] end let(:fqdn_hostent) do [ "local.dx.internal.cloudapp.net", [], 23, "address", ] end before do @plugin = get_plugin("hostname") allow(WmiLite::Wmi).to receive(:new).and_return(success) allow(success).to receive(:first_of).with("Win32_ComputerSystem").and_return(host) allow(Socket).to receive(:gethostname).and_return("local") allow(Socket).to receive(:gethostbyname).with(anything).and_return(info) end context "when hostname is not set for the machine" do it "returns short machine name" do allow(Socket).to receive(:gethostbyaddr).with(anything).and_return(local_hostent) @plugin.run expect(@plugin[:fqdn]).to eq("local") end end context "when hostname is set for the machine" do it "returns the fqdn of the machine" do allow(Socket).to receive(:gethostbyaddr).with(anything).and_return(fqdn_hostent) @plugin.run expect(@plugin[:fqdn]).to eq("local.dx.internal.cloudapp.net") end end end ohai-16.0.7/spec/unit/plugins/init_package_spec.rb000066400000000000000000000033561362624620500221110ustar00rootroot00000000000000# # Author:: Caleb Tennis () # Copyright:: Copyright (c) 2012-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Init package" do let(:plugin) do p = get_plugin("init_package") allow(p).to receive(:collect_os).and_return("linux") p end let(:proc1_content) { "init\n" } let(:proc1_exists) { true } let(:proc_1_file_path) { "/proc/1/comm" } let(:proc_1_file) { double(proc_1_file_path, gets: proc1_content) } before do allow(File).to receive(:exist?).with(proc_1_file_path).and_return(proc1_exists) allow(File).to receive(:open).with(proc_1_file_path).and_return(proc_1_file) end it "sets init_package to init" do plugin.run expect(plugin[:init_package]).to eq("init") end describe "when init_package is systemd" do let(:proc1_content) { "systemd\n" } it "sets init_package to systemd" do plugin.run expect(plugin[:init_package]).to eq("systemd") end end describe "when /proc/1/comm doesn't exist" do let(:proc1_exists) { false } it "sets init_package to init" do plugin.run expect(plugin[:init_package]).to eq("init") end end end ohai-16.0.7/spec/unit/plugins/java_spec.rb000066400000000000000000000175071362624620500204170ustar00rootroot00000000000000# # Author:: Benjamin Black () # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin java (Java5 Client VM)" do let(:plugin) { get_plugin("java") } before do plugin[:languages] = Mash.new end shared_examples_for "when the JRE is installed" do before do stderr = "java version \"1.5.0_16\"\nJava(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284)\nJava HotSpot(TM) Client VM (build 1.5.0_16-133, mixed mode, sharing)" allow(plugin).to receive(:shell_out).with("java -mx64m -version").and_return(mock_shell_out(0, "", stderr)) end it "runs java -mx64m -version" do expect(plugin).to receive(:shell_out).with("java -mx64m -version") plugin.run end it "sets java[:version]" do plugin.run expect(plugin[:languages][:java][:version]).to eql("1.5.0_16") end it "sets java[:runtime][:name] to runtime name" do plugin.run expect(plugin[:languages][:java][:runtime][:name]).to eql("Java(TM) 2 Runtime Environment, Standard Edition") end it "sets java[:runtime][:build] to runtime build" do plugin.run expect(plugin[:languages][:java][:runtime][:build]).to eql("1.5.0_16-b06-284") end it "sets java[:hotspot][:name] to hotspot name" do plugin.run expect(plugin[:languages][:java][:hotspot][:name]).to eql("Java HotSpot(TM) Client VM") end it "sets java[:hotspot][:build] to hotspot build" do plugin.run expect(plugin[:languages][:java][:hotspot][:build]).to eql("1.5.0_16-133, mixed mode, sharing") end it "does not set the languages[:java] tree up if java command fails" do stderr = "Some error output here" allow(plugin).to receive(:shell_out).with("java -mx64m -version").and_return(mock_shell_out(1, "", stderr)) plugin.run expect(plugin[:languages]).not_to have_key(:java) end it "does not set the languages[:java] tree up if java command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin[:languages]).not_to have_key(:java) end end shared_examples_for "when the Server JRE is installed" do before do stderr = "java version \"1.6.0_22\"\nJava(TM) 2 Runtime Environment (build 1.6.0_22-b04)\nJava HotSpot(TM) Server VM (build 17.1-b03, mixed mode)" allow(plugin).to receive(:shell_out).with("java -mx64m -version").and_return(mock_shell_out(0, "", stderr)) end it "runs java -mx64m -version" do expect(plugin).to receive(:shell_out).with("java -mx64m -version") plugin.run end it "sets java[:version]" do plugin.run expect(plugin[:languages][:java][:version]).to eql("1.6.0_22") end it "sets java[:runtime][:name] to runtime name" do plugin.run expect(plugin[:languages][:java][:runtime][:name]).to eql("Java(TM) 2 Runtime Environment") end it "sets java[:runtime][:build] to runtime build" do plugin.run expect(plugin[:languages][:java][:runtime][:build]).to eql("1.6.0_22-b04") end it "sets java[:hotspot][:name] to hotspot name" do plugin.run expect(plugin[:languages][:java][:hotspot][:name]).to eql("Java HotSpot(TM) Server VM") end it "sets java[:hotspot][:build] to hotspot build" do plugin.run expect(plugin[:languages][:java][:hotspot][:build]).to eql("17.1-b03, mixed mode") end it "does not set the languages[:java] tree up if java command fails" do stderr = "Some error output here" allow(plugin).to receive(:shell_out).with("java -mx64m -version").and_return(mock_shell_out(0, "", stderr)) plugin.run expect(plugin[:languages]).not_to have_key(:java) end end shared_examples_for "when the openjdk 1.8 is installed" do before do stderr = "openjdk version \"1.8.0_71\"\nOpenJDK Runtime Environment (build 1.8.0_71-b15)\nOpenJDK 64-Bit Server VM (build 25.71-b15, mixed mode)" allow(plugin).to receive(:shell_out).with("java -mx64m -version").and_return(mock_shell_out(0, "", stderr)) end it "runs java -mx64m -version" do expect(plugin).to receive(:shell_out).with("java -mx64m -version") plugin.run end it "sets java[:version]" do plugin.run expect(plugin[:languages][:java][:version]).to eql("1.8.0_71") end it "sets java[:runtime][:name] to runtime name" do plugin.run expect(plugin[:languages][:java][:runtime][:name]).to eql("OpenJDK Runtime Environment") end it "sets java[:runtime][:build] to runtime build" do plugin.run expect(plugin[:languages][:java][:runtime][:build]).to eql("1.8.0_71-b15") end it "sets java[:hotspot][:name] to hotspot name" do plugin.run expect(plugin[:languages][:java][:hotspot][:name]).to eql("OpenJDK 64-Bit Server VM") end it "sets java[:hotspot][:build] to hotspot build" do plugin.run expect(plugin[:languages][:java][:hotspot][:build]).to eql("25.71-b15, mixed mode") end it "does not set the languages[:java] tree up if java command fails" do stderr = "Some error output here" allow(plugin).to receive(:shell_out).with("java -mx64m -version").and_return(mock_shell_out(0, "", stderr)) plugin.run expect(plugin[:languages]).not_to have_key(:java) end end context "when not on Mac OS X" do before do stub_const("RUBY_PLATFORM", "x86_64-linux") end context "and the client JRE is installed" do include_examples "when the JRE is installed" end context "and the server JRE is installed" do include_examples "when the Server JRE is installed" end context "and the openjdk 1.8 is installed" do include_examples "when the openjdk 1.8 is installed" end end context "when on Mac OS X with Java installed" do before do stub_const("RUBY_PLATFORM", "x86_64-darwin12.3.0") end it "detects that it is on a darwin platform" do expect(plugin).to be_on_darwin end context "and real Java is installed" do before do java_home_status = double(Process::Status, success?: true) java_home_cmd = double(Mixlib::ShellOut, status: java_home_status) expect(plugin).to receive(:shell_out).with("/usr/libexec/java_home").and_return(java_home_cmd) end context "and the client JRE is installed" do include_examples "when the JRE is installed" end context "and the server JRE is installed" do include_examples "when the Server JRE is installed" end context "and the openjdk 1.8 is installed" do include_examples "when the openjdk 1.8 is installed" end end context "and the JVM stubs are installed" do before do java_home_status = double(Process::Status, success?: false) java_home_cmd = double(Mixlib::ShellOut, status: java_home_status) expect(plugin).to receive(:shell_out).with("/usr/libexec/java_home").and_return(java_home_cmd) end it "does not attempt to get java info" do expect(plugin).not_to receive(:shell_out).with("java -mx64m -version") plugin.run expect(plugin[:languages]).not_to have_key(:java) end end end end ohai-16.0.7/spec/unit/plugins/joyent_spec.rb000066400000000000000000000056421362624620500210030ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin joyent" do let(:plugin) { get_plugin("joyent") } describe "without joyent" do before do allow(plugin).to receive(:is_smartos?).and_return(false) end it "DOES NOT create joyent mash" do plugin.run expect(plugin[:joyent]).to be_nil end end describe "with joyent" do before do allow(plugin).to receive(:is_smartos?).and_return(true) plugin[:virtualization] = Mash.new plugin[:virtualization][:guest_uuid] = "global" end it "creates joyent mash" do plugin.run expect(plugin[:joyent]).not_to be_nil end describe "under global zone" do before do plugin.run end it "detects global zone" do expect(plugin[:joyent][:sm_uuid]).to eql "global" end it "DOES NOT create sm_id" do expect(plugin[:joyent][:sm_id]).to be_nil end end describe "under smartmachine" do before do plugin[:virtualization][:guest_uuid] = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" plugin[:virtualization][:guest_id] = "30" etc_product = <<~EOS Name: Joyent Instance Image: pkgbuild 16.3.1 Documentation: https://docs.joyent.com/images/smartos/pkgbuild EOS pkg_install_conf = <<~EOS GPG_KEYRING_VERIFY=/opt/local/etc/gnupg/pkgsrc.gpg GPG_KEYRING_PKGVULN=/opt/local/share/gnupg/pkgsrc-security.gpg PKG_PATH=https://pkgsrc.joyent.com/packages/SmartOS/2016Q3/x86_64/All VERIFIED_INSTALLATION=trusted EOS allow(::File).to receive(:read).with("/etc/product").and_return(etc_product) allow(::File).to receive(:read).with("/opt/local/etc/pkg_install.conf").and_return(pkg_install_conf) plugin.run end it "retrieves zone uuid" do expect(plugin[:joyent][:sm_uuid]).to eql "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" end it "collects sm_id" do expect(plugin[:joyent][:sm_id]).to eql "30" end it "collects images" do expect(plugin[:joyent][:sm_image_id]).to eql "pkgbuild" expect(plugin[:joyent][:sm_image_ver]).to eql "16.3.1" end it "collects pkgsrc" do expect(plugin[:joyent][:sm_pkgsrc]).to eql "https://pkgsrc.joyent.com/packages/SmartOS/2016Q3/x86_64/All" end end end end ohai-16.0.7/spec/unit/plugins/kernel_spec.rb000066400000000000000000000040551362624620500207500ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin kernel" do before do @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:default) # for debugging allow(@plugin).to receive(:shell_out).with("uname -s").and_return(mock_shell_out(0, "Darwin\n", "")) allow(@plugin).to receive(:shell_out).with("uname -r").and_return(mock_shell_out(0, "9.5.0\n", "")) allow(@plugin).to receive(:shell_out).with("uname -v").and_return(mock_shell_out(0, "Darwin Kernel Version 9.5.0: Wed Sep 3 11:29:43 PDT 2008; root:xnu-1228.7.58~1\/RELEASE_I386\n", "")) allow(@plugin).to receive(:shell_out).with("uname -m").and_return(mock_shell_out(0, "i386\n", "")) allow(@plugin).to receive(:shell_out).with("uname -o").and_return(mock_shell_out(0, "Linux\n", "")) allow(@plugin).to receive(:shell_out).with("uname -p").and_return(mock_shell_out(0, "i386\n", "")) end it_should_check_from_mash("kernel", "name", "uname -s", [0, "Darwin\n", ""]) it_should_check_from_mash("kernel", "release", "uname -r", [0, "9.5.0\n", ""]) it_should_check_from_mash("kernel", "version", "uname -v", [0, "Darwin Kernel Version 9.5.0: Wed Sep 3 11:29:43 PDT 2008; root:xnu-1228.7.58~1\/RELEASE_I386\n", ""]) it_should_check_from_mash("kernel", "machine", "uname -m", [0, "i386\n", ""]) it_should_check_from_mash("kernel", "processor", "uname -p", [0, "i386\n", ""]) end ohai-16.0.7/spec/unit/plugins/linode_spec.rb000066400000000000000000000066551362624620500207520ustar00rootroot00000000000000# # Author:: Aaron Kalin () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin linode" do let(:plugin) { get_plugin("linode") } before do plugin[:network] = { "interfaces" => { "eth0" => { "addresses" => { "1.2.3.4" => { "broadcast" => "67.23.20.255", "netmask" => "255.255.255.0", "family" => "inet", }, "fe80::4240:95ff:fe47:6eed" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "40:40:95:47:6E:ED" => { "family" => "lladdr", }, }, }, }, } end shared_examples_for "!linode" do it "does not create the linode mash" do plugin.run expect(plugin[:linode]).to be_nil end end shared_examples_for "linode" do it "creates the linode mash" do plugin.run expect(plugin[:linode]).not_to be_nil end it "has public_ip attribute" do plugin.run expect(plugin[:linode][:public_ip]).not_to be_nil end it "has correct value for public_ip attribute" do plugin.run expect(plugin[:linode][:public_ip]).to eq("1.2.3.4") end end context "without linode kernel" do before do plugin[:kernel] = { "release" => "3.5.2-x86_64" } end it_behaves_like "!linode" end context "with linode kernel" do before do plugin[:kernel] = { "release" => "3.5.2-x86_64-linode24" } end it_behaves_like "linode" # This test is an interface created according to this guide by Linode # http://library.linode.com/networking/configuring-static-ip-interfaces context "with configured private ip address as suggested by linode" do before do plugin[:network][:interfaces]["eth0:1"] = { "addresses" => { "5.6.7.8" => { "broadcast" => "10.176.191.255", "netmask" => "255.255.224.0", "family" => "inet", }, "fe80::4240:f5ff:feab:2836" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "40:40:F5:AB:28:36" => { "family" => "lladdr", }, }, } end it "detects and sets the private ip" do plugin.run expect(plugin[:linode][:private_ip]).not_to be_nil expect(plugin[:linode][:private_ip]).to eq("5.6.7.8") end end end describe "with linode hint file" do before do allow(plugin).to receive(:hint?).with("linode").and_return({}) end it_behaves_like "linode" end describe "without hint file" do before do allow(plugin).to receive(:hint?).with("linode").and_return(false) end it_behaves_like "!linode" end end ohai-16.0.7/spec/unit/plugins/linux/000077500000000000000000000000001362624620500172645ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/linux/block_device_spec.rb000066400000000000000000000042071362624620500232370ustar00rootroot00000000000000# # Author:: Jennifer Marie Howard-Brown # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux Block Device Plugin" do DISKS = { "sda" => { "size" => "7814037168", "removable" => "0", "model" => "WDC WD4000F9YZ-0", "rev" => "1A01", "state" => "running", "timeout" => "30", "queue_depth" => "1", "vendor" => "ATA", }, "dm-0" => { "size" => "7806976", "removable" => "0", }, }.freeze def file_double(value) tmp_double = double expect(tmp_double).to receive(:read_nonblock).and_return(value) tmp_double end before do @plugin = get_plugin("linux/block_device") allow(@plugin).to receive(:collect_os).and_return(:linux) allow(File).to receive(:exist?).with("/sys/block").and_return(true) allow(Dir).to receive(:[]).with("/sys/block/*") do DISKS.collect { |disk, _files| "/sys/block/#{disk}" } end DISKS.each do |disk, checks| checks.each do |check, value| allow(File).to receive(:open).with(Regexp.new("#{disk}.*#{check}")).and_yield(file_double(value)) end allow(File).to receive(:exist?).with(Regexp.new(disk)) do |arg| filepath = arg.split("/") checks[filepath.last].nil? ? false : true end allow(File).to receive(:basename) do |arg| arg.split("/").last end end end it "collects all relevant data from disks" do @plugin.run DISKS.each do |disk, checks| expect(@plugin[:block_device][disk.to_sym]).to include(checks) end end end ohai-16.0.7/spec/unit/plugins/linux/cpu_spec.rb000066400000000000000000000357521362624620500214260ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "tempfile" require "spec_helper" shared_examples "Common cpu info" do |total_cpu, real_cpu| describe "cpu" do it "has cpu[:total] equals to #{total_cpu}" do plugin.run expect(plugin[:cpu][:total]).to eq(total_cpu) end it "has cpu[:real] equals to #{real_cpu}" do plugin.run expect(plugin[:cpu][:real]).to eq(real_cpu) end it "has a cpu 0" do plugin.run expect(plugin[:cpu]).to have_key("0") end end end shared_examples "S390 processor info" do |cpu_no, version, identification, machine| describe "S390 processor" do it "has a version for cpu #{cpu_no}" do plugin.run expect(plugin[:cpu][cpu_no.to_s]).to have_key("version") expect(plugin[:cpu][cpu_no.to_s]["version"]).to eql(version) end it "has a identification for cpu #{cpu_no}" do plugin.run expect(plugin[:cpu][cpu_no.to_s]).to have_key("identification") expect(plugin[:cpu][cpu_no.to_s]["identification"]).to eql(identification) end it "has a machine for cpu #{cpu_no}" do plugin.run expect(plugin[:cpu][cpu_no.to_s]).to have_key("machine") expect(plugin[:cpu][cpu_no.to_s]["machine"]).to eql(machine) end end end shared_examples "arm64 processor info" do |cpu_no, bogomips, features| describe "arm64 processor" do it "has bogomips for cpu #{cpu_no}" do plugin.run expect(plugin[:cpu][cpu_no.to_s]).to have_key("bogomips") expect(plugin[:cpu][cpu_no.to_s]["bogomips"]).to eql(bogomips) end it "has features for cpu #{cpu_no}" do plugin.run expect(plugin[:cpu][cpu_no.to_s]).to have_key("features") expect(plugin[:cpu][cpu_no.to_s]["features"]).to eql(features) end end end describe Ohai::System, "General Linux cpu plugin" do let(:plugin) { get_plugin("cpu") } let(:tempfile_handle) do tempfile = Tempfile.new("ohai-rspec-proc-cpuinfo") tempfile.write cpuinfo_contents tempfile.rewind tempfile end before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(File).to receive(:open).with("/proc/cpuinfo").and_return(tempfile_handle) end after do tempfile.close tempfile.unlink rescue # really do not care end context "with old kernel that doesn't include cores in /proc/cpuinfo" do let(:cpuinfo_contents) do <<-EOF processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 23 model name : Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz stepping : 6 cpu MHz : 1968.770 cache size : 64 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu pse tsc msr mce cx8 sep mtrr pge cmov bogomips : 2575.86 clflush size : 32 EOF end let(:lscpu) do <<~EOF Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 1 On-line CPU(s) list: 0 Thread(s) per core: 1 Core(s) per socket: 1 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 23 Model name: Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz Stepping: 2 CPU MHz: 1968.770 BogoMIPS: 2575.86 Hypervisor vendor: Xen Virtualization type: full L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 30720K NUMA node0 CPU(s): 0 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm fsgsbase bmi1 avx2 smep bmi2 erms invpcid xsaveopt EOF end before do allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(0, lscpu, "")) end it_behaves_like "Common cpu info", 1, 1 it "gets total cores" do plugin.run expect(plugin[:cpu][:cores]).to be(1) end it "doesn't have a cpu 1" do plugin.run expect(plugin[:cpu]).not_to have_key("1") end it "has a vendor_id for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("vendor_id") expect(plugin[:cpu]["0"]["vendor_id"]).to eql("GenuineIntel") end it "has a family for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("family") expect(plugin[:cpu]["0"]["family"]).to eql("6") end it "has a model for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("model") expect(plugin[:cpu]["0"]["model"]).to eql("23") end it "has a stepping for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("stepping") expect(plugin[:cpu]["0"]["stepping"]).to eql("6") end it "doesn't have a phyiscal_id for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).not_to have_key("physical_id") end it "doesn't have a core_id for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).not_to have_key("core_id") end it "doesn't have a cores for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).not_to have_key("cores") end it "has a model name for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("model_name") expect(plugin[:cpu]["0"]["model_name"]).to eql("Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz") end it "has a mhz for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("mhz") expect(plugin[:cpu]["0"]["mhz"]).to eql("1968.770") end it "has a cache_size for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("cache_size") expect(plugin[:cpu]["0"]["cache_size"]).to eql("64 KB") end it "has flags for cpu 0" do plugin.run expect(plugin[:cpu]["0"]).to have_key("flags") expect(plugin[:cpu]["0"]["flags"]).to eq(%w{fpu pse tsc msr mce cx8 sep mtrr pge cmov}) end end context "with a dual-core hyperthreaded /proc/cpuinfo" do let(:cpuinfo_contents) do <<~EOF processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 69 model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz stepping : 1 microcode : 0x17 cpu MHz : 774.000 cache size : 4096 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid bogomips : 3591.40 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management: processor : 1 vendor_id : GenuineIntel cpu family : 6 model : 69 model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz stepping : 1 microcode : 0x17 cpu MHz : 1600.000 cache size : 4096 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 2 apicid : 1 initial apicid : 1 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid bogomips : 3591.40 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management: processor : 2 vendor_id : GenuineIntel cpu family : 6 model : 69 model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz stepping : 1 microcode : 0x17 cpu MHz : 800.000 cache size : 4096 KB physical id : 0 siblings : 4 core id : 1 cpu cores : 2 apicid : 2 initial apicid : 2 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid bogomips : 3591.40 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management: processor : 3 vendor_id : GenuineIntel cpu family : 6 model : 69 model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz stepping : 1 microcode : 0x17 cpu MHz : 774.000 cache size : 4096 KB physical id : 0 siblings : 4 core id : 1 cpu cores : 2 apicid : 3 initial apicid : 3 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid bogomips : 3591.40 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management: EOF end it "has 1 physical socket" do plugin.run expect(plugin[:cpu][:real]).to eq(1) end it "has 2 physical cores" do plugin.run expect(plugin[:cpu][:cores]).to eq(2) end it "has 4 logical, hyper-threaded cores" do plugin.run expect(plugin[:cpu][:total]).to eq(4) end end end describe Ohai::System, "S390 linux cpu plugin" do let(:plugin) { get_plugin("cpu") } before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", "")) @double_file = double("/proc/cpuinfo") allow(@double_file).to receive(:each) .and_yield("vendor_id : IBM/S390") .and_yield("# processors : 2") .and_yield("bogomips per cpu: 9328.00") .and_yield("features : esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs") .and_yield("processor 0: version = EE, identification = 06E276, machine = 2717") .and_yield("processor 1: version = FF, identification = 06E278, machine = 2818") allow(File).to receive(:open).with("/proc/cpuinfo").and_return(@double_file) end it_behaves_like "Common cpu info", 2, nil it "has a cpu 1" do plugin.run expect(plugin[:cpu]).to have_key("1") end it "has a vendor_id" do plugin.run expect(plugin[:cpu]).to have_key("vendor_id") expect(plugin[:cpu]["vendor_id"]).to eql("IBM/S390") end it "has a bogomips per cpu" do plugin.run expect(plugin[:cpu]).to have_key("bogomips_per_cpu") expect(plugin[:cpu]["bogomips_per_cpu"]).to eql("9328.00") end it "has features" do plugin.run expect(plugin[:cpu]).to have_key("features") expect(plugin[:cpu]["features"]).to eq(%w{esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs}) end it_behaves_like "S390 processor info", 0, "EE", "06E276", "2717" it_behaves_like "S390 processor info", 1, "FF", "06E278", "2818" end describe Ohai::System, "arm64 linux cpu plugin" do let(:plugin) { get_plugin("cpu") } before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("lscpu").and_return(mock_shell_out(1, "", "")) @double_file = double("/proc/cpuinfo") allow(@double_file).to receive(:each) .and_yield("processor : 0") .and_yield("BogoMIPS : 40.00") .and_yield("Features : fp asimd evtstrm aes pmull sha1 sha2 crc32") .and_yield("") .and_yield("processor : 1") .and_yield("BogoMIPS : 40.00") .and_yield("Features : fp asimd evtstrm aes pmull sha1 sha2 crc32") .and_yield("") allow(File).to receive(:open).with("/proc/cpuinfo").and_return(@double_file) end it_behaves_like "Common cpu info", 2, nil it "has a cpu 1" do plugin.run expect(plugin[:cpu]).to have_key("1") end features = %w{fp asimd evtstrm aes pmull sha1 sha2 crc32} it_behaves_like "arm64 processor info", 0, "40.00", features it_behaves_like "arm64 processor info", 1, "40.00", features end ohai-16.0.7/spec/unit/plugins/linux/filesystem_spec.rb000066400000000000000000000712101362624620500230100ustar00rootroot00000000000000# # Author:: Matthew Kent () # Copyright:: Copyright (c) 2011-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux filesystem plugin" do let(:plugin) { get_plugin("filesystem") } before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:which).with("lsblk").and_return(nil) allow(plugin).to receive(:which).with("df").and_return("/bin/df") allow(plugin).to receive(:which).with("mount").and_return("/bin/mount") allow(plugin).to receive(:which).with("blkid").and_return("/sbin/blkid") allow(plugin).to receive(:shell_out).with("/sbin/blkid", timeout: 60).and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out) .with("lsblk -n -P -o NAME,UUID,LABEL,FSTYPE", timeout: 60) .and_return(mock_shell_out(0, "", "")) allow(File).to receive(:exist?).with("/proc/mounts").and_return(false) %w{sdb1 sdb2 sda1 sda2 md0 md1 md2}.each do |name| allow(File).to receive(:exist?).with("/dev/#{name}").and_return(true) end %w{ sys.vg-root.lv sys.vg-swap.lv sys.vg-tmp.lv sys.vg-usr.lv sys.vg-var.lv sys.vg-home.lv debian--7-root }.each do |name| allow(File).to receive(:exist?).with("/dev/#{name}").and_return(false) allow(File).to receive(:exist?).with("/dev/mapper/#{name}").and_return(true) end end describe "when gathering filesystem usage data from df" do before do @stdout = <<~DF Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% / tmpfs 2030944 0 2030944 0% /lib/init/rw udev 2025576 228 2025348 1% /dev tmpfs 2030944 2960 2027984 1% /dev/shm /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home /dev/mapper/sys.vg-special.lv 97605057 53563253 44041805 56% /special /dev/mapper/sys.vg-tmp.lv 1919048 46588 1774976 3% /tmp /dev/mapper/sys.vg-usr.lv 19223252 5479072 12767696 31% /usr /dev/mapper/sys.vg-var.lv 19223252 3436556 14810212 19% /var /dev/md0 960492 36388 875312 4% /boot DF allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, @stdout, "")) @inode_stdout = <<~DFI Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 1310720 107407 1203313 9% / /dev/mapper/sys.vg-special.lv 124865 380 124485 1% /special tmpfs 126922 273 126649 1% /run none 126922 1 126921 1% /run/lock none 126922 1 126921 1% /run/shm DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) end it "runs df -P and df -iP" do expect(plugin).to receive(:shell_out).ordered.with("df -P").and_return(mock_shell_out(0, @stdout, "")) expect(plugin).to receive(:shell_out).ordered.with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) plugin.run end it "sets kb_size to value from df -P" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:kb_size]).to eq("97605057") end it "sets kb_used to value from df -P" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:kb_used]).to eq("53563253") end it "sets kb_available to value from df -P" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:kb_available]).to eq("44041805") end it "sets percent_used to value from df -P" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:percent_used]).to eq("56%") end it "sets mount to value from df -P" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:mount]).to eq("/special") end it "sets total_inodes to value from df -iP" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:total_inodes]).to eq("124865") end it "sets inodes_used to value from df -iP" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:inodes_used]).to eq("380") end it "sets inodes_available to value from df -iP" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:inodes_available]).to eq("124485") end end describe "when gathering mounted filesystem data from mount" do before do @stdout = <<~MOUNT /dev/mapper/sys.vg-root.lv on / type ext4 (rw,noatime,errors=remount-ro) tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) udev on /dev type tmpfs (rw,mode=0755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) /dev/mapper/sys.vg-home.lv on /home type xfs (rw,noatime) /dev/mapper/sys.vg-special.lv on /special type xfs (ro,noatime) /dev/mapper/sys.vg-tmp.lv on /tmp type ext4 (rw,noatime) /dev/mapper/sys.vg-usr.lv on /usr type ext4 (rw,noatime) /dev/mapper/sys.vg-var.lv on /var type ext4 (rw,noatime) /dev/md0 on /boot type ext3 (rw,noatime,errors=remount-ro) fusectl on /sys/fs/fuse/connections type fusectl (rw) binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev) MOUNT allow(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @stdout, "")) end it "runs mount" do expect(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, @stdout, "")) plugin.run end it "sets mount to value from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:mount]).to eq("/special") end it "sets fs_type to value from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:fs_type]).to eq("xfs") end it "sets mount_options to an array of values from mount" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:mount_options]).to eq(%w{ro noatime}) end end describe "when gathering filesystem type data from blkid" do before do # blkid and lsblk output are coorelated with df/mount output, so the # most full test of them actually requires we have both @dfstdout = <<~DF Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% / tmpfs 2030944 0 2030944 0% /lib/init/rw udev 2025576 228 2025348 1% /dev tmpfs 2030944 2960 2027984 1% /dev/shm /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home /dev/mapper/sys.vg-special.lv 97605057 53563253 44041805 56% /special /dev/mapper/sys.vg-tmp.lv 1919048 46588 1774976 3% /tmp /dev/mapper/sys.vg-usr.lv 19223252 5479072 12767696 31% /usr /dev/mapper/sys.vg-var.lv 19223252 3436556 14810212 19% /var /dev/md0 960492 36388 875312 4% /boot DF allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, @dfstdout, "")) @inode_stdout = <<~DFI Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 1310720 107407 1203313 9% / /dev/mapper/sys.vg-special.lv 124865 380 124485 1% /special tmpfs 126922 273 126649 1% /run none 126922 1 126921 1% /run/lock none 126922 1 126921 1% /run/shm DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) @stdout = <<~BLKID_TYPE /dev/sdb1: LABEL=\"fuego:0\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" TYPE=\"linux_raid_member\" /dev/sdb2: LABEL=\"fuego:1\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" TYPE=\"linux_raid_member\" /dev/sda1: LABEL=\"fuego:0\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" TYPE=\"linux_raid_member\" /dev/sda2: LABEL=\"fuego:1\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" TYPE=\"linux_raid_member\" /dev/md0: LABEL=\"/boot\" UUID=\"37b8de8e-0fe3-4b5a-b9b4-dde33e19bb32\" TYPE=\"ext3\" /dev/md1: UUID=\"YsIe0R-fj1y-LXTd-imla-opKo-OuIe-TBoxSK\" TYPE=\"LVM2_member\" /dev/mapper/sys.vg-root.lv: LABEL=\"/\" UUID=\"7742d14b-80a3-4e97-9a32-478be9ea9aea\" TYPE=\"ext4\" /dev/mapper/sys.vg-swap.lv: UUID=\"9bc2e515-8ddc-41c3-9f63-4eaebde9ce96\" TYPE=\"swap\" /dev/mapper/sys.vg-tmp.lv: LABEL=\"/tmp\" UUID=\"74cf7eb9-428f-479e-9a4a-9943401e81e5\" TYPE=\"ext4\" /dev/mapper/sys.vg-usr.lv: LABEL=\"/usr\" UUID=\"26ec33c5-d00b-4f88-a550-492def013bbc\" TYPE=\"ext4\" /dev/mapper/sys.vg-var.lv: LABEL=\"/var\" UUID=\"6b559c35-7847-4ae2-b512-c99012d3f5b3\" TYPE=\"ext4\" /dev/mapper/sys.vg-home.lv: LABEL=\"/home\" UUID=\"d6efda02-1b73-453c-8c74-7d8dee78fa5e\" TYPE=\"xfs\" BLKID_TYPE allow(plugin).to receive(:shell_out).with("/sbin/blkid", timeout: 60).and_return(mock_shell_out(0, @stdout, "")) end it "runs blkid" do plugin.run end it "sets kb_size to value from blkid" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/md1,"][:fs_type]).to eq("LVM2_member") expect(plugin[:filesystem]["by_pair"]["/dev/sda2,"][:uuid]).to eq("e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa") expect(plugin[:filesystem]["by_pair"]["/dev/md0,/boot"][:label]).to eq("/boot") end end describe "when gathering filesystem type data from lsblk" do before do @dfstdout = <<~DF Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% / tmpfs 2030944 0 2030944 0% /lib/init/rw udev 2025576 228 2025348 1% /dev tmpfs 2030944 2960 2027984 1% /dev/shm /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home /dev/mapper/sys.vg-special.lv 97605057 53563253 44041805 56% /special /dev/mapper/sys.vg-tmp.lv 1919048 46588 1774976 3% /tmp /dev/mapper/sys.vg-usr.lv 19223252 5479072 12767696 31% /usr /dev/mapper/sys.vg-var.lv 19223252 3436556 14810212 19% /var /dev/md0 960492 36388 875312 4% /boot DF allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, @dfstdout, "")) @inode_stdout = <<~DFI Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 1310720 107407 1203313 9% / /dev/mapper/sys.vg-special.lv 124865 380 124485 1% /special tmpfs 126922 273 126649 1% /run none 126922 1 126921 1% /run/lock none 126922 1 126921 1% /run/shm DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) allow(plugin).to receive(:which).with("lsblk").and_return("/sbin/lsblk") allow(plugin).to receive(:which).with("blkid").and_return(nil) @stdout = <<~BLKID_TYPE NAME=\"sdb1\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" LABEL=\"fuego:0\" FSTYPE=\"LVM2_member\" NAME=\"sdb2\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" LABEL=\"fuego:1\" FSTYPE=\"LVM2_member\" NAME=\"sda1\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" LABEL=\"fuego:0\" FSTYPE=\"LVM2_member\" NAME=\"sda2\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" LABEL=\"fuego:1\" FSTYPE=\"LVM2_member\" NAME=\"md0\" UUID=\"37b8de8e-0fe3-4b5a-b9b4-dde33e19bb32\" LABEL=\"/boot\" FSTYPE=\"ext3\" NAME=\"md1\" UUID=\"YsIe0R-fj1y-LXTd-imla-opKo-OuIe-TBoxSK\" LABEL=\"\" FSTYPE=\"LVM2_member\" NAME=\"sys.vg-root.lv\" UUID=\"7742d14b-80a3-4e97-9a32-478be9ea9aea\" LABEL=\"/\" FSTYPE=\"ext4\" NAME=\"sys.vg-swap.lv\" UUID=\"9bc2e515-8ddc-41c3-9f63-4eaebde9ce96\" LABEL=\"\" FSTYPE=\"swap\" NAME=\"sys.vg-tmp.lv\" UUID=\"74cf7eb9-428f-479e-9a4a-9943401e81e5\" LABEL=\"/tmp\" FSTYPE=\"ext4\" NAME=\"sys.vg-usr.lv\" UUID=\"26ec33c5-d00b-4f88-a550-492def013bbc\" LABEL=\"/usr\" FSTYPE=\"ext4\" NAME=\"sys.vg-var.lv\" UUID=\"6b559c35-7847-4ae2-b512-c99012d3f5b3\" LABEL=\"/var\" FSTYPE=\"ext4\" NAME=\"sys.vg-home.lv\" UUID=\"d6efda02-1b73-453c-8c74-7d8dee78fa5e\" LABEL=\"/home\" FSTYPE=\"xfs\" NAME=\"debian--7-root (dm-0)\" UUID=\"09187faa-3512-4505-81af-7e86d2ccb99a\" LABEL=\"root\" FSTYPE=\"ext4\" BLKID_TYPE allow(plugin).to receive(:shell_out) .with("/sbin/lsblk -n -P -o NAME,UUID,LABEL,FSTYPE", timeout: 60) .and_return(mock_shell_out(0, @stdout, "")) end it "runs lsblk -n -P -o NAME,UUID,LABEL,FSTYPE" do plugin.run end it "sets kb_size to value from lsblk -n -P -o NAME,UUID,LABEL,FSTYPE" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/md1,"][:fs_type]).to eq("LVM2_member") expect(plugin[:filesystem]["by_pair"]["/dev/sda2,"][:uuid]).to eq("e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa") expect(plugin[:filesystem]["by_pair"]["/dev/md0,/boot"][:label]).to eq("/boot") end it "ignores extra info in name and set label to value from lsblk -n -P -o NAME,UUID,LABEL,FSTYPE" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/debian--7-root,"][:label]).to eq("root") end end describe "when gathering filesystem type data from both lsblk and blkid" do before do @dfstdout = <<~DF Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% / tmpfs 2030944 0 2030944 0% /lib/init/rw udev 2025576 228 2025348 1% /dev tmpfs 2030944 2960 2027984 1% /dev/shm /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home /dev/mapper/sys.vg-special.lv 97605057 53563253 44041805 56% /special /dev/mapper/sys.vg-tmp.lv 1919048 46588 1774976 3% /tmp /dev/mapper/sys.vg-usr.lv 19223252 5479072 12767696 31% /usr /dev/mapper/sys.vg-var.lv 19223252 3436556 14810212 19% /var /dev/md0 960492 36388 875312 4% /boot DF allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, @dfstdout, "")) @inode_stdout = <<~DFI Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 1310720 107407 1203313 9% / /dev/mapper/sys.vg-special.lv 124865 380 124485 1% /special tmpfs 126922 273 126649 1% /run none 126922 1 126921 1% /run/lock none 126922 1 126921 1% /run/shm DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) allow(plugin).to receive(:which).with("lsblk").and_return("/sbin/lsblk") allow(plugin).to receive(:which).with("blkid").and_return("/sbin/blkid") @stdout = <<~BLKID_TYPE NAME=\"sdb1\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" LABEL=\"fuego:0\" FSTYPE=\"LVM2_member\" NAME=\"sdb2\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" LABEL=\"fuego:1\" FSTYPE=\"LVM2_member\" NAME=\"sda1\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" LABEL=\"fuego:0\" FSTYPE=\"LVM2_member\" NAME=\"sda2\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" LABEL=\"fuego:1\" FSTYPE=\"LVM2_member\" NAME=\"md0\" UUID=\"37b8de8e-0fe3-4b5a-b9b4-dde33e19bb32\" LABEL=\"/boot\" FSTYPE=\"ext3\" NAME=\"md1\" UUID=\"YsIe0R-fj1y-LXTd-imla-opKo-OuIe-TBoxSK\" LABEL=\"\" FSTYPE=\"LVM2_member\" NAME=\"sys.vg-root.lv\" UUID=\"7742d14b-80a3-4e97-9a32-478be9ea9aea\" LABEL=\"/\" NAME=\"sys.vg-swap.lv\" UUID=\"9bc2e515-8ddc-41c3-9f63-4eaebde9ce96\" LABEL=\"\" FSTYPE=\"swap\" NAME=\"sys.vg-tmp.lv\" UUID=\"74cf7eb9-428f-479e-9a4a-9943401e81e5\" LABEL=\"/tmp\" FSTYPE=\"ext4\" NAME=\"sys.vg-usr.lv\" UUID=\"26ec33c5-d00b-4f88-a550-492def013bbc\" LABEL=\"/usr\" NAME=\"sys.vg-var.lv\" UUID=\"6b559c35-7847-4ae2-b512-c99012d3f5b3\" LABEL=\"/var\" FSTYPE=\"ext4\" NAME=\"sys.vg-home.lv\" UUID=\"d6efda02-1b73-453c-8c74-7d8dee78fa5e\" LABEL=\"/BADhome\" FSTYPE=\"xfs\" NAME=\"debian--7-root (dm-0)\" UUID=\"09187faa-3512-4505-81af-7e86d2ccb99a\" LABEL=\"root\" FSTYPE=\"ext4\" BLKID_TYPE allow(plugin).to receive(:shell_out) .with("/sbin/lsblk -n -P -o NAME,UUID,LABEL,FSTYPE", timeout: 60) .and_return(mock_shell_out(0, @stdout, "")) @stdout = <<~BLKID_TYPE /dev/sdb1: LABEL=\"fuego:0\" TYPE=\"linux_raid_member\" /dev/sdb2: LABEL=\"fuego:1\" TYPE=\"linux_raid_member\" /dev/sda1: LABEL=\"fuego:0\" UUID=\"bd1197e0-6997-1f3a-e27e-7801388308b5\" TYPE=\"linux_raid_member\" /dev/sda2: LABEL=\"fuego:1\" UUID=\"e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa\" TYPE=\"linux_raid_member\" /dev/md0: LABEL=\"/boot\" UUID=\"37b8de8e-0fe3-4b5a-b9b4-dde33e19bb32\" TYPE=\"ext3\" /dev/md1: UUID=\"YsIe0R-fj1y-LXTd-imla-opKo-OuIe-TBoxSK\" TYPE=\"LVM2_member\" /dev/mapper/sys.vg-root.lv: LABEL=\"/\" UUID=\"7742d14b-80a3-4e97-9a32-478be9ea9aea\" TYPE=\"ext4\" /dev/mapper/sys.vg-swap.lv: UUID=\"9bc2e515-8ddc-41c3-9f63-4eaebde9ce96\" TYPE=\"swap\" /dev/mapper/sys.vg-tmp.lv: LABEL=\"/tmp\" UUID=\"74cf7eb9-428f-479e-9a4a-9943401e81e5\" TYPE=\"ext4\" /dev/mapper/sys.vg-usr.lv: LABEL=\"/usr\" UUID=\"26ec33c5-d00b-4f88-a550-492def013bbc\" TYPE=\"ext4\" /dev/mapper/sys.vg-var.lv: LABEL=\"/var\" UUID=\"6b559c35-7847-4ae2-b512-c99012d3f5b3\" TYPE=\"ext4\" /dev/mapper/sys.vg-home.lv: LABEL=\"/home\" UUID=\"d6efda02-1b73-453c-8c74-7d8dee78fa5e\" TYPE=\"xfs\" BLKID_TYPE allow(plugin).to receive(:shell_out).with("/sbin/blkid", timeout: 60).and_return(mock_shell_out(0, @stdout, "")) end it "fills in missing FS data from lsblk using blkid" do plugin.run pairs = plugin[:filesystem]["by_pair"] expect(pairs["/dev/mapper/sys.vg-root.lv,/"]["fs_type"]).to eq("ext4") expect(pairs["/dev/mapper/sys.vg-usr.lv,/usr"]["fs_type"]).to eq("ext4") end it "fills in missing FS data from blkid using lsblk" do plugin.run pairs = plugin[:filesystem]["by_pair"] expect(pairs["/dev/sdb1,"]["uuid"]).to eq("bd1197e0-6997-1f3a-e27e-7801388308b5") expect(pairs["/dev/sdb2,"]["uuid"]).to eq("e36d933e-e5b9-cfe5-6845-1f84d0f7fbfa") end it "prefers lsblk data to blkid data when they conflict" do plugin.run pairs = plugin[:filesystem]["by_pair"] expect(pairs["/dev/mapper/sys.vg-home.lv,/home"]["label"]).to eq("/home") end end describe "when gathering data from /proc/mounts" do before do allow(File).to receive(:exist?).with("/proc/mounts").and_return(true) @double_file = double("/proc/mounts") @mounts = <<~MOUNTS rootfs / rootfs rw 0 0 none /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 none /proc proc rw,nosuid,nodev,noexec,relatime 0 0 none /dev devtmpfs rw,relatime,size=2025576k,nr_inodes=506394,mode=755 0 0 none /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 /dev/mapper/sys.vg-root.lv / ext4 rw,noatime,errors=remount-ro,barrier=1,data=ordered 0 0 tmpfs /lib/init/rw tmpfs rw,nosuid,relatime,mode=755 0 0 tmpfs /dev/shm tmpfs rw,nosuid,nodev,relatime 0 0 /dev/mapper/sys.vg-home.lv /home xfs rw,noatime,attr2,noquota 0 0 /dev/mapper/sys.vg-special.lv /special xfs ro,noatime,attr2,noquota 0 0 /dev/mapper/sys.vg-tmp.lv /tmp ext4 rw,noatime,barrier=1,data=ordered 0 0 /dev/mapper/sys.vg-usr.lv /usr ext4 rw,noatime,barrier=1,data=ordered 0 0 /dev/mapper/sys.vg-var.lv /var ext4 rw,noatime,barrier=1,data=ordered 0 0 /dev/md0 /boot ext3 rw,noatime,errors=remount-ro,data=ordered 0 0 fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0 binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0 MOUNTS @counter = 0 allow(@double_file).to receive(:read_nonblock) do @counter += 1 raise EOFError if @counter == 2 @mounts end allow(@double_file).to receive(:close) allow(File).to receive(:open).with("/proc/mounts").and_return(@double_file) end it "sets mount to value from /proc/mounts" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:mount]).to eq("/special") end it "sets fs_type to value from /proc/mounts" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:fs_type]).to eq("xfs") end it "sets mount_options to an array of values from /proc/mounts" do plugin.run expect(plugin[:filesystem]["by_pair"]["/dev/mapper/sys.vg-special.lv,/special"][:mount_options]).to eq(%w{ro noatime attr2 noquota}) end end describe "when gathering filesystem data with devices mounted more than once" do before do # there's a few different examples one can run into in this output: # 1. A device physically mounted in more than one place: /home and /home2 # 2. A bind-mounted directory, which shows up as the same device in a # subdir: / and /var/chroot # 3. tmpfs in multiple places. @dfstdout = <<~DF Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% / tmpfs 2030944 0 2030944 0% /lib/init/rw udev 2025576 228 2025348 1% /dev tmpfs 2030944 2960 2027984 1% /dev/shm /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home2 /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% /var/chroot DF allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, @dfstdout, "")) @inode_stdout = <<~DFI Filesystem Inodes IUsed IFree IUse% Mounted on /dev/mapper/sys.vg-root.lv 1310720 107407 1203313 9% / tmpfs 126922 273 126649 1% /lib/init/rw none 126922 1 126921 1% /dev/shm udev 126922 1 126921 1% /dev /dev/mapper/sys.vg-home.lv 60891136 4696030 56195106 8% /home /dev/mapper/sys.vg-home.lv 60891136 4696030 56195106 8% /home2 /dev/mapper/sys.vg-root.lv 1310720 107407 1203313 9% /var/chroot DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) allow(plugin).to receive(:which).with("lsblk").and_return("/sbin/lsblk") allow(plugin).to receive(:which).with("blkid").and_return(nil) @stdout = <<~BLKID_TYPE NAME=\"/dev/mapper/sys.vg-root.lv\" UUID=\"7742d14b-80a3-4e97-9a32-478be9ea9aea\" LABEL=\"/\" FSTYPE=\"ext4\" NAME=\"/dev/mapper/sys.vg-home.lv\" UUID=\"d6efda02-1b73-453c-8c74-7d8dee78fa5e\" LABEL=\"/home\" FSTYPE=\"xfs\" BLKID_TYPE allow(plugin).to receive(:shell_out) .with("/sbin/lsblk -n -P -o NAME,UUID,LABEL,FSTYPE", timeout: 60) .and_return(mock_shell_out(0, @stdout, "")) end it "provides a devices view with all mountpoints" do plugin.run expect(plugin[:filesystem]["by_device"]["/dev/mapper/sys.vg-root.lv"][:mounts]).to eq(["/", "/var/chroot"]) expect(plugin[:filesystem]["by_device"]["/dev/mapper/sys.vg-home.lv"][:mounts]).to eq(["/home", "/home2"]) expect(plugin[:filesystem]["by_device"]["tmpfs"][:mounts]).to eq(["/lib/init/rw", "/dev/shm"]) end end describe "when gathering filesystem data with double-mounts" do before do @dfstdout = <<~DF Filesystem 1024-blocks Used Available Capacity Mounted on /dev/mapper/sys.vg-root.lv 4805760 378716 4182924 9% / tmpfs 2030944 0 2030944 0% /lib/init/rw udev 2025576 228 2025348 1% /dev tmpfs 2030944 2960 2027984 1% /dev/shm /dev/mapper/sys.vg-home.lv 97605056 53563252 44041804 55% /home /dev/sdb1 97605056 53563252 44041804 55% /mnt /dev/sdc1 4805760 378716 4182924 9% /mnt DF allow(plugin).to receive(:shell_out).with("df -P").and_return(mock_shell_out(0, @dfstdout, "")) @inode_stdout = <<~DFI Filesystem Inodes IUsed IFree IUse% Mounted on /dev/mapper/sys.vg-root.lv 1310720 107407 1203313 9% / tmpfs 126922 273 126649 1% /lib/init/rw none 126922 1 126921 1% /dev/shm udev 126922 1 126921 1% /dev /dev/mapper/sys.vg-home.lv 60891136 4696030 56195106 8% /home /dev/sdb1 60891136 4696030 56195106 8% /mnt /dev/sdc1 1310720 107407 1203313 9% /mnt DFI allow(plugin).to receive(:shell_out).with("df -iP").and_return(mock_shell_out(0, @inode_stdout, "")) allow(plugin).to receive(:which).with("lsblk").and_return("/sbin/lsblk") allow(plugin).to receive(:which).with("blkid").and_return(nil) @stdout = <<~BLKID_TYPE NAME=\"/dev/mapper/sys.vg-root.lv\" UUID=\"7742d14b-80a3-4e97-9a32-478be9ea9aea\" LABEL=\"/\" FSTYPE=\"ext4\" NAME=\"/dev/sdb1\" UUID=\"6b559c35-7847-4ae2-b512-c99012d3f5b3\" LABEL=\"/mnt\" FSTYPE=\"ext4\" NAME=\"/dev/sdc1\" UUID=\"7f1e51bf-3608-4351-b7cd-379e39cff36a\" LABEL=\"/mnt\" FSTYPE=\"ext4\" NAME=\"/dev/mapper/sys.vg-home.lv\" UUID=\"d6efda02-1b73-453c-8c74-7d8dee78fa5e\" LABEL=\"/home\" FSTYPE=\"xfs\" BLKID_TYPE allow(plugin).to receive(:shell_out) .with("/sbin/lsblk -n -P -o NAME,UUID,LABEL,FSTYPE", timeout: 60) .and_return(mock_shell_out(0, @stdout, "")) end it "provides a mounts view with all devices" do plugin.run expect(plugin[:filesystem]["by_mountpoint"]["/mnt"][:devices]).to eq(["/dev/sdb1", "/dev/sdc1"]) end end %w{df mount}.each do |command| describe "when :allow_partial_data set, #{command} does not exist" do before do Ohai.config[:plugin][:filesystem][:allow_partial_data] = true end after do Ohai.config[:plugin][:filesystem][:allow_partial_data] = false end it "logs warning about #{command} missing" do Ohai.config[:plugin][:filesystem][:allow_partial_data] = true allow(plugin).to receive(:shell_out).with(/#{command}/).and_raise(Ohai::Exceptions::Exec) expect_any_instance_of(Mixlib::Log::Child).to receive(:warn).with("Plugin Filesystem: #{command} binary is not available. Some data will not be available.") plugin.run end end end end ohai-16.0.7/spec/unit/plugins/linux/fips_spec.rb000066400000000000000000000030211362624620500215600ustar00rootroot00000000000000# # Author:: Matt Wrock () # Copyright:: Copyright (c) 2016-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "openssl" describe Ohai::System, "plugin fips" do subject do plugin.run plugin["fips"]["kernel"]["enabled"] end let(:enabled) { "0" } let(:plugin) { get_plugin("linux/fips") } let(:openssl_test_mode) { false } before do allow(plugin).to receive(:collect_os).and_return(:linux) end around do |ex| $FIPS_TEST_MODE = openssl_test_mode ex.run ensure $FIPS_TEST_MODE = false end context "with OpenSSL.fips_mode == false" do before { allow(OpenSSL).to receive(:fips_mode).and_return(false) } it "does not set fips plugin" do expect(subject).to be(false) end end context "with OpenSSL.fips_mode == true" do before { allow(OpenSSL).to receive(:fips_mode).and_return(true) } it "sets fips plugin" do expect(subject).to be(true) end end end ohai-16.0.7/spec/unit/plugins/linux/hostname_spec.rb000066400000000000000000000034441362624620500224460ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:linux) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return(mock_shell_out(0, "katie", "")) allow(@plugin).to receive(:shell_out).with("hostname --fqdn").and_return(mock_shell_out(0, "katie.bethell", "")) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie.local", "")) end it_should_check_from("linux::hostname", "hostname", "hostname -s", "katie") it_should_check_from("linux::hostname", "fqdn", "hostname --fqdn", "katie.bethell") it_should_check_from("linux::hostname", "machinename", "hostname", "katie.local") describe "when domain name is unset" do before do expect(@plugin).to receive(:shell_out).with("hostname --fqdn").and_raise("Ohai::Exception::Exec") end it "does not raise an error" do expect { @plugin.run }.not_to raise_error end it "does not set fqdn" do @plugin.run expect(@plugin.fqdn).to eq(nil) end end end ohai-16.0.7/spec/unit/plugins/linux/hostnamectl_spec.rb000066400000000000000000000041611362624620500231460ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux hostnamectl plugin" do let(:plugin) { get_plugin("linux/hostnamectl") } before do allow(plugin).to receive(:collect_os).and_return(:linux) end it "populates hostnamectl if hostnamectl is available" do hostnamectl_out = <<-HOSTNAMECTL_OUT Static hostname: foo Icon name: computer-laptop Chassis: laptop Machine ID: 6f702523e2fc7499eb1dc68e5314dacf Boot ID: e085ae9e65e245a8a7b62912adeebe97 Operating System: Debian GNU/Linux 8 (jessie) Kernel: Linux 4.3.0-0.bpo.1-amd64 Architecture: x86-64 HOSTNAMECTL_OUT allow(plugin).to receive(:which).with("hostnamectl").and_return("/bin/hostnamectl") allow(plugin).to receive(:shell_out).with("/bin/hostnamectl").and_return(mock_shell_out(0, hostnamectl_out, "")) plugin.run expect(plugin[:hostnamectl].to_hash).to eq({ "static_hostname" => "foo", "icon_name" => "computer-laptop", "chassis" => "laptop", "machine_id" => "6f702523e2fc7499eb1dc68e5314dacf", "boot_id" => "e085ae9e65e245a8a7b62912adeebe97", "operating_system" => "Debian GNU/Linux 8 (jessie)", "kernel" => "Linux 4.3.0-0.bpo.1-amd64", "architecture" => "x86-64", }) end it "does not populate hostnamectl if hostnamectl is not available" do allow(plugin).to receive(:which).with("hostnamectl").and_return(false) expect(plugin[:hostnamectl]).to eq(nil) end end ohai-16.0.7/spec/unit/plugins/linux/kernel_spec.rb000066400000000000000000000053001362624620500221010ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux kernel plugin" do before do @env_lsmod = <<~ENV_LSMOD Module Size Used by dm_crypt 22321 0 psmouse 81038 0 acpiphp 23314 0 microcode 18286 0 serio_raw 13031 0 virtio_balloon 13168 0 floppy 55441 0 ENV_LSMOD @version_module = { dm_crypt: "", psmouse: "", acpiphp: "", microcode: "1.2.3", serio_raw: "", virtio_balloon: "", floppy: "", } @expected_result = { "dm_crypt" => { "size" => "22321", "refcount" => "0" }, "psmouse" => { "size" => "81038", "refcount" => "0" }, "acpiphp" => { "size" => "23314", "refcount" => "0" }, "microcode" => { "size" => "18286", "refcount" => "0", "version" => "1.2.3" }, "serio_raw" => { "size" => "13031", "refcount" => "0" }, "virtio_balloon" => { "size" => "13168", "refcount" => "0" }, "floppy" => { "size" => "55441", "refcount" => "0" }, } @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:linux) allow(@plugin).to receive(:init_kernel).and_return({}) allow(@plugin).to receive(:shell_out).with("uname -o").and_return(mock_shell_out(0, "Linux", "")) allow(@plugin).to receive(:shell_out).with("env lsmod").and_return(mock_shell_out(0, @env_lsmod, "")) @version_module.each do |mod, vers| allow(File).to receive(:exist?).with("/sys/module/#{mod}/version").and_return(true) allow(File).to receive(:read).with("/sys/module/#{mod}/version").and_return(vers) end expect(@plugin).to receive(:shell_out).with("env lsmod").at_least(:once) @plugin.run end it_should_check_from_deep_mash("linux::kernel", "kernel", "os", "uname -o", [0, "Linux", ""]) it "collects linux::kernel::modules" do expect(@plugin.data["kernel"]["modules"]).to eq(@expected_result) end end ohai-16.0.7/spec/unit/plugins/linux/lsb_spec.rb000066400000000000000000000107061362624620500214070ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" # We do not alter case for lsb attributes and consume them as provided describe Ohai::System, "Linux lsb plugin" do before do @plugin = get_plugin("linux/lsb") allow(@plugin).to receive(:collect_os).and_return(:linux) end describe "on systems with /etc/lsb-release" do before do @double_file = double("/etc/lsb-release") allow(@double_file).to receive(:each) .and_yield("DISTRIB_ID=Ubuntu") .and_yield("DISTRIB_RELEASE=8.04") .and_yield("DISTRIB_CODENAME=hardy") .and_yield('DISTRIB_DESCRIPTION="Ubuntu 8.04"') allow(File).to receive(:open).with("/etc/lsb-release").and_return(@double_file) allow(File).to receive(:exist?).with("/usr/bin/lsb_release").and_return(false) allow(File).to receive(:exist?).with("/etc/lsb-release").and_return(true) end it "sets lsb[:id]" do @plugin.run expect(@plugin[:lsb][:id]).to eq("Ubuntu") end it "sets lsb[:release]" do @plugin.run expect(@plugin[:lsb][:release]).to eq("8.04") end it "sets lsb[:codename]" do @plugin.run expect(@plugin[:lsb][:codename]).to eq("hardy") end it "sets lsb[:description]" do @plugin.run expect(@plugin[:lsb][:description]).to eq("Ubuntu 8.04") end end describe "on systems with /usr/bin/lsb_release" do before do allow(File).to receive(:exist?).with("/usr/bin/lsb_release").and_return(true) @stdin = double("STDIN", { close: true }) @pid = 10 @stderr = double("STDERR") @stdout = double("STDOUT") @status = 0 end describe "on Centos 5.4 correctly" do before do @stdout = <<~LSB_RELEASE LSB Version: :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch Distributor ID: CentOS Description: CentOS release 5.4 (Final) Release: 5.4 Codename: Final LSB_RELEASE allow(@plugin).to receive(:shell_out).with("lsb_release -a").and_return(mock_shell_out(0, @stdout, "")) end it "sets lsb[:id]" do @plugin.run expect(@plugin[:lsb][:id]).to eq("CentOS") end it "sets lsb[:release]" do @plugin.run expect(@plugin[:lsb][:release]).to eq("5.4") end it "sets lsb[:codename]" do @plugin.run expect(@plugin[:lsb][:codename]).to eq("Final") end it "sets lsb[:description]" do @plugin.run expect(@plugin[:lsb][:description]).to eq("CentOS release 5.4 (Final)") end end describe "on Fedora 14 correctly" do before do @stdout = <<~LSB_RELEASE LSB Version: :core-4.0-ia32:core-4.0-noarch Distributor ID: Fedora Description: Fedora release 14 (Laughlin) Release: 14 Codename: Laughlin LSB_RELEASE allow(@plugin).to receive(:shell_out).with("lsb_release -a").and_return(mock_shell_out(0, @stdout, "")) end it "sets lsb[:id]" do @plugin.run expect(@plugin[:lsb][:id]).to eq("Fedora") end it "sets lsb[:release]" do @plugin.run expect(@plugin[:lsb][:release]).to eq("14") end it "sets lsb[:codename]" do @plugin.run expect(@plugin[:lsb][:codename]).to eq("Laughlin") end it "sets lsb[:description]" do @plugin.run expect(@plugin[:lsb][:description]).to eq("Fedora release 14 (Laughlin)") end end end it "does not set any lsb values if /etc/lsb-release or /usr/bin/lsb_release do not exist " do allow(File).to receive(:exist?).with("/etc/lsb-release").and_return(false) allow(File).to receive(:exist?).with("/usr/bin/lsb_release").and_return(false) expect(@plugin.attribute?(:lsb)).to be(false) end end ohai-16.0.7/spec/unit/plugins/linux/lspci_spec.rb000066400000000000000000000100101362624620500217250ustar00rootroot00000000000000# # Author:: Phil Dibowitz # Copyright:: Copyright (c) 2017 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux lspci plugin" do let(:plugin) { get_plugin("linux/lspci") } before do allow(plugin).to receive(:collect_os).and_return(:linux) @stdout = <<~LSPCI Device: 00:1f.3 Class: Audio device [0403] Vendor: Intel Corporation [8086] Device: Sunrise Point-LP HD Audio [9d71] SVendor: Lenovo [17aa] SDevice: Sunrise Point-LP HD Audio [224e] Rev: 21 Driver: snd_hda_intel Module: snd_hda_intel Module: snd_soc_skl Device: 00:1f.4 Class: SMBus [0c05] Vendor: Intel Corporation [8086] Device: Sunrise Point-LP SMBus [9d23] SVendor: Lenovo [17aa] SDevice: Sunrise Point-LP SMBus [224e] Rev: 21 Driver: i801_smbus Module: i2c_i801 Device: 00:1f.6 Class: Ethernet controller [0200] Vendor: Intel Corporation [8086] Device: Ethernet Connection (4) I219-LM [15d7] SVendor: Lenovo [17aa] SDevice: Ethernet Connection (4) I219-LM [224e] Rev: 21 Driver: e1000e Module: e1000e Device: 02:00.0 Class: Unassigned class [ff00] Vendor: Realtek Semiconductor Co., Ltd. [10ec] Device: RTS525A PCI Express Card Reader [525a] SVendor: Lenovo [17aa] SDevice: RTS525A PCI Express Card Reader [224e] Rev: 01 Driver: rtsx_pci Module: rtsx_pci Device: 04:00.0 Class: Network controller [0280] Vendor: Intel Corporation [8086] Device: Wireless 8265 / 8275 [24fd] SVendor: Intel Corporation [8086] SDevice: Wireless 8265 / 8275 [0130] Rev: 88 Driver: iwlwifi Module: iwlwifi Device: 05:00.0 Class: Non-Volatile memory controller [0108] Vendor: Toshiba America Info Systems [1179] Device: Device [0115] SVendor: Toshiba America Info Systems [1179] SDevice: Device [0001] Rev: 01 ProgIf: 02 Driver: nvme Module: nvme NUMANode: 0 LSPCI allow(plugin).to receive(:shell_out).with("lspci -vnnmk").and_return( mock_shell_out(0, @stdout, "") ) end describe "when gathering data from lspci" do it "lists all devices" do plugin.run expect(plugin[:pci].keys).to eq( ["00:1f.3", "00:1f.4", "00:1f.6", "02:00.0", "04:00.0", "05:00.0"] ) end it "parses out device name vs id" do plugin.run expect(plugin[:pci]["04:00.0"]["device_name"]).to eq("Wireless 8265 / 8275") expect(plugin[:pci]["04:00.0"]["device_id"]).to eq("24fd") end it "parses out sdevice name vs id" do plugin.run expect(plugin[:pci]["04:00.0"]["sdevice_name"]).to eq("Wireless 8265 / 8275") expect(plugin[:pci]["04:00.0"]["sdevice_id"]).to eq("0130") end it "parses out class name vs id" do plugin.run expect(plugin[:pci]["04:00.0"]["class_name"]).to eq("Network controller") expect(plugin[:pci]["04:00.0"]["class_id"]).to eq("0280") end it "parses out vendor name vs id" do plugin.run expect(plugin[:pci]["04:00.0"]["vendor_name"]).to eq("Intel Corporation") expect(plugin[:pci]["04:00.0"]["vendor_id"]).to eq("8086") end it "provides drivers and modules" do plugin.run expect(plugin[:pci]["04:00.0"]["driver"]).to eq(["iwlwifi"]) expect(plugin[:pci]["04:00.0"]["module"]).to eq(["iwlwifi"]) end end end ohai-16.0.7/spec/unit/plugins/linux/machineid_spec.rb000066400000000000000000000031621362624620500225460ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Machine id plugin" do let(:plugin) { get_plugin("linux/machineid") } before do allow(plugin).to receive(:collect_os).and_return(:linux) end it "reads /etc/machine-id if available" do machine_id = "6f702523e2fc7499eb1dc68e5314dacf" allow(::File).to receive(:exist?).with("/etc/machine-id").and_return(true) allow(::File).to receive(:read).with("/etc/machine-id").and_return(machine_id) plugin.run expect(plugin[:machine_id]).to eq(machine_id) end it "reads /var/lib/dbus/machine-id if available" do machine_id = "6f702523e2fc7499eb1dc68e5314dacf" allow(::File).to receive(:exist?).with("/etc/machine-id").and_return(false) allow(::File).to receive(:exist?).with("/var/lib/dbus/machine-id").and_return(true) allow(::File).to receive(:read).with("/var/lib/dbus/machine-id").and_return(machine_id) plugin.run expect(plugin[:machine_id]).to eq(machine_id) end end ohai-16.0.7/spec/unit/plugins/linux/mdadm_spec.rb000066400000000000000000000147521362624620500217160ustar00rootroot00000000000000# # Author:: Tim Smith # Copyright:: Copyright (c) 2014 Limelight Networks, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux Mdadm Plugin" do before do @md0 = <<~MD /dev/md0: Version : 1.2 Creation Time : Thu Jan 30 03:11:40 2014 Raid Level : raid10 Array Size : 2929893888 (2794.16 GiB 3000.21 GB) Used Dev Size : 976631296 (931.39 GiB 1000.07 GB) Raid Devices : 6 Total Devices : 6 Persistence : Superblock is persistent Update Time : Tue May 6 23:30:32 2014 State : clean Active Devices : 6 Working Devices : 6 Failed Devices : 0 Spare Devices : 0 Layout : near=2 Chunk Size : 256K Name : host.therealtimsmith.com:3 (local to host host.therealtimsmith.com) UUID : 5ed74d5b:70bfe21d:8cd57792:c1e13d65 Events : 155 Number Major Minor RaidDevice State 0 8 32 0 active sync /dev/sdc 1 8 48 1 active sync /dev/sdd 2 8 64 2 active sync /dev/sde 3 8 80 3 active sync /dev/sdf 4 8 96 4 active sync /dev/sdg 5 8 112 5 active sync /dev/sdh MD @plugin = get_plugin("linux/mdadm") allow(@plugin).to receive(:collect_os).and_return(:linux) @double_file = double("/proc/mdstat") allow(@double_file).to receive(:each) .and_yield("Personalities : [raid1] [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid10]") .and_yield("md0 : active raid10 sdh[5] sdg[4] sdf[3] sde[2] sdd[1] sdc[0]") .and_yield(" 2929893888 blocks super 1.2 256K chunks 2 near-copies [6/6] [UUUUUU]") allow(File).to receive(:open).with("/proc/mdstat").and_return(@double_file) allow(File).to receive(:exist?).with("/proc/mdstat").and_return(true) allow(@plugin).to receive(:shell_out).with("mdadm --detail /dev/md0").and_return(mock_shell_out(0, @md0, "")) end describe "gathering Mdadm information via /proc/mdstat and mdadm" do it "does not raise an error" do expect { @plugin.run }.not_to raise_error end it "detects raid level" do @plugin.run expect(@plugin[:mdadm][:md0][:level]).to eq(10) end it "detects raid state" do @plugin.run expect(@plugin[:mdadm][:md0][:state]).to eq("clean") end it "detects raid size" do @plugin.run expect(@plugin[:mdadm][:md0][:size]).to eq(2794.16) end it "detects raid metadata level" do @plugin.run expect(@plugin[:mdadm][:md0][:version]).to eq(1.2) end device_counts = { raid: 6, total: 6, active: 6, working: 6, failed: 0, spare: 0 } device_counts.each_pair do |item, expected_value| it "detects device count of \"#{item}\"" do @plugin.run expect(@plugin[:mdadm][:md0][:device_counts][item]).to eq(expected_value) end end it "detects member devices" do @plugin.run expect(@plugin[:mdadm][:md0][:members].sort).to eq( %w{sdc sdd sde sdf sdg sdh} ) end it "detects member devices even if there are multi-digit numbers" do new_mdstat = double("/proc/mdstat2") allow(new_mdstat).to receive(:each) .and_yield("Personalities : [raid1] [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid10]") .and_yield("md0 : active raid10 sdj[2010] sdi[99] sdh[5] sdg[4] sdf[3] sde[2] sdd[1] sdc[0]") .and_yield(" 2929893888 blocks super 1.2 256K chunks 2 near-copies [6/6] [UUUUUU]") allow(File).to receive(:open).with("/proc/mdstat").and_return(new_mdstat) @plugin.run expect(@plugin[:mdadm][:md0][:members].sort).to eq( %w{sdc sdd sde sdf sdg sdh sdi sdj} ) end it "detects member devices even if mdstat has extra entries" do new_mdstat = double("/proc/mdstat2") allow(new_mdstat).to receive(:each) .and_yield("Personalities : [raid1] [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid10]") .and_yield("md0 : active (somecraphere) raid10 sdh[5] sdg[4] sdf[3] sde[2] sdd[1] sdc[0]") .and_yield(" 2929893888 blocks super 1.2 256K chunks 2 near-copies [6/6] [UUUUUU]") allow(File).to receive(:open).with("/proc/mdstat").and_return(new_mdstat) @plugin.run expect(@plugin[:mdadm][:md0][:members].sort).to eq( %w{sdc sdd sde sdf sdg sdh} ) end it "accuratelies report inactive arrays" do new_mdstat = double("/proc/mdstat_inactive") allow(new_mdstat).to receive(:each) .and_yield("Personalities :") .and_yield("md0 : inactive nvme2n1p3[2](S)") allow(File).to receive(:open).with("/proc/mdstat").and_return(new_mdstat) @plugin.run expect(@plugin[:mdadm][:md0][:spares]).to eq(%w{nvme2n1p3}) end it "reports journal devices" do new_mdstat = double("/proc/mdstat_journal") allow(new_mdstat).to receive(:each) .and_yield("Personalies : [raid6]") .and_yield("md0 : active (somecraphere) # Author:: Chris Read # Copyright:: Copyright (c) 2011-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ipaddress" describe Ohai::System, "Linux Network Plugin" do let(:plugin) { get_plugin("linux/network") } let(:linux_ifconfig) do <<~EOM eth0 Link encap:Ethernet HWaddr 12:31:3D:02:BE:A2 inet addr:10.116.201.76 Bcast:10.116.201.255 Mask:255.255.255.0 inet6 addr: fe80::1031:3dff:fe02:bea2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2659966 errors:0 dropped:0 overruns:0 frame:0 TX packets:1919690 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1392844460 (1.2 GiB) TX bytes:691785313 (659.7 MiB) Interrupt:16 eth0:5 Link encap:Ethernet HWaddr 00:0c:29:41:71:45 inet addr:192.168.5.1 Bcast:192.168.5.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 eth0.11 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee inet addr:192.168.0.16 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::2aa:bbff:fecc:ddee/64 Scope:Link inet6 addr: 1111:2222:3333:4444::2/64 Scope:Global inet6 addr: 1111:2222:3333:4444::3/64 Scope:Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1208795008 errors:0 dropped:0 overruns:0 frame:0 TX packets:3269635153 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1751940374 (1.6 GiB) TX bytes:2195567597 (2.0 GiB) eth0.151 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee inet addr:10.151.0.16 Bcast:10.151.0.255 Mask:255.255.255.0 inet6 addr: fe80::2aa:bbff:fecc:ddee/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:206553677 errors:0 dropped:0 overruns:0 frame:0 TX packets:163901336 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3190792261 (2.9 GiB) TX bytes:755086548 (720.1 MiB) eth0.152 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee inet addr:10.152.1.16 Bcast:10.152.3.255 Mask:255.255.252.0 inet6 addr: fe80::2aa:bbff:fecc:ddee/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:14016741 errors:0 dropped:0 overruns:0 frame:0 TX packets:55232 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:664957462 (634.1 MiB) TX bytes:4876434 (4.6 MiB) eth0.153 Link encap:Ethernet HWaddr 00:aa:bb:cc:dd:ee inet addr:10.153.1.16 Bcast:10.153.3.255 Mask:255.255.252.0 inet6 addr: fe80::2aa:bbff:fecc:ddee/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2022667595 errors:0 dropped:0 overruns:0 frame:0 TX packets:1798627472 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:4047036732 (3.7 GiB) TX bytes:3451231474 (3.2 GiB) foo:veth0@eth0 Link encap:Ethernet HWaddr ca:b3:73:8b:0c:e4 BROADCAST MULTICAST MTU:1500 Metric:1 tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:172.16.19.39 P-t-P:172.16.19.1 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1418 Metric:1 RX packets:57200 errors:0 dropped:0 overruns:0 frame:0 TX packets:13782 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:7377600 (7.0 MiB) TX bytes:1175481 (1.1 MiB) venet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1418 Metric:1 RX packets:57200 errors:0 dropped:0 overruns:0 frame:0 TX packets:13782 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:7377600 (7.0 MiB) TX bytes:1175481 (1.1 MiB) venet0:0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1418 Metric:1 RX packets:57200 errors:0 dropped:0 overruns:0 frame:0 TX packets:13782 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:7377600 (7.0 MiB) TX bytes:1175481 (1.1 MiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:524 errors:0 dropped:0 overruns:0 frame:0 TX packets:524 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:35224 (34.3 KiB) TX bytes:35224 (34.3 KiB) eth3 Link encap:Ethernet HWaddr E8:39:35:C5:C8:54 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:13395101 errors:0 dropped:0 overruns:0 frame:0 TX packets:9492909 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1325650573 (1.2 GiB) TX bytes:1666310189 (1.5 GiB) Interrupt:36 Memory:f4800000-f4ffffff ovs-system Link encap:Ethernet HWaddr 7A:7A:80:80:6C:24 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) xapi1 Link encap:Ethernet HWaddr E8:39:35:C5:C8:50 inet addr:192.168.13.34 Bcast:192.168.13.255 Mask:255.255.255.0 UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:160275 errors:0 dropped:0 overruns:0 frame:0 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:21515031 (20.5 MiB) TX bytes:2052 (2.0 KiB) fwdintf Link encap:Ethernet HWaddr 00:00:00:00:00:0a inet6 addr: fe80::200:ff:fe00:a/64 Scope:Link UP RUNNING NOARP MULTICAST MTU:1496 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:1 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:140 (140.0 B) EOM # Note that ifconfig shows foo:veth0@eth0 but fails to show any address information. # This was not a mistake collecting the output and Apparently ifconfig is broken in this regard. end let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel 192.168.5.0/24 dev eth0 proto kernel src 192.168.5.1 192.168.212.0/24 dev foo:veth0@eth0 proto kernel src 192.168.212.2 172.16.151.0/24 dev eth0 proto kernel src 172.16.151.100 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2 10.5.4.0/24 \\ nexthop via 10.5.4.1 dev eth0 weight 1\\ nexthop via 10.5.4.2 dev eth0 weight 1 default via 10.116.201.1 dev eth0 EOM end let(:linux_route_n) do <<~EOM Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.116.201.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 10.116.201.1 0.0.0.0 UG 0 0 0 eth0 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 expires 86023sec default via 1111:2222:3333:4444::1 dev eth0.11 metric 1024 EOM end let(:linux_ip_addr) do <<~EOM 1: lo: mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 12:31:3d:02:be:a2 brd ff:ff:ff:ff:ff:ff inet 10.116.201.76/24 brd 10.116.201.255 scope global eth0 inet 10.116.201.75/32 scope global eth0 inet 10.116.201.74/24 scope global secondary eth0 inet 192.168.5.1/24 brd 192.168.5.255 scope global eth0:5 inet6 fe80::1031:3dff:fe02:bea2/64 scope link valid_lft forever preferred_lft forever inet6 2001:44b8:4160:8f00:a00:27ff:fe13:eacd/64 scope global dynamic valid_lft 6128sec preferred_lft 2526sec 3: eth0.11@eth0: mtu 1500 qdisc noqueue state UP link/ether 00:aa:bb:cc:dd:ee brd ff:ff:ff:ff:ff:ff inet 192.168.0.16/24 brd 192.168.0.255 scope global eth0.11 inet6 fe80::2e0:81ff:fe2b:48e7/64 scope link inet6 1111:2222:3333:4444::2/64 scope global valid_lft forever preferred_lft forever inet6 1111:2222:3333:4444::3/64 scope global valid_lft forever preferred_lft forever 4: eth0.151@eth0: mtu 1500 qdisc noqueue state UP link/ether 00:aa:bb:cc:dd:ee brd ff:ff:ff:ff:ff:ff inet 10.151.0.16/24 brd 10.151.0.255 scope global eth0.151 inet 10.151.1.16/24 scope global eth0.151 inet6 fe80::2e0:81ff:fe2b:48e7/64 scope link valid_lft forever preferred_lft forever 5: eth0.152@eth0: mtu 1500 qdisc noqueue state UP link/ether 00:aa:bb:cc:dd:ee brd ff:ff:ff:ff:ff:ff inet 10.152.1.16/22 brd 10.152.3.255 scope global eth0.152 inet6 fe80::2e0:81ff:fe2b:48e7/64 scope link valid_lft forever preferred_lft forever 6: eth0.153@eth0: mtu 1500 qdisc noqueue state UP link/ether 00:aa:bb:cc:dd:ee brd ff:ff:ff:ff:ff:ff inet 10.153.1.16/22 brd 10.153.3.255 scope global eth0.153 inet6 fe80::2e0:81ff:fe2b:48e7/64 scope link valid_lft forever preferred_lft forever 7: foo:veth0@eth0@veth0: mtu 1500 qdisc noop state DOWN link/ether ca:b3:73:8b:0c:e4 brd ff:ff:ff:ff:ff:ff inet 192.168.212.2/24 scope global foo:veth0@eth0 8: tun0: mtu 1500 qdisc mq state UP qlen 1000 link/none inet 172.16.19.39 peer 172.16.19.1 scope global tun0 9: venet0: mtu 1500 qdisc mq state UP qlen 1000 link/void inet 127.0.0.2/32 scope host venet0 inet 172.16.19.48/32 scope global venet0:0 12: xapi1: mtu 1500 qdisc noqueue state UNKNOWN link/ether e8:39:35:c5:c8:50 brd ff:ff:ff:ff:ff:ff inet 192.168.13.34/24 brd 192.168.13.255 scope global xapi1 valid_lft forever preferred_lft forever 13: fwdintf: mtu 1496 qdisc pfifo_fast state UNKNOWN group default qlen 1000 link/ether 00:00:00:00:00:0a brd ff:ff:ff:ff:ff:ff 14: ip6tnl0@NONE: mtu 1452 qdisc noqueue state UNKNOWN group default qlen 1 link/tunnel6 :: brd :: inet6 fe80::f47a:2aff:fef0:c6ef/64 scope link valid_lft forever preferred_lft forever EOM end let(:linux_ip_link_s_d) do <<~EOM 1: lo: mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 RX: bytes packets errors dropped overrun mcast 35224 524 0 0 0 0 TX: bytes packets errors dropped carrier collsns 35224 524 0 0 0 0 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 12:31:3d:02:be:a2 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 1392844460 2659966 0 0 0 0 TX: bytes packets errors dropped carrier collsns 691785313 1919690 0 0 0 0 3: eth0.11@eth0: mtu 1500 qdisc noqueue state UP link/ether 00:0c:29:41:71:45 brd ff:ff:ff:ff:ff:ff vlan id 11 RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 4: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 100 link/none RX: bytes packets errors dropped overrun mcast 1392844460 2659966 0 0 0 0 TX: bytes packets errors dropped carrier collsns 691785313 1919690 0 0 0 0 5: venet0: mtu 1500 qdisc mq state UP qlen 1000 link/void RX: bytes packets errors dropped overrun mcast 1392844460 2659966 0 0 0 0 TX: bytes packets errors dropped carrier collsns 691785313 1919690 0 0 0 0 10: eth3: mtu 1500 qdisc mq master ovs-system state UP mode DEFAULT qlen 1000 link/ether e8:39:35:c5:c8:54 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 1321907045 13357087 0 0 0 3126613 TX: bytes packets errors dropped carrier collsns 1661526184 9467091 0 0 0 0 11: ovs-system: mtu 1500 qdisc noop state DOWN mode DEFAULT link/ether 7a:7a:80:80:6c:24 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 12: xapi1: mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT link/ether e8:39:35:c5:c8:50 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 21468183 159866 0 0 0 0 TX: bytes packets errors dropped carrier collsns 2052 6 0 0 0 0 13: fwdintf: mtu 1496 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 00:00:00:00:00:0a brd ff:ff:ff:ff:ff:ff promiscuity 0 RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 140 2 0 1 0 0 14: ip6tnl0@NONE: mtu 1452 qdisc noop state DOWN mode DEFAULT group default qlen 1 link/tunnel6 :: brd :: promiscuity 0 ip6tnl ip6ip6 remote :: local :: encaplimit 0 hoplimit 0 tclass 0x00 flowlabel 0x00000 (flowinfo 0x00000000) addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 EOM end let(:linux_arp_an) do <<~EOM ? (10.116.201.1) at fe:ff:ff:ff:ff:ff [ether] on eth0 EOM end let(:linux_ip_neighbor_show) do <<~EOM 10.116.201.1 dev eth0 lladdr fe:ff:ff:ff:ff:ff REACHABLE EOM end let(:linux_ip_inet6_neighbor_show) do <<~EOM 1111:2222:3333:4444::1 dev eth0.11 lladdr 00:1c:0e:12:34:56 router REACHABLE fe80::21c:eff:fe12:3456 dev eth0.11 lladdr 00:1c:0e:30:28:00 router REACHABLE fe80::21c:eff:fe12:3456 dev eth0.153 lladdr 00:1c:0e:30:28:00 router REACHABLE EOM end let(:linux_ethtool) do <<~EOM Settings for eth0: Supported ports: [ FIBRE ] Supported link modes: 1000baseT/Full 10000baseT/Full Supported pause frame use: No Supports auto-negotiation: Yes Advertised link modes: 1000baseT/Full 10000baseT/Full Advertised pause frame use: No Advertised auto-negotiation: Yes Speed: 10000Mb/s Duplex: Full Port: FIBRE PHYAD: 0 Transceiver: external Auto-negotiation: on Supports Wake-on: d Wake-on: d Current message level: 0x00000007 (7) drv probe link Link detected: yes EOM end let(:linux_ethtool_g) do <<~EOM Ring parameters for eth0: Pre-set maximums: RX: 8192 RX Mini: 0 RX Jumbo: 0 TX: 8192 Current hardware settings: RX: 8192 RX Mini: 0 RX Jumbo: 0 TX: 8192 EOM end before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("ip addr").and_return(mock_shell_out(0, linux_ip_addr, "")) allow(plugin).to receive(:shell_out).with("ip -d -s link").and_return(mock_shell_out(0, linux_ip_link_s_d, "")) allow(plugin).to receive(:shell_out).with("ip -f inet neigh show").and_return(mock_shell_out(0, linux_ip_neighbor_show, "")) allow(plugin).to receive(:shell_out).with("ip -f inet6 neigh show").and_return(mock_shell_out(0, linux_ip_inet6_neighbor_show, "")) allow(plugin).to receive(:shell_out).with("ip -o -f inet route show table main").and_return(mock_shell_out(0, linux_ip_route, "")) allow(plugin).to receive(:shell_out).with("ip -o -f inet6 route show table main").and_return(mock_shell_out(0, linux_ip_route_inet6, "")) allow(plugin).to receive(:shell_out).with("route -n").and_return(mock_shell_out(0, linux_route_n, "")) allow(plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, linux_ifconfig, "")) allow(plugin).to receive(:shell_out).with("arp -an").and_return(mock_shell_out(0, linux_arp_an, "")) allow(plugin).to receive(:shell_out).with(/ethtool -g/).and_return(mock_shell_out(0, linux_ethtool_g, "")) allow(plugin).to receive(:shell_out).with(/ethtool [^\-]/).and_return(mock_shell_out(0, linux_ethtool, "")) end describe "#interface_has_no_addresses_in_family?" do context "when interface has no addresses" do let(:iface) { {} } it "returns true" do expect(plugin.interface_has_no_addresses_in_family?(iface, "inet")).to eq(true) end end context "when an interface has no addresses in family" do let(:iface) { { addresses: { "1.2.3.4" => { "family" => "inet6" } } } } it "returns true" do expect(plugin.interface_has_no_addresses_in_family?(iface, "inet")).to eq(true) end end context "when an interface has addresses in family" do let(:iface) { { addresses: { "1.2.3.4" => { "family" => "inet" } } } } it "returns false" do expect(plugin.interface_has_no_addresses_in_family?(iface, "inet")).to eq(false) end end end describe "#interface_have_address?" do context "when interface has no addresses" do let(:iface) { {} } it "returns false" do expect(plugin.interface_have_address?(iface, "1.2.3.4")).to eq(false) end end context "when interface has a matching address" do let(:iface) { { addresses: { "1.2.3.4" => {} } } } it "returns true" do expect(plugin.interface_have_address?(iface, "1.2.3.4")).to eq(true) end end context "when interface does not have a matching address" do let(:iface) { { addresses: { "4.3.2.1" => {} } } } it "returns false" do expect(plugin.interface_have_address?(iface, "1.2.3.4")).to eq(false) end end end describe "#interface_address_not_link_level?" do context "when the address scope is link" do let(:iface) { { addresses: { "1.2.3.4" => { scope: "Link" } } } } it "returns false" do expect(plugin.interface_address_not_link_level?(iface, "1.2.3.4")).to eq(false) end end context "when the address scope is global" do let(:iface) { { addresses: { "1.2.3.4" => { scope: "Global" } } } } it "returns true" do expect(plugin.interface_address_not_link_level?(iface, "1.2.3.4")).to eq(true) end end end describe "#interface_valid_for_route?" do let(:iface) { double("iface") } let(:address) { "1.2.3.4" } let(:family) { "inet" } context "when interface has no addresses" do it "returns true" do expect(plugin).to receive(:interface_has_no_addresses_in_family?).with(iface, family).and_return(true) expect(plugin.interface_valid_for_route?(iface, address, family)).to eq(true) end end context "when interface has addresses" do before do expect(plugin).to receive(:interface_has_no_addresses_in_family?).with(iface, family).and_return(false) end context "when interface contains the address" do before do expect(plugin).to receive(:interface_have_address?).with(iface, address).and_return(true) end context "when interface address is not a link-level address" do it "returns true" do expect(plugin).to receive(:interface_address_not_link_level?).with(iface, address).and_return(true) expect(plugin.interface_valid_for_route?(iface, address, family)).to eq(true) end end context "when the interface address is a link-level address" do it "returns false" do expect(plugin).to receive(:interface_address_not_link_level?).with(iface, address).and_return(false) expect(plugin.interface_valid_for_route?(iface, address, family)).to eq(false) end end end context "when interface does not contain the address" do it "returns false" do expect(plugin).to receive(:interface_have_address?).with(iface, address).and_return(false) expect(plugin.interface_valid_for_route?(iface, address, family)).to eq(false) end end end end describe "#route_is_valid_default_route?" do context "when the route destination is default" do let(:route) { { destination: "default" } } let(:default_route) { double("default_route") } it "returns true" do expect(plugin.route_is_valid_default_route?(route, default_route)).to eq(true) end end context "when the route destination is not default" do let(:route) { { destination: "10.0.0.0/24" } } context "when the default route does not have a gateway" do let(:default_route) { {} } it "returns false" do expect(plugin.route_is_valid_default_route?(route, default_route)).to eq(false) end end context "when the gateway is within the destination" do let(:default_route) { { via: "10.0.0.1" } } it "returns true" do expect(plugin.route_is_valid_default_route?(route, default_route)).to eq(true) end end context "when the gateway is not within the destination" do let(:default_route) { { via: "20.0.0.1" } } it "returns false" do expect(plugin.route_is_valid_default_route?(route, default_route)).to eq(false) end end end end %w{ifconfig iproute2}.each do |network_method| describe "gathering IP layer address info via #{network_method}" do before do allow(plugin).to receive(:which).with("ip").and_return( network_method == "iproute2" ? "/sbin/ip" : false ) allow(plugin).to receive(:which).with("ethtool").and_return( "/sbin/ethtool" ) plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "detects the interfaces" do if network_method == "iproute2" expect(plugin["network"]["interfaces"].keys.sort).to eq(["eth0", "eth0.11", "eth0.151", "eth0.152", "eth0.153", "eth0:5", "eth3", "foo:veth0@eth0", "fwdintf", "ip6tnl0", "lo", "ovs-system", "tun0", "venet0", "venet0:0", "xapi1"]) else expect(plugin["network"]["interfaces"].keys.sort).to eq(["eth0", "eth0.11", "eth0.151", "eth0.152", "eth0.153", "eth0:5", "eth3", "foo:veth0@eth0", "fwdintf", "lo", "ovs-system", "tun0", "venet0", "venet0:0", "xapi1"]) end end it "detects the layer one details of an ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["link_speed"]).to eq(10000) expect(plugin["network"]["interfaces"]["eth0"]["duplex"]).to eq("Full") expect(plugin["network"]["interfaces"]["eth0"]["port"]).to eq("FIBRE") expect(plugin["network"]["interfaces"]["eth0"]["transceiver"]).to eq("external") expect(plugin["network"]["interfaces"]["eth0"]["auto_negotiation"]).to eq("on") expect(plugin["network"]["interfaces"]["eth0"]["mdi_x"]).to be_nil expect(plugin["network"]["interfaces"]["eth0"]["ring_params"]["max_tx"]).to eq(8192) expect(plugin["network"]["interfaces"]["eth0"]["ring_params"]["max_rx"]).to eq(8192) expect(plugin["network"]["interfaces"]["eth0"]["ring_params"]["current_tx"]).to eq(8192) expect(plugin["network"]["interfaces"]["eth0"]["ring_params"]["current_rx"]).to eq(8192) end it "detects the ipv4 addresses of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["addresses"].keys).to include("10.116.201.76") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["10.116.201.76"]["netmask"]).to eq("255.255.255.0") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["10.116.201.76"]["broadcast"]).to eq("10.116.201.255") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["10.116.201.76"]["family"]).to eq("inet") end it "detects the ipv4 addresses of an ethernet subinterface" do expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"].keys).to include("192.168.0.16") expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"]["192.168.0.16"]["netmask"]).to eq("255.255.255.0") expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"]["192.168.0.16"]["broadcast"]).to eq("192.168.0.255") expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"]["192.168.0.16"]["family"]).to eq("inet") end it "detects the ipv6 addresses of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["addresses"].keys).to include("fe80::1031:3dff:fe02:bea2") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["fe80::1031:3dff:fe02:bea2"]["scope"]).to eq("Link") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["fe80::1031:3dff:fe02:bea2"]["prefixlen"]).to eq("64") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["fe80::1031:3dff:fe02:bea2"]["family"]).to eq("inet6") end it "detects the ipv6 addresses of an ethernet subinterface" do %w{ 1111:2222:3333:4444::2 1111:2222:3333:4444::3 }.each do |addr| expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"].keys).to include(addr) expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"][addr]["scope"]).to eq("Global") expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"][addr]["prefixlen"]).to eq("64") expect(plugin["network"]["interfaces"]["eth0.11"]["addresses"][addr]["family"]).to eq("inet6") end end it "detects the mac addresses of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["addresses"].keys).to include("12:31:3D:02:BE:A2") expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["12:31:3D:02:BE:A2"]["family"]).to eq("lladdr") end it "detects the encapsulation type of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["encapsulation"]).to eq("Ethernet") end it "detects the flags of the ethernet interface" do if network_method == "ifconfig" expect(plugin["network"]["interfaces"]["eth0"]["flags"].sort).to eq(%w{BROADCAST MULTICAST RUNNING UP}) else expect(plugin["network"]["interfaces"]["eth0"]["flags"].sort).to eq(%w{BROADCAST LOWER_UP MULTICAST UP}) end end it "detects the number of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["number"]).to eq("0") end it "detects the mtu of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["mtu"]).to eq("1500") end it "detects the ipv4 addresses of the loopback interface" do expect(plugin["network"]["interfaces"]["lo"]["addresses"].keys).to include("127.0.0.1") expect(plugin["network"]["interfaces"]["lo"]["addresses"]["127.0.0.1"]["netmask"]).to eq("255.0.0.0") expect(plugin["network"]["interfaces"]["lo"]["addresses"]["127.0.0.1"]["family"]).to eq("inet") end it "detects the ipv6 addresses of the loopback interface" do expect(plugin["network"]["interfaces"]["lo"]["addresses"].keys).to include("::1") expect(plugin["network"]["interfaces"]["lo"]["addresses"]["::1"]["scope"]).to eq("Node") expect(plugin["network"]["interfaces"]["lo"]["addresses"]["::1"]["prefixlen"]).to eq("128") expect(plugin["network"]["interfaces"]["lo"]["addresses"]["::1"]["family"]).to eq("inet6") end it "detects the encapsulation type of the loopback interface" do expect(plugin["network"]["interfaces"]["lo"]["encapsulation"]).to eq("Loopback") end it "detects the flags of the ethernet interface" do if network_method == "ifconfig" expect(plugin["network"]["interfaces"]["lo"]["flags"].sort).to eq(%w{LOOPBACK RUNNING UP}) else expect(plugin["network"]["interfaces"]["lo"]["flags"].sort).to eq(%w{LOOPBACK LOWER_UP UP}) end end it "detects the mtu of the loopback interface" do expect(plugin["network"]["interfaces"]["lo"]["mtu"]).to eq("16436") end it "detects the arp entries" do expect(plugin["network"]["interfaces"]["eth0"]["arp"]["10.116.201.1"]).to eq("fe:ff:ff:ff:ff:ff") end if network_method == "iproute2" it "detects the tunnel information" do expect(plugin["network"]["interfaces"]["ip6tnl0"]["tunnel_info"]).to eq( { "proto" => "ip6ip6", "remote" => "::", "local" => "::", "encaplimit" => "0", "hoplimit" => "0", "tclass" => "0x00", "flowlabel" => "0x00000", "addrgenmode" => "eui64", "numtxqueues" => "1", "numrxqueues" => "1", "gso_max_size" => "65536", "gso_max_segs" => "65535", } ) end end end describe "gathering interface counters via #{network_method}" do before do allow(plugin).to receive(:which).with("ip").and_return(network_method == "iproute2" ? "/sbin/ip" : false) allow(plugin).to receive(:which).with("ethtool").and_return("/sbin/ethtool") plugin.run end it "detects the ethernet counters" do expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["bytes"]).to eq("691785313") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["packets"]).to eq("1919690") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["collisions"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["queuelen"]).to eq("1000") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["errors"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["carrier"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["tx"]["drop"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["rx"]["bytes"]).to eq("1392844460") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["rx"]["packets"]).to eq("2659966") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["rx"]["errors"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["rx"]["overrun"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["eth0"]["rx"]["drop"]).to eq("0") end it "detects the loopback counters" do expect(plugin["counters"]["network"]["interfaces"]["lo"]["tx"]["bytes"]).to eq("35224") expect(plugin["counters"]["network"]["interfaces"]["lo"]["tx"]["packets"]).to eq("524") expect(plugin["counters"]["network"]["interfaces"]["lo"]["tx"]["collisions"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["lo"]["tx"]["errors"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["lo"]["tx"]["carrier"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["lo"]["tx"]["drop"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["lo"]["rx"]["bytes"]).to eq("35224") expect(plugin["counters"]["network"]["interfaces"]["lo"]["rx"]["packets"]).to eq("524") expect(plugin["counters"]["network"]["interfaces"]["lo"]["rx"]["errors"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["lo"]["rx"]["overrun"]).to eq("0") expect(plugin["counters"]["network"]["interfaces"]["lo"]["rx"]["drop"]).to eq("0") end end describe "setting the node's default IP address attribute with #{network_method}" do before do allow(plugin).to receive(:which).with("ip").and_return(network_method == "iproute2" ? "/sbin/ip" : false) allow(plugin).to receive(:which).with("ethtool").and_return("/sbin/ethtool") plugin.run end describe "without a subinterface" do it "finds the default interface by asking which iface has the default route" do expect(plugin["network"]["default_interface"]).to eq("eth0") end it "finds the default gateway by asking which iface has the default route" do expect(plugin["network"]["default_gateway"]).to eq("10.116.201.1") end end describe "with a link level default route" do let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel default dev eth0 scope link EOM end let(:linux_route_n) do <<~EOM Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.116.201.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 eth0 EOM end before do plugin.run end it "finds the default interface by asking which iface has the default route" do expect(plugin["network"]["default_interface"]).to eq("eth0") end it "finds the default interface by asking which iface has the default route" do expect(plugin["network"]["default_gateway"]).to eq("0.0.0.0") end end describe "with a subinterface" do let(:linux_ip_route) do <<~EOM 192.168.0.0/24 dev eth0.11 proto kernel src 192.168.0.2 default via 192.168.0.15 dev eth0.11 EOM end let(:linux_route_n) do <<~EOM Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0.11 0.0.0.0 192.168.0.15 0.0.0.0 UG 0 0 0 eth0.11 EOM end before do plugin.run end it "finds the default interface by asking which iface has the default route" do expect(plugin["network"]["default_interface"]).to eq("eth0.11") end it "finds the default interface by asking which iface has the default route" do expect(plugin["network"]["default_gateway"]).to eq("192.168.0.15") end end end end describe "for newer network features using iproute2 only" do before do allow(plugin).to receive(:which).with("ip").and_return("/sbin/ip") allow(plugin).to receive(:which).with("ethtool").and_return( "/sbin/ethtool" ) allow(File).to receive(:exist?).with("/proc/net/if_inet6").and_return(true) # ipv6 is enabled plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "finds the default inet6 interface if there's a inet6 default route" do expect(plugin["network"]["default_inet6_interface"]).to eq("eth0.11") end it "finds the default inet6 gateway if there's a inet6 default route" do expect(plugin["network"]["default_inet6_gateway"]).to eq("1111:2222:3333:4444::1") end it "finds inet6 neighbours" do expect(plugin["network"]["interfaces"]["eth0.11"]["neighbour_inet6"]["1111:2222:3333:4444::1"]).to eq("00:1c:0e:12:34:56") end it "detects the ipv4 addresses of an ethernet interface with a crazy name" do expect(plugin["network"]["interfaces"]["foo:veth0@eth0"]["addresses"].keys).to include("192.168.212.2") expect(plugin["network"]["interfaces"]["foo:veth0@eth0"]["addresses"]["192.168.212.2"]["netmask"]).to eq("255.255.255.0") expect(plugin["network"]["interfaces"]["foo:veth0@eth0"]["addresses"]["192.168.212.2"]["family"]).to eq("inet") end it "generates a fake interface for ip aliases for backward compatibility" do expect(plugin["network"]["interfaces"]["eth0:5"]["addresses"].keys).to include("192.168.5.1") expect(plugin["network"]["interfaces"]["eth0:5"]["addresses"]["192.168.5.1"]["netmask"]).to eq("255.255.255.0") expect(plugin["network"]["interfaces"]["eth0:5"]["addresses"]["192.168.5.1"]["family"]).to eq("inet") end it "adds the vlan information of an interface" do expect(plugin["network"]["interfaces"]["eth0.11"]["vlan"]["id"]).to eq("11") expect(plugin["network"]["interfaces"]["eth0.11"]["vlan"]["flags"]).to eq([ "REORDER_HDR" ]) end it "adds the state of an interface" do expect(plugin["network"]["interfaces"]["eth0.11"]["state"]).to eq("up") end it "detects interfaces only visible via ip link" do expect(plugin["network"]["interfaces"]["eth3"]["state"]).to eq("up") end it "detects tags on v6 addresses of the ethernet interface" do expect(plugin["network"]["interfaces"]["eth0"]["addresses"]["2001:44b8:4160:8f00:a00:27ff:fe13:eacd"]["tags"]).to eq(["dynamic"]) end describe "when IPv6 is disabled" do before do allow(File).to receive(:exist?).with("/proc/net/if_inet6").and_return(false) plugin.run end it "doesn't set ip6address" do expect(plugin["ip6address"]).to be_nil end end describe "when dealing with routes" do it "adds routes" do plugin.run expect(plugin["network"]["interfaces"]["eth0"]["routes"]).to include Mash.new( destination: "10.116.201.0/24", proto: "kernel", family: "inet" ) expect(plugin["network"]["interfaces"]["eth0"]["routes"]).to include Mash.new( destination: "10.5.4.0/24", family: "inet", via: "10.5.4.1") expect(plugin["network"]["interfaces"]["eth0"]["routes"]).to include Mash.new( destination: "10.5.4.0/24", family: "inet", via: "10.5.4.2") expect(plugin["network"]["interfaces"]["foo:veth0@eth0"]["routes"]).to include Mash.new( destination: "192.168.212.0/24", proto: "kernel", src: "192.168.212.2", family: "inet" ) expect(plugin["network"]["interfaces"]["eth0"]["routes"]).to include Mash.new( destination: "fe80::/64", metric: "256", proto: "kernel", family: "inet6" ) expect(plugin["network"]["interfaces"]["eth0.11"]["routes"]).to include Mash.new( destination: "1111:2222:3333:4444::/64", metric: "1024", family: "inet6" ) expect(plugin["network"]["interfaces"]["eth0.11"]["routes"]).to include Mash.new( destination: "default", via: "1111:2222:3333:4444::1", metric: "1024", family: "inet6") end describe "when there isn't a source field in route entries and no ipv6 default routes" do let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 expires 86023sec EOM end before do plugin.run end it "doesn't set ipaddress" do expect(plugin["ipaddress"]).to be nil end it "doesn't set macaddress" do expect(plugin["macaddress"]).to be nil end it "doesn't set ip6address" do expect(plugin["ip6address"]).to be nil end end describe "when there's a source field in the default route entry" do let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel 192.168.5.0/24 dev eth0 proto kernel src 192.168.5.1 192.168.212.0/24 dev foo:veth0@eth0 proto kernel src 192.168.212.2 172.16.151.0/24 dev eth0 proto kernel src 172.16.151.100 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2 default via 10.116.201.1 dev eth0 src 10.116.201.76 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 default via 1111:2222:3333:4444::1 dev eth0.11 metric 1024 src 1111:2222:3333:4444::3 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "sets ipaddress" do expect(plugin["ipaddress"]).to eq("10.116.201.76") end it "sets ip6address" do expect(plugin["ip6address"]).to eq("1111:2222:3333:4444::3") end end describe "when there're several default routes" do let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel src 10.116.201.76 192.168.5.0/24 dev eth0 proto kernel src 192.168.5.1 192.168.212.0/24 dev foo:veth0@eth0 proto kernel src 192.168.212.2 172.16.151.0/24 dev eth0 proto kernel src 172.16.151.100 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2 default via 10.116.201.1 dev eth0 metric 10 default via 10.116.201.254 dev eth0 metric 9 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 src 1111:2222:3333:4444::3 default via 1111:2222:3333:4444::1 dev eth0.11 metric 1024 default via 1111:2222:3333:4444::ffff dev eth0.11 metric 1023 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "sets default ipv4 interface and gateway" do expect(plugin["network"]["default_interface"]).to eq("eth0") expect(plugin["network"]["default_gateway"]).to eq("10.116.201.254") end it "sets default ipv6 interface and gateway" do expect(plugin["network"]["default_inet6_interface"]).to eq("eth0.11") expect(plugin["network"]["default_inet6_gateway"]).to eq("1111:2222:3333:4444::ffff") end end describe "when there're a mixed setup of routes that could be used to set ipaddress" do let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel src 10.116.201.76 192.168.5.0/24 dev eth0 proto kernel src 192.168.5.1 192.168.212.0/24 dev foo:veth0@eth0 proto kernel src 192.168.212.2 172.16.151.0/24 dev eth0 proto kernel src 172.16.151.100 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2 default via 10.116.201.1 dev eth0 metric 10 default via 10.116.201.254 dev eth0 metric 9 src 10.116.201.74 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 src 1111:2222:3333:4444::3 default via 1111:2222:3333:4444::1 dev eth0.11 metric 1024 default via 1111:2222:3333:4444::ffff dev eth0.11 metric 1023 src 1111:2222:3333:4444::2 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "sets ipaddress" do expect(plugin["ipaddress"]).to eq("10.116.201.74") end it "sets ip6address" do expect(plugin["ip6address"]).to eq("1111:2222:3333:4444::2") end end describe "when there's a source field in a local route entry but it isnt in the default route" do let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel src 10.116.201.76 192.168.5.0/24 dev eth0 proto kernel src 192.168.5.1 192.168.212.0/24 dev foo:veth0@eth0 proto kernel src 192.168.212.2 172.16.151.0/24 dev eth0 proto kernel src 172.16.151.100 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2 default via 10.116.201.1 dev eth0 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 src 1111:2222:3333:4444::3 default via 1111:2222:3333:4444::1 dev eth0.11 metric 1024 EOM end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) plugin.run expect(plugin["network"]).not_to be_nil end it "sets ipaddress" do plugin.run expect(plugin["ipaddress"]).to eq("10.116.201.76") end # without a source address on the default route we cannot pick the an ipv6 address from the interface # In the future an RFC6724 compliant process should choose ip6address in the network plugin it "does not set ip6address" do plugin.run expect(plugin["ip6address"]).to eq(nil) end context "with only ipv6 routes" do let(:linux_ip_route) { "" } it "sets macaddress to the mac address of the ip6 default interface" do expect(plugin["macaddress"]).to eq("00:AA:BB:CC:DD:EE") end end describe "when about to set macaddress" do it "sets macaddress" do plugin.run expect(plugin["macaddress"]).to eq("12:31:3D:02:BE:A2") end context "when then ipv4 interface has the NOARP flag and no ipv6 routes exist" do let(:linux_ip_route) do <<~EOM 10.118.19.1 dev tun0 proto kernel src 10.118.19.39 default via 172.16.19.1 dev tun0 EOM end let(:linux_ip_route_inet6) { "" } it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) plugin.run expect(plugin["network"]).not_to be_nil end it "doesn't set macaddress" do plugin.run expect(plugin["macaddress"]).to be_nil end end end end describe "with a link level default route" do let(:linux_ip_route) do <<~EOM default dev venet0 scope link EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "doesn't set ipaddress" do expect(plugin["ipaddress"]).to be_nil end end describe "with a link level default route to an unaddressed int" do let(:linux_ip_route) do <<~EOM default dev eth3 scope link EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "sets default_interface" do expect(plugin["network"]["default_interface"]).to eq("eth3") end it "doesn't set ipaddress" do expect(plugin["ipaddress"]).to be_nil end end describe "with a link level default route with a source" do let(:linux_ip_route) do <<~EOM default dev fwdintf scope link src 2.2.2.2 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "sets default_interface" do expect(plugin["network"]["default_interface"]).to eq("fwdintf") end it "sets ipaddress" do expect(plugin["ipaddress"]).to eq("2.2.2.2") end end describe "when not having a global scope ipv6 address" do let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 default via fe80::21c:eff:fe12:3456 dev eth0.153 src fe80::2e0:81ff:fe2b:48e7 metric 1024 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "doesn't set ip6address" do expect(plugin["ip6address"]).to be_nil end end describe "with no default route" do let(:linux_ip_route) do <<~EOM 10.116.201.0/24 dev eth0 proto kernel src 10.116.201.76 192.168.5.0/24 dev eth0 proto kernel src 192.168.5.1 192.168.212.0/24 dev foo:veth0@eth0 proto kernel src 192.168.212.2 172.16.151.0/24 dev eth0 proto kernel src 172.16.151.100 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 src 1111:2222:3333:4444::3 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "doesn't set ipaddress" do expect(plugin["ipaddress"]).to be_nil end it "doesn't set ip6address" do expect(plugin["ip6address"]).to be_nil end end describe "with openvz setup" do let(:linux_ip_route) { "default dev venet0 scope link" } let(:linux_ip_addr) do <<~EOM 1: lo: mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: venet0: mtu 1500 qdisc noqueue state UNKNOWN link/void inet 127.0.0.2/32 scope host venet0 inet 10.116.201.76/24 brd 10.116.201.255 scope global venet0:0 inet6 2001:44b8:4160:8f00:a00:27ff:fe13:eacd/64 scope global dynamic valid_lft 6128sec preferred_lft 2526sec EOM end # We don't have the corresponding ipv6 data for these tests let(:linux_ip_route_inet6) { "" } let(:linux_ip_inet6_neighbor_show) { "" } before do allow(plugin).to receive(:is_openvz?).and_return true allow(plugin).to receive(:is_openvz_host?).and_return false plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "sets default ipv4 interface and gateway" do expect(plugin["network"]["default_interface"]).to eq("venet0:0") expect(plugin["network"]["default_gateway"]).to eq("0.0.0.0") end it "sets correct routing information" do expect(plugin["network"]["interfaces"]["venet0:0"]["routes"]).to eq([Mash.new( destination: "default", family: "inet", scope: "link" )]) end it "sets correct address information" do expect(plugin["network"]["interfaces"]["venet0:0"]["addresses"]).to eq("10.116.201.76" => Mash.new(family: "inet", prefixlen: "24", netmask: "255.255.255.0", broadcast: "10.116.201.255", scope: "Global")) end end describe "with irrelevant routes (container setups)" do let(:linux_ip_route) do <<~EOM 10.116.201.0/26 dev eth0 proto kernel src 10.116.201.39 10.116.201.0/26 dev if4 proto kernel src 10.116.201.45 10.118.19.0/26 dev eth0 proto kernel src 10.118.19.39 10.118.19.0/26 dev if5 proto kernel src 10.118.19.45 default via 10.116.201.1 dev eth0 src 10.116.201.99 EOM end let(:linux_ip_route_inet6) do <<~EOM fe80::/64 dev eth0 proto kernel metric 256 fe80::/64 dev eth0.11 proto kernel metric 256 1111:2222:3333:4444::/64 dev eth0.11 metric 1024 src 1111:2222:3333:4444::FFFF:2 default via 1111:2222:3333:4444::1 dev eth0.11 metric 1024 EOM end before do plugin.run end it "completes the run" do expect(plugin.logger).not_to receive(:trace).with(/Plugin linux::network threw exception/) expect(plugin["network"]).not_to be_nil end it "doesn't add bogus routes" do expect(plugin["network"]["interfaces"]["eth0"]["routes"]).not_to include Mash.new( destination: "10.116.201.0/26", proto: "kernel", family: "inet", via: "10.116.201.39" ) expect(plugin["network"]["interfaces"]["eth0"]["routes"]).not_to include Mash.new( destination: "10.118.19.0/26", proto: "kernel", family: "inet", via: "10.118.19.39" ) expect(plugin["network"]["interfaces"]["eth0"]["routes"]).not_to include Mash.new( destination: "1111:2222:3333:4444::/64", family: "inet6", metric: "1024" ) end it "doesn't set ipaddress" do expect(plugin["ipaddress"]).to be_nil end it "doesn't set ip6address" do expect(plugin["ip6address"]).to be_nil end end # This should never happen in the real world. describe "when encountering a surprise interface" do let(:linux_ip_route) do <<~EOM 192.168.122.0/24 dev virbr0 proto kernel src 192.168.122.1 EOM end it "logs a message and skips previously unseen interfaces in 'ip route show'" do expect(plugin.logger).to receive(:trace).with(/Skipping previously unseen interface from 'ip route show': virbr0/).once allow(plugin.logger).to receive(:trace) # Catches the 'Loading plugin network' type messages plugin.run end end describe "when running with ip version ss131122" do let(:linux_ip_link_s_d) do <<~EOM 1: lo: mtu 16436 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 RX: bytes packets errors dropped overrun mcast 35224 524 0 0 0 0 TX: bytes packets errors dropped carrier collsns 35224 524 0 0 0 0 2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 12:31:3d:02:be:a2 brd ff:ff:ff:ff:ff:ff promiscuity 0 RX: bytes packets errors dropped overrun mcast 1392844460 2659966 0 0 0 0 TX: bytes packets errors dropped carrier collsns 691785313 1919690 0 0 0 0 3: eth0.11@eth0: mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 00:0c:29:41:71:45 brd ff:ff:ff:ff:ff:ff promiscuity 0 vlan protocol 802.1Q id 11 RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 4: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 100 link/none promiscuity 0 RX: bytes packets errors dropped overrun mcast 1392844460 2659966 0 0 0 0 TX: bytes packets errors dropped carrier collsns 691785313 1919690 0 0 0 0 5: venet0: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/void promiscuity 0 RX: bytes packets errors dropped overrun mcast 1392844460 2659966 0 0 0 0 TX: bytes packets errors dropped carrier collsns 691785313 1919690 0 0 0 0 EOM end it "adds the vlan information of an interface" do plugin.run expect(plugin["network"]["interfaces"]["eth0.11"]["vlan"]["id"]).to eq("11") expect(plugin["network"]["interfaces"]["eth0.11"]["vlan"]["protocol"]).to eq("802.1Q") expect(plugin["network"]["interfaces"]["eth0.11"]["vlan"]["flags"]).to eq([ "REORDER_HDR" ]) end end end end end ohai-16.0.7/spec/unit/plugins/linux/platform_spec.rb000066400000000000000000000736341362624620500224640ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux plugin platform" do let(:plugin) { get_plugin("linux/platform") } describe "#read_os_release_info" do let(:file_contents) { "COW=MOO\nDOG=\"BARK\"" } it "returns nil if the file does not exist" do allow(File).to receive(:exist?).with("/etc/test-release").and_return(false) expect(plugin.read_os_release_info("/etc/test-release")).to be nil end it "returns a hash of expected contents" do allow(File).to receive(:exist?).with("/etc/test-release").and_return(true) allow(File).to receive(:read).with("/etc/test-release").and_return(file_contents) release_info = plugin.read_os_release_info("/etc/test-release") expect(release_info["COW"]).to eq("MOO") expect(release_info["DOG"]).to eq("BARK") end end describe "#os_release_info" do context "when CISCO_RELEASE_INFO is not populated" do let(:release_info) { { "ID" => "os_id" } } before do allow(File).to receive(:exist?).with("/etc/os-release").and_return(true) allow(plugin).to receive(:read_os_release_info).with("/etc/os-release").and_return(release_info) end it "reads the os-release file" do expect(plugin).to receive(:read_os_release_info).with("/etc/os-release").and_return(release_info) plugin.os_release_info end it "returns a hash of expected contents" do expect(plugin.os_release_info["ID"]).to eq("os_id") end end context "when CISCO_RELEASE_INFO is populated" do let(:release_info) { { "ID" => "os_id", "CISCO_RELEASE_INFO" => "/etc/cisco-release" } } let(:cisco_release_info) { { "ID" => "cisco_id" } } before do allow(File).to receive(:exist?).with("/etc/os-release").and_return(true) allow(File).to receive(:exist?).with("/etc/cisco-release").and_return(true) allow(plugin).to receive(:read_os_release_info).with("/etc/os-release").and_return(release_info) allow(plugin).to receive(:read_os_release_info).with("/etc/cisco-release").and_return(cisco_release_info) end it "reads the os-release AND the cisco-release file" do expect(plugin).to receive(:read_os_release_info).with("/etc/os-release").and_return(release_info) expect(plugin).to receive(:read_os_release_info).with("/etc/cisco-release").and_return(release_info) plugin.os_release_info end it "returns the ID from the cisco-release file instead of the os-release file" do expect(plugin.os_release_info["ID"]).to eq("cisco_id") end end end describe "#platform_id_remap" do # https://github.com/chef/os_release/blob/master/redhat_7 it "returns redhat for rhel os-release id" do expect(plugin.platform_id_remap("rhel")).to eq("redhat") end # https://github.com/chef/os_release/blob/master/amazon_2018 it "returns amazon for amzn os-release id" do expect(plugin.platform_id_remap("amzn")).to eq("amazon") end # https://github.com/chef/os_release/blob/master/oracle_7 it "returns oracle for ol os-release id" do expect(plugin.platform_id_remap("ol")).to eq("oracle") end # https://github.com/chef/os_release/blob/master/sles_sap_12_3 it "returns suse for sles_sap os-release id" do expect(plugin.platform_id_remap("sles_sap")).to eq("suse") end # https://github.com/chef/os_release/blob/master/archarm it "returns arch for archarm" do expect(plugin.platform_id_remap("archarm")).to eq("arch") end # https://github.com/chef/os_release/blob/master/sles_15_0 it "returns suse for sles os-release id" do expect(plugin.platform_id_remap("sles")).to eq("suse") end # https://github.com/chef/os_release/blob/master/opensuseleap_15_0 it "returns opensuseleap for opensuse-leap os-release id" do expect(plugin.platform_id_remap("opensuse-leap")).to eq("opensuseleap") end # https://github.com/chef/os_release/blob/master/xenserver_7_6 it "returns xenserver for xenenterprise os-release id" do expect(plugin.platform_id_remap("xenenterprise")).to eq("xenserver") end # https://github.com/chef/os_release/blob/master/cumulus_3_7 it "returns cumulus for cumulus-linux os-release id" do expect(plugin.platform_id_remap("cumulus-linux")).to eq("cumulus") end it "does not transformation for any other platform" do expect(plugin.platform_id_remap("ubuntu")).to eq("ubuntu") end context "when on a centos subshell on a nexus switch" do let(:os_release_content) do <<~OS_RELEASE NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" CISCO_RELEASE_INFO=/etc/shared/os-release OS_RELEASE end let(:cisco_release_content) do <<~CISCO_RELEASE ID=nexus ID_LIKE=wrlinux NAME=Nexus VERSION="7.0(3)I2(0.475E.6)" VERSION_ID="7.0(3)I2" PRETTY_NAME="Nexus 7.0(3)I2" HOME_URL=http://www.cisco.com BUILD_ID=6 CISCO_RELEASE_INFO=/etc/shared/os-release CISCO_RELEASE end it "returns nexus_centos for centos os-release id" do expect(File).to receive(:exist?).at_least(:once).with("/etc/shared/os-release").and_return(true) expect(File).to receive(:exist?).at_least(:once).with("/etc/os-release").and_return(true) expect(File).to receive(:read).with("/etc/os-release").and_return(os_release_content) expect(File).to receive(:read).with("/etc/shared/os-release").and_return(cisco_release_content) expect(plugin.platform_id_remap("centos")).to eq("nexus_centos") end end end describe "#platform_family_from_platform" do %w{oracle centos redhat scientific enterpriseenterprise xenserver cloudlinux ibm_powerkvm parallels nexus_centos clearos bigip}.each do |p| it "returns rhel for #{p} platform" do expect(plugin.platform_family_from_platform(p)).to eq("rhel") end end %w{suse sles opensuse opensuseleap sled}.each do |p| it "returns suse for #{p} platform_family" do expect(plugin.platform_family_from_platform(p)).to eq("suse") end end %w{fedora pidora arista_eos}.each do |p| it "returns fedora for #{p} platform_family" do expect(plugin.platform_family_from_platform(p)).to eq("fedora") end end %w{nexus ios_xr}.each do |p| it "returns wrlinux for #{p} platform_family" do expect(plugin.platform_family_from_platform(p)).to eq("wrlinux") end end %w{arch manjaro antergos}.each do |p| it "returns arch for #{p} platform_family" do expect(plugin.platform_family_from_platform(p)).to eq("arch") end end %w{amazon slackware gentoo exherbo alpine clearlinux}.each do |same_name| it "returns #{same_name} for #{same_name} platform_family" do expect(plugin.platform_family_from_platform(same_name)).to eq(same_name) end end it "returns mandriva for mangeia platform" do expect(plugin.platform_family_from_platform("mangeia")).to eq("mandriva") end end describe "on system with /etc/os-release" do before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(::File).to receive(:exist?).with("/etc/os-release").and_return(true) end context "when os-release data is correct" do let(:os_data) do <<~OS_DATA NAME="Ubuntu" VERSION="14.04.5 LTS, Trusty Tahr" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 14.04.5 LTS" VERSION_ID="14.04" OS_DATA end before do expect(File).to receive(:read).with("/etc/os-release").and_return(os_data) end it "sets platform, platform_family, and platform_version from os-release" do plugin.run expect(plugin[:platform]).to eq("ubuntu") expect(plugin[:platform_family]).to eq("debian") expect(plugin[:platform_version]).to eq("14.04") end end context "when os-release data is missing a version_id" do let(:os_data) do <<~OS_DATA NAME="Arch Linux" PRETTY_NAME="Arch Linux" ID=arch ID_LIKE=archlinux OS_DATA end before do expect(File).to receive(:read).with("/etc/os-release").and_return(os_data) end it "sets platform_version using kernel version from uname" do allow(plugin).to receive(:shell_out).with("/bin/uname -r").and_return(mock_shell_out(0, "3.18.2-2-ARCH\n", "")) plugin.run expect(plugin[:platform]).to eq("arch") expect(plugin[:platform_family]).to eq("arch") expect(plugin[:platform_version]).to eq("3.18.2-2-ARCH") end end context "when platform requires remapping" do let(:os_data) do <<~OS_DATA NAME="openSUSE Leap" VERSION="15.0" ID="opensuse-leap" ID_LIKE="suse opensuse" VERSION_ID="15.0" PRETTY_NAME="openSUSE Leap 15.0" OS_DATA end before do expect(File).to receive(:read).with("/etc/os-release").and_return(os_data) end it "sets platform, platform_family, and platform_version from os-release" do plugin.run expect(plugin[:platform]).to eq("opensuseleap") expect(plugin[:platform_family]).to eq("suse") expect(plugin[:platform_version]).to eq("15.0") end end context "when on centos where version data in os-release is wrong" do let(:os_data) do <<~OS_DATA NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" OS_DATA end before do expect(File).to receive(:read).with("/etc/os-release").and_return(os_data) expect(File).to receive(:read).with("/etc/redhat-release").and_return("CentOS Linux release 7.5.1804 (Core)") end it "sets platform, platform_family, and platform_version from os-release" do plugin.run expect(plugin[:platform]).to eq("centos") expect(plugin[:platform_family]).to eq("rhel") expect(plugin[:platform_version]).to eq("7.5.1804") end end end context "when on system without /etc/os-release (legacy)" do let(:have_debian_version) { false } let(:have_redhat_release) { false } let(:have_exherbo_release) { false } let(:have_eos_release) { false } let(:have_suse_release) { false } let(:have_system_release) { false } let(:have_slackware_version) { false } let(:have_enterprise_release) { false } let(:have_oracle_release) { false } let(:have_parallels_release) { false } let(:have_os_release) { false } let(:have_os_release) { false } let(:have_usr_lib_os_release) { false } let(:have_cisco_release) { false } let(:have_f5_release) { false } before do allow(plugin).to receive(:collect_os).and_return(:linux) plugin[:lsb] = Mash.new allow(File).to receive(:exist?).with("/etc/debian_version").and_return(have_debian_version) allow(File).to receive(:exist?).with("/etc/redhat-release").and_return(have_redhat_release) allow(File).to receive(:exist?).with("/etc/exherbo-release").and_return(have_exherbo_release) allow(File).to receive(:exist?).with("/etc/Eos-release").and_return(have_eos_release) allow(File).to receive(:exist?).with("/etc/SuSE-release").and_return(have_suse_release) allow(File).to receive(:exist?).with("/etc/system-release").and_return(have_system_release) allow(File).to receive(:exist?).with("/etc/slackware-version").and_return(have_slackware_version) allow(File).to receive(:exist?).with("/etc/enterprise-release").and_return(have_enterprise_release) allow(File).to receive(:exist?).with("/etc/oracle-release").and_return(have_oracle_release) allow(File).to receive(:exist?).with("/etc/parallels-release").and_return(have_parallels_release) allow(File).to receive(:exist?).with("/etc/os-release").and_return(have_os_release) allow(File).to receive(:exist?).with("/etc/f5-release").and_return(have_f5_release) allow(File).to receive(:exist?).with("/usr/lib/os-release").and_return(have_usr_lib_os_release) allow(File).to receive(:exist?).with("/etc/shared/os-release").and_return(have_cisco_release) allow(File).to receive(:read).with("PLEASE STUB ALL File.read CALLS") end describe "on lsb compliant distributions" do before do plugin[:lsb][:id] = "Ubuntu" plugin[:lsb][:release] = "18.04" end it "sets platform to lowercased lsb[:id]" do plugin.run expect(plugin[:platform]).to eq("ubuntu") end it "sets platform_version to lsb[:release]" do plugin.run expect(plugin[:platform_version]).to eq("18.04") end it "sets platform to ubuntu and platform_family to debian [:lsb][:id] contains Ubuntu" do plugin[:lsb][:id] = "Ubuntu" plugin.run expect(plugin[:platform]).to eq("ubuntu") expect(plugin[:platform_family]).to eq("debian") end it "sets platform to debian and platform_family to debian [:lsb][:id] contains Debian" do plugin[:lsb][:id] = "Debian" plugin.run expect(plugin[:platform]).to eq("debian") expect(plugin[:platform_family]).to eq("debian") end it "sets platform to redhat and platform_family to rhel when [:lsb][:id] contains Redhat" do plugin[:lsb][:id] = "RedHatEnterpriseServer" plugin[:lsb][:release] = "7.5" plugin.run expect(plugin[:platform]).to eq("redhat") expect(plugin[:platform_family]).to eq("rhel") end it "sets platform to amazon and platform_family to rhel when [:lsb][:id] contains Amazon" do plugin[:lsb][:id] = "AmazonAMI" plugin[:lsb][:release] = "2018.03" plugin.run expect(plugin[:platform]).to eq("amazon") expect(plugin[:platform_family]).to eq("amazon") end it "sets platform to scientific when [:lsb][:id] contains ScientificSL" do plugin[:lsb][:id] = "ScientificSL" plugin[:lsb][:release] = "7.5" plugin.run expect(plugin[:platform]).to eq("scientific") end it "sets platform to ibm_powerkvm and platform_family to rhel when [:lsb][:id] contains IBM_PowerKVM" do plugin[:lsb][:id] = "IBM_PowerKVM" plugin[:lsb][:release] = "2.1" plugin.run expect(plugin[:platform]).to eq("ibm_powerkvm") expect(plugin[:platform_family]).to eq("rhel") end end describe "on debian" do let(:have_debian_version) { true } before do plugin.lsb = nil end it "reads the version from /etc/debian_version" do expect(File).to receive(:read).with("/etc/debian_version").and_return("9.5") plugin.run expect(plugin[:platform_version]).to eq("9.5") end it "correctlies strip any newlines" do expect(File).to receive(:read).with("/etc/debian_version").and_return("9.5\n") plugin.run expect(plugin[:platform_version]).to eq("9.5") end # Ubuntu has /etc/debian_version as well it "detects Ubuntu as itself rather than debian" do plugin[:lsb][:id] = "Ubuntu" plugin[:lsb][:release] = "18.04" plugin.run expect(plugin[:platform]).to eq("ubuntu") end end describe "on slackware" do let(:have_slackware_version) { true } before do plugin.lsb = nil end it "sets platform and platform_family to slackware" do expect(File).to receive(:read).with("/etc/slackware-version").and_return("Slackware 12.0.0") plugin.run expect(plugin[:platform]).to eq("slackware") expect(plugin[:platform_family]).to eq("slackware") end it "sets platform_version on slackware" do expect(File).to receive(:read).with("/etc/slackware-version").and_return("Slackware 12.0.0") plugin.run expect(plugin[:platform_version]).to eq("12.0.0") end end describe "on arista eos" do let(:have_system_release) { true } let(:have_redhat_release) { true } let(:have_eos_release) { true } before do plugin.lsb = nil end it "sets platform to arista_eos" do expect(File).to receive(:read).with("/etc/Eos-release").and_return("Arista Networks EOS 4.21.1.1F") plugin.run expect(plugin[:platform]).to eq("arista_eos") expect(plugin[:platform_family]).to eq("fedora") expect(plugin[:platform_version]).to eq("4.21.1.1F") end end describe "on f5 big-ip" do let(:have_f5_release) { true } before do plugin.lsb = nil end it "sets platform to bigip" do expect(File).to receive(:read).with("/etc/f5-release").and_return("BIG-IP release 13.0.0 (Final)") plugin.run expect(plugin[:platform]).to eq("bigip") expect(plugin[:platform_family]).to eq("rhel") expect(plugin[:platform_version]).to eq("13.0.0") end end describe "on exherbo" do let(:have_exherbo_release) { true } before do allow(plugin).to receive(:shell_out).with("/bin/uname -r").and_return(mock_shell_out(0, "3.18.2-2-ARCH\n", "")) plugin.lsb = nil end it "sets platform and platform_family to exherbo" do plugin.run expect(plugin[:platform]).to eq("exherbo") expect(plugin[:platform_family]).to eq("exherbo") end it "sets platform_version to kernel release" do plugin.run expect(plugin[:platform_version]).to eq("3.18.2-2-ARCH") end end describe "on redhat breeds" do describe "with lsb_release results" do it "sets the platform to redhat and platform_family to rhel even if the LSB name is something absurd but redhat like" do plugin[:lsb][:id] = "RedHatEnterpriseServer" plugin[:lsb][:release] = "7.5" plugin.run expect(plugin[:platform]).to eq("redhat") expect(plugin[:platform_version]).to eq("7.5") expect(plugin[:platform_family]).to eq("rhel") end it "sets the platform to centos and platform_family to rhel" do plugin[:lsb][:id] = "CentOS" plugin[:lsb][:release] = "7.5" plugin.run expect(plugin[:platform]).to eq("centos") expect(plugin[:platform_version]).to eq("7.5") expect(plugin[:platform_family]).to eq("rhel") end end describe "without lsb_release results" do let(:have_redhat_release) { true } before do plugin.lsb = nil end it "reads the platform as centos and version as 7.5" do expect(File).to receive(:read).with("/etc/redhat-release").and_return("CentOS Linux release 7.5.1804 (Core)") plugin.run expect(plugin[:platform]).to eq("centos") expect(plugin[:platform_version]).to eq("7.5.1804") end it "reads platform of Red Hat with a space" do expect(File).to receive(:read).with("/etc/redhat-release").and_return("Red Hat Enterprise Linux Server release 6.5 (Santiago)") plugin.run expect(plugin[:platform]).to eq("redhat") end it "reads the platform as redhat without a space" do expect(File).to receive(:read).with("/etc/redhat-release").and_return("RedHat release 5.3") plugin.run expect(plugin[:platform]).to eq("redhat") expect(plugin[:platform_version]).to eq("5.3") end end end describe "on pcs linux" do let(:have_redhat_release) { true } let(:have_parallels_release) { true } describe "with lsb_result" do it "reads the platform as parallels and version as 6.0.5" do plugin[:lsb][:id] = "CloudLinuxServer" plugin[:lsb][:release] = "6.5" allow(File).to receive(:read).with("/etc/redhat-release").and_return("CloudLinux Server release 6.5 (Pavel Popovich)") expect(File).to receive(:read).with("/etc/parallels-release").and_return("Parallels Cloud Server 6.0.5 (20007)") plugin.run expect(plugin[:platform]).to eq("parallels") expect(plugin[:platform_version]).to eq("6.0.5") expect(plugin[:platform_family]).to eq("rhel") end end describe "without lsb_results" do before do plugin.lsb = nil end it "reads the platform as parallels and version as 6.0.5" do allow(File).to receive(:read).with("/etc/redhat-release").and_return("CloudLinux Server release 6.5 (Pavel Popovich)") expect(File).to receive(:read).with("/etc/parallels-release").and_return("Parallels Cloud Server 6.0.5 (20007)") plugin.run expect(plugin[:platform]).to eq("parallels") expect(plugin[:platform_version]).to eq("6.0.5") expect(plugin[:platform_family]).to eq("rhel") end end end describe "on oracle enterprise linux" do let(:have_redhat_release) { true } context "with lsb_results" do context "when on version 5.x" do let(:have_enterprise_release) { true } it "reads the platform as oracle and version as 5.7" do plugin[:lsb][:id] = "EnterpriseEnterpriseServer" plugin[:lsb][:release] = "5.7" allow(File).to receive(:read).with("/etc/redhat-release").and_return("Red Hat Enterprise Linux Server release 5.7 (Tikanga)") expect(File).to receive(:read).with("/etc/enterprise-release").and_return("Enterprise Linux Enterprise Linux Server release 5.7 (Carthage)") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("5.7") end end context "when on version 6.x" do let(:have_oracle_release) { true } it "reads the platform as oracle and version as 6.1" do plugin[:lsb][:id] = "OracleServer" plugin[:lsb][:release] = "6.1" allow(File).to receive(:read).with("/etc/redhat-release").and_return("Red Hat Enterprise Linux Server release 6.1 (Santiago)") expect(File).to receive(:read).with("/etc/oracle-release").and_return("Oracle Linux Server release 6.1") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("6.1") end end end context "without lsb_results" do before do plugin.lsb = nil end context "when on version 5.x" do let(:have_enterprise_release) { true } it "reads the platform as oracle and version as 5" do allow(File).to receive(:read).with("/etc/redhat-release").and_return("Enterprise Linux Enterprise Linux Server release 5 (Carthage)") expect(File).to receive(:read).with("/etc/enterprise-release").and_return("Enterprise Linux Enterprise Linux Server release 5 (Carthage)") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("5") end it "reads the platform as oracle and version as 5.1" do allow(File).to receive(:read).with("/etc/redhat-release").and_return("Enterprise Linux Enterprise Linux Server release 5.1 (Carthage)") expect(File).to receive(:read).with("/etc/enterprise-release").and_return("Enterprise Linux Enterprise Linux Server release 5.1 (Carthage)") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("5.1") end it "reads the platform as oracle and version as 5.7" do allow(File).to receive(:read).with("/etc/redhat-release").and_return("Red Hat Enterprise Linux Server release 5.7 (Tikanga)") expect(File).to receive(:read).with("/etc/enterprise-release").and_return("Enterprise Linux Enterprise Linux Server release 5.7 (Carthage)") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("5.7") end end context "when on version 6.x" do let(:have_oracle_release) { true } it "reads the platform as oracle and version as 6.0" do allow(File).to receive(:read).with("/etc/redhat-release").and_return("Red Hat Enterprise Linux Server release 6.0 (Santiago)") expect(File).to receive(:read).with("/etc/oracle-release").and_return("Oracle Linux Server release 6.0") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("6.0") end it "reads the platform as oracle and version as 6.1" do allow(File).to receive(:read).with("/etc/redhat-release").and_return("Red Hat Enterprise Linux Server release 6.1 (Santiago)") expect(File).to receive(:read).with("/etc/oracle-release").and_return("Oracle Linux Server release 6.1") plugin.run expect(plugin[:platform]).to eq("oracle") expect(plugin[:platform_version]).to eq("6.1") end end end end describe "on suse" do context "when on versions that have no /etc/os-release but /etc/SuSE-release (e.g. SLES12.1)" do let(:have_suse_release) { true } let(:have_os_release) { false } describe "with lsb_release results" do before do plugin[:lsb][:id] = "SUSE LINUX" end it "reads the platform as opensuse on openSUSE" do plugin[:lsb][:release] = "12.1" expect(File).to receive(:read).with("/etc/SuSE-release").and_return("openSUSE 12.1 (x86_64)\nVERSION = 12.1\nCODENAME = Asparagus\n") plugin.run expect(plugin[:platform]).to eq("opensuse") expect(plugin[:platform_family]).to eq("suse") end end end context "when on openSUSE and older SLES versions" do let(:have_suse_release) { true } describe "without lsb_release results" do before do plugin.lsb = nil end it "sets platform and platform_family to suse and bogus verion to 10.0" do expect(File).to receive(:read).with("/etc/SuSE-release").at_least(:once).and_return("VERSION = 10.0") plugin.run expect(plugin[:platform]).to eq("suse") expect(plugin[:platform_family]).to eq("suse") end it "reads the version as 11.2" do expect(File).to receive(:read).with("/etc/SuSE-release").and_return("SUSE Linux Enterprise Server 11.2 (i586)\nVERSION = 11\nPATCHLEVEL = 2\n") plugin.run expect(plugin[:platform]).to eq("suse") expect(plugin[:platform_version]).to eq("11.2") expect(plugin[:platform_family]).to eq("suse") end it "[OHAI-272] should read the version as 11.3" do expect(File).to receive(:read).with("/etc/SuSE-release").once.and_return("openSUSE 11.3 (x86_64)\nVERSION = 11.3") plugin.run expect(plugin[:platform]).to eq("opensuse") expect(plugin[:platform_version]).to eq("11.3") expect(plugin[:platform_family]).to eq("suse") end it "[OHAI-272] should read the version as 11.4" do expect(File).to receive(:read).with("/etc/SuSE-release").once.and_return("openSUSE 11.4 (i586)\nVERSION = 11.4\nCODENAME = Celadon") plugin.run expect(plugin[:platform]).to eq("opensuse") expect(plugin[:platform_version]).to eq("11.4") expect(plugin[:platform_family]).to eq("suse") end it "reads the platform as opensuse on openSUSE" do expect(File).to receive(:read).with("/etc/SuSE-release").and_return("openSUSE 12.2 (x86_64)\nVERSION = 12.2\nCODENAME = Mantis\n") plugin.run expect(plugin[:platform]).to eq("opensuse") expect(plugin[:platform_family]).to eq("suse") end it "reads the platform as opensuseleap on openSUSE Leap" do expect(File).to receive(:read).with("/etc/SuSE-release").and_return("openSUSE 42.1 (x86_64)\nVERSION = 42.1\nCODENAME = Malachite\n") plugin.run expect(plugin[:platform]).to eq("opensuseleap") expect(plugin[:platform_family]).to eq("suse") end end end end describe "on clearlinux" do let(:have_usr_lib_os_release) { true } let(:usr_lib_os_release_content) do <<~CLEARLINUX_RELEASE NAME="Clear Linux OS" VERSION=1 ID=clear-linux-os ID_LIKE=clear-linux-os VERSION_ID=26290 PRETTY_NAME="Clear Linux OS" CLEARLINUX_RELEASE end before do expect(File).to receive(:read).with("/usr/lib/os-release").and_return(usr_lib_os_release_content) end it "sets platform to clearlinux and platform_family to clearlinux" do plugin.lsb = nil plugin.run expect(plugin[:platform]).to eq("clearlinux") expect(plugin[:platform_family]).to eq("clearlinux") expect(plugin[:platform_version]).to eq("26290") end end end end ohai-16.0.7/spec/unit/plugins/linux/sessions_spec.rb000066400000000000000000000053671362624620500225040ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux sessions plugin" do let(:plugin) { get_plugin("linux/sessions") } before do allow(plugin).to receive(:collect_os).and_return(:linux) end it "populates sessions if loginctl is found" do loginctl_out = <<-LOGINCTL_OUT c1 118 Debian-gdm seat0 318 0 root 46 0 root 306 1000 joe LOGINCTL_OUT allow(plugin).to receive(:which).with("loginctl").and_return("/bin/loginctl") allow(plugin).to receive(:shell_out).with("/bin/loginctl --no-pager --no-legend --no-ask-password list-sessions").and_return(mock_shell_out(0, loginctl_out, "")) plugin.run expect(plugin[:sessions].to_hash).to eq({ "by_session" => { "c1" => { "session" => "c1", "uid" => "118", "user" => "Debian-gdm", "seat" => "seat0", }, "318" => { "session" => "318", "uid" => "0", "user" => "root", "seat" => nil, }, "46" => { "session" => "46", "uid" => "0", "user" => "root", "seat" => nil, }, "306" => { "session" => "306", "uid" => "1000", "user" => "joe", "seat" => nil, }, }, "by_user" => { "Debian-gdm" => [{ "session" => "c1", "uid" => "118", "user" => "Debian-gdm", "seat" => "seat0", }], "root" => [{ "session" => "318", "uid" => "0", "user" => "root", "seat" => nil, }, { "session" => "46", "uid" => "0", "user" => "root", "seat" => nil, }], "joe" => [{ "session" => "306", "uid" => "1000", "user" => "joe", "seat" => nil, }], }, }) end it "does not populate sessions if loginctl is not found" do allow(plugin).to receive(:which).with("loginctl").and_return(false) plugin.run expect(plugin[:sessions]).to be(nil) end end ohai-16.0.7/spec/unit/plugins/linux/sysctl_spec.rb000066400000000000000000000035521362624620500221510ustar00rootroot00000000000000# # Author:: Joshua Miller # Copyright:: Copyright (c) 2019 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "../../../spec_helper.rb" describe Ohai::System, "sysctl plugin", :unix_only do let(:plugin) { get_plugin("linux/sysctl") } it "populates sysctl if sysctl is found" do sysctl_out = <<-SYSCTL_OUT vm.nr_overcommit_hugepages = 0 vm.numa_stat = 1 vm.numa_zonelist_order = Node vm.oom_dump_tasks = 1 vm.oom_kill_allocating_task = 0 vm.overcommit_kbytes = 0 SYSCTL_OUT allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:which).with("sysctl").and_return("/usr/sbin/sysctl") allow(plugin).to receive(:shell_out).with("/usr/sbin/sysctl -a").and_return(mock_shell_out(0, sysctl_out, "")) plugin.run expect(plugin[:sysctl].to_hash).to eq({ "vm.nr_overcommit_hugepages" => "0", "vm.numa_stat" => "1", "vm.numa_zonelist_order" => "Node", "vm.oom_dump_tasks" => "1", "vm.oom_kill_allocating_task" => "0", "vm.overcommit_kbytes" => "0", }) end it "does not populate sysctl if sysctl is not found" do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:which).with("sysctl").and_return(false) plugin.run expect(plugin[:sysctl]).to be(nil) end end ohai-16.0.7/spec/unit/plugins/linux/systemd_paths_spec.rb000066400000000000000000000124621362624620500235170ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2017 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS"BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper.rb") describe Ohai::System, "Linux systemd paths plugin" do let(:plugin) { get_plugin("linux/systemd_paths") } before do allow(plugin).to receive(:collect_os).and_return(:linux) end it "populates systemd_paths if systemd-path is found" do systemd_path_out = <<~SYSTEMD_PATH_OUT temporary: /tmp temporary-large: /var/tmp system-binaries: /usr/bin system-include: /usr/include system-library-private: /usr/lib system-library-arch: /usr/lib/x86_64-linux-gnu system-shared: /usr/share system-configuration-factory: /usr/share/factory/etc system-state-factory: /usr/share/factory/var system-configuration: /etc system-runtime: /run system-runtime-logs: /run/log system-state-private: /var/lib system-state-logs: /var/log system-state-cache: /var/cache system-state-spool: /var/spool user-binaries: /home/foo/.local/bin user-library-private: /home/foo/.local/lib user-library-arch: /home/foo/.local/lib/x86_64-linux-gnu user-shared: /home/foo/.local/share user-configuration: /home/foo/.config user-runtime: /run/user/1000 user-state-cache: /home/foo/.cache user: /home/foo user-documents: /home/foo/Documents user-music: /home/foo/Music user-pictures: /home/foo/Pictures user-videos: /home/foo/Videos user-download: /home/foo/Downloads user-public: /home/foo/Public user-templates: /home/foo/Templates user-desktop: /home/foo/Desktop search-binaries: /home/foo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/opt/facebook/bin:/home/foo/.rvm/bin:/home/foo/.rvm/bin search-library-private: /home/foo/.local/lib:/usr/local/lib:/usr/lib:/lib search-library-arch: /home/foo/.local/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu search-shared: /home/foo/.local/share:/usr/share/gnome:/home/foo/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share search-configuration-factory: /usr/local/share/factory/etc:/usr/share/factory/etc search-state-factory: /usr/local/share/factory/var:/usr/share/factory/var search-configuration: /home/foo/.config:/etc SYSTEMD_PATH_OUT allow(plugin).to receive(:which).with("systemd-path").and_return("/bin/systemd-path") allow(plugin).to receive(:shell_out).with("/bin/systemd-path").and_return(mock_shell_out(0, systemd_path_out, "")) plugin.run expect(plugin[:systemd_paths].to_hash).to eq({ "search-binaries" => "/home/foo/bin", "search-configuration" => "/home/foo/.config", "search-configuration-factory" => "/usr/local/share/factory/etc", "search-library-arch" => "/home/foo/.local/lib/x86_64-linux-gnu", "search-library-private" => "/home/foo/.local/lib", "search-shared" => "/home/foo/.local/share", "search-state-factory" => "/usr/local/share/factory/var", "system-binaries" => "/usr/bin", "system-configuration" => "/etc", "system-configuration-factory" => "/usr/share/factory/etc", "system-include" => "/usr/include", "system-library-arch" => "/usr/lib/x86_64-linux-gnu", "system-library-private" => "/usr/lib", "system-runtime" => "/run", "system-runtime-logs" => "/run/log", "system-shared" => "/usr/share", "system-state-cache" => "/var/cache", "system-state-factory" => "/usr/share/factory/var", "system-state-logs" => "/var/log", "system-state-private" => "/var/lib", "system-state-spool" => "/var/spool", "temporary" => "/tmp", "temporary-large" => "/var/tmp", "user" => "/home/foo", "user-binaries" => "/home/foo/.local/bin", "user-configuration" => "/home/foo/.config", "user-desktop" => "/home/foo/Desktop", "user-documents" => "/home/foo/Documents", "user-download" => "/home/foo/Downloads", "user-library-arch" => "/home/foo/.local/lib/x86_64-linux-gnu", "user-library-private" => "/home/foo/.local/lib", "user-music" => "/home/foo/Music", "user-pictures" => "/home/foo/Pictures", "user-public" => "/home/foo/Public", "user-runtime" => "/run/user/1000", "user-shared" => "/home/foo/.local/share", "user-state-cache" => "/home/foo/.cache", "user-templates" => "/home/foo/Templates", "user-videos" => "/home/foo/Videos", }) end it "does not populate systemd paths if systemd-path is not found" do allow(plugin).to receive(:which).with("systemd-path").and_return(false) plugin.run expect(plugin[:systemd_paths]).to be(nil) end end ohai-16.0.7/spec/unit/plugins/linux/uptime_spec.rb000066400000000000000000000027631362624620500221360ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux plugin uptime" do before do @plugin = get_plugin("uptime") allow(@plugin).to receive(:collect_os).and_return(:linux) @double_file = double("/proc/uptime", { gets: "18423 989" }) allow(File).to receive(:open).with("/proc/uptime").and_return(@double_file) end it "sets uptime_seconds to uptime" do @plugin.run expect(@plugin[:uptime_seconds]).to eq(18423) end it "sets uptime to a human readable date" do @plugin.run expect(@plugin[:uptime]).to eq("5 hours 07 minutes 03 seconds") end it "sets idletime_seconds to uptime" do @plugin.run expect(@plugin[:idletime_seconds]).to eq(989) end it "sets idletime to a human readable date" do @plugin.run expect(@plugin[:idletime]).to eq("16 minutes 29 seconds") end end ohai-16.0.7/spec/unit/plugins/linux/virtualization_spec.rb000066400000000000000000000753221362624620500237200ustar00rootroot00000000000000# # Author:: Thom May () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Linux virtualization platform" do let(:plugin) { get_plugin("linux/virtualization") } before do allow(plugin).to receive(:collect_os).and_return(:linux) # default to all requested Files not existing allow(File).to receive(:exist?).with("/proc/xen").and_return(false) allow(File).to receive(:exist?).with("/proc/xen/capabilities").and_return(false) allow(File).to receive(:exist?).with("/proc/modules").and_return(false) allow(File).to receive(:exist?).with("/proc/cpuinfo").and_return(false) allow(File).to receive(:exist?).with("/var/lib/hyperv/.kvp_pool_3").and_return(false) allow(File).to receive(:exist?).with("/proc/self/status").and_return(false) allow(File).to receive(:exist?).with("/proc/bc/0").and_return(false) allow(File).to receive(:exist?).with("/proc/vz").and_return(false) allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(false) allow(File).to receive(:exist?).with("/.dockerenv").and_return(false) allow(File).to receive(:exist?).with("/.dockerinit").and_return(false) allow(File).to receive(:exist?).with("/sys/devices/virtual/misc/kvm").and_return(false) allow(File).to receive(:exist?).with("/dev/lxd/sock").and_return(false) allow(File).to receive(:exist?).with("/var/lib/lxd/devlxd").and_return(false) allow(File).to receive(:exist?).with("/var/snap/lxd/common/lxd/devlxd").and_return(false) allow(File).to receive(:exist?).with("/proc/1/environ").and_return(false) # default the which wrappers to nil allow(plugin).to receive(:which).with("lxc-version").and_return(nil) allow(plugin).to receive(:which).with("lxc-start").and_return(nil) allow(plugin).to receive(:which).with("docker").and_return(nil) allow(plugin).to receive(:nova_exists?).and_return(false) end describe "when we are checking for xen" do it "sets xen guest if /proc/xen exists but /proc/xen/capabilities does not" do expect(File).to receive(:exist?).with("/proc/xen").and_return(true) expect(File).to receive(:exist?).with("/proc/xen/capabilities").and_return(false) plugin.run expect(plugin[:virtualization][:system]).to eq("xen") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:xen]).to eq("guest") end it "sets xen host if /proc/xen/capabilities contains control_d " do expect(File).to receive(:exist?).with("/proc/xen").and_return(true) expect(File).to receive(:exist?).with("/proc/xen/capabilities").and_return(true) allow(File).to receive(:read).with("/proc/xen/capabilities").and_return("control_d") plugin.run expect(plugin[:virtualization][:system]).to eq("xen") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:xen]).to eq("host") end it "sets xen guest if /proc/xen/capabilities exists but is empty" do expect(File).to receive(:exist?).with("/proc/xen").and_return(true) expect(File).to receive(:exist?).with("/proc/xen/capabilities").and_return(true) allow(File).to receive(:read).with("/proc/xen/capabilities").and_return("") plugin.run expect(plugin[:virtualization][:system]).to eq("xen") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:xen]).to eq("guest") end it "does not set virtualization if xen isn't there" do expect(File).to receive(:exist?).at_least(:once).and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are checking for docker" do it "sets docker host if docker binary exists" do allow(plugin).to receive(:which).with("docker").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:docker]).to eq("host") end end describe "when we are checking for openstack" do it "sets openstack host if nova binary exists" do allow(plugin).to receive(:nova_exists?).and_return("/usr/bin/nova") plugin.run expect(plugin[:virtualization][:system]).to eq("openstack") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:openstack]).to eq("host") end end describe "when we are checking for kvm" do it "sets kvm guest if /sys/devices/virtual/misc/kvm exists & hypervisor cpu feature is present" do allow(File).to receive(:exist?).with("/sys/devices/virtual/misc/kvm").and_return(true) allow(File).to receive(:read).with("/proc/cpuinfo").and_return("fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon rep_good nopl pni vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt hypervisor lahf_lm vnmi ept tsc_adjust") plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:kvm]).to eq("guest") end it "sets kvm host if /sys/devices/virtual/misc/kvm exists & hypervisor cpu feature is not present" do allow(File).to receive(:exist?).with("/sys/devices/virtual/misc/kvm").and_return(true) allow(File).to receive(:read).with("/proc/cpuinfo").and_return("fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm dca sse4_1 sse4_2 popcnt lahf_lm ida dtherm tpr_shadow vnmi flexpriority ept vpid") plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:kvm]).to eq("host") end it "sets kvm guest if /proc/cpuinfo contains QEMU Virtual CPU" do expect(File).to receive(:exist?).with("/proc/cpuinfo").and_return(true) allow(File).to receive(:read).with("/proc/cpuinfo").and_return("QEMU Virtual CPU") plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:kvm]).to eq("guest") end it "sets kvm guest if /proc/cpuinfo contains Common KVM processor" do expect(File).to receive(:exist?).with("/proc/cpuinfo").and_return(true) allow(File).to receive(:read).with("/proc/cpuinfo").and_return("Common KVM processor") plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:kvm]).to eq("guest") end it "sets kvm guest if /proc/cpuinfo contains Common 32-bit KVM processor" do expect(File).to receive(:exist?).with("/proc/cpuinfo").and_return(true) allow(File).to receive(:read).with("/proc/cpuinfo").and_return("Common 32-bit KVM processor") plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:kvm]).to eq("guest") end it "does not set virtualization if kvm isn't there" do expect(File).to receive(:exist?).at_least(:once).and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are checking for VirtualBox" do it "sets vbox host if /proc/modules contains vboxdrv" do expect(File).to receive(:exist?).with("/proc/modules").and_return(true) allow(File).to receive(:read).with("/proc/modules").and_return("vboxdrv 268268 3 vboxnetadp,vboxnetflt") plugin.run expect(plugin[:virtualization][:system]).to eq("vbox") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:vbox]).to eq("host") end it "sets vbox gues if /proc/modules contains vboxguest" do expect(File).to receive(:exist?).with("/proc/modules").and_return(true) allow(File).to receive(:read).with("/proc/modules").and_return("vboxguest 214901 2 vboxsf, Live 0xffffffffa00db000 (OF)") plugin.run expect(plugin[:virtualization][:system]).to eq("vbox") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:vbox]).to eq("guest") end it "does not set virtualization if vbox isn't there" do expect(File).to receive(:exist?).at_least(:once).and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are parsing DMI data" do it "sets virtualization attributes if the appropriate DMI data is present" do plugin[:dmi] = { system: { manufacturer: "Amazon EC2", product: "c5n.large", version: nil, }, } plugin.run expect(plugin[:virtualization][:system]).to eq("amazonec2") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:amazonec2]).to eq("guest") end it "sets empty virtualization attributes if nothing is detected" do plugin[:dmi] = { system: { manufacturer: "Supermicro", product: "X10SLH-N6-ST031", version: "0123456789", }, } plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are checking for Hyper-V guest and the hostname of the host" do it "sets Hyper-V guest if /var/lib/hyperv/.kvp_pool_3 contains hyper_v.example.com" do expect(File).to receive(:exist?).with("/var/lib/hyperv/.kvp_pool_3").and_return(true) allow(File).to receive(:read).with("/var/lib/hyperv/.kvp_pool_3").and_return("HostNamehyper_v.example.comHostingSystemEditionId") plugin.run expect(plugin[:virtualization][:system]).to eq("hyperv") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems]["hyperv"]).to eq("guest") expect(plugin[:virtualization]["hypervisor_host"]).to eq("hyper_v.example.com") end end describe "when we are checking for Linux-VServer" do it "sets Linux-VServer host if /proc/self/status contains s_context: 0" do expect(File).to receive(:exist?).with("/proc/self/status").and_return(true) allow(File).to receive(:read).with("/proc/self/status").and_return("s_context: 0") plugin.run expect(plugin[:virtualization][:system]).to eq("linux-vserver") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems]["linux-vserver"]).to eq("host") end it "sets Linux-VServer host if /proc/self/status contains VxID: 0" do expect(File).to receive(:exist?).with("/proc/self/status").and_return(true) allow(File).to receive(:read).with("/proc/self/status").and_return("VxID: 0") plugin.run expect(plugin[:virtualization][:system]).to eq("linux-vserver") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems]["linux-vserver"]).to eq("host") end it "sets Linux-VServer host if /proc/self/status contains multiple space VxID: 0" do expect(File).to receive(:exist?).with("/proc/self/status").and_return(true) allow(File).to receive(:read).with("/proc/self/status").and_return("VxID: 0") plugin.run expect(plugin[:virtualization][:system]).to eq("linux-vserver") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems]["linux-vserver"]).to eq("host") end it "sets Linux-VServer host if /proc/self/status contains tabbed VxID:\t0" do expect(File).to receive(:exist?).with("/proc/self/status").and_return(true) allow(File).to receive(:read).with("/proc/self/status").and_return("VxID:\t0") plugin.run expect(plugin[:virtualization][:system]).to eq("linux-vserver") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems]["linux-vserver"]).to eq("host") end it "sets Linux-VServer guest if /proc/self/status contains s_context > 0" do expect(File).to receive(:exist?).with("/proc/self/status").and_return(true) allow(File).to receive(:read).with("/proc/self/status").and_return("s_context: 2") plugin.run expect(plugin[:virtualization][:system]).to eq("linux-vserver") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems]["linux-vserver"]).to eq("guest") end it "sets Linux-VServer guest if /proc/self/status contains VxID > 0" do expect(File).to receive(:exist?).with("/proc/self/status").and_return(true) allow(File).to receive(:read).with("/proc/self/status").and_return("VxID: 2") plugin.run expect(plugin[:virtualization][:system]).to eq("linux-vserver") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems]["linux-vserver"]).to eq("guest") end it "does not set virtualization if Linux-VServer isn't there" do expect(File).to receive(:exist?).at_least(:once).and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are checking for openvz" do it "sets openvz host if /proc/bc/0 exists" do expect(File).to receive(:exist?).with("/proc/bc/0").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("openvz") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:openvz]).to eq("host") end it "sets openvz guest if /proc/bc/0 does not exist and /proc/vz exists" do expect(File).to receive(:exist?).with("/proc/bc/0").and_return(false) expect(File).to receive(:exist?).with("/proc/vz").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("openvz") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:openvz]).to eq("guest") end it "does not set virtualization if openvz isn't there" do expect(File).to receive(:exist?).with("/proc/bc/0").and_return(false) expect(File).to receive(:exist?).with("/proc/vz").and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are checking for lxd" do it "sets lxc guest if /dev/lxd/sock exists" do expect(File).to receive(:exist?).with("/dev/lxd/sock").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("lxd") expect(plugin[:virtualization][:role]).to eq("guest") end it "sets lxd host if /var/lib/lxd/devlxd exists" do expect(File).to receive(:exist?).with("/var/lib/lxd/devlxd").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("lxd") expect(plugin[:virtualization][:role]).to eq("host") end it "sets lxd host if /var/snap/lxd/common/lxd/devlxd exists" do expect(File).to receive(:exist?).with("/var/snap/lxd/common/lxd/devlxd").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("lxd") expect(plugin[:virtualization][:role]).to eq("host") end end describe "when we are checking for lxc" do it "sets lxc guest if /proc/self/cgroup exist and there are /lxc/ mounts" do self_cgroup = <<~CGROUP 8:blkio:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 7:net_cls:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 6:freezer:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 5:devices:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 4:memory:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 3:cpuacct:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 2:cpu:/lxc/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 1:cpuset:/ CGROUP expect(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization][:system]).to eq("lxc") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:lxc]).to eq("guest") end it "sets lxc guest if /proc/self/cgroup exist and there are /lxc/ mounts" do self_cgroup = <<~CGROUP 8:blkio:/lxc/vanilla 7:net_cls:/lxc/vanilla 6:freezer:/lxc/vanilla 5:devices:/lxc/vanilla 4:memory:/lxc/vanilla 3:cpuacct:/lxc/vanilla 2:cpu:/lxc/vanilla 1:cpuset:/lxc/vanilla CGROUP expect(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization][:system]).to eq("lxc") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:lxc]).to eq("guest") end it "sets not set anything if /proc/self/cgroup exist and the cgroup is named arbitrarily, it isn't necessarily lxc." do self_cgroup = <<~CGROUP 8:blkio:/Charlie 7:net_cls:/Charlie 6:freezer:/Charlie 5:devices:/Charlie 4:memory:/Charlie 3:cpuacct:/Charlie 2:cpu:/Charlie 1:cpuset:/Charlie CGROUP allow(File).to receive(:read).with("/proc/1/environ").and_return("") expect(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end context "/proc/self/cgroup only has / mounts" do before do self_cgroup = <<~CGROUP 8:blkio:/ 7:net_cls:/ 6:freezer:/ 5:devices:/ 4:memory:/ 3:cpuacct:/ 2:cpu:/ 1:cpuset:/ CGROUP expect(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) allow(File).to receive(:read).with("/proc/1/environ").and_return("") end it "sets lxc host if lxc-version exists" do allow(plugin).to receive(:which).with("lxc-start").and_return("/usr/bin/lxc-version") plugin.run expect(plugin[:virtualization][:system]).to eq("lxc") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:lxc]).to eq("host") end it "sets lxc host if lxc-start exists" do allow(plugin).to receive(:which).with("lxc-start").and_return("/usr/bin/lxc-start") plugin.run expect(plugin[:virtualization][:system]).to eq("lxc") expect(plugin[:virtualization][:role]).to eq("host") expect(plugin[:virtualization][:systems][:lxc]).to eq("host") end it "does not set the old virtualization attributes if they are already set" do allow(plugin).to receive(:which).with("lxc-version").and_return("/usr/bin/lxc-version") plugin[:virtualization] = Mash.new plugin[:virtualization][:system] = "the cloud" plugin[:virtualization][:role] = "cumulonimbus" plugin.run expect(plugin[:virtualization][:system]).not_to eq("lxc") expect(plugin[:virtualization][:role]).not_to eq("host") end it "does not set lxc host if neither lxc-version nor lxc-start exists" do plugin.run expect(plugin[:virtualization][:system]).to be_nil expect(plugin[:virtualization][:role]).to be_nil expect(plugin[:virtualization]).to eq({ "systems" => {} }) end it "sets lxc guest if /proc/1/environ has lxccontainer string in it" do one_environ = "container=lxccontainer_ttys=/dev/pts/0 /dev/pts/1 /dev/pts/2 /dev/pts/3".chomp allow(File).to receive(:read).with("/proc/1/environ").and_return(one_environ) plugin.run expect(plugin[:virtualization][:system]).to eq("lxc") expect(plugin[:virtualization][:role]).to eq("guest") end end it "does not set virtualization if /proc/self/cgroup isn't there" do expect(File).to receive(:exist?).with("/proc/self/cgroup").and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end describe "when we are checking for systemd-nspawn" do it "sets nspawn guest if /proc/1/environ has nspawn string in it" do allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) one_environ = "container=systemd-nspawn_ttys=/dev/pts/0 /dev/pts/1 /dev/pts/2 /dev/pts/3".chomp allow(File).to receive(:read).with("/proc/1/environ").and_return(one_environ) allow(File).to receive(:read).with("/proc/self/cgroup").and_return("") plugin.run expect(plugin[:virtualization][:system]).to eq("nspawn") expect(plugin[:virtualization][:role]).to eq("guest") end end describe "when we are checking for docker" do it "sets docker guest if /proc/self/cgroup exist and there are /docker/ mounts" do self_cgroup = <<~CGROUP 8:blkio:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 7:net_cls:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 6:freezer:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 5:devices:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 4:memory:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 3:cpuacct:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 2:cpu:/docker/baa660ed81bc81d262ac6e19486142aeec5fce2043e2a173eb2505c6fbed89bc 1:cpuset:/ CGROUP allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:docker]).to eq("guest") end it "sets docker guest if /proc/self/cgroup exist and there are /docker/ mounts" do self_cgroup = <<~CGROUP 8:blkio:/docker/vanilla 7:net_cls:/docker/vanilla 6:freezer:/docker/vanilla 5:devices:/docker/vanilla 4:memory:/docker/vanilla 3:cpuacct:/docker/vanilla 2:cpu:/docker/vanilla 1:cpuset:/docker/vanilla CGROUP allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:docker]).to eq("guest") end it "sets docker guest if /proc/self/cgroup exist and there are /docker/docker-ce/ mounts" do self_cgroup = <<~CGROUP 13:name=systemd:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 12:pids:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 11:hugetlb:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 10:net_prio:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 9:perf_event:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 8:net_cls:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 7:freezer:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 6:devices:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 5:memory:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 4:blkio:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 3:cpuacct:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 2:cpu:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 1:cpuset:/docker-ce/docker/b15b85d19304436488a78d06afeb108d94b20bb6898d852b65cad51bd7dc9468 CGROUP allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:docker]).to eq("guest") end # Relevant at least starting docker 1.6.2, kernel 4.0.5 & systemd 224-1. # Doi not exactly know which software/version really matters here. it "sets docker guest if /proc/self/cgroup exists and there are /system.slice/docker- mounts (systemd managed cgroup)" do self_cgroup = <<~CGROUP 8:devices:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope 7:cpuset:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope 6:blkio:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope 5:freezer:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope 4:net_cls:/ 3:memory:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope 2:cpu,cpuacct:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope 1:name=systemd:/system.slice/docker-47341c91be8d491cb3b8a475ad5b4aef6e79bf728cbb351c384e4a6c410f172f.scope CGROUP allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:docker]).to eq("guest") end it "sets not set anything if /proc/self/cgroup exist and the cgroup is named arbitrarily, it isn't necessarily lxc." do self_cgroup = <<~CGROUP 8:blkio:/Charlie 7:net_cls:/Charlie 6:freezer:/Charlie 5:devices:/Charlie 4:memory:/Charlie 3:cpuacct:/Charlie 2:cpu:/Charlie 1:cpuset:/Charlie CGROUP allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) allow(File).to receive(:read).with("/proc/1/environ").and_return("") plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end context "when /proc/self/cgroup only has / mounts" do before do self_cgroup = <<~CGROUP 8:blkio:/ 7:net_cls:/ 6:freezer:/ 5:devices:/ 4:memory:/ 3:cpuacct:/ 2:cpu:/ 1:cpuset:/ CGROUP allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(true) allow(File).to receive(:read).with("/proc/self/cgroup").and_return(self_cgroup) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end it "does not set the old virtualization attributes if they are already set" do plugin[:virtualization] = Mash.new plugin[:virtualization][:system] = "the cloud" plugin[:virtualization][:role] = "cumulonimbus" plugin.run expect(plugin[:virtualization][:system]).not_to eq("docker") expect(plugin[:virtualization][:role]).not_to eq("host") end it "does not set docker host if docker does not exist" do plugin.run expect(plugin[:virtualization][:system]).to be_nil expect(plugin[:virtualization][:role]).to be_nil expect(plugin[:virtualization]).to eq({ "systems" => {} }) end it "does not set virtualization if /proc/self/cgroup isn't there" do allow(File).to receive(:exist?).with("/proc/self/cgroup").and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end it "sets virtualization if /.dockerenv exists" do allow(File).to receive(:exist?).with("/.dockerenv").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:docker]).to eq("guest") end it "sets virtualization if /.dockerinit exists" do allow(File).to receive(:exist?).with("/.dockerinit").and_return(true) plugin.run expect(plugin[:virtualization][:system]).to eq("docker") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:docker]).to eq("guest") end it "does not set virtualization if /.dockerenv or /.dockerinit does not exists" do allow(File).to receive(:exist?).with("/.dockerenv").and_return(false) allow(File).to receive(:exist?).with("/.dockerinit").and_return(false) plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end it "does not set virtualization if no tests match" do plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end ohai-16.0.7/spec/unit/plugins/lua_spec.rb000066400000000000000000000040471362624620500202520ustar00rootroot00000000000000# # Author:: Doug MacEachern # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2009 VMware, Inc. # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin lua" do let(:plugin) { get_plugin("lua") } before do plugin[:languages] = Mash.new @message = "Lua 5.1.2 Copyright (C) 1994-2008 Lua.org, PUC-Rio\n" allow(plugin).to receive(:shell_out).with("lua -v").and_return(mock_shell_out(0, "", @message)) end it "gets the lua version from running lua -v" do expect(plugin).to receive(:shell_out).with("lua -v") plugin.run end it "sets languages[:lua][:version]" do plugin.run expect(plugin.languages[:lua][:version]).to eql("5.1.2") end it "does not set languages[:lua] if lua command fails" do allow(plugin).to receive(:shell_out).with("lua -v").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:lua) end it "does not set languages[:lua] if lua command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:lua) end it "sets languages[:lua][:version] when 'lua -v' returns output on stdout not stderr" do allow(plugin).to receive(:shell_out).with("lua -v").and_return(mock_shell_out(0, @message, "")) plugin.run expect(plugin.languages[:lua][:version]).to eql("5.1.2") end end ohai-16.0.7/spec/unit/plugins/mono_spec.rb000066400000000000000000000044171362624620500204420ustar00rootroot00000000000000# # Author:: Doug MacEachern # Copyright:: Copyright (c) 2009 VMware, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin mono" do let(:plugin) { get_plugin("mono") } before do plugin[:languages] = Mash.new @stdout = <<~OUT Mono JIT compiler version 4.2.3 (Stable 4.2.3.4/832de4b Wed Mar 30 13:57:48 PDT 2016) Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com TLS: normal SIGSEGV: altstack Notification: kqueue Architecture: amd64 Disabled: none Misc: softdebug LLVM: supported, not enabled. GC: sgen OUT allow(plugin).to receive(:shell_out).with("mono -V").and_return(mock_shell_out(0, @stdout, "")) end it "gets the mono version from running mono -V" do expect(plugin).to receive(:shell_out).with("mono -V").and_return(mock_shell_out(0, @stdout, "")) plugin.run end it "sets languages[:mono][:version]" do plugin.run expect(plugin.languages[:mono][:version]).to eql("4.2.3") end it "sets languages[:mono][:builddate]" do plugin.run expect(plugin.languages[:mono][:builddate]).to eql("Wed Mar 30 13:57:48 PDT 2016") end it "does not set the languages[:mono] if mono command fails" do allow(plugin).to receive(:shell_out).with("mono -V").and_return(mock_shell_out(1, @stdout, "")) plugin.run expect(plugin.languages).not_to have_key(:mono) end it "does not set languages[:mono] if mono command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:mono) end end ohai-16.0.7/spec/unit/plugins/netbsd/000077500000000000000000000000001362624620500174045ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/netbsd/hostname_spec.rb000066400000000000000000000030741362624620500225650ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "NetBSD hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:netbsd) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return(mock_shell_out(0, "katie\n", "")) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie.local", "")) allow(@plugin).to receive(:resolve_fqdn).and_return("katie.bethell") end it_should_check_from("linux::hostname", "hostname", "hostname -s", "katie") it_should_check_from("linux::hostname", "machinename", "hostname", "katie.local") it "uses #resolve_fqdn to find the fqdn" do @plugin.run expect(@plugin[:fqdn]).to eq("katie.bethell") end it "sets the domain to everything after the first dot of the fqdn" do @plugin.run expect(@plugin[:domain]).to eq("bethell") end end ohai-16.0.7/spec/unit/plugins/netbsd/kernel_spec.rb000066400000000000000000000027061362624620500222300ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "NetBSD kernel plugin" do before do @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:netbsd) allow(@plugin).to receive(:init_kernel).and_return({}) allow(@plugin).to receive(:shell_out).with("uname -i").and_return(mock_shell_out(0, "foo", "")) allow(@plugin).to receive(:shell_out).with("sysctl kern.securelevel").and_return(mock_shell_out(0, "kern.securelevel: 1\n", "")) allow(@plugin).to receive(:shell_out).with((Ohai.abs_path( "/usr/bin/modstat" )).to_s).and_return(mock_shell_out(0, " 1 7 0xc0400000 97f830 kernel", "")) end it "sets the kernel_os to the kernel_name value" do @plugin.run expect(@plugin[:kernel][:os]).to eq(@plugin[:kernel][:name]) end end ohai-16.0.7/spec/unit/plugins/netbsd/platform_spec.rb000066400000000000000000000024731362624620500225750ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "NetBSD plugin platform" do before do @plugin = get_plugin("netbsd/platform") allow(@plugin).to receive(:shell_out).with("uname -s").and_return(mock_shell_out(0, "NetBSD\n", "")) allow(@plugin).to receive(:shell_out).with("uname -r").and_return(mock_shell_out(0, "4.5\n", "")) allow(@plugin).to receive(:collect_os).and_return(:netbsd) end it "sets platform to lowercased lsb[:id]" do @plugin.run expect(@plugin[:platform]).to eq("netbsd") end it "sets platform_version to lsb[:release]" do @plugin.run expect(@plugin[:platform_version]).to eq("4.5") end end ohai-16.0.7/spec/unit/plugins/network_spec.rb000066400000000000000000001135231362624620500211620ustar00rootroot00000000000000# # Author:: Laurent Desarmes # Copyright:: Copyright (c) 2012 Laurent Desarmes # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" def it_doesnt_fail it "doesnt fail" do allow(@plugin.logger).to receive(:warn) expect(@plugin.logger).not_to receive(:trace).with(/^Plugin network threw exception/) @plugin.run end end # basic sanity check that is called in all describes below def it_populates_ipaddress_attributes source = caller[0] it "populates ipaddress, macaddress and ip6address" do allow(@plugin.logger).to receive(:warn) expect(@plugin.logger).not_to receive(:trace).with(/^Plugin network threw exception/) @plugin.run %w{ ipaddress macaddress ip6address }.each do |attribute| expect(@plugin).to have_key(attribute) end rescue Exception puts "RSpec context: #{source}" raise end end describe Ohai::System, "Network Plugin" do # output of network plugins on particular platforms to mock plugin runs basic_data = { "freebsd" => { "network" => { "interfaces" => { "vr0" => { "type" => "vr", "number" => "0", "flags" => %w{UP BROADCAST RUNNING SIMPLEX MULTICAST}, "addresses" => { "00:00:24:c9:5e:b8" => { "family" => "lladdr", }, "fe80::200:24ff:fec9:5eb8" => { "family" => "inet6", "zoneid" => "vr0", "prefixlen" => "64", "scopeid" => "0x1", }, "76.91.1.255" => { "family" => "inet", "netmask" => "255.255.252.0", "broadcast" => "255.255.255.255", }, }, "arp" => { "76.91.1.255" => "00:00:24:c9:5e:b8", "76.91.0.1" => "00:01:5c:24:8c:01", }, }, "vr1" => { "type" => "vr", "number" => "1", "flags" => %w{UP BROADCAST RUNNING PROMISC SIMPLEX MULTICAST}, "addresses" => { "00:00:24:c9:5e:b9" => { "family" => "lladdr", }, "fe80::200:24ff:fec9:5eb9" => { "family" => "inet6", "zoneid" => "vr1", "prefixlen" => "64", "scopeid" => "0x2", }, }, }, "vr2" => { "type" => "vr", "number" => "2", "flags" => %w{UP BROADCAST RUNNING PROMISC SIMPLEX MULTICAST}, "addresses" => { "00:00:24:c9:5e:ba" => { "family" => "lladdr", }, "fe80::200:24ff:fec9:5eba" => { "family" => "inet6", "zoneid" => "vr2", "prefixlen" => "64", "scopeid" => "0x3", }, }, }, "vr3" => { "type" => "vr", "number" => "3", "flags" => %w{UP BROADCAST RUNNING PROMISC SIMPLEX MULTICAST}, "addresses" => { "00:00:24:c9:5e:bb" => { "family" => "lladdr", }, "fe80::200:24ff:fec9:5ebb" => { "family" => "inet6", "zoneid" => "vr3", "prefixlen" => "64", "scopeid" => "0x4", }, }, }, "ipfw0" => { # OHAI-492: Ensure network plugin works with interfaces without addresses. "type" => "ipfw", "number" => "0", "flags" => %w{UP SIMPLEX MULTICAST}, }, "lo0" => { "type" => "lo", "number" => "0", "flags" => %w{UP LOOPBACK RUNNING MULTICAST}, "addresses" => { "127.0.0.1" => { "family" => "inet", "netmask" => "255.0.0.0", }, "::1" => { "family" => "inet6", "prefixlen" => "128", }, "fe80::1" => { "family" => "inet6", "zoneid" => "lo0", "prefixlen" => "64", "scopeid" => "0x8", }, }, }, "bridge0" => { "type" => "bridge", "number" => "0", "flags" => %w{LEARNING DISCOVER AUTOEDGE AUTOPTP}, "addresses" => { "02:20:6f:d2:c4:00" => { "family" => "lladdr", }, "192.168.2.1" => { "family" => "inet", "netmask" => "255.255.255.0", "broadcast" => "192.168.2.255", }, "2001:470:d:cb4::1" => { "family" => "inet6", "prefixlen" => "64", }, "fe80::cafe:babe:dead:beef" => { "family" => "inet6", "zoneid" => "bridge0", "prefixlen" => "64", "scopeid" => "0x9", }, }, "arp" => { "192.168.2.142" => "60:67:20:75:a2:0c", "192.168.2.205" => "c0:c1:c0:f9:40:ed", "192.168.2.160" => "cc:3a:61:cf:67:13", "192.168.2.1" => "02:20:6f:d2:c4:00", "192.168.2.135" => "f8:0c:f3:d7:c6:b6", "192.168.2.165" => "f8:8f:ca:24:49:ad", "192.168.2.158" => "48:5d:60:1f:ea:d1", "192.168.2.150" => "60:a4:4c:60:b3:d9", }, }, "gif0" => { "type" => "gif", "number" => "0", "flags" => %w{UP POINTOPOINT RUNNING MULTICAST}, "addresses" => { "fe80::200:24ff:fec9:5eb8" => { "family" => "inet6", "zoneid" => "gif0", "prefixlen" => "64", "scopeid" => "0xa", }, }, }, }, "default_gateway" => "76.91.0.1", "default_interface" => "vr0", "default_inet6_gateway" => "2001:470:d:cb4::2", "default_inet6_interface" => "bridge0", }, }, "linux" => { "network" => { # pp Hash[node['network']] from chef-shell to get the network data # have just removed the neighbour and route entries by hand "interfaces" => { "lo" => { "flags" => %w{LOOPBACK UP}, "addresses" => { "::1" => { "scope" => "Node", "prefixlen" => "128", "family" => "inet6", }, "127.0.0.1" => { "scope" => "Node", "netmask" => "255.0.0.0", "prefixlen" => "8", "family" => "inet", }, }, "mtu" => "16436", "encapsulation" => "Loopback", "state" => "unknown", }, "eth0" => { "flags" => %w{BROADCAST MULTICAST UP}, "number" => "0", "addresses" => { "fe80::216:3eff:fe2f:3679" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "00:16:3E:2F:36:79" => { "family" => "lladdr", }, "192.168.66.33" => { "scope" => "Global", "netmask" => "255.255.255.0", "broadcast" => "192.168.66.255", "prefixlen" => "24", "family" => "inet", }, "3ffe:1111:2222::33" => { "prefixlen" => "48", "family" => "inet6", "scope" => "Global", "state" => "up", }, }, "mtu" => "1500", "type" => "eth", "encapsulation" => "Ethernet", }, "eth1" => { "flags" => %w{BROADCAST MULTICAST UP}, "number" => "1", "addresses" => { "fe80::216:3eff:fe2f:3680" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "00:16:3E:2F:36:80" => { "family" => "lladdr", }, "192.168.99.11" => { "scope" => "Global", "netmask" => "255.255.255.0", "broadcast" => "192.168.99.255", "prefixlen" => "24", "family" => "inet", }, "3ffe:1111:3333::1" => { "prefixlen" => "48", "family" => "inet6", "scope" => "Global", }, }, "mtu" => "1500", "type" => "eth", "encapsulation" => "Ethernet", }, }, "default_gateway" => "192.168.66.15", "default_interface" => "eth0", "default_inet6_gateway" => "3ffe:1111:2222::", "default_inet6_interface" => "eth0", }, }, "windows" => { "network" => { "interfaces" => { "0xb" => { "addresses" => { "172.19.0.130" => { "prefixlen" => "24", "netmask" => "255.255.255.0", "broadcast" => "172.19.0.255", "family" => "inet", }, "fe80::698d:3e37:7950:b28c" => { "prefixlen" => "64", "family" => "inet6", "scope" => "Link", }, "52:54:44:66:66:02" => { "family" => "lladdr", }, }, "mtu" => nil, "type" => "Ethernet 802.3", "encapsulation" => "Ethernet", }, }, "default_gateway" => "172.19.0.1", "default_interface" => "0xb", }, }, } describe "on linux" do before do @plugin = get_plugin("network") @plugin["network"] = basic_data["linux"]["network"] end describe "when the linux::network plugin hasn't set any of {ip,ip6,mac}address attributes" do describe "simple network setup" do it_populates_ipaddress_attributes it "detects {ip,ip6,mac}address" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.33") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") end end describe "default ipv4 and ipv6 gateway on different interfaces" do describe "both interfaces have an ARP" do before do @plugin["network"]["default_inet6_gateway"] = "3ffe:1111:3333::" @plugin["network"]["default_inet6_interface"] = "eth1" end it_populates_ipaddress_attributes it "detects {ip,ip6}address" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.33") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end it "set macaddress from the ipv4 setup" do @plugin.run expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") end it "informs about this setup" do expect(@plugin.logger).to receive(:trace).with(/ipaddress and ip6address are set from different interfaces/) allow(@plugin.logger).to receive(:trace) @plugin.run end end describe "ipv4 interface has no ARP" do before do @plugin["network"]["interfaces"]["eth0"]["addresses"].delete_if { |k, kv| kv["family"] == "lladdr" } # not really checked by this pluging @plugin["network"]["interfaces"]["eth0"]["flags"] << "NOARP" @plugin["network"]["default_inet6_gateway"] = "3ffe:1111:3333::" @plugin["network"]["default_inet6_interface"] = "eth1" end it_populates_ipaddress_attributes it "detects {ip,ip6}address" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.33") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end it "sets macaddress to the ipv6 interface because it hadn't set one for ipv4 first" do @plugin.run expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:80") end it "informs about this setup" do expect(@plugin.logger).to receive(:trace).with(/ipaddress and ip6address are set from different interfaces/) allow(@plugin.logger).to receive(:trace) @plugin.run end end end describe "conflicting results from the linux::network plugin" do describe "default interface doesn't match the default_gateway" do before do @plugin["network"]["default_interface"] = "eth1" @plugin["network"]["default_inet6_interface"] = "eth1" end it_populates_ipaddress_attributes it "picks {ip,ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.99.11") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:80") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end it "warns about this conflict" do expect(@plugin.logger).to receive(:trace).with(%r{\[inet\] no ipaddress/mask on eth1}).once expect(@plugin.logger).to receive(:trace).with(%r{\[inet6\] no ipaddress/mask on eth1}).once allow(@plugin.logger).to receive(:trace) @plugin.run end end describe "there's a default gateway, none of the configured ip/mask theorically allows to reach it" do before do @plugin["network"]["default_gateway"] = "172.16.12.42" @plugin["network"]["default_inet6_gateway"] = "3ffe:12:42::7070" end it "picks {ip,ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.33") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") end end describe "no ip address for the given default interface/gateway" do before do @plugin["network"]["interfaces"]["eth0"]["addresses"].delete_if { |k, v| %w{inet inet6}.include? v["family"] } end it_doesnt_fail it "doesn't detect {ip,ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to be_nil expect(@plugin["macaddress"]).to be_nil expect(@plugin["ip6address"]).to be_nil end it "warns about this conflict" do expect(@plugin.logger).to receive(:warn).with(/unable to detect ipaddress/).once expect(@plugin.logger).to receive(:warn).with(/\[inet\] no ip address on eth0/).once expect(@plugin.logger).to receive(:trace).with(/unable to detect ip6address/).once expect(@plugin.logger).to receive(:trace).with(/unable to detect macaddress/).twice # for each family expect(@plugin.logger).to receive(:warn).with(/\[inet6\] no ip address on eth0/).once @plugin.run end end describe "no ip at all" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["default_inet6_gateway"] = nil @plugin["network"]["default_inet6_interface"] = nil @plugin["network"]["interfaces"].each_value do |val| val["addresses"].delete_if { |k, kv| %w{inet inet6}.include? kv["family"] } end end it_doesnt_fail it "doesn't detect {ip,ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to be_nil expect(@plugin["macaddress"]).to be_nil expect(@plugin["ip6address"]).to be_nil end it "warns about it" do expect(@plugin.logger).to receive(:warn).with(/unable to detect ipaddress/).once expect(@plugin.logger).to receive(:trace).with(/unable to detect macaddress/).twice # for each family expect(@plugin.logger).to receive(:trace).with(/unable to detect ip6address/).once @plugin.run end end end describe "several ipaddresses matching the default route" do describe "bigger prefix not set on the default interface" do before do @plugin["network"]["interfaces"]["eth2"] = { "flags" => %w{BROADCAST MULTICAST UP}, "number" => "2", "addresses" => { "fe80::216:3eff:fe2f:3681" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "00:16:3E:2F:36:81" => { "family" => "lladdr" }, "192.168.66.99" => { "scope" => "Global", "netmask" => "255.255.255.128", "broadcast" => "192.168.99.127", "prefixlen" => "25", "family" => "inet", }, "3ffe:1111:2222:0:4444::1" => { "prefixlen" => "64", "family" => "inet6", "scope" => "Global", }, }, } end it_populates_ipaddress_attributes it "sets {ip,ip6,mac}address correctly" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.33") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") end end describe "bigger prefix set on the default interface" do before do @plugin["network"]["interfaces"]["eth0"]["addresses"]["192.168.66.99"] = { "scope" => "Global", "netmask" => "255.255.255.128", "broadcast" => "192.168.66.127", "prefixlen" => "25", "family" => "inet", } @plugin["network"]["interfaces"]["eth0"]["addresses"]["3ffe:1111:2222:0:4444::1"] = { "prefixlen" => "64", "family" => "inet6", "scope" => "Global", } end it_populates_ipaddress_attributes it "sets {ip,ip6,mac}address correctly" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.99") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222:0:4444::1") end end describe "smallest ip not set on the default_interface" do before do @plugin["network"]["interfaces"]["eth2"] = { "flags" => %w{BROADCAST MULTICAST UP}, "number" => "2", "addresses" => { "fe80::216:3eff:fe2f:3681" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "00:16:3E:2F:36:81" => { "family" => "lladdr" }, "192.168.66.32" => { "scope" => "Global", "netmask" => "255.255.255.0", "broadcast" => "192.168.66.255", "prefixlen" => "24", "family" => "inet", }, "3ffe:1111:2222::32" => { "prefixlen" => "48", "family" => "inet6", "scope" => "Global", }, }, } end it_populates_ipaddress_attributes it "sets {ip,ip6,mac}address correctly" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.33") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") end end describe "smallest ip set on the default_interface" do before do @plugin["network"]["interfaces"]["eth0"]["addresses"]["192.168.66.32"] = { "scope" => "Global", "netmask" => "255.255.255.0", "broadcast" => "192.168.66.255", "prefixlen" => "24", "family" => "inet", } @plugin["network"]["interfaces"]["eth0"]["addresses"]["3ffe:1111:2222::32"] = { "prefixlen" => "48", "family" => "inet6", "scope" => "Global", } end it_populates_ipaddress_attributes it "sets {ip,ip6,mac}address correctly" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.32") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::32") end end end describe "no default route" do describe "first interface is not the best choice" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["default_inet6_gateway"] = nil @plugin["network"]["default_inet6_interface"] = nil # removing inet* addresses from eth0, to complicate things a bit @plugin["network"]["interfaces"]["eth0"]["addresses"].delete_if { |k, v| %w{inet inet6}.include? v["family"] } end it_populates_ipaddress_attributes it "picks {ip,mac,ip6}address from the first interface" do expect(@plugin.logger).to receive(:trace).with(/\[inet\] no default interface/).once expect(@plugin.logger).to receive(:trace).with(/\[inet6\] no default interface/).once allow(@plugin.logger).to receive(:trace) @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.99.11") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:80") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end end describe "can choose from addresses with different scopes" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["default_inet6_gateway"] = nil @plugin["network"]["default_inet6_interface"] = nil # just changing scopes to lInK for eth0 addresses @plugin["network"]["interfaces"]["eth0"]["addresses"].each_value { |v| v[:scope] = "lInK" if %w{inet inet6}.include? v["family"] } end it_populates_ipaddress_attributes it "prefers global scope addressses to set {ip,mac,ip6}address" do expect(@plugin.logger).to receive(:trace).with(/\[inet\] no default interface/).once expect(@plugin.logger).to receive(:trace).with(/\[inet6\] no default interface/).once allow(@plugin.logger).to receive(:trace) @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.99.11") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:80") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end end end describe "link level default route" do describe "simple setup" do before do @plugin["network"]["default_gateway"] = "0.0.0.0" @plugin["network"]["default_interface"] = "eth1" @plugin["network"]["default_inet6_gateway"] = "::" @plugin["network"]["default_inet6_interface"] = "eth1" end it_populates_ipaddress_attributes it "picks {ip,mac,ip6}address from the default interface" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.99.11") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:80") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end end describe "fe80::1 as a default gateway" do before do @plugin["network"]["default_inet6_gateway"] = "fe80::1" end it_populates_ipaddress_attributes it "picks {ip,mac,ip6}address from the default interface" do @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") end end describe "can choose from addresses with different scopes" do before do @plugin["network"]["default_gateway"] = "0.0.0.0" @plugin["network"]["default_interface"] = "eth1" @plugin["network"]["default_inet6_gateway"] = "::" @plugin["network"]["default_inet6_interface"] = "eth1" @plugin["network"]["interfaces"]["eth1"]["addresses"]["127.0.0.2"] = { "scope" => "host", "netmask" => "255.255.255.255", "prefixlen" => "32", "family" => "inet", } end it_populates_ipaddress_attributes it "picks {ip,mac,ip6}address from the default interface" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.99.11") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:80") expect(@plugin["ip6address"]).to eq("3ffe:1111:3333::1") end end end describe "point to point address" do before do @plugin["network"]["interfaces"]["eth2"] = { "flags" => %w{POINTOPOINT BROADCAST MULTICAST UP}, "number" => "2", "addresses" => { "fe80::216:3eff:fe2f:3681" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "00:16:3E:2F:36:81" => { "family" => "lladdr" }, "192.168.66.99" => { "scope" => "Global", "netmask" => "255.255.255.255", "peer" => "192.168.99.126", "prefixlen" => "32", "family" => "inet", }, "3ffe:1111:2222:0:4444::1" => { "prefixlen" => "128", "peer" => "3ffe:1111:2222:0:4444::2", "family" => "inet6", "scope" => "Global", }, }, } @plugin["network"]["default_gateway"] = "192.168.99.126" @plugin["network"]["default_interface"] = "eth2" @plugin["network"]["default_inet6_gateway"] = "3ffe:1111:2222:0:4444::2" @plugin["network"]["default_inet6_interface"] = "eth2" end it_populates_ipaddress_attributes it "picks {ip,mac,ip6}address from the default interface" do @plugin.run expect(@plugin["ipaddress"]).to eq("192.168.66.99") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:81") expect(@plugin["ip6address"]).to eq("3ffe:1111:2222:0:4444::1") end end describe "ipv6 only node" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["interfaces"].each_value do |val| val["addresses"].delete_if { |k, kv| kv["family"] == "inet" } end end it_doesnt_fail it "can't detect ipaddress" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to be_nil end it "warns about not being able to set {ip,mac}address (ipv4)" do expect(@plugin.logger).to receive(:warn).with(/unable to detect ipaddress/).once expect(@plugin.logger).to receive(:trace).with(/unable to detect macaddress/) # for ipv4 expect(@plugin.logger).to receive(:trace).with(/setting macaddress to/) # for ipv6 expect(@plugin.logger).to receive(:trace).with(/\[inet6\] Using default interface eth0 and default gateway/) # for ipv6 @plugin.run end it "sets {ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") end it "informs about macaddress being set using the ipv6 setup" do expect(@plugin.logger).to receive(:trace).with(/setting macaddress to '00:16:3E:2F:36:79'/) allow(@plugin.logger).to receive(:trace) @plugin.run end end describe "ipv6 only with ipv4 loopback" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["interfaces"].each do |i, iv| next if i == "lo" iv["addresses"].delete_if { |k, kv| kv["family"] == "inet" } end end it_doesnt_fail it "can't detect ipaddress" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to eq("127.0.0.1") end it "sets {ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:1111:2222::33") expect(@plugin["macaddress"]).to eq("00:16:3E:2F:36:79") end it "informs about macaddress being set using the ipv6 setup" do expect(@plugin.logger).to receive(:trace).with(/setting macaddress to '00:16:3E:2F:36:79'/) allow(@plugin.logger).to receive(:trace) @plugin.run end end end # specs using network plugin data for each mocked OS (freebsd,linux,windows) basic_data.keys.sort.each do |os| describe "the #{os}::network has already set some of the {ip,mac,ip6}address attributes" do before do @plugin["network"] = basic_data[os]["network"] end describe "{ip,mac}address are already set" do before do @plugin["ipaddress"] = "10.11.12.13" @plugin["macaddress"] = "00:AA:BB:CC:DD:EE" @expected_results = { "freebsd" => { "ip6address" => "2001:470:d:cb4::1", "macaddress" => "02:20:6f:d2:c4:00", }, "linux" => { "ip6address" => "3ffe:1111:2222::33", "macaddress" => "00:16:3E:2F:36:79", }, "windows" => { "ip6address" => "fe80::698d:3e37:7950:b28c", "macaddress" => "00:AA:BB:CC:DD:EE", }, } end it_populates_ipaddress_attributes it "detects ip6address" do @plugin.run expect(@plugin["ip6address"]).to eq(@expected_results[os]["ip6address"]) end it "doesn't overwrite {ip,mac}address" do @plugin.run expect(@plugin["ipaddress"]).to eq("10.11.12.13") expect(@plugin["macaddress"]).to eq("00:AA:BB:CC:DD:EE") end end describe "ip6address is already set" do describe "node has ipv4 and ipv6" do before do @plugin["ip6address"] = "3ffe:8888:9999::1" @expected_results = { "freebsd" => { "ipaddress" => "76.91.1.255", "macaddress" => "00:00:24:c9:5e:b8", }, "linux" => { "ipaddress" => "192.168.66.33", "macaddress" => "00:16:3E:2F:36:79", }, "windows" => { "ipaddress" => "172.19.0.130", "macaddress" => "52:54:44:66:66:02", }, } end it_populates_ipaddress_attributes it "detects {ip,mac}address" do @plugin.run expect(@plugin["ipaddress"]).to eq(@expected_results[os]["ipaddress"]) expect(@plugin["macaddress"]).to eq(@expected_results[os]["macaddress"]) end it "doesn't overwrite ip6address" do @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:8888:9999::1") end end describe "ipv6 only node" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["interfaces"].each_value do |val| if val.key? "addresses" val["addresses"].delete_if { |k, kv| kv["family"] == "inet" } end end @plugin["ip6address"] = "3ffe:8888:9999::1" @expected_results = { "freebsd" => { "macaddress" => "02:20:6f:d2:c4:00", }, "linux" => { "macaddress" => "00:16:3E:2F:36:79", }, "windows" => { "macaddress" => "52:54:44:66:66:02", }, } end it_doesnt_fail it "can't detect ipaddress (ipv4)" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to be_nil end it "takes the macaddress from ipv6" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["macaddress"]).to eq(@expected_results[os]["macaddress"]) end it "warns about not being able to set ipaddress" do expect(@plugin.logger).to receive(:warn).with(/unable to detect ipaddress/).once @plugin.run end it "doesn't overwrite ip6address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:8888:9999::1") end end end describe "{mac,ip6}address are already set" do describe "valid ipv4 setup" do before do @plugin["macaddress"] = "00:AA:BB:CC:DD:EE" @plugin["ip6address"] = "3ffe:8888:9999::1" @expected_results = { "freebsd" => { "ipaddress" => "76.91.1.255", "macaddress" => "00:00:24:c9:5e:b8", }, "linux" => { "ipaddress" => "192.168.66.33", "macaddress" => "00:16:3E:2F:36:79", }, "windows" => { "ipaddress" => "172.19.0.130", "macaddress" => "52:54:44:66:66:02", }, } end it_populates_ipaddress_attributes it "detects ipaddress and does not overwrite macaddress" do @plugin.run expect(@plugin["ipaddress"]).to eq(@expected_results[os]["ipaddress"]) expect(@plugin["macaddress"]).to eq(@plugin["macaddress"]) end it "doesn't overwrite ip6address" do @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:8888:9999::1") end end describe "ipv6 only node" do before do @plugin["network"]["default_gateway"] = nil @plugin["network"]["default_interface"] = nil @plugin["network"]["interfaces"].each_value do |val| if val.key? "addresses" val["addresses"].delete_if { |k, kv| kv["family"] == "inet" } end end @plugin["macaddress"] = "00:AA:BB:CC:DD:EE" @plugin["ip6address"] = "3ffe:8888:9999::1" end it_doesnt_fail it "can't set ipaddress" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ipaddress"]).to be_nil end it "doesn't overwrite {ip6,mac}address" do allow(@plugin.logger).to receive(:warn) @plugin.run expect(@plugin["ip6address"]).to eq("3ffe:8888:9999::1") expect(@plugin["macaddress"]).to eq("00:AA:BB:CC:DD:EE") end end end describe "{ip,mac,ip6}address are already set" do before do @plugin["ipaddress"] = "10.11.12.13" @plugin["macaddress"] = "00:AA:BB:CC:DD:EE" @plugin["ip6address"] = "3ffe:8888:9999::1" end it_populates_ipaddress_attributes it "doesn't overwrite {ip,mac,ip6}address" do @plugin.run expect(@plugin["ipaddress"]).to eq("10.11.12.13") expect(@plugin["macaddress"]).to eq("00:AA:BB:CC:DD:EE") expect(@plugin["ip6address"]).to eq("3ffe:8888:9999::1") end end describe "{ip,ip6}address are already set" do before do @plugin["ipaddress"] = "10.11.12.13" @plugin["ip6address"] = "3ffe:8888:9999::1" end it_doesnt_fail it "doesn't overwrite {ip,ip6}address" do @plugin.run expect(@plugin["ipaddress"]).to eq("10.11.12.13") expect(@plugin["ip6address"]).to eq("3ffe:8888:9999::1") end end end end end end ohai-16.0.7/spec/unit/plugins/nodejs_spec.rb000066400000000000000000000034411362624620500207500ustar00rootroot00000000000000# # Author:: Jacques Marneweck () # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) Jacques Marneweck # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin nodejs" do let(:plugin) { get_plugin("nodejs") } before do plugin[:languages] = Mash.new @stdout = "v0.8.11\n" allow(plugin).to receive(:shell_out).with("node -v").and_return(mock_shell_out(0, @stdout, "")) end it "gets the nodejs version from running node -v" do expect(plugin).to receive(:shell_out).with("node -v") plugin.run end it "sets languages[:nodejs][:version]" do plugin.run expect(plugin.languages[:nodejs][:version]).to eql("0.8.11") end it "does not set the languages[:nodejs] tree up if node command fails" do allow(plugin).to receive(:shell_out).with("node -v").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:nodejs) end it "does not set languages[:nodejs] if node command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:nodejs) end end ohai-16.0.7/spec/unit/plugins/ohai_spec.rb000066400000000000000000000020731362624620500204060ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Tollef Fog Heen # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2010 Tollef Fog Heen # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin ohai" do before do @plugin = get_plugin("ohai") end it "sets [:chef_packages][:ohai][:version] to the current version" do @plugin.run expect(@plugin[:chef_packages][:ohai][:version]).to eq(Ohai::VERSION) end end ohai-16.0.7/spec/unit/plugins/ohai_time_spec.rb000066400000000000000000000023721362624620500214260ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin ohai_time" do before do @plugin = get_plugin("ohai_time") end it "gets the current time" do expect(Time).to receive(:now) @plugin.run end it "turns the time into a floating point number" do time = Time.now expect(time).to receive(:to_f) allow(Time).to receive(:now).and_return(time) @plugin.run end it "sets ohai_time to the current time" do time = Time.now allow(Time).to receive(:now).and_return(time) @plugin.run expect(@plugin[:ohai_time]).to eq(time.to_f) end end ohai-16.0.7/spec/unit/plugins/openbsd/000077500000000000000000000000001362624620500175575ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/openbsd/hostname_spec.rb000066400000000000000000000030761362624620500227420ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "OpenBSD hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:openbsd) allow(@plugin).to receive(:shell_out).with("hostname -s").and_return(mock_shell_out(0, "katie\n", "")) allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "katie.local", "")) allow(@plugin).to receive(:resolve_fqdn).and_return("katie.bethell") end it_should_check_from("linux::hostname", "hostname", "hostname -s", "katie") it_should_check_from("linux::hostname", "machinename", "hostname", "katie.local") it "uses #resolve_fqdn to find the fqdn" do @plugin.run expect(@plugin[:fqdn]).to eq("katie.bethell") end it "sets the domain to everything after the first dot of the fqdn" do @plugin.run expect(@plugin[:domain]).to eq("bethell") end end ohai-16.0.7/spec/unit/plugins/openbsd/kernel_spec.rb000066400000000000000000000027031362624620500224000ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "OpenBSD kernel plugin" do before do @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:openbsd) allow(@plugin).to receive(:init_kernel).and_return({}) allow(@plugin).to receive(:shell_out).with("uname -i").and_return(mock_shell_out(0, "foo", "")) allow(@plugin).to receive(:shell_out).with("sysctl kern.securelevel").and_return(mock_shell_out(0, "kern.securelevel: 1\n", "")) allow(@plugin).to receive(:shell_out).with( Ohai.abs_path( "/usr/bin/modstat" )).and_return(mock_shell_out(0, " 1 7 0xc0400000 97f830 kernel", "")) end it "sets the kernel_os to the kernel_name value" do @plugin.run expect(@plugin[:kernel][:os]).to eq(@plugin[:kernel][:name]) end end ohai-16.0.7/spec/unit/plugins/openbsd/platform_spec.rb000066400000000000000000000023121362624620500227400ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "OpenBSD plugin platform" do before do @plugin = get_plugin("openbsd/platform") allow(@plugin).to receive(:shell_out).with("uname -s").and_return(mock_shell_out(0, "OpenBSD\n", "")) allow(@plugin).to receive(:shell_out).with("uname -r").and_return(mock_shell_out(0, "4.5\n", "")) allow(@plugin).to receive(:collect_os).and_return(:openbsd) end it "sets platform_version to lsb[:release]" do @plugin.run expect(@plugin[:platform_version]).to eq("4.5") end end ohai-16.0.7/spec/unit/plugins/openstack_spec.rb000066400000000000000000000263171362624620500214640ustar00rootroot00000000000000# # Author:: Daniel DeLeo (dan@chef.io) # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDIT"Net::HTTP Response"NS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin openstack" do let(:plugin) { get_plugin("openstack") } let(:default_timeout) { 2 } before do PasswdEntry = Struct.new(:name, :uid, :gid, :dir, :shell, :gecos) allow(plugin).to receive(:hint?).with("openstack").and_return(false) plugin[:virtualization] = { systems: {} } end context "when there is no relevant hint or virtualization data" do it "does not set any openstack data" do plugin.run expect(plugin[:openstack]).to be_nil end end context "when virtualization data is Openstack", :unix_only do context "and the metadata service is not available" do before do allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, default_timeout) .and_return(false) plugin[:virtualization] = { systems: { openstack: "guest" } } plugin.run end it "sets provider attribute to openstack" do expect(plugin[:openstack][:provider]).to eq("openstack") end it "doesn't set metadata attributes" do expect(plugin[:openstack][:instance_id]).to be_nil end end end context "when running on dreamhost", :unix_only do it "sets openstack provider attribute to dreamhost" do plugin["etc"] = { "passwd" => { "dhc-user" => {} } } allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, default_timeout) .and_return(false) plugin[:virtualization] = { systems: { openstack: "guest" } } expect(Etc::Passwd).to receive(:entries).and_return([PasswdEntry.new("dhc-user", 800, 800, "/var/www", "/bin/false", "The dreamhost user")]) plugin.run expect(plugin[:openstack][:provider]).to eq("dreamhost") end end context "when the hint is present" do context "and the metadata service is not available" do before do allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, default_timeout) .and_return(false) allow(plugin).to receive(:hint?).with("openstack").and_return(true) plugin.run end it "sets openstack provider attribute if the hint is provided" do expect(plugin[:openstack][:provider]).to eq("openstack") end it "doesn't set metadata attributes" do expect(plugin[:openstack][:instance_id]).to be_nil end context "when timout was set" do let(:override_timout) { 10 } before do Ohai::Config.ohai[:openstack_metadata_timeout] = override_timout end after do Ohai::Config.ohai[:openstack_metadata_timeout] = nil end it "overwrite timout by setting" do allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, override_timout) .and_return(false) allow(plugin).to receive(:hint?).with("openstack").and_return(true) plugin.run end end end context "and the metadata service is available" do let(:metadata_version) { "2009-04-04" } let(:metadata_root) do <<~EOM reservation-id public-keys/ security-groups public-ipv4 ami-manifest-path instance-type instance-id local-ipv4 ari-id local-hostname placement/ ami-launch-index public-hostname hostname ami-id instance-action aki-id block-device-mapping/ EOM end let(:metadata_values) do { "reservation-id" => "r-4tjvl99h", "public-keys/" => "0=dan-default", "public-keys/0/" => "openssh-key", "public-keys/0/openssh-key" => "SSH KEY DATA", "security-groups" => "default", "public-ipv4" => "172.31.7.2", "public-ipv6" => "", "ami-manifest-path" => "FIXME", "instance-type" => "opc-tester", "instance-id" => "i-0000162a", "local-ipv4" => "172.31.7.23", "ari-id" => "ari-00000037", "local-hostname" => "ohai-7-system-test.opscode.us", "placement/" => "availability-zone", "placement/availability-zone" => "nova", "ami-launch-index" => "0", "public-hostname" => "ohai-7-system-test.opscode.us", "hostname" => "ohai-7-system-test.opscode.us", "ami-id" => "ami-00000035", "instance-action" => "none", "aki-id" => "aki-00000036", "block-device-mapping/" => "ami\nroot", "block-device-mapping/ami" => "vda", "block-device-mapping/root" => "/dev/vda", } end let(:openstack_metadata_version) { "2009-04-04" } let(:openstack_metadata_endpoint) { "http://169.254.169.254/" } let(:openstack_metadata_values) do '{ "availability_zone" : "nova", "hostname" : "ohai.novalocal", "launch_index" : 0, "meta" : { "priority" : "low", "role" : "ohaiserver" }, "name" : "ohai_spec", "public_keys" : { "mykey" : "SSH KEY DATA" }, "uuid" : "00000000-0000-0000-0000-100000000000" }' end let(:http_client) { double("Net::HTTP", { :read_timeout= => nil, :keep_alive_timeout= => nil } ) } def allow_get(url, response_body) allow(http_client).to receive(:get) .with(url) .and_return(double("HTTP Response", code: "200", body: response_body)) end def allow_get_response(url, response_body) allow(http_client).to receive(:get_response) .with(url, nil, nil) .and_return(double("HTTP Response", code: "200", body: response_body)) end before do allow(plugin).to receive(:hint?).with("openstack").and_return(true) allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, default_timeout) .and_return(true) allow(Net::HTTP).to receive(:start) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR) .and_return(http_client) allow(plugin).to receive(:best_api_version).and_return(metadata_version) allow_get("/#{metadata_version}/meta-data/", metadata_root) metadata_values.each do |md_id, md_value| allow_get("/#{metadata_version}/meta-data/#{md_id}", md_value) end allow_get_response( URI.parse("#{openstack_metadata_endpoint}#{openstack_metadata_version}/meta_data.json"), openstack_metadata_values ) plugin.run end it "reads the reservation_id from the metadata service" do expect(plugin["openstack"]["reservation_id"]).to eq("r-4tjvl99h") end it "reads the public_keys_0_openssh_key from the metadata service" do expect(plugin["openstack"]["public_keys_0_openssh_key"]).to eq("SSH KEY DATA") end it "reads the security_groups from the metadata service" do expect(plugin["openstack"]["security_groups"]).to eq(["default"]) end it "reads the public_ipv4 from the metadata service" do expect(plugin["openstack"]["public_ipv4"]).to eq("172.31.7.2") end it "ignore the public_ipv6 from the metadata service when empty" do expect(plugin["openstack"]).not_to have_key("public_ipv6") end it "reads the ami_manifest_path from the metadata service" do expect(plugin["openstack"]["ami_manifest_path"]).to eq("FIXME") end it "reads the instance_type from the metadata service" do expect(plugin["openstack"]["instance_type"]).to eq("opc-tester") end it "reads the instance_id from the metadata service" do expect(plugin["openstack"]["instance_id"]).to eq("i-0000162a") end it "reads the local_ipv4 from the metadata service" do expect(plugin["openstack"]["local_ipv4"]).to eq("172.31.7.23") end it "reads the ari_id from the metadata service" do expect(plugin["openstack"]["ari_id"]).to eq("ari-00000037") end it "reads the local_hostname from the metadata service" do expect(plugin["openstack"]["local_hostname"]).to eq("ohai-7-system-test.opscode.us") end it "reads the placement_availability_zone from the metadata service" do expect(plugin["openstack"]["placement_availability_zone"]).to eq("nova") end it "reads the ami_launch_index from the metadata service" do expect(plugin["openstack"]["ami_launch_index"]).to eq("0") end it "reads the public_hostname from the metadata service" do expect(plugin["openstack"]["public_hostname"]).to eq("ohai-7-system-test.opscode.us") end it "reads the hostname from the metadata service" do expect(plugin["openstack"]["hostname"]).to eq("ohai-7-system-test.opscode.us") end it "reads the ami_id from the metadata service" do expect(plugin["openstack"]["ami_id"]).to eq("ami-00000035") end it "reads the instance_action from the metadata service" do expect(plugin["openstack"]["instance_action"]).to eq("none") end it "reads the aki_id from the metadata service" do expect(plugin["openstack"]["aki_id"]).to eq("aki-00000036") end it "reads the block_device_mapping_ami from the metadata service" do expect(plugin["openstack"]["block_device_mapping_ami"]).to eq("vda") end it "reads the block_device_mapping_root from the metadata service" do expect(plugin["openstack"]["block_device_mapping_root"]).to eq("/dev/vda") end it "sets the provider to openstack" do expect(plugin["openstack"]["provider"]).to eq("openstack") end end end context "when openstack virtualization is present" do context "and the metadata service is not available" do before do allow(plugin).to receive(:can_socket_connect?) .with(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80, default_timeout) .and_return(false) plugin[:virtualization] = { systems: { openstack: "guest" } } plugin.run end it "sets openstack provider attribute since virtualization is present" do expect(plugin[:openstack][:provider]).to eq("openstack") end it "doesn't set metadata attributes" do expect(plugin[:openstack][:instance_id]).to be_nil end end end end ohai-16.0.7/spec/unit/plugins/os_spec.rb000066400000000000000000000060231362624620500201060ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Richard Manyanza () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # Copyright:: Copyright (c) 2014 Richard Manyanza. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" ORIGINAL_CONFIG_HOST_OS = ::RbConfig::CONFIG["host_os"] describe Ohai::System, "plugin os" do before do @plugin = get_plugin("os") @plugin[:kernel] = Mash.new @plugin[:kernel][:release] = "kings of leon" end after do ::RbConfig::CONFIG["host_os"] = ORIGINAL_CONFIG_HOST_OS end it "sets os_version to kernel_release" do @plugin.run expect(@plugin[:os_version]).to eq(@plugin[:kernel][:release]) end describe "on linux" do before do ::RbConfig::CONFIG["host_os"] = "linux" end it "sets the os to linux" do @plugin.run expect(@plugin[:os]).to eq("linux") end end describe "on darwin" do before do ::RbConfig::CONFIG["host_os"] = "darwin10.0" end it "sets the os to darwin" do @plugin.run expect(@plugin[:os]).to eq("darwin") end end describe "on solaris" do before do ::RbConfig::CONFIG["host_os"] = "solaris2.42" # heh end it "sets the os to solaris2" do @plugin.run expect(@plugin[:os]).to eq("solaris2") end end describe "on AIX" do before do @plugin = get_plugin("os") allow(@plugin).to receive(:collect_os).and_return(:aix) allow(@plugin).to receive(:shell_out).with("oslevel -s").and_return(mock_shell_out(0, "7200-00-01-1543\n", nil)) @plugin.run end it "sets the top-level os attribute" do expect(@plugin[:os]).to be(:aix) end it "sets the top-level os_level attribute" do expect(@plugin[:os_version]).to eql("7200-00-01-1543") end end describe "on FreeBSD" do before do @plugin = get_plugin("os") allow(@plugin).to receive(:shell_out).with("sysctl -n kern.osreldate").and_return(mock_shell_out(0, "902001\n", "")) allow(@plugin).to receive(:collect_os).and_return(:freebsd) end it "sets os_version to __FreeBSD_version" do @plugin.run expect(@plugin[:os_version]).to eq("902001") end end describe "on something we have never seen before, but ruby has" do before do ::RbConfig::CONFIG["host_os"] = "tron" end it "sets the os to the ruby 'host_os'" do @plugin.run expect(@plugin[:os]).to eq("tron") end end end ohai-16.0.7/spec/unit/plugins/packages_spec.rb000066400000000000000000000310661362624620500212500ustar00rootroot00000000000000# Author:: Christopher M. Luciano () # Author:: Shahul Khajamohideen () # Copyright (C) 2015 IBM Corp. # Copyright (C) 2015 Bloomberg Finance L.P. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin packages" do context "when on debian" do let(:plugin) do get_plugin("packages").tap do |plugin| plugin[:platform_family] = "debian" end end let(:format) { '${Package}\t${Version}\t${Architecture}\n' } let(:stdout) do File.read(File.join(SPEC_PLUGIN_PATH, "dpkg-query.output")) end before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out) .with("dpkg-query -W -f='#{format}'") .and_return(mock_shell_out(0, stdout, "")) plugin.run end it "calls dpkg query" do expect(plugin).to receive(:shell_out) .with("dpkg-query -W -f='#{format}'") .and_return(mock_shell_out(0, stdout, "")) plugin.run end it "gets packages and versions - arch" do expect(plugin[:packages]["libc6"][:version]).to eq("2.19-18+deb8u3") expect(plugin[:packages]["libc6"][:arch]).to eq("amd64") end it "gets packages and versions - noarch" do expect(plugin[:packages]["tzdata"][:version]).to eq("2015g-0+deb8u1") expect(plugin[:packages]["tzdata"][:arch]).to eq("all") end end context "when on fedora" do let(:plugin) do get_plugin("packages").tap do |plugin| plugin[:platform_family] = "fedora" end end let(:format) { '%{NAME}\t%|EPOCH?{%{EPOCH}}:{0}|\t%{VERSION}\t%{RELEASE}\t%{INSTALLTIME}\t%{ARCH}\n' } let(:stdout) do File.read(File.join(SPEC_PLUGIN_PATH, "rpmquery.output")) end before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("rpm -qa --qf '#{format}'").and_return(mock_shell_out(0, stdout, "")) plugin.run end it "calls rpm -qa" do expect(plugin).to receive(:shell_out) .with("rpm -qa --qf '#{format}'") .and_return(mock_shell_out(0, stdout, "")) plugin.run end it "gets packages and versions/release - arch" do expect(plugin[:packages]["glibc"][:version]).to eq("2.17") expect(plugin[:packages]["glibc"][:release]).to eq("106.el7_2.6") expect(plugin[:packages]["glibc"][:epoch]).to eq("0") expect(plugin[:packages]["glibc"][:installdate]).to eq("1463486666") expect(plugin[:packages]["glibc"][:arch]).to eq("x86_64") end it "gets packages and versions/release - noarch" do expect(plugin[:packages]["tzdata"][:version]).to eq("2016d") expect(plugin[:packages]["tzdata"][:release]).to eq("1.el7") expect(plugin[:packages]["tzdata"][:epoch]).to eq("0") expect(plugin[:packages]["tzdata"][:installdate]).to eq("1463486618") expect(plugin[:packages]["tzdata"][:arch]).to eq("noarch") end it "handles multiple packages with the same name" do expect(plugin[:packages]["kernel"][:version]).to eq("3.10.0") expect(plugin[:packages]["kernel"][:release]).to eq("862.el7") expect(plugin[:packages]["kernel"][:epoch]).to eq("0") expect(plugin[:packages]["kernel"][:installdate]).to eq("1521745632") expect(plugin[:packages]["kernel"][:arch]).to eq("x86_64") # and now the version list: expect(plugin[:packages]["kernel"]["versions"].first[:version]).to eq("3.10.0") expect(plugin[:packages]["kernel"]["versions"].first[:release]).to eq("862.2.3.el7") expect(plugin[:packages]["kernel"]["versions"].first[:epoch]).to eq("0") expect(plugin[:packages]["kernel"]["versions"].first[:installdate]).to eq("1526310781") expect(plugin[:packages]["kernel"]["versions"].first[:arch]).to eq("x86_64") expect(plugin[:packages]["kernel"]["versions"].last[:version]).to eq("3.10.0") expect(plugin[:packages]["kernel"]["versions"].last[:release]).to eq("862.el7") expect(plugin[:packages]["kernel"]["versions"].last[:epoch]).to eq("0") expect(plugin[:packages]["kernel"]["versions"].last[:installdate]).to eq("1521745632") expect(plugin[:packages]["kernel"]["versions"].last[:arch]).to eq("x86_64") end end context "when on arch" do let(:plugin) do get_plugin("packages").tap do |plugin| plugin[:platform_family] = "arch" end end let(:stdout) do File.read(File.join(SPEC_PLUGIN_PATH, "pacman.output")) end before do allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("LANG=C pacman -Qi").and_return(mock_shell_out(0, stdout, "")) plugin.run end it "calls LANG=C pacman -Qi" do expect(plugin).to receive(:shell_out) .with("LANG=C pacman -Qi") .and_return(mock_shell_out(0, stdout, "")) plugin.run end it "gets packages and versions/release - normal case" do expect(plugin[:packages]["acl"][:version]).to eq("2.2.52-3") expect(plugin[:packages]["acl"][:installdate]).to eq("1500780345") expect(plugin[:packages]["acl"][:arch]).to eq("x86_64") end it "gets packages and versions/release - multiline optdeps" do expect(plugin[:packages]["abcde"][:version]).to eq("2.8.1-2") expect(plugin[:packages]["abcde"][:installdate]).to eq("1493998583") expect(plugin[:packages]["abcde"][:arch]).to eq("any") end end context "when on windows", :windows_only do let(:plugin) do get_plugin("packages").tap do |plugin| plugin[:platform_family] = "windows" end end let(:win_reg_double) do instance_double("Win32::Registry") end let(:win_reg_keys) do [ "{22FA28AB-3C1B-438B-A8B5-E23892C8B567}", "{0D4BCDCD-6225-4BA5-91A3-54AFCECC281E}" ] end let(:i386_reg_type) do Win32::Registry::KEY_READ | 0x100 end let(:x86_64_reg_type) do Win32::Registry::KEY_READ | 0x200 end let(:win_reg_output) do [{ "DisplayName" => "NXLOG-CE", "DisplayVersion" => "2.8.1248", "Publisher" => "nxsec.com", "InstallDate" => "20150511", }, { "DisplayName" => "Chef Development Kit v0.7.0", "DisplayVersion" => "0.7.0.1", "Publisher" => "\"Chef Software, Inc. \"", "InstallDate" => "20150925" }] end shared_examples "windows_package_plugin" do it "gets package info" do plugin.run expect(plugin[:packages]["Chef Development Kit v0.7.0"][:version]).to eq("0.7.0.1") expect(plugin[:packages]["Chef Development Kit v0.7.0"][:publisher]).to eq("\"Chef Software, Inc. \"") expect(plugin[:packages]["Chef Development Kit v0.7.0"][:installdate]).to eq("20150925") expect(plugin[:packages]["NXLOG-CE"][:version]).to eq("2.8.1248") expect(plugin[:packages]["NXLOG-CE"][:publisher]).to eq("nxsec.com") expect(plugin[:packages]["NXLOG-CE"][:installdate]).to eq("20150511") end end before do allow(plugin).to receive(:collect_os).and_return(:windows) allow(win_reg_double).to receive(:open).with(win_reg_keys[0]).and_return(win_reg_output[0]) allow(win_reg_double).to receive(:open).with(win_reg_keys[1]).and_return(win_reg_output[1]) allow(win_reg_double).to receive(:each_key).and_yield(win_reg_keys[0], 0).and_yield(win_reg_keys[1], 1) end describe "on 32 bit ruby" do before do stub_const("::RbConfig::CONFIG", { "target_cpu" => "i386" } ) allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open).with('Software\Microsoft\Windows\CurrentVersion\Uninstall', i386_reg_type).and_yield(win_reg_double) allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open).with('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall', i386_reg_type).and_yield(win_reg_double) end it_behaves_like "windows_package_plugin" end describe "on 64 bit ruby" do before do stub_const("::RbConfig::CONFIG", { "target_cpu" => "x86_64" } ) allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open).with('Software\Microsoft\Windows\CurrentVersion\Uninstall', x86_64_reg_type).and_yield(win_reg_double) allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open).with('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall', x86_64_reg_type).and_yield(win_reg_double) end it_behaves_like "windows_package_plugin" end describe "on unknown ruby" do before do stub_const("::RbConfig::CONFIG", { "target_cpu" => nil } ) allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open).with('Software\Microsoft\Windows\CurrentVersion\Uninstall', Win32::Registry::KEY_READ).and_yield(win_reg_double) allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open).with('Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall', Win32::Registry::KEY_READ).and_yield(win_reg_double) end it_behaves_like "windows_package_plugin" end end context "when on aix" do let(:plugin) { get_plugin("packages") } let(:stdout) do File.read(File.join(SPEC_PLUGIN_PATH, "lslpp.output")) end before do allow(plugin).to receive(:collect_os).and_return(:aix) allow(plugin).to receive(:shell_out).with("lslpp -L -q -c").and_return(mock_shell_out(0, stdout, "")) plugin.run end it "calls lslpp -L -q -c" do expect(plugin).to receive(:shell_out) .with("lslpp -L -q -c") .and_return(mock_shell_out(0, stdout, "")) plugin.run end it "gets packages with version" do expect(plugin[:packages]["chef"][:version]).to eq("12.5.1.1") end it "properly parses package names for RPMs" do expect(plugin[:packages]["wget"][:version]).to eq("1.9.1-3") end end context "when on freebsd" do let(:plugin) { get_plugin("packages") } let(:stdout) do File.read(File.join(SPEC_PLUGIN_PATH, "pkg-query.output")) end before do allow(plugin).to receive(:collect_os).and_return(:freebsd) allow(plugin).to receive(:shell_out).with('pkg query -a "%n %v"').and_return(mock_shell_out(0, stdout, "")) plugin.run end it 'calls pkg query -a "%n %v"' do expect(plugin).to receive(:shell_out) .with('pkg query -a "%n %v"') .and_return(mock_shell_out(0, stdout, "")) plugin.run end it "gets packages with version" do expect(plugin[:packages]["rubygem-chef"][:version]).to eq("12.6.0_1") end end context "when on solaris2" do let(:plugin) { get_plugin("packages") } let(:pkglist_output) do File.read(File.join(SPEC_PLUGIN_PATH, "pkglist.output")) end let(:pkginfo_output) do File.read(File.join(SPEC_PLUGIN_PATH, "pkginfo.output")) end before do allow(plugin).to receive(:collect_os).and_return(:solaris2) allow(plugin).to receive(:shell_out).with("pkg list -H").and_return(mock_shell_out(0, pkglist_output, "")) allow(plugin).to receive(:shell_out).with("pkginfo -l").and_return(mock_shell_out(0, pkginfo_output, "")) plugin.run end it "calls pkg list -H" do expect(plugin).to receive(:shell_out) .with("pkg list -H") .and_return(mock_shell_out(0, pkglist_output, "")) plugin.run end it "calls pkginfo -l" do expect(plugin).to receive(:shell_out) .with("pkginfo -l") .and_return(mock_shell_out(0, pkginfo_output, "")) plugin.run end it "gets ips packages with version" do expect(plugin[:packages]["chef"][:version]).to eq("12.5.1") end it "gets ips packages with version and publisher" do expect(plugin[:packages]["system/EMCpower"][:version]).to eq("6.0.0.1.0-3") expect(plugin[:packages]["system/EMCpower"][:publisher]).to eq("emc.com") end it "gets sysv packages with version" do expect(plugin[:packages]["chef"][:version]).to eq("12.5.1") end it "gets sysv packages with version" do expect(plugin[:packages]["mqm"][:version]).to eq("7.0.1.4") end end end ohai-16.0.7/spec/unit/plugins/passwd_spec.rb000066400000000000000000000055751362624620500210010ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # Copyright:: 2019 Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin etc", :unix_only do let(:plugin) { get_plugin("passwd") } PasswdEntry = Struct.new(:name, :uid, :gid, :dir, :shell, :gecos) GroupEntry = Struct.new(:name, :gid, :mem) it "includes a list of all users" do expect(Etc).to receive(:passwd).and_yield(PasswdEntry.new("root", 1, 1, "/root", "/bin/zsh", "BOFH")) .and_yield(PasswdEntry.new("www", 800, 800, "/var/www", "/bin/false", "Serving the web since 1970")) plugin.run expect(plugin[:etc][:passwd]["root"]).to eq(Mash.new(shell: "/bin/zsh", gecos: "BOFH", gid: 1, uid: 1, dir: "/root")) expect(plugin[:etc][:passwd]["www"]).to eq(Mash.new(shell: "/bin/false", gecos: "Serving the web since 1970", gid: 800, uid: 800, dir: "/var/www")) end it "ignores duplicate users" do expect(Etc).to receive(:passwd).and_yield(PasswdEntry.new("root", 1, 1, "/root", "/bin/zsh", "BOFH")) .and_yield(PasswdEntry.new("root", 1, 1, "/", "/bin/false", "I do not belong")) plugin.run expect(plugin[:etc][:passwd]["root"]).to eq(Mash.new(shell: "/bin/zsh", gecos: "BOFH", gid: 1, uid: 1, dir: "/root")) end it "sets the current user" do expect(Process).to receive(:euid).and_return("31337") expect(Etc).to receive(:getpwuid).and_return(PasswdEntry.new("chef", 31337, 31337, "/home/chef", "/bin/ksh", "Julia Child")) plugin.run expect(plugin[:current_user]).to eq("chef") end it "sets the available groups" do expect(Etc).to receive(:group).and_yield(GroupEntry.new("admin", 100, %w{root chef})).and_yield(GroupEntry.new("www", 800, %w{www deploy})) plugin.run expect(plugin[:etc][:group]["admin"]).to eq(Mash.new(gid: 100, members: %w{root chef})) expect(plugin[:etc][:group]["www"]).to eq(Mash.new(gid: 800, members: %w{www deploy})) end if "".respond_to?(:force_encoding) it "sets the encoding of strings to the default external encoding" do fields = ["root", 1, 1, "/root", "/bin/zsh", "BOFH"] fields.each { |f| f.force_encoding(Encoding::ASCII_8BIT) if f.respond_to?(:force_encoding) } allow(Etc).to receive(:passwd).and_yield(PasswdEntry.new(*fields)) plugin.run root = plugin[:etc][:passwd]["root"] expect(root["gecos"].encoding).to eq(Encoding.default_external) end end end ohai-16.0.7/spec/unit/plugins/perl_spec.rb000066400000000000000000000041451362624620500204320ustar00rootroot00000000000000# # Author:: Joshua Timberman() # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin perl" do let(:plugin) { get_plugin("perl") } before do plugin[:languages] = Mash.new @stdout = "version='5.8.8';#{$/}archname='darwin-thread-multi-2level';" allow(plugin).to receive(:shell_out).with("perl -V:version -V:archname").and_return(mock_shell_out(0, @stdout, "")) end it "runs perl -V:version -V:archname" do expect(plugin).to receive(:shell_out).with("perl -V:version -V:archname").and_return(mock_shell_out(0, "", "")) plugin.run end it "sets languages[:perl][:version]" do plugin.run expect(plugin.languages[:perl][:version]).to eql("5.8.8") end it "sets languages[:perl][:archname]" do plugin.run expect(plugin.languages[:perl][:archname]).to eql("darwin-thread-multi-2level") end it "sets languages[:perl] if perl command succeeds" do plugin.run expect(plugin.languages).to have_key(:perl) end it "does not set languages[:perl] if perl command fails" do allow(plugin).to receive(:shell_out).with("perl -V:version -V:archname").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:perl) end it "does not set languages[:perl] if perl command doesn't exist" do allow(plugin).to receive(:shell_out).and_raise(Ohai::Exceptions::Exec) plugin.run expect(plugin.languages).not_to have_key(:perl) end end ohai-16.0.7/spec/unit/plugins/php_spec.rb000066400000000000000000000072611362624620500202610ustar00rootroot00000000000000# # Author:: Doug MacEachern # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2009 VMware, Inc. # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin php" do let(:plugin) { get_plugin("php") } before do plugin[:languages] = Mash.new @stdout = <<~OUT PHP 5.1.6 (cli) (built: Jul 16 2008 19:52:52) Copyright (c) 1997-2006 The PHP Group Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies OUT allow(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(0, @stdout, "")) end it "gets the php version by running php -V" do expect(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(0, @stdout, "")) plugin.run end it "sets languages[:php][:version] on PHP 5.X" do plugin.run expect(plugin.languages[:php][:version]).to eql("5.1.6") end it "sets languages[:php][:version] on PHP 7.0" do stdout = <<~OUT PHP 7.0.4-7ubuntu2.1 (cli) ( NTS ) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies OUT allow(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(0, stdout, "")) plugin.run expect(plugin.languages[:php][:version]).to eql("7.0.4-7ubuntu2.1") end it "does not set the languages[:php] tree up if php command fails" do allow(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin.languages).not_to have_key(:php) end it "parses builddate even if PHP is Suhosin patched" do stdout = <<~OUT PHP 5.3.27 with Suhosin-Patch (cli) (built: Aug 30 2013 04:30:30) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies OUT allow(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(0, stdout, "")) plugin.run expect(plugin.languages[:php][:builddate]).to eql("Aug 30 2013 04:30:30") end it "does not set zend_optcache_version if not compiled with opcache" do stdout = <<~OUT PHP 5.1.6 (cli) (built: Jul 16 2008 19:52:52) Copyright (c) 1997-2006 The PHP Group Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies OUT allow(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(0, stdout, "")) plugin.run expect(plugin.languages[:php]).not_to have_key(:zend_opcache_version) end it "sets zend_optcache_version if compiled with opcache" do stdout = <<~OUT PHP 5.5.9-1ubuntu4.5 (cli) (built: Oct 29 2014 11:59:10) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies OUT allow(plugin).to receive(:shell_out).with("php -v").and_return(mock_shell_out(0, stdout, "")) plugin.run expect(plugin.languages[:php][:zend_opcache_version]).to eql("7.0.3") end end ohai-16.0.7/spec/unit/plugins/platform_spec.rb000066400000000000000000000041421362624620500213110ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin platform" do before do @plugin = get_plugin("platform") allow(@plugin).to receive(:collect_os).and_return(:default) @plugin[:os] = "monkey" @plugin[:os_version] = "poop" end it "sets the platform and platform family to the os if it was not set earlier" do @plugin.run expect(@plugin[:platform]).to eql("monkey") expect(@plugin[:platform_family]).to eql("monkey") end it "does not set the platform to the os if it was set earlier" do @plugin[:platform] = "lars" @plugin.run expect(@plugin[:platform]).to eql("lars") end it "sets the platform_family to the platform if platform was set earlier but not platform_family" do @plugin[:platform] = "lars" @plugin[:platform_family] = "jack" @plugin.run expect(@plugin[:platform_family]).to eql("jack") end it "does not set the platform_family if the platform_family was set earlier." do @plugin[:platform] = "lars" @plugin.run expect(@plugin[:platform]).to eql("lars") expect(@plugin[:platform_family]).to eql("lars") end it "sets the platform_version to the os_version if it was not set earlier" do @plugin.run expect(@plugin[:os_version]).to eql("poop") end it "does not set the platform to the os if it was set earlier" do @plugin[:platform_version] = "ulrich" @plugin.run expect(@plugin[:platform_version]).to eql("ulrich") end end ohai-16.0.7/spec/unit/plugins/powershell_spec.rb000066400000000000000000000051611362624620500216530ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2014 Chef Software, Inc # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin powershell" do let(:plugin) { get_plugin("powershell") } before do stub_const("::RbConfig::CONFIG", { "host_os" => "windows" }) end before do plugin[:languages] = Mash.new end it "sets languages[:powershell][:version] for v4" do v4_output = <<~END Name Value ---- ----- PSVersion 4.0 WSManStackVersion 3.0 SerializationVersion 1.1.0.1 CLRVersion 4.0.30319.34014 BuildVersion 6.3.9600.16394 PSCompatibleVersions {1.0, 2.0, 3.0, 4.0} PSRemotingProtocolVersion 2.2 END compat_version_array = ["1.0", "2.0", "3.0", "4.0"] allow(plugin).to receive(:shell_out).with(anything).and_return(mock_shell_out(0, v4_output, "")) allow(plugin).to receive(:parse_compatible_versions).and_return(compat_version_array) plugin.run expect(plugin.languages[:powershell][:version]).to eql("4.0") expect(plugin.languages[:powershell][:ws_man_stack_version]).to eql("3.0") expect(plugin.languages[:powershell][:serialization_version]).to eql("1.1.0.1") expect(plugin.languages[:powershell][:clr_version]).to eql("4.0.30319.34014") expect(plugin.languages[:powershell][:build_version]).to eql("6.3.9600.16394") expect(plugin.languages[:powershell][:compatible_versions]).to eql(["1.0", "2.0", "3.0", "4.0"]) expect(plugin.languages[:powershell][:remoting_protocol_version]).to eql("2.2") end it "does not set the languages[:powershell] tree up if powershell command fails" do error_output = <<~END 'powershell.exe' is not recognized as an internal or external command, operable program or batch file. END allow(plugin).to receive(:shell_out).with(anything).and_return(mock_shell_out(1, error_output, "")) plugin.run expect(plugin.languages).not_to have_key(:powershell) end end ohai-16.0.7/spec/unit/plugins/python_spec.rb000066400000000000000000000030711362624620500210060ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Theodore Nordsieck () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin python" do let(:stdout) { "2.5.2 (r252:60911, Jan 4 2009, 17:40:26)\n[GCC 4.3.2]\n" } let(:retval) { 0 } let(:plugin) do plugin = get_plugin("python") plugin[:languages] = Mash.new expect(plugin).to receive(:shell_out).with("python -c \"import sys; print (sys.version)\"").and_return(mock_shell_out(retval, stdout, "")) plugin end it "gets the python version from printing sys.version and sys.platform" do plugin.run end it "sets languages[:python][:version]" do plugin.run expect(plugin.languages[:python][:version]).to eql("2.5.2") end context "when the python command fails" do let(:retval) { 1 } it "does not set the languages[:python] tree up" do plugin.run expect(plugin.languages).not_to have_key(:python) end end end ohai-16.0.7/spec/unit/plugins/rackspace_spec.rb000066400000000000000000000276421362624620500214330ustar00rootroot00000000000000# # Author:: Cary Penniman () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "resolv" require "spec_helper" describe Ohai::System, "plugin rackspace" do let(:plugin) { get_plugin("rackspace") } before do allow(Resolv).to receive(:getname).and_return("1.2.3.4") plugin[:hostname] = "katie" plugin[:network] = { interfaces: { eth0: { "addresses" => { "1.2.3.4" => { "broadcast" => "67.23.20.255", "netmask" => "255.255.255.0", "family" => "inet", }, "2a00:1a48:7805:111:e875:efaf:ff08:75" => { "family" => "inet6", "prefixlen" => "64", "scope" => "Global", }, "fe80::4240:95ff:fe47:6eed" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "40:40:95:47:6E:ED" => { "family" => "lladdr", }, }, }, }, } plugin[:network][:interfaces][:eth1] = { addresses: { "fe80::4240:f5ff:feab:2836" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "5.6.7.8" => { "broadcast" => "10.176.191.255", "netmask" => "255.255.224.0", "family" => "inet", }, "40:40:F5:AB:28:36" => { "family" => "lladdr", }, }, } # In olden days we could detect rackspace by a -rscloud suffix on the kernel # This is here to make #has_rackspace_kernel? fail until we remove that check plugin[:kernel] = { release: "1.2.13-not-rackspace" } # We need a generic stub here for the later stubs with arguments to work # Because, magic. allow(plugin).to receive(:shell_out).and_return(mock_shell_out(1, "", "")) end shared_examples_for "!rackspace" do it "does not create rackspace attribute" do plugin.run expect(plugin[:rackspace]).to be_nil end end shared_examples_for "rackspace" do it "has rackspace attribute" do plugin.run expect(plugin[:rackspace]).not_to be_nil end it "has expected rackspace ip/hostname attributes" do plugin.run expect(plugin[:rackspace][:public_ip]).not_to be_nil expect(plugin[:rackspace][:private_ip]).not_to be_nil expect(plugin[:rackspace][:public_ipv4]).not_to be_nil expect(plugin[:rackspace][:local_ipv4]).not_to be_nil expect(plugin[:rackspace][:public_ipv6]).not_to be_nil expect(plugin[:rackspace][:local_ipv6]).to be_nil expect(plugin[:rackspace][:local_hostname]).not_to be_nil expect(plugin[:rackspace][:public_hostname]).not_to be_nil end it "resolves hostname if reverse dns is set" do allow(Resolv).to receive(:getname).and_return("1234.resolved.com") plugin.run expect(plugin[:rackspace][:public_hostname]).to eq("1234.resolved.com") end [Resolv::ResolvError, Resolv::ResolvTimeout].each do |exception| it "returns ip address when reverse dns returns exception: #{exception}" do allow(Resolv).to receive(:getname).and_raise(exception) plugin.run expect(plugin[:rackspace][:public_hostname]).to eq("1.2.3.4") end end it "has correct values for all attributes" do plugin.run expect(plugin[:rackspace][:public_ip]).to eq("1.2.3.4") expect(plugin[:rackspace][:private_ip]).to eq("5.6.7.8") expect(plugin[:rackspace][:public_ipv4]).to eq("1.2.3.4") expect(plugin[:rackspace][:local_ipv4]).to eq("5.6.7.8") expect(plugin[:rackspace][:public_ipv6]).to eq("2a00:1a48:7805:111:e875:efaf:ff08:75") expect(plugin[:rackspace][:local_hostname]).to eq("katie") expect(plugin[:rackspace][:public_hostname]).to eq("1.2.3.4") end it "captures region information" do provider_data = <<~OUT provider = "Rackspace" service_type = "cloudServers" server_id = "21301000" created_at = "2012-12-06T22:08:16Z" region = "dfw" OUT allow(plugin).to receive(:shell_out).with("xenstore-ls vm-data/provider_data").and_return(mock_shell_out(0, provider_data, "")) plugin.run expect(plugin[:rackspace][:region]).to eq("dfw") end it "logs a debug message when region info cannot be collected" do expect(plugin) .to receive(:shell_out) .with("xenstore-ls vm-data/provider_data") .and_raise(Ohai::Exceptions::Exec) expect(plugin.logger) .to receive(:trace) .with("Plugin Rackspace: Unable to find xenstore-ls, cannot capture " \ "region information for Rackspace cloud") plugin.run expect(plugin[:rackspace]).not_to have_key(:region) end it "captures instance ID information" do provider_data = "instance-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" allow(plugin).to receive(:shell_out).with("xenstore-read name").and_return(mock_shell_out(0, provider_data, "")) plugin.run expect(plugin[:rackspace][:instance_id]).to eq("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") end it "logs error if instance id cannot be found" do expect(plugin) .to receive(:shell_out) .with("xenstore-read name") .and_raise(Ohai::Exceptions::Exec) expect(plugin.logger) .to receive(:trace) .with("Plugin Rackspace: Unable to find xenstore-read, cannot capture " \ "instance ID information for Rackspace cloud") plugin.run expect(plugin[:rackspace]).not_to have_key(:instance_id) end end describe "with rackspace hint file" do before do allow(Resolv).to receive(:getname).and_raise(Resolv::ResolvError) allow(File).to receive(:exist?).with("/etc/resolv.conf").and_return(true) allow(File).to receive(:read).with("/etc/resolv.conf").and_return("") allow(plugin).to receive(:hint?).with("rackspace").and_return(true) end it_behaves_like "rackspace" describe "with no public interfaces (empty eth0)" do before do # unset public (eth0) addresses plugin[:network][:interfaces][:eth0]["addresses"] = {} end it "has correct rackspace attributes" do plugin.run # expliticly nil expect(plugin[:rackspace][:public_ip]).to be_nil expect(plugin[:rackspace][:public_ipv4]).to be_nil expect(plugin[:rackspace][:public_ipv6]).to be_nil expect(plugin[:rackspace][:public_hostname]).to be_nil # per normal expect(plugin[:rackspace][:local_ipv6]).to be_nil expect(plugin[:rackspace][:private_ip]).to eq("5.6.7.8") expect(plugin[:rackspace][:local_ipv4]).to eq("5.6.7.8") expect(plugin[:rackspace][:local_hostname]).to eq("katie") end end end describe "without hint file" do before do allow(plugin).to receive(:hint?).with("rackspace").and_return(false) end it_behaves_like "!rackspace" end describe "with Rackspace windows manufacturer data" do before do allow(plugin).to receive(:hint?).with("rackspace").and_return(false) allow(plugin).to receive(:has_rackspace_manufacturer?).and_return(true) end it "has rackspace attribute" do plugin.run expect(plugin[:rackspace]).not_to be_nil end end describe "xenstore provider returns rackspace" do before do stdout = "Rackspace\n" allow(plugin).to receive(:hint?).with("rackspace").and_return(false) allow(plugin).to receive(:shell_out).with("xenstore-read vm-data/provider_data/provider").and_return(mock_shell_out(0, stdout, "" )) end it_behaves_like "rackspace" end describe "xenstore provider does not return rackspace" do before do allow(plugin).to receive(:hint?).with("rackspace").and_return(false) stdout = "cumulonimbus\n" allow(plugin).to receive(:shell_out).with("xenstore-read vm-data/provider_data/provider").and_return(mock_shell_out(0, stdout, "" )) end it_behaves_like "!rackspace" end describe "xenstore provider does not exist" do before do allow(plugin).to receive(:hint?).with("rackspace").and_return(false) allow(plugin) .to receive(:shell_out) .with("xenstore-read vm-data/provider_data/provider") .and_raise(Ohai::Exceptions::Exec) end it_behaves_like "!rackspace" end describe "when private networks shell out fails" do it "logs an error and does not collect private_networks" do allow(plugin).to receive(:hint?).with("rackspace").and_return(true) expect(plugin) .to receive(:shell_out) .with("xenstore-ls vm-data/networking") .and_raise(Ohai::Exceptions::Exec) expect(plugin.logger) .to receive(:trace) .with("Plugin Rackspace: Unable to capture custom private networking " \ "information for Rackspace cloud") plugin.run expect(plugin[:rackspace]).not_to have_key(:private_networks) end end describe "does not have private networks" do before do stdout = 'BC764E20422B = "{"label": "public"}"\n' allow(plugin).to receive(:hint?).with("rackspace").and_return(true) allow(plugin).to receive(:shell_out).with("xenstore-ls vm-data/networking").and_return(mock_shell_out(0, stdout, "" )) stdout = '{"label": "public", "broadcast": "9.10.11.255", "ips": [{"ip": "9.10.11.12", "netmask": "255.255.255.0", "enabled": "1", "gateway": null}], "mac": "BC:76:4E:20:42:2B", "dns": ["69.20.0.164", "69.20.0.196"], "gateway": null}' allow(plugin).to receive(:shell_out).with("xenstore-read vm-data/networking/BC764E20422B").and_return(mock_shell_out(0, stdout, "" )) end it "does not have private_networks object" do plugin.run expect(plugin[:rackspace][:private_networks]).to eq([]) end end describe "has private networks" do before do plugin[:network][:interfaces][:eth2] = { addresses: { "fe80::be76:4eff:fe20:422b" => { "scope" => "Link", "prefixlen" => "64", "family" => "inet6", }, "9.10.11.12" => { "broadcast" => "9.10.11.255", "netmask" => "255.255.255.0", "family" => "inet", }, "BC:76:4E:20:42:2B" => { "family" => "lladdr", }, }, } stdout = 'BC764E20422B = "{"label": "private-network"}"\n' allow(plugin).to receive(:shell_out).with("xenstore-ls vm-data/networking").and_return(mock_shell_out(0, stdout, "" )) stdout = '{"label": "private-network", "broadcast": "9.10.11.255", "ips": [{"ip": "9.10.11.12", "netmask": "255.255.255.0", "enabled": "1", "gateway": null}], "mac": "BC:76:4E:20:42:2B", "dns": ["69.20.0.164", "69.20.0.196"], "gateway": null}' allow(plugin).to receive(:shell_out).with("xenstore-read vm-data/networking/BC764E20422B").and_return(mock_shell_out(0, stdout, "" )) allow(plugin).to receive(:hint?).with("rackspace").and_return(true) end it "has private_networks object" do plugin.run expect(plugin[:rackspace][:private_networks]).not_to be_nil end it "has correct values for all rackspace attributes" do plugin.run expect(plugin[:rackspace][:private_networks][0][:label]).to eq("private-network") expect(plugin[:rackspace][:private_networks][0][:broadcast]).to eq("9.10.11.255") expect(plugin[:rackspace][:private_networks][0][:mac]).to eq("BC:76:4E:20:42:2B") end end end ohai-16.0.7/spec/unit/plugins/root_group_spec.rb000066400000000000000000000050611362624620500216650ustar00rootroot00000000000000# # Author:: Joseph Anthony Pasquale Holsten () # Copyright:: Copyright (c) 2013 Joseph Anthony Pasquale Holsten # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "root_group" do before do @plugin = get_plugin("root_group") end describe "unix platform", :unix_only do before do # this is deeply intertwingled. unfortunately, the law of demeter # apparently didn't apply to this api. we're just trying to fake # Etc.getgrgid(Etc.getpwnam('root').gid).name @pwnam = Object.new allow(@pwnam).to receive(:gid).and_return(0) allow(Etc).to receive(:getpwnam).with("root").and_return(@pwnam) @grgid = Object.new allow(Etc).to receive(:getgrgid).and_return(@grgid) end describe "with wheel group" do before do allow(@grgid).to receive(:name).and_return("wheel") end it "has a root_group of wheel" do @plugin.run expect(@plugin[:root_group]).to eq("wheel") end end describe "with root group" do before do allow(@grgid).to receive(:name).and_return("root") end it "has a root_group of root" do @plugin.run expect(@plugin[:root_group]).to eq("root") end end describe "platform aix with system group" do before do allow(@grgid).to receive(:name).and_return("system") end it "has a root_group of system" do @plugin.run expect(@plugin[:root_group]).to eq("system") end end end describe "windows platform" do let(:wmi) { double("wmi", { query: "" }) } before do allow(WmiLite::Wmi).to receive(:new).and_return(wmi) allow(@plugin).to receive(:collect_os).and_return(:windows) end it "returns the group Administrators" do expect(wmi) .to receive(:query) .with("select * from Win32_Group where sid like 'S-1-5-32-544' and LocalAccount=True") .and_return("Administrators") @plugin.run end end end ohai-16.0.7/spec/unit/plugins/ruby_spec.rb000066400000000000000000000036741362624620500204570ustar00rootroot00000000000000# # Author:: Adam Jacob () # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" ruby_bin = File.join(::RbConfig::CONFIG["bindir"], ::RbConfig::CONFIG["ruby_install_name"]) describe Ohai::System, "plugin ruby" do before(:all) do @plugin = get_plugin("ruby") @plugin[:languages] = Mash.new @plugin.run @ruby_ohai_data_pristine = @plugin[:languages][:ruby] end before do @ruby_ohai_data = @ruby_ohai_data_pristine.dup end { platform: RUBY_PLATFORM, version: RUBY_VERSION, release_date: RUBY_RELEASE_DATE, target: ::RbConfig::CONFIG["target"], target_cpu: ::RbConfig::CONFIG["target_cpu"], target_vendor: ::RbConfig::CONFIG["target_vendor"], target_os: ::RbConfig::CONFIG["target_os"], host: ::RbConfig::CONFIG["host"], host_cpu: ::RbConfig::CONFIG["host_cpu"], host_os: ::RbConfig::CONFIG["host_os"], host_vendor: ::RbConfig::CONFIG["host_vendor"], gems_dir: `#{ruby_bin} #{::RbConfig::CONFIG["bindir"]}/gem env gemdir`.chomp, gem_bin: [ ::Gem.default_exec_format % "gem", "gem" ].map do |bin| "#{::RbConfig::CONFIG["bindir"]}/#{bin}" end.find { |bin| ::File.exist? bin }, ruby_bin: ruby_bin, }.each do |attribute, value| it "has #{attribute} set to #{value.inspect}" do expect(@ruby_ohai_data[attribute]).to eql(value) end end end ohai-16.0.7/spec/unit/plugins/rust_spec.rb000066400000000000000000000030031362624620500204550ustar00rootroot00000000000000# Author:: Christopher M Luciano () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin rust" do let(:stdout) { "rustc 1.0.0-nightly (29bd9a06e 2015-01-20 23:03:09 +0000)" } let(:plugin) do plugin = get_plugin("rust") plugin[:languages] = Mash.new allow(plugin).to receive(:shell_out).with("rustc --version").and_return(mock_shell_out(0, stdout, "")) plugin end it "gets the rust version" do expect(plugin).to receive(:shell_out).with("rustc --version").and_return(mock_shell_out(0, stdout, "")) plugin.run end it "sets languages[:rust][:version]" do plugin.run expect(plugin.languages[:rust][:version]).to eql("1.0.0-nightly") end it "does not set the languages[:rust] if rust command fails" do allow(plugin).to receive(:shell_out).with("rustc --version").and_return(mock_shell_out(1, stdout, "")) plugin.run expect(plugin.languages).not_to have_key(:rust) end end ohai-16.0.7/spec/unit/plugins/scala_spec.rb000066400000000000000000000031451362624620500205520ustar00rootroot00000000000000# Author:: Christopher M Luciano () # Β© Copyright IBM Corporation 2015. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin scala" do let(:plugin) do get_plugin("scala").tap do |plugin| plugin[:languages] = Mash.new end end let(:scala_out) { "Scala code runner version 2.11.6 -- Copyright 2002-2013, LAMP/EPFL" } def setup_plugin allow(plugin).to receive(:shell_out) .with("scala -version") .and_return(mock_shell_out(0, "", scala_out)) end context "when scala is installed" do before do setup_plugin plugin.run end it "sets languages[:scala][:version]" do expect(plugin[:languages][:scala][:version]).to eql("2.11.6") end end context "when scala is not installed" do before do allow(plugin).to receive(:shell_out) .and_raise( Ohai::Exceptions::Exec ) plugin.run end it "does NOT set the languages[:scala] if scala commands fails" do expect(plugin[:languages]).not_to have_key(:scala) end end end ohai-16.0.7/spec/unit/plugins/scaleway_spec.rb000066400000000000000000000120251362624620500212740ustar00rootroot00000000000000# # Author:: Jonathan Amiez () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin scaleway" do let(:plugin) { get_plugin("scaleway") } before do allow(plugin).to receive(:hint?).with("scaleway").and_return(false) allow(File).to receive(:read).with("/proc/cmdline").and_return(false) end shared_examples_for "!scaleway" do it "does not attempt to fetch the scaleway metadata" do expect(plugin).not_to receive(:http_client) expect(plugin[:scaleway]).to be_nil plugin.run end end shared_examples_for "scaleway" do before do @http_client = double("Net::HTTP client") allow(plugin).to receive(:http_client).and_return(@http_client) allow(IO).to receive(:select).and_return([[], [1], []]) t = double("connection") allow(t).to receive(:connect_nonblock).and_raise(Errno::EINPROGRESS) allow(Socket).to receive(:new).and_return(t) allow(Socket).to receive(:pack_sockaddr_in).and_return(nil) end let(:body) do '{"tags": [], "state_detail": "booted", "public_ip": {"dynamic": false, "id": "7564c721-a128-444e-9c95-0754a7616482", "address": "5.1.9.3"}, "ssh_public_keys": [{"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEA5qK2s41yyrNpaXXiQtb/1ADaVHVZZp9rYEtG6Dz7trOPtxkxNsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/j2C+NAzo6TZCLTbJjBf89ieazqVqhY/dMNLDJINY2Ss2ytgyiJm9bp5bYcZz441czijBlmY/qmI0cFCVOJoDq6X9Lmn/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee+hmLFaTE3FeMr1hmeZT2ChH6ruHi8m6m18SfW0fl2fS8zG4yB+WE2IawdsoZmtgtY/Re3CpvhYP9S/JxpUedl+zzzzzzzzzzzzzzzzz5+YONBAt/PWMelXThfMukbwykto6IXmsX2qflBPsRVrWe0D7vt48loVScHDv5D05ZwqWY9rizFqCx3Y8xCLr6649ieonnnjHEsSOBREU507eXVJL6njHard+s+vuTC4bNH5LiP2INQS+9MaT37/l8WzIAL3U+hvcj95HS8KfATX+7XWa54bGJgeOnPle8ojwp1ssl7ddh2yFJozgk2CkUEyE4f1lmEX2YFJGoEoaW0QC2j0nNYiLs37yHG0h84AOgjoIAJo1rxpBAGGJOgFTkgnSdHjtDZsC9WjJYeu/QpxQ7Lf2Z+FCKoypfnZz/F10/z6nxnkZ3IKKM=", "fingerprint": "4096 4c:71:db:64:cd:24:da:4a:fa:5f:9e:70:af:ea:40:6e (no comment) (RSA)"}], "private_ip": "10.8.23.7", "timezone": "UTC", "id": "77fab916-e7ff-44c6-a025-ae08837b4c4f", "extra_networks": [], "name": "sample-hostname", "hostname": "sample-hostname", "bootscript": {"kernel": "http://169.254.42.24/kernel/x86_64-4.9.20-std-1/vmlinuz-4.9.20-std-1", "title": "x86_64 4.9.20 std #1 (longterm/latest)", "default": false, "dtb": "", "public": false, "initrd": "http://169.254.42.24/initrd/initrd-Linux-x86_64-v3.12.7.gz", "bootcmdargs": "LINUX_COMMON scaleway boot=local", "architecture": "x86_64", "organization": "11111110-1112-4112-8112-111111111116", "id": "855f21ba-e7f9-421d-91b0-976a6ad59910"}, "location": {"platform_id": "21", "hypervisor_id": "518", "node_id": "4", "cluster_id": "82", "zone_id": "par1"}, "volumes": {"0": {"name": "x86_64-debian-stretch-2017-06-29_10:17", "modification_date": "2018-01-26T10:22:28.268074+00:00", "export_uri": "device://dev/vda", "volume_type": "l_ssd", "creation_date": "2018-01-26T10:22:28.268074+00:00", "organization": "90f39224-d0a2-4771-a2f0-1036a9402b97", "server": {"id": "77fab916-e7ff-44c6-a024-ae08837b4c4f", "name": "sample-hostname"}, "id": "3be53d4d-93d7-4430-a513-61cb4410624b", "size": 50000000000}}, "ipv6": null, "organization": "89f39224-d0a2-4771-a2f0-1036a9402b97", "commercial_type": "VC1S"}' end it "fetches and properly parse json metadata" do expect(@http_client).to receive(:get) .with("/conf?format=json") .and_return(double("Net::HTTP Response", body: body, code: "200")) plugin.run expect(plugin[:scaleway]).not_to be_nil expect(plugin[:scaleway]["id"]).to eq("77fab916-e7ff-44c6-a025-ae08837b4c4f") expect(plugin[:scaleway]["hostname"]).to eq("sample-hostname") end it "completes the run despite unavailable metadata" do expect(@http_client).to receive(:get) .with("/conf?format=json") .and_return(double("Net::HTTP Response", body: "", code: "404")) plugin.run expect(plugin[:scaleway]).not_to be_nil end end describe "without hint or cmdline" do it_behaves_like "!scaleway" end describe "with scaleway hint file" do before do allow(plugin).to receive(:hint?).with("scaleway").and_return(true) end it_behaves_like "scaleway" end describe "with scaleway cmdline" do before do allow(File).to receive(:read).with("/proc/cmdline").and_return("initrd=initrd showopts console=ttyS0,115200 nousb vga=0 root=/dev/vda scaleway boot=local") end it_behaves_like "scaleway" end end ohai-16.0.7/spec/unit/plugins/scsi_spec.rb000066400000000000000000000044101362624620500204240ustar00rootroot00000000000000# # Author:: Phil Dibowitz # Copyright:: Copyright (c) 2018 Facebook, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "lsscsi plugin" do let(:plugin) { get_plugin("scsi") } before do allow(plugin).to receive(:collect_os).and_return(:linux) @stdout = <<~LSSCSI [5:0:0:0] disk ATA Hitachi HUA72205 A3EA /dev/sda [6:2:0:0] disk LSI MR9286CV-8e 3.41 /dev/sdb [6:2:1:0] disk LSI MR9286CV-8e 3.41 /dev/sdc [6:2:2:0] disk LSI MR9286CV-8e 3.41 /dev/sdd [6:2:3:0] disk LSI MR9286CV-8e 3.41 /dev/sde [6:2:4:0] disk LSI MR9286CV-8e 3.41 /dev/sdf LSSCSI allow(plugin).to receive(:shell_out).with("lsscsi").and_return( mock_shell_out(0, @stdout, "") ) plugin.run end describe "when gathering data from lsscsi" do it "lists all devices" do expect(plugin[:scsi].keys).to eq( ["5:0:0:0", "6:2:0:0", "6:2:1:0", "6:2:2:0", "6:2:3:0", "6:2:4:0"] ) end it "parses out type" do expect(plugin[:scsi]["6:2:0:0"]["type"]).to eq("disk") end it "parses out transport" do expect(plugin[:scsi]["5:0:0:0"]["transport"]).to eq("ATA") expect(plugin[:scsi]["6:2:0:0"]["transport"]).to eq("LSI") end it "parses out device" do expect(plugin[:scsi]["6:2:0:0"]["device"]).to eq("/dev/sdb") end it "parses out revision" do expect(plugin[:scsi]["6:2:3:0"]["revision"]).to eq("3.41") end it "parses out name" do expect(plugin[:scsi]["5:0:0:0"]["name"]).to eq("Hitachi HUA72205") expect(plugin[:scsi]["6:2:4:0"]["name"]).to eq("MR9286CV-8e") end end end ohai-16.0.7/spec/unit/plugins/shard_spec.rb000066400000000000000000000073421362624620500205730ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "digest/md5" require "spec_helper" describe Ohai::System, "shard plugin" do subject do plugin.run plugin[:shard_seed] end let(:plugin) { get_plugin("shard") } let(:fqdn) { "somehost004.someregion.somecompany.com" } let(:uuid) { "48555CF4-5BB1-21D9-BC4C-E8B73DDE5801" } let(:serial) { "234du3m4i498xdjr2" } let(:machine_id) { "0a1f869f457a4c8080ab19faf80af9cc" } let(:machinename) { "somehost004" } let(:fips) { false } let(:os) { "linux" } before do plugin["machinename"] = machinename plugin["machine_id"] = machine_id plugin["fqdn"] = fqdn plugin["dmi"] = { "system" => {} } plugin["dmi"]["system"]["uuid"] = uuid plugin["dmi"]["system"]["serial_number"] = serial plugin["fips"] = { "kernel" => { "enabled" => fips } } allow(plugin).to receive(:collect_os).and_return(os) end it "provides a shard with a default-safe set of sources" do expect(subject).to eq(27767217) end it "provides a shard with a configured source" do Ohai.config[:plugin][:shard_seed][:sources] = [:fqdn] expect(subject).to eq(203669792) end it "fails on an unrecognized source" do Ohai.config[:plugin][:shard_seed][:sources] = [:GreatGooglyMoogly] expect { subject }.to raise_error(RuntimeError) end it "provides a shard with a configured algorithm" do Ohai.config[:plugin][:shard_seed][:digest_algorithm] = "sha256" expect(Digest::MD5).not_to receive(:new) expect(subject).to eq(117055036) end context "with Darwin OS" do let(:os) { "darwin" } before do plugin.data.delete("fips") # FIPS is undefined on Macs, make sure this still work plugin["hardware"] = { "serial_number" => serial, "platform_UUID" => uuid } end it "provides a shard with a default-safe set of sources" do expect(subject).to eq(27767217) end end context "with Windows OS" do let(:os) { "windows" } before do wmi = double("WmiLite::Wmi") allow(WmiLite::Wmi).to receive(:new).and_return(wmi) allow(wmi).to receive(:first_of).with("Win32_BIOS").and_return("SerialNumber" => serial) allow(wmi).to receive(:first_of).with("Win32_ComputerSystemProduct").and_return("UUID" => uuid) plugin["kernel"] = { "os_info" => { "serial_number" => serial + "0" } } plugin.data.delete("dmi") # To make sure we aren't using the wrong data. end it "provides a shard with a default-safe set of sources" do expect(subject).to eq(27767217) end it "allows os_serial source" do Ohai.config[:plugin][:shard_seed][:sources] = %i{machinename os_serial uuid} # Different from above. expect(subject).to eq(178738102) end end context "with a weird OS" do let(:os) { "aix" } it "provides a shard with a default-safe set of sources" do # Note: this is different than the other defaults. expect(subject).to eq(253499154) end end context "with FIPS mode enabled" do let(:fips) { true } it "uses SHA2" do expect(Digest::MD5).not_to receive(:hexdigest) expect(subject).to eq(117055036) end end end ohai-16.0.7/spec/unit/plugins/shells_spec.rb000066400000000000000000000040461362624620500207620ustar00rootroot00000000000000# # Author:: Tim Smith () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "plugin shells" do let(:plugin) { get_plugin("shells") } # content from OS X 10.11 shell_file = ["# List of acceptable shells for chpass(1).\n", "# Ftpd will not allow users to connect who are not using\n", "# one of these shells.\n", "\n", "/bin/bash\n", "/bin/csh\n", "/bin/ksh\n", "/bin/sh\n", "/bin/tcsh\n", "/bin/zsh\n"] let(:shell_file_content) { shell_file } it "does not set shells attribute if /etc/shells does not exist" do allow(::File).to receive(:exist?).with("/etc/shells").and_return(false) plugin.run expect(plugin).not_to have_key(:shells) end it "sets shells to an array of shells if /etc/shells exists" do allow(::File).to receive(:readlines).with("/etc/shells").and_return(shell_file_content) allow(::File).to receive(:exist?).with("/etc/shells").and_return(true) plugin.run expect(plugin.shells).to match_array([ "/bin/bash", "/bin/csh", "/bin/ksh", "/bin/sh", "/bin/tcsh", "/bin/zsh", ]) end end ohai-16.0.7/spec/unit/plugins/softlayer_spec.rb000066400000000000000000000045501362624620500215000ustar00rootroot00000000000000# # Author:: Alexey Karpik # Author:: Peter Schroeter # Author:: Stas Turlo # Copyright:: Copyright (c) 2010-2014 RightScale Inc # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "plugin softlayer" do let(:plugin) { get_plugin("softlayer") } it "not create softlayer if hint file doesn't exists" do allow(plugin).to receive(:hint?).with("softlayer").and_return(false) plugin.run expect(plugin[:softlayer]).to be_nil end it "do not create node if fetch_metadata raise an error" do allow(plugin).to receive(:hint?).with("softlayer").and_return(false) allow(plugin).to receive(:fetch_metadata).and_raise(StandardError.new("TEST")) plugin.run expect(plugin[:softlayer]).to be_nil end it "create empty node if fetch_metadata return empty hash" do allow(plugin).to receive(:hint?).with("softlayer").and_return(true) allow(plugin).to receive(:fetch_metadata).and_return({}) plugin.run expect(plugin[:softlayer]).to eq({}) end it "create empty node if fetch_metadata return hash with nil values" do metadata = { "local_ipv4" => nil, "public_ipv4" => nil, "public_fqdn" => nil } allow(plugin).to receive(:hint?).with("softlayer").and_return(true) allow(plugin).to receive(:fetch_metadata).and_return(metadata) plugin.run expect(plugin[:softlayer]).to eq(metadata) end it "populate softlayer node with required attributes" do metadata = { "local_ipv4" => "192.168.0.1", "public_ipv4" => "8.8.8.8", "public_fqdn" => "abc1234.public.com" } allow(plugin).to receive(:hint?).with("softlayer").and_return(true) allow(plugin).to receive(:fetch_metadata).and_return(metadata) plugin.run expect(plugin[:softlayer]).to eq(metadata) end end ohai-16.0.7/spec/unit/plugins/solaris2/000077500000000000000000000000001362624620500176635ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/solaris2/cpu_spec.rb000066400000000000000000004455271362624620500220320ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris2.X cpu plugin" do before do @plugin = get_plugin("cpu") allow(@plugin).to receive(:collect_os).and_return("solaris2") end describe "on x86 processors" do before do kstatinfo_output = <<~END cpu_info:0:cpu_info0:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:0:cpu_info0:cache_id 1 cpu_info:0:cpu_info0:chip_id 1 cpu_info:0:cpu_info0:class misc cpu_info:0:cpu_info0:clock_MHz 1933 cpu_info:0:cpu_info0:clog_id 0 cpu_info:0:cpu_info0:core_id 8 cpu_info:0:cpu_info0:cpu_type i386 cpu_info:0:cpu_info0:crtime 300.455409162 cpu_info:0:cpu_info0:current_clock_Hz 2925945978 cpu_info:0:cpu_info0:current_cstate 0 cpu_info:0:cpu_info0:family 12 cpu_info:0:cpu_info0:fpu_type i387 compatible cpu_info:0:cpu_info0:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:0:cpu_info0:model 93 cpu_info:0:cpu_info0:ncore_per_chip 4 cpu_info:0:cpu_info0:ncpu_per_chip 8 cpu_info:0:cpu_info0:pg_id 1 cpu_info:0:cpu_info0:pkg_core_id 0 cpu_info:0:cpu_info0:snaptime 12444687.9690404 cpu_info:0:cpu_info0:state off-line cpu_info:0:cpu_info0:state_begin 1427142581 cpu_info:0:cpu_info0:stepping 9 cpu_info:0:cpu_info0:supported_frequencies_Hz 2925945978 cpu_info:0:cpu_info0:supported_max_cstates 1 cpu_info:0:cpu_info0:vendor_id CrazyTown cpu_info:1:cpu_info1:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:1:cpu_info1:cache_id 0 cpu_info:1:cpu_info1:chip_id 0 cpu_info:1:cpu_info1:class misc cpu_info:1:cpu_info1:clock_MHz 2926 cpu_info:1:cpu_info1:clog_id 0 cpu_info:1:cpu_info1:core_id 0 cpu_info:1:cpu_info1:cpu_type i386 cpu_info:1:cpu_info1:crtime 308.198046165 cpu_info:1:cpu_info1:current_clock_Hz 2925945978 cpu_info:1:cpu_info1:current_cstate 1 cpu_info:1:cpu_info1:family 6 cpu_info:1:cpu_info1:fpu_type i387 compatible cpu_info:1:cpu_info1:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:1:cpu_info1:model 26 cpu_info:1:cpu_info1:ncore_per_chip 4 cpu_info:1:cpu_info1:ncpu_per_chip 8 cpu_info:1:cpu_info1:pg_id 4 cpu_info:1:cpu_info1:pkg_core_id 0 cpu_info:1:cpu_info1:snaptime 12444687.9693359 cpu_info:1:cpu_info1:state on-line cpu_info:1:cpu_info1:state_begin 1427142588 cpu_info:1:cpu_info1:stepping 5 cpu_info:1:cpu_info1:supported_frequencies_Hz 2925945978 cpu_info:1:cpu_info1:supported_max_cstates 1 cpu_info:1:cpu_info1:vendor_id GenuineIntel cpu_info:2:cpu_info2:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:2:cpu_info2:cache_id 1 cpu_info:2:cpu_info2:chip_id 1 cpu_info:2:cpu_info2:class misc cpu_info:2:cpu_info2:clock_MHz 1933 cpu_info:2:cpu_info2:clog_id 2 cpu_info:2:cpu_info2:core_id 9 cpu_info:2:cpu_info2:cpu_type i386 cpu_info:2:cpu_info2:crtime 308.280117986 cpu_info:2:cpu_info2:current_clock_Hz 2925945978 cpu_info:2:cpu_info2:current_cstate 0 cpu_info:2:cpu_info2:family 12 cpu_info:2:cpu_info2:fpu_type i387 compatible cpu_info:2:cpu_info2:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:2:cpu_info2:model 93 cpu_info:2:cpu_info2:ncore_per_chip 4 cpu_info:2:cpu_info2:ncpu_per_chip 8 cpu_info:2:cpu_info2:pg_id 7 cpu_info:2:cpu_info2:pkg_core_id 1 cpu_info:2:cpu_info2:snaptime 12444687.9695684 cpu_info:2:cpu_info2:state off-line cpu_info:2:cpu_info2:state_begin 1427142588 cpu_info:2:cpu_info2:stepping 9 cpu_info:2:cpu_info2:supported_frequencies_Hz 2925945978 cpu_info:2:cpu_info2:supported_max_cstates 1 cpu_info:2:cpu_info2:vendor_id CrazyTown cpu_info:3:cpu_info3:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:3:cpu_info3:cache_id 0 cpu_info:3:cpu_info3:chip_id 0 cpu_info:3:cpu_info3:class misc cpu_info:3:cpu_info3:clock_MHz 2926 cpu_info:3:cpu_info3:clog_id 2 cpu_info:3:cpu_info3:core_id 1 cpu_info:3:cpu_info3:cpu_type i386 cpu_info:3:cpu_info3:crtime 308.310124315 cpu_info:3:cpu_info3:current_clock_Hz 2925945978 cpu_info:3:cpu_info3:current_cstate 1 cpu_info:3:cpu_info3:family 6 cpu_info:3:cpu_info3:fpu_type i387 compatible cpu_info:3:cpu_info3:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:3:cpu_info3:model 26 cpu_info:3:cpu_info3:ncore_per_chip 4 cpu_info:3:cpu_info3:ncpu_per_chip 8 cpu_info:3:cpu_info3:pg_id 8 cpu_info:3:cpu_info3:pkg_core_id 1 cpu_info:3:cpu_info3:snaptime 12444687.9698122 cpu_info:3:cpu_info3:state on-line cpu_info:3:cpu_info3:state_begin 1427142588 cpu_info:3:cpu_info3:stepping 5 cpu_info:3:cpu_info3:supported_frequencies_Hz 2925945978 cpu_info:3:cpu_info3:supported_max_cstates 1 cpu_info:3:cpu_info3:vendor_id GenuineIntel cpu_info:4:cpu_info4:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:4:cpu_info4:cache_id 1 cpu_info:4:cpu_info4:chip_id 1 cpu_info:4:cpu_info4:class misc cpu_info:4:cpu_info4:clock_MHz 1933 cpu_info:4:cpu_info4:clog_id 4 cpu_info:4:cpu_info4:core_id 10 cpu_info:4:cpu_info4:cpu_type i386 cpu_info:4:cpu_info4:crtime 308.340112555 cpu_info:4:cpu_info4:current_clock_Hz 2925945978 cpu_info:4:cpu_info4:current_cstate 0 cpu_info:4:cpu_info4:family 12 cpu_info:4:cpu_info4:fpu_type i387 compatible cpu_info:4:cpu_info4:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:4:cpu_info4:model 93 cpu_info:4:cpu_info4:ncore_per_chip 4 cpu_info:4:cpu_info4:ncpu_per_chip 8 cpu_info:4:cpu_info4:pg_id 9 cpu_info:4:cpu_info4:pkg_core_id 2 cpu_info:4:cpu_info4:snaptime 12444687.9700613 cpu_info:4:cpu_info4:state off-line cpu_info:4:cpu_info4:state_begin 1427142588 cpu_info:4:cpu_info4:stepping 9 cpu_info:4:cpu_info4:supported_frequencies_Hz 2925945978 cpu_info:4:cpu_info4:supported_max_cstates 1 cpu_info:4:cpu_info4:vendor_id CrazyTown cpu_info:5:cpu_info5:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:5:cpu_info5:cache_id 0 cpu_info:5:cpu_info5:chip_id 0 cpu_info:5:cpu_info5:class misc cpu_info:5:cpu_info5:clock_MHz 2926 cpu_info:5:cpu_info5:clog_id 4 cpu_info:5:cpu_info5:core_id 2 cpu_info:5:cpu_info5:cpu_type i386 cpu_info:5:cpu_info5:crtime 308.370191347 cpu_info:5:cpu_info5:current_clock_Hz 2925945978 cpu_info:5:cpu_info5:current_cstate 1 cpu_info:5:cpu_info5:family 6 cpu_info:5:cpu_info5:fpu_type i387 compatible cpu_info:5:cpu_info5:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:5:cpu_info5:model 26 cpu_info:5:cpu_info5:ncore_per_chip 4 cpu_info:5:cpu_info5:ncpu_per_chip 8 cpu_info:5:cpu_info5:pg_id 10 cpu_info:5:cpu_info5:pkg_core_id 2 cpu_info:5:cpu_info5:snaptime 12444687.9702885 cpu_info:5:cpu_info5:state on-line cpu_info:5:cpu_info5:state_begin 1427142589 cpu_info:5:cpu_info5:stepping 5 cpu_info:5:cpu_info5:supported_frequencies_Hz 2925945978 cpu_info:5:cpu_info5:supported_max_cstates 1 cpu_info:5:cpu_info5:vendor_id GenuineIntel cpu_info:6:cpu_info6:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:6:cpu_info6:cache_id 1 cpu_info:6:cpu_info6:chip_id 1 cpu_info:6:cpu_info6:class misc cpu_info:6:cpu_info6:clock_MHz 1933 cpu_info:6:cpu_info6:clog_id 6 cpu_info:6:cpu_info6:core_id 11 cpu_info:6:cpu_info6:cpu_type i386 cpu_info:6:cpu_info6:crtime 308.400119134 cpu_info:6:cpu_info6:current_clock_Hz 2925945978 cpu_info:6:cpu_info6:current_cstate 1 cpu_info:6:cpu_info6:family 12 cpu_info:6:cpu_info6:fpu_type i387 compatible cpu_info:6:cpu_info6:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:6:cpu_info6:model 93 cpu_info:6:cpu_info6:ncore_per_chip 4 cpu_info:6:cpu_info6:ncpu_per_chip 8 cpu_info:6:cpu_info6:pg_id 11 cpu_info:6:cpu_info6:pkg_core_id 3 cpu_info:6:cpu_info6:snaptime 12444687.9705136 cpu_info:6:cpu_info6:state off-line cpu_info:6:cpu_info6:state_begin 1427142589 cpu_info:6:cpu_info6:stepping 9 cpu_info:6:cpu_info6:supported_frequencies_Hz 2925945978 cpu_info:6:cpu_info6:supported_max_cstates 1 cpu_info:6:cpu_info6:vendor_id CrazyTown cpu_info:7:cpu_info7:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:7:cpu_info7:cache_id 0 cpu_info:7:cpu_info7:chip_id 0 cpu_info:7:cpu_info7:class misc cpu_info:7:cpu_info7:clock_MHz 2926 cpu_info:7:cpu_info7:clog_id 6 cpu_info:7:cpu_info7:core_id 3 cpu_info:7:cpu_info7:cpu_type i386 cpu_info:7:cpu_info7:crtime 308.430139185 cpu_info:7:cpu_info7:current_clock_Hz 2925945978 cpu_info:7:cpu_info7:current_cstate 1 cpu_info:7:cpu_info7:family 6 cpu_info:7:cpu_info7:fpu_type i387 compatible cpu_info:7:cpu_info7:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:7:cpu_info7:model 26 cpu_info:7:cpu_info7:ncore_per_chip 4 cpu_info:7:cpu_info7:ncpu_per_chip 8 cpu_info:7:cpu_info7:pg_id 12 cpu_info:7:cpu_info7:pkg_core_id 3 cpu_info:7:cpu_info7:snaptime 12444687.9707517 cpu_info:7:cpu_info7:state on-line cpu_info:7:cpu_info7:state_begin 1427142589 cpu_info:7:cpu_info7:stepping 5 cpu_info:7:cpu_info7:supported_frequencies_Hz 2925945978 cpu_info:7:cpu_info7:supported_max_cstates 1 cpu_info:7:cpu_info7:vendor_id GenuineIntel cpu_info:8:cpu_info8:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:8:cpu_info8:cache_id 1 cpu_info:8:cpu_info8:chip_id 1 cpu_info:8:cpu_info8:class misc cpu_info:8:cpu_info8:clock_MHz 1933 cpu_info:8:cpu_info8:clog_id 1 cpu_info:8:cpu_info8:core_id 8 cpu_info:8:cpu_info8:cpu_type i386 cpu_info:8:cpu_info8:crtime 308.460126522 cpu_info:8:cpu_info8:current_clock_Hz 2925945978 cpu_info:8:cpu_info8:current_cstate 1 cpu_info:8:cpu_info8:family 12 cpu_info:8:cpu_info8:fpu_type i387 compatible cpu_info:8:cpu_info8:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:8:cpu_info8:model 93 cpu_info:8:cpu_info8:ncore_per_chip 4 cpu_info:8:cpu_info8:ncpu_per_chip 8 cpu_info:8:cpu_info8:pg_id 1 cpu_info:8:cpu_info8:pkg_core_id 0 cpu_info:8:cpu_info8:snaptime 12444687.9709846 cpu_info:8:cpu_info8:state off-line cpu_info:8:cpu_info8:state_begin 1427142589 cpu_info:8:cpu_info8:stepping 9 cpu_info:8:cpu_info8:supported_frequencies_Hz 2925945978 cpu_info:8:cpu_info8:supported_max_cstates 1 cpu_info:8:cpu_info8:vendor_id CrazyTown cpu_info:9:cpu_info9:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:9:cpu_info9:cache_id 0 cpu_info:9:cpu_info9:chip_id 0 cpu_info:9:cpu_info9:class misc cpu_info:9:cpu_info9:clock_MHz 2926 cpu_info:9:cpu_info9:clog_id 1 cpu_info:9:cpu_info9:core_id 0 cpu_info:9:cpu_info9:cpu_type i386 cpu_info:9:cpu_info9:crtime 308.490165484 cpu_info:9:cpu_info9:current_clock_Hz 2925945978 cpu_info:9:cpu_info9:current_cstate 1 cpu_info:9:cpu_info9:family 6 cpu_info:9:cpu_info9:fpu_type i387 compatible cpu_info:9:cpu_info9:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:9:cpu_info9:model 26 cpu_info:9:cpu_info9:ncore_per_chip 4 cpu_info:9:cpu_info9:ncpu_per_chip 8 cpu_info:9:cpu_info9:pg_id 4 cpu_info:9:cpu_info9:pkg_core_id 0 cpu_info:9:cpu_info9:snaptime 12444687.9712051 cpu_info:9:cpu_info9:state on-line cpu_info:9:cpu_info9:state_begin 1427142589 cpu_info:9:cpu_info9:stepping 5 cpu_info:9:cpu_info9:supported_frequencies_Hz 2925945978 cpu_info:9:cpu_info9:supported_max_cstates 1 cpu_info:9:cpu_info9:vendor_id GenuineIntel cpu_info:10:cpu_info10:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:10:cpu_info10:cache_id 1 cpu_info:10:cpu_info10:chip_id 1 cpu_info:10:cpu_info10:class misc cpu_info:10:cpu_info10:clock_MHz 1933 cpu_info:10:cpu_info10:clog_id 3 cpu_info:10:cpu_info10:core_id 9 cpu_info:10:cpu_info10:cpu_type i386 cpu_info:10:cpu_info10:crtime 308.520151852 cpu_info:10:cpu_info10:current_clock_Hz 2925945978 cpu_info:10:cpu_info10:current_cstate 1 cpu_info:10:cpu_info10:family 12 cpu_info:10:cpu_info10:fpu_type i387 compatible cpu_info:10:cpu_info10:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:10:cpu_info10:model 93 cpu_info:10:cpu_info10:ncore_per_chip 4 cpu_info:10:cpu_info10:ncpu_per_chip 8 cpu_info:10:cpu_info10:pg_id 7 cpu_info:10:cpu_info10:pkg_core_id 1 cpu_info:10:cpu_info10:snaptime 12444687.9714381 cpu_info:10:cpu_info10:state off-line cpu_info:10:cpu_info10:state_begin 1427142589 cpu_info:10:cpu_info10:stepping 9 cpu_info:10:cpu_info10:supported_frequencies_Hz 2925945978 cpu_info:10:cpu_info10:supported_max_cstates 1 cpu_info:10:cpu_info10:vendor_id CrazyTown cpu_info:11:cpu_info11:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:11:cpu_info11:cache_id 0 cpu_info:11:cpu_info11:chip_id 0 cpu_info:11:cpu_info11:class misc cpu_info:11:cpu_info11:clock_MHz 2926 cpu_info:11:cpu_info11:clog_id 3 cpu_info:11:cpu_info11:core_id 1 cpu_info:11:cpu_info11:cpu_type i386 cpu_info:11:cpu_info11:crtime 308.550150882 cpu_info:11:cpu_info11:current_clock_Hz 2925945978 cpu_info:11:cpu_info11:current_cstate 1 cpu_info:11:cpu_info11:family 6 cpu_info:11:cpu_info11:fpu_type i387 compatible cpu_info:11:cpu_info11:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:11:cpu_info11:model 26 cpu_info:11:cpu_info11:ncore_per_chip 4 cpu_info:11:cpu_info11:ncpu_per_chip 8 cpu_info:11:cpu_info11:pg_id 8 cpu_info:11:cpu_info11:pkg_core_id 1 cpu_info:11:cpu_info11:snaptime 12444687.9716655 cpu_info:11:cpu_info11:state on-line cpu_info:11:cpu_info11:state_begin 1427142589 cpu_info:11:cpu_info11:stepping 5 cpu_info:11:cpu_info11:supported_frequencies_Hz 2925945978 cpu_info:11:cpu_info11:supported_max_cstates 1 cpu_info:11:cpu_info11:vendor_id GenuineIntel cpu_info:12:cpu_info12:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:12:cpu_info12:cache_id 1 cpu_info:12:cpu_info12:chip_id 1 cpu_info:12:cpu_info12:class misc cpu_info:12:cpu_info12:clock_MHz 1933 cpu_info:12:cpu_info12:clog_id 5 cpu_info:12:cpu_info12:core_id 10 cpu_info:12:cpu_info12:cpu_type i386 cpu_info:12:cpu_info12:crtime 308.580146834 cpu_info:12:cpu_info12:current_clock_Hz 2925945978 cpu_info:12:cpu_info12:current_cstate 1 cpu_info:12:cpu_info12:family 12 cpu_info:12:cpu_info12:fpu_type i387 compatible cpu_info:12:cpu_info12:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:12:cpu_info12:model 93 cpu_info:12:cpu_info12:ncore_per_chip 4 cpu_info:12:cpu_info12:ncpu_per_chip 8 cpu_info:12:cpu_info12:pg_id 9 cpu_info:12:cpu_info12:pkg_core_id 2 cpu_info:12:cpu_info12:snaptime 12444687.9718927 cpu_info:12:cpu_info12:state off-line cpu_info:12:cpu_info12:state_begin 1427142589 cpu_info:12:cpu_info12:stepping 9 cpu_info:12:cpu_info12:supported_frequencies_Hz 2925945978 cpu_info:12:cpu_info12:supported_max_cstates 1 cpu_info:12:cpu_info12:vendor_id CrazyTown cpu_info:13:cpu_info13:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:13:cpu_info13:cache_id 0 cpu_info:13:cpu_info13:chip_id 0 cpu_info:13:cpu_info13:class misc cpu_info:13:cpu_info13:clock_MHz 2926 cpu_info:13:cpu_info13:clog_id 5 cpu_info:13:cpu_info13:core_id 2 cpu_info:13:cpu_info13:cpu_type i386 cpu_info:13:cpu_info13:crtime 308.610149804 cpu_info:13:cpu_info13:current_clock_Hz 2925945978 cpu_info:13:cpu_info13:current_cstate 1 cpu_info:13:cpu_info13:family 6 cpu_info:13:cpu_info13:fpu_type i387 compatible cpu_info:13:cpu_info13:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:13:cpu_info13:model 26 cpu_info:13:cpu_info13:ncore_per_chip 4 cpu_info:13:cpu_info13:ncpu_per_chip 8 cpu_info:13:cpu_info13:pg_id 10 cpu_info:13:cpu_info13:pkg_core_id 2 cpu_info:13:cpu_info13:snaptime 12444687.9721356 cpu_info:13:cpu_info13:state on-line cpu_info:13:cpu_info13:state_begin 1427142589 cpu_info:13:cpu_info13:stepping 5 cpu_info:13:cpu_info13:supported_frequencies_Hz 2925945978 cpu_info:13:cpu_info13:supported_max_cstates 1 cpu_info:13:cpu_info13:vendor_id GenuineIntel cpu_info:14:cpu_info14:brand Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz cpu_info:14:cpu_info14:cache_id 1 cpu_info:14:cpu_info14:chip_id 1 cpu_info:14:cpu_info14:class misc cpu_info:14:cpu_info14:clock_MHz 1933 cpu_info:14:cpu_info14:clog_id 7 cpu_info:14:cpu_info14:core_id 11 cpu_info:14:cpu_info14:cpu_type i386 cpu_info:14:cpu_info14:crtime 308.640144708 cpu_info:14:cpu_info14:current_clock_Hz 2925945978 cpu_info:14:cpu_info14:current_cstate 1 cpu_info:14:cpu_info14:family 12 cpu_info:14:cpu_info14:fpu_type i387 compatible cpu_info:14:cpu_info14:implementation x86 (chipid 0x1 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:14:cpu_info14:model 93 cpu_info:14:cpu_info14:ncore_per_chip 4 cpu_info:14:cpu_info14:ncpu_per_chip 8 cpu_info:14:cpu_info14:pg_id 11 cpu_info:14:cpu_info14:pkg_core_id 3 cpu_info:14:cpu_info14:snaptime 12444687.9723752 cpu_info:14:cpu_info14:state off-line cpu_info:14:cpu_info14:state_begin 1427142589 cpu_info:14:cpu_info14:stepping 9 cpu_info:14:cpu_info14:supported_frequencies_Hz 2925945978 cpu_info:14:cpu_info14:supported_max_cstates 1 cpu_info:14:cpu_info14:vendor_id CrazyTown cpu_info:15:cpu_info15:brand Intel(r) Xeon(r) CPU X5570 @ 2.93GHz cpu_info:15:cpu_info15:cache_id 0 cpu_info:15:cpu_info15:chip_id 0 cpu_info:15:cpu_info15:class misc cpu_info:15:cpu_info15:clock_MHz 2926 cpu_info:15:cpu_info15:clog_id 7 cpu_info:15:cpu_info15:core_id 3 cpu_info:15:cpu_info15:cpu_type i386 cpu_info:15:cpu_info15:crtime 308.670163124 cpu_info:15:cpu_info15:current_clock_Hz 2925945978 cpu_info:15:cpu_info15:current_cstate 1 cpu_info:15:cpu_info15:family 6 cpu_info:15:cpu_info15:fpu_type i387 compatible cpu_info:15:cpu_info15:implementation x86 (chipid 0x0 GenuineIntel family 6 model 26 step 5 clock 2926 MHz) cpu_info:15:cpu_info15:model 26 cpu_info:15:cpu_info15:ncore_per_chip 4 cpu_info:15:cpu_info15:ncpu_per_chip 8 cpu_info:15:cpu_info15:pg_id 12 cpu_info:15:cpu_info15:pkg_core_id 3 cpu_info:15:cpu_info15:snaptime 12444687.9726021 cpu_info:15:cpu_info15:state on-line cpu_info:15:cpu_info15:state_begin 1427142589 cpu_info:15:cpu_info15:stepping 5 cpu_info:15:cpu_info15:supported_frequencies_Hz 2925945978 cpu_info:15:cpu_info15:supported_max_cstates 1 cpu_info:15:cpu_info15:vendor_id GenuineIntel END allow(@plugin).to receive(:shell_out).with("kstat -p cpu_info").and_return(mock_shell_out(0, kstatinfo_output, "")) @plugin.run end it "gets the total virtual processor count" do expect(@plugin["cpu"]["total"]).to be(16) end it "gets the total processor count" do expect(@plugin["cpu"]["real"]).to be(2) end it "gets the number of threads per core" do expect(@plugin["cpu"]["corethreads"]).to be(2) end it "gets the total number of online cores" do expect(@plugin["cpu"]["cpustates"]["on-line"]).to be(8) end it "gets the total number of offline cores" do expect(@plugin["cpu"]["cpustates"]["off-line"]).to be(8) end describe "per-cpu information" do it "includes processor vendor_ids" do # CPU Socket 0 expect(@plugin["cpu"]["15"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["13"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["11"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["9"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["7"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["5"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["3"]["vendor_id"]).to eql("GenuineIntel") expect(@plugin["cpu"]["1"]["vendor_id"]).to eql("GenuineIntel") # CPU Socket 1 expect(@plugin["cpu"]["14"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["12"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["10"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["8"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["6"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["4"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["2"]["vendor_id"]).to eql("CrazyTown") expect(@plugin["cpu"]["0"]["vendor_id"]).to eql("CrazyTown") end it "includes processor families" do expect(@plugin["cpu"]["15"]["family"]).to eql("6") expect(@plugin["cpu"]["13"]["family"]).to eql("6") expect(@plugin["cpu"]["11"]["family"]).to eql("6") expect(@plugin["cpu"]["9"]["family"]).to eql("6") expect(@plugin["cpu"]["7"]["family"]).to eql("6") expect(@plugin["cpu"]["5"]["family"]).to eql("6") expect(@plugin["cpu"]["3"]["family"]).to eql("6") expect(@plugin["cpu"]["1"]["family"]).to eql("6") expect(@plugin["cpu"]["14"]["family"]).to eql("12") expect(@plugin["cpu"]["12"]["family"]).to eql("12") expect(@plugin["cpu"]["10"]["family"]).to eql("12") expect(@plugin["cpu"]["8"]["family"]).to eql("12") expect(@plugin["cpu"]["6"]["family"]).to eql("12") expect(@plugin["cpu"]["4"]["family"]).to eql("12") expect(@plugin["cpu"]["2"]["family"]).to eql("12") expect(@plugin["cpu"]["0"]["family"]).to eql("12") end it "includes processor models" do expect(@plugin["cpu"]["15"]["model"]).to eql("26") expect(@plugin["cpu"]["13"]["model"]).to eql("26") expect(@plugin["cpu"]["11"]["model"]).to eql("26") expect(@plugin["cpu"]["9"]["model"]).to eql("26") expect(@plugin["cpu"]["7"]["model"]).to eql("26") expect(@plugin["cpu"]["5"]["model"]).to eql("26") expect(@plugin["cpu"]["3"]["model"]).to eql("26") expect(@plugin["cpu"]["1"]["model"]).to eql("26") expect(@plugin["cpu"]["14"]["model"]).to eql("93") expect(@plugin["cpu"]["12"]["model"]).to eql("93") expect(@plugin["cpu"]["10"]["model"]).to eql("93") expect(@plugin["cpu"]["8"]["model"]).to eql("93") expect(@plugin["cpu"]["6"]["model"]).to eql("93") expect(@plugin["cpu"]["4"]["model"]).to eql("93") expect(@plugin["cpu"]["2"]["model"]).to eql("93") expect(@plugin["cpu"]["0"]["model"]).to eql("93") end it "includs processor architecture" do expect(@plugin["cpu"]["15"]["arch"]).to eql("i386") expect(@plugin["cpu"]["13"]["arch"]).to eql("i386") expect(@plugin["cpu"]["11"]["arch"]).to eql("i386") expect(@plugin["cpu"]["9"]["arch"]).to eql("i386") expect(@plugin["cpu"]["7"]["arch"]).to eql("i386") expect(@plugin["cpu"]["5"]["arch"]).to eql("i386") expect(@plugin["cpu"]["3"]["arch"]).to eql("i386") expect(@plugin["cpu"]["1"]["arch"]).to eql("i386") expect(@plugin["cpu"]["14"]["arch"]).to eql("i386") expect(@plugin["cpu"]["12"]["arch"]).to eql("i386") expect(@plugin["cpu"]["10"]["arch"]).to eql("i386") expect(@plugin["cpu"]["8"]["arch"]).to eql("i386") expect(@plugin["cpu"]["6"]["arch"]).to eql("i386") expect(@plugin["cpu"]["4"]["arch"]).to eql("i386") expect(@plugin["cpu"]["2"]["arch"]).to eql("i386") expect(@plugin["cpu"]["0"]["arch"]).to eql("i386") end it "includes processor stepping" do expect(@plugin["cpu"]["15"]["stepping"]).to eql("5") expect(@plugin["cpu"]["13"]["stepping"]).to eql("5") expect(@plugin["cpu"]["11"]["stepping"]).to eql("5") expect(@plugin["cpu"]["9"]["stepping"]).to eql("5") expect(@plugin["cpu"]["7"]["stepping"]).to eql("5") expect(@plugin["cpu"]["5"]["stepping"]).to eql("5") expect(@plugin["cpu"]["3"]["stepping"]).to eql("5") expect(@plugin["cpu"]["1"]["stepping"]).to eql("5") expect(@plugin["cpu"]["14"]["stepping"]).to eql("9") expect(@plugin["cpu"]["12"]["stepping"]).to eql("9") expect(@plugin["cpu"]["10"]["stepping"]).to eql("9") expect(@plugin["cpu"]["8"]["stepping"]).to eql("9") expect(@plugin["cpu"]["6"]["stepping"]).to eql("9") expect(@plugin["cpu"]["4"]["stepping"]).to eql("9") expect(@plugin["cpu"]["2"]["stepping"]).to eql("9") expect(@plugin["cpu"]["0"]["stepping"]).to eql("9") end it "includes processor model names" do expect(@plugin["cpu"]["15"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["13"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["11"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["9"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["7"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["5"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["3"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["1"]["model_name"]).to eql("Intel(r) Xeon(r) CPU X5570 @ 2.93GHz") expect(@plugin["cpu"]["14"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["12"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["10"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["8"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["6"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["4"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["2"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") expect(@plugin["cpu"]["0"]["model_name"]).to eql("Crazy(r) Argon(r) CPU Y5570 @ 1.93GHz") end it "includes processor speed in MHz" do expect(@plugin["cpu"]["15"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["13"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["11"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["9"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["7"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["5"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["3"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["1"]["mhz"]).to eql("2926") expect(@plugin["cpu"]["14"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["12"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["10"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["8"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["6"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["4"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["2"]["mhz"]).to eql("1933") expect(@plugin["cpu"]["0"]["mhz"]).to eql("1933") end it "includes processor state" do expect(@plugin["cpu"]["15"]["state"]).to eql("on-line") expect(@plugin["cpu"]["13"]["state"]).to eql("on-line") expect(@plugin["cpu"]["11"]["state"]).to eql("on-line") expect(@plugin["cpu"]["9"]["state"]).to eql("on-line") expect(@plugin["cpu"]["7"]["state"]).to eql("on-line") expect(@plugin["cpu"]["5"]["state"]).to eql("on-line") expect(@plugin["cpu"]["3"]["state"]).to eql("on-line") expect(@plugin["cpu"]["1"]["state"]).to eql("on-line") expect(@plugin["cpu"]["14"]["state"]).to eql("off-line") expect(@plugin["cpu"]["12"]["state"]).to eql("off-line") expect(@plugin["cpu"]["10"]["state"]).to eql("off-line") expect(@plugin["cpu"]["8"]["state"]).to eql("off-line") expect(@plugin["cpu"]["6"]["state"]).to eql("off-line") expect(@plugin["cpu"]["4"]["state"]).to eql("off-line") expect(@plugin["cpu"]["2"]["state"]).to eql("off-line") expect(@plugin["cpu"]["0"]["state"]).to eql("off-line") end end end describe "on sparc processors" do before do kstatinfo_output = <<~END cpu_info:0:cpu_info0:brand SPARC-T3 cpu_info:0:cpu_info0:chip_id 0 cpu_info:0:cpu_info0:class misc cpu_info:0:cpu_info0:clock_MHz 1649 cpu_info:0:cpu_info0:core_id 1026 cpu_info:0:cpu_info0:cpu_fru hc:///component= cpu_info:0:cpu_info0:cpu_type sparcv9 cpu_info:0:cpu_info0:crtime 182.755017565 cpu_info:0:cpu_info0:current_clock_Hz 1648762500 cpu_info:0:cpu_info0:device_ID 0 cpu_info:0:cpu_info0:fpu_type sparcv9 cpu_info:0:cpu_info0:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:0:cpu_info0:pg_id 1 cpu_info:0:cpu_info0:snaptime 9305222.45903973 cpu_info:0:cpu_info0:state on-line cpu_info:0:cpu_info0:state_begin 1430258900 cpu_info:0:cpu_info0:supported_frequencies_Hz 1648762500 cpu_info:1:cpu_info1:brand SPARC-T3 cpu_info:1:cpu_info1:chip_id 0 cpu_info:1:cpu_info1:class misc cpu_info:1:cpu_info1:clock_MHz 1649 cpu_info:1:cpu_info1:core_id 1026 cpu_info:1:cpu_info1:cpu_fru hc:///component= cpu_info:1:cpu_info1:cpu_type sparcv9 cpu_info:1:cpu_info1:crtime 185.891012056 cpu_info:1:cpu_info1:current_clock_Hz 1648762500 cpu_info:1:cpu_info1:device_ID 1 cpu_info:1:cpu_info1:fpu_type sparcv9 cpu_info:1:cpu_info1:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:1:cpu_info1:pg_id 1 cpu_info:1:cpu_info1:snaptime 9305222.46043854 cpu_info:1:cpu_info1:state on-line cpu_info:1:cpu_info1:state_begin 1430258903 cpu_info:1:cpu_info1:supported_frequencies_Hz 1648762500 cpu_info:2:cpu_info2:brand SPARC-T3 cpu_info:2:cpu_info2:chip_id 0 cpu_info:2:cpu_info2:class misc cpu_info:2:cpu_info2:clock_MHz 1649 cpu_info:2:cpu_info2:core_id 1026 cpu_info:2:cpu_info2:cpu_fru hc:///component= cpu_info:2:cpu_info2:cpu_type sparcv9 cpu_info:2:cpu_info2:crtime 185.89327726 cpu_info:2:cpu_info2:current_clock_Hz 1648762500 cpu_info:2:cpu_info2:device_ID 2 cpu_info:2:cpu_info2:fpu_type sparcv9 cpu_info:2:cpu_info2:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:2:cpu_info2:pg_id 1 cpu_info:2:cpu_info2:snaptime 9305222.46159979 cpu_info:2:cpu_info2:state on-line cpu_info:2:cpu_info2:state_begin 1430258903 cpu_info:2:cpu_info2:supported_frequencies_Hz 1648762500 cpu_info:3:cpu_info3:brand SPARC-T3 cpu_info:3:cpu_info3:chip_id 0 cpu_info:3:cpu_info3:class misc cpu_info:3:cpu_info3:clock_MHz 1649 cpu_info:3:cpu_info3:core_id 1026 cpu_info:3:cpu_info3:cpu_fru hc:///component= cpu_info:3:cpu_info3:cpu_type sparcv9 cpu_info:3:cpu_info3:crtime 185.895286738 cpu_info:3:cpu_info3:current_clock_Hz 1648762500 cpu_info:3:cpu_info3:device_ID 3 cpu_info:3:cpu_info3:fpu_type sparcv9 cpu_info:3:cpu_info3:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:3:cpu_info3:pg_id 1 cpu_info:3:cpu_info3:snaptime 9305222.46276104 cpu_info:3:cpu_info3:state on-line cpu_info:3:cpu_info3:state_begin 1430258903 cpu_info:3:cpu_info3:supported_frequencies_Hz 1648762500 cpu_info:4:cpu_info4:brand SPARC-T3 cpu_info:4:cpu_info4:chip_id 0 cpu_info:4:cpu_info4:class misc cpu_info:4:cpu_info4:clock_MHz 1649 cpu_info:4:cpu_info4:core_id 1026 cpu_info:4:cpu_info4:cpu_fru hc:///component= cpu_info:4:cpu_info4:cpu_type sparcv9 cpu_info:4:cpu_info4:crtime 185.897635787 cpu_info:4:cpu_info4:current_clock_Hz 1648762500 cpu_info:4:cpu_info4:device_ID 4 cpu_info:4:cpu_info4:fpu_type sparcv9 cpu_info:4:cpu_info4:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:4:cpu_info4:pg_id 4 cpu_info:4:cpu_info4:snaptime 9305222.46392368 cpu_info:4:cpu_info4:state on-line cpu_info:4:cpu_info4:state_begin 1430258903 cpu_info:4:cpu_info4:supported_frequencies_Hz 1648762500 cpu_info:5:cpu_info5:brand SPARC-T3 cpu_info:5:cpu_info5:chip_id 0 cpu_info:5:cpu_info5:class misc cpu_info:5:cpu_info5:clock_MHz 1649 cpu_info:5:cpu_info5:core_id 1026 cpu_info:5:cpu_info5:cpu_fru hc:///component= cpu_info:5:cpu_info5:cpu_type sparcv9 cpu_info:5:cpu_info5:crtime 185.899706751 cpu_info:5:cpu_info5:current_clock_Hz 1648762500 cpu_info:5:cpu_info5:device_ID 5 cpu_info:5:cpu_info5:fpu_type sparcv9 cpu_info:5:cpu_info5:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:5:cpu_info5:pg_id 4 cpu_info:5:cpu_info5:snaptime 9305222.4651017 cpu_info:5:cpu_info5:state on-line cpu_info:5:cpu_info5:state_begin 1430258903 cpu_info:5:cpu_info5:supported_frequencies_Hz 1648762500 cpu_info:6:cpu_info6:brand SPARC-T3 cpu_info:6:cpu_info6:chip_id 0 cpu_info:6:cpu_info6:class misc cpu_info:6:cpu_info6:clock_MHz 1649 cpu_info:6:cpu_info6:core_id 1026 cpu_info:6:cpu_info6:cpu_fru hc:///component= cpu_info:6:cpu_info6:cpu_type sparcv9 cpu_info:6:cpu_info6:crtime 185.901703653 cpu_info:6:cpu_info6:current_clock_Hz 1648762500 cpu_info:6:cpu_info6:device_ID 6 cpu_info:6:cpu_info6:fpu_type sparcv9 cpu_info:6:cpu_info6:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:6:cpu_info6:pg_id 4 cpu_info:6:cpu_info6:snaptime 9305222.46627134 cpu_info:6:cpu_info6:state on-line cpu_info:6:cpu_info6:state_begin 1430258903 cpu_info:6:cpu_info6:supported_frequencies_Hz 1648762500 cpu_info:7:cpu_info7:brand SPARC-T3 cpu_info:7:cpu_info7:chip_id 0 cpu_info:7:cpu_info7:class misc cpu_info:7:cpu_info7:clock_MHz 1649 cpu_info:7:cpu_info7:core_id 1026 cpu_info:7:cpu_info7:cpu_fru hc:///component= cpu_info:7:cpu_info7:cpu_type sparcv9 cpu_info:7:cpu_info7:crtime 185.903769027 cpu_info:7:cpu_info7:current_clock_Hz 1648762500 cpu_info:7:cpu_info7:device_ID 7 cpu_info:7:cpu_info7:fpu_type sparcv9 cpu_info:7:cpu_info7:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:7:cpu_info7:pg_id 4 cpu_info:7:cpu_info7:snaptime 9305222.46743538 cpu_info:7:cpu_info7:state on-line cpu_info:7:cpu_info7:state_begin 1430258903 cpu_info:7:cpu_info7:supported_frequencies_Hz 1648762500 cpu_info:8:cpu_info8:brand SPARC-T3 cpu_info:8:cpu_info8:chip_id 0 cpu_info:8:cpu_info8:class misc cpu_info:8:cpu_info8:clock_MHz 1649 cpu_info:8:cpu_info8:core_id 1033 cpu_info:8:cpu_info8:cpu_fru hc:///component= cpu_info:8:cpu_info8:cpu_type sparcv9 cpu_info:8:cpu_info8:crtime 185.905770121 cpu_info:8:cpu_info8:current_clock_Hz 1648762500 cpu_info:8:cpu_info8:device_ID 8 cpu_info:8:cpu_info8:fpu_type sparcv9 cpu_info:8:cpu_info8:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:8:cpu_info8:pg_id 5 cpu_info:8:cpu_info8:snaptime 9305222.46859244 cpu_info:8:cpu_info8:state on-line cpu_info:8:cpu_info8:state_begin 1430258903 cpu_info:8:cpu_info8:supported_frequencies_Hz 1648762500 cpu_info:9:cpu_info9:brand SPARC-T3 cpu_info:9:cpu_info9:chip_id 0 cpu_info:9:cpu_info9:class misc cpu_info:9:cpu_info9:clock_MHz 1649 cpu_info:9:cpu_info9:core_id 1033 cpu_info:9:cpu_info9:cpu_fru hc:///component= cpu_info:9:cpu_info9:cpu_type sparcv9 cpu_info:9:cpu_info9:crtime 185.907807547 cpu_info:9:cpu_info9:current_clock_Hz 1648762500 cpu_info:9:cpu_info9:device_ID 9 cpu_info:9:cpu_info9:fpu_type sparcv9 cpu_info:9:cpu_info9:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:9:cpu_info9:pg_id 5 cpu_info:9:cpu_info9:snaptime 9305222.46975928 cpu_info:9:cpu_info9:state on-line cpu_info:9:cpu_info9:state_begin 1430258903 cpu_info:9:cpu_info9:supported_frequencies_Hz 1648762500 cpu_info:10:cpu_info10:brand SPARC-T3 cpu_info:10:cpu_info10:chip_id 0 cpu_info:10:cpu_info10:class misc cpu_info:10:cpu_info10:clock_MHz 1649 cpu_info:10:cpu_info10:core_id 1033 cpu_info:10:cpu_info10:cpu_fru hc:///component= cpu_info:10:cpu_info10:cpu_type sparcv9 cpu_info:10:cpu_info10:crtime 185.909912049 cpu_info:10:cpu_info10:current_clock_Hz 1648762500 cpu_info:10:cpu_info10:device_ID 10 cpu_info:10:cpu_info10:fpu_type sparcv9 cpu_info:10:cpu_info10:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:10:cpu_info10:pg_id 5 cpu_info:10:cpu_info10:snaptime 9305222.47092053 cpu_info:10:cpu_info10:state on-line cpu_info:10:cpu_info10:state_begin 1430258903 cpu_info:10:cpu_info10:supported_frequencies_Hz 1648762500 cpu_info:11:cpu_info11:brand SPARC-T3 cpu_info:11:cpu_info11:chip_id 0 cpu_info:11:cpu_info11:class misc cpu_info:11:cpu_info11:clock_MHz 1649 cpu_info:11:cpu_info11:core_id 1033 cpu_info:11:cpu_info11:cpu_fru hc:///component= cpu_info:11:cpu_info11:cpu_type sparcv9 cpu_info:11:cpu_info11:crtime 185.912115767 cpu_info:11:cpu_info11:current_clock_Hz 1648762500 cpu_info:11:cpu_info11:device_ID 11 cpu_info:11:cpu_info11:fpu_type sparcv9 cpu_info:11:cpu_info11:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:11:cpu_info11:pg_id 5 cpu_info:11:cpu_info11:snaptime 9305222.47210972 cpu_info:11:cpu_info11:state on-line cpu_info:11:cpu_info11:state_begin 1430258903 cpu_info:11:cpu_info11:supported_frequencies_Hz 1648762500 cpu_info:12:cpu_info12:brand SPARC-T3 cpu_info:12:cpu_info12:chip_id 0 cpu_info:12:cpu_info12:class misc cpu_info:12:cpu_info12:clock_MHz 1649 cpu_info:12:cpu_info12:core_id 1033 cpu_info:12:cpu_info12:cpu_fru hc:///component= cpu_info:12:cpu_info12:cpu_type sparcv9 cpu_info:12:cpu_info12:crtime 185.914137822 cpu_info:12:cpu_info12:current_clock_Hz 1648762500 cpu_info:12:cpu_info12:device_ID 12 cpu_info:12:cpu_info12:fpu_type sparcv9 cpu_info:12:cpu_info12:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:12:cpu_info12:pg_id 7 cpu_info:12:cpu_info12:snaptime 9305222.47335901 cpu_info:12:cpu_info12:state on-line cpu_info:12:cpu_info12:state_begin 1430258903 cpu_info:12:cpu_info12:supported_frequencies_Hz 1648762500 cpu_info:13:cpu_info13:brand SPARC-T3 cpu_info:13:cpu_info13:chip_id 0 cpu_info:13:cpu_info13:class misc cpu_info:13:cpu_info13:clock_MHz 1649 cpu_info:13:cpu_info13:core_id 1033 cpu_info:13:cpu_info13:cpu_fru hc:///component= cpu_info:13:cpu_info13:cpu_type sparcv9 cpu_info:13:cpu_info13:crtime 185.916718841 cpu_info:13:cpu_info13:current_clock_Hz 1648762500 cpu_info:13:cpu_info13:device_ID 13 cpu_info:13:cpu_info13:fpu_type sparcv9 cpu_info:13:cpu_info13:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:13:cpu_info13:pg_id 7 cpu_info:13:cpu_info13:snaptime 9305222.47452166 cpu_info:13:cpu_info13:state on-line cpu_info:13:cpu_info13:state_begin 1430258903 cpu_info:13:cpu_info13:supported_frequencies_Hz 1648762500 cpu_info:14:cpu_info14:brand SPARC-T3 cpu_info:14:cpu_info14:chip_id 0 cpu_info:14:cpu_info14:class misc cpu_info:14:cpu_info14:clock_MHz 1649 cpu_info:14:cpu_info14:core_id 1033 cpu_info:14:cpu_info14:cpu_fru hc:///component= cpu_info:14:cpu_info14:cpu_type sparcv9 cpu_info:14:cpu_info14:crtime 185.918743691 cpu_info:14:cpu_info14:current_clock_Hz 1648762500 cpu_info:14:cpu_info14:device_ID 14 cpu_info:14:cpu_info14:fpu_type sparcv9 cpu_info:14:cpu_info14:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:14:cpu_info14:pg_id 7 cpu_info:14:cpu_info14:snaptime 9305222.4756871 cpu_info:14:cpu_info14:state on-line cpu_info:14:cpu_info14:state_begin 1430258903 cpu_info:14:cpu_info14:supported_frequencies_Hz 1648762500 cpu_info:15:cpu_info15:brand SPARC-T3 cpu_info:15:cpu_info15:chip_id 0 cpu_info:15:cpu_info15:class misc cpu_info:15:cpu_info15:clock_MHz 1649 cpu_info:15:cpu_info15:core_id 1033 cpu_info:15:cpu_info15:cpu_fru hc:///component= cpu_info:15:cpu_info15:cpu_type sparcv9 cpu_info:15:cpu_info15:crtime 185.920867756 cpu_info:15:cpu_info15:current_clock_Hz 1648762500 cpu_info:15:cpu_info15:device_ID 15 cpu_info:15:cpu_info15:fpu_type sparcv9 cpu_info:15:cpu_info15:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:15:cpu_info15:pg_id 7 cpu_info:15:cpu_info15:snaptime 9305222.47686092 cpu_info:15:cpu_info15:state on-line cpu_info:15:cpu_info15:state_begin 1430258903 cpu_info:15:cpu_info15:supported_frequencies_Hz 1648762500 cpu_info:16:cpu_info16:brand SPARC-T3 cpu_info:16:cpu_info16:chip_id 0 cpu_info:16:cpu_info16:class misc cpu_info:16:cpu_info16:clock_MHz 1649 cpu_info:16:cpu_info16:core_id 1040 cpu_info:16:cpu_info16:cpu_fru hc:///component= cpu_info:16:cpu_info16:cpu_type sparcv9 cpu_info:16:cpu_info16:crtime 185.923040731 cpu_info:16:cpu_info16:current_clock_Hz 1648762500 cpu_info:16:cpu_info16:device_ID 16 cpu_info:16:cpu_info16:fpu_type sparcv9 cpu_info:16:cpu_info16:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:16:cpu_info16:pg_id 8 cpu_info:16:cpu_info16:snaptime 9305222.47804034 cpu_info:16:cpu_info16:state on-line cpu_info:16:cpu_info16:state_begin 1430258903 cpu_info:16:cpu_info16:supported_frequencies_Hz 1648762500 cpu_info:17:cpu_info17:brand SPARC-T3 cpu_info:17:cpu_info17:chip_id 0 cpu_info:17:cpu_info17:class misc cpu_info:17:cpu_info17:clock_MHz 1649 cpu_info:17:cpu_info17:core_id 1040 cpu_info:17:cpu_info17:cpu_fru hc:///component= cpu_info:17:cpu_info17:cpu_type sparcv9 cpu_info:17:cpu_info17:crtime 185.925129862 cpu_info:17:cpu_info17:current_clock_Hz 1648762500 cpu_info:17:cpu_info17:device_ID 17 cpu_info:17:cpu_info17:fpu_type sparcv9 cpu_info:17:cpu_info17:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:17:cpu_info17:pg_id 8 cpu_info:17:cpu_info17:snaptime 9305222.4791974 cpu_info:17:cpu_info17:state on-line cpu_info:17:cpu_info17:state_begin 1430258903 cpu_info:17:cpu_info17:supported_frequencies_Hz 1648762500 cpu_info:18:cpu_info18:brand SPARC-T3 cpu_info:18:cpu_info18:chip_id 0 cpu_info:18:cpu_info18:class misc cpu_info:18:cpu_info18:clock_MHz 1649 cpu_info:18:cpu_info18:core_id 1040 cpu_info:18:cpu_info18:cpu_fru hc:///component= cpu_info:18:cpu_info18:cpu_type sparcv9 cpu_info:18:cpu_info18:crtime 185.927358733 cpu_info:18:cpu_info18:current_clock_Hz 1648762500 cpu_info:18:cpu_info18:device_ID 18 cpu_info:18:cpu_info18:fpu_type sparcv9 cpu_info:18:cpu_info18:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:18:cpu_info18:pg_id 8 cpu_info:18:cpu_info18:snaptime 9305222.48035585 cpu_info:18:cpu_info18:state on-line cpu_info:18:cpu_info18:state_begin 1430258903 cpu_info:18:cpu_info18:supported_frequencies_Hz 1648762500 cpu_info:19:cpu_info19:brand SPARC-T3 cpu_info:19:cpu_info19:chip_id 0 cpu_info:19:cpu_info19:class misc cpu_info:19:cpu_info19:clock_MHz 1649 cpu_info:19:cpu_info19:core_id 1040 cpu_info:19:cpu_info19:cpu_fru hc:///component= cpu_info:19:cpu_info19:cpu_type sparcv9 cpu_info:19:cpu_info19:crtime 185.929506555 cpu_info:19:cpu_info19:current_clock_Hz 1648762500 cpu_info:19:cpu_info19:device_ID 19 cpu_info:19:cpu_info19:fpu_type sparcv9 cpu_info:19:cpu_info19:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:19:cpu_info19:pg_id 8 cpu_info:19:cpu_info19:snaptime 9305222.4815143 cpu_info:19:cpu_info19:state on-line cpu_info:19:cpu_info19:state_begin 1430258903 cpu_info:19:cpu_info19:supported_frequencies_Hz 1648762500 cpu_info:20:cpu_info20:brand SPARC-T3 cpu_info:20:cpu_info20:chip_id 0 cpu_info:20:cpu_info20:class misc cpu_info:20:cpu_info20:clock_MHz 1649 cpu_info:20:cpu_info20:core_id 1040 cpu_info:20:cpu_info20:cpu_fru hc:///component= cpu_info:20:cpu_info20:cpu_type sparcv9 cpu_info:20:cpu_info20:crtime 185.931632019 cpu_info:20:cpu_info20:current_clock_Hz 1648762500 cpu_info:20:cpu_info20:device_ID 20 cpu_info:20:cpu_info20:fpu_type sparcv9 cpu_info:20:cpu_info20:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:20:cpu_info20:pg_id 10 cpu_info:20:cpu_info20:snaptime 9305222.48268953 cpu_info:20:cpu_info20:state on-line cpu_info:20:cpu_info20:state_begin 1430258903 cpu_info:20:cpu_info20:supported_frequencies_Hz 1648762500 cpu_info:21:cpu_info21:brand SPARC-T3 cpu_info:21:cpu_info21:chip_id 0 cpu_info:21:cpu_info21:class misc cpu_info:21:cpu_info21:clock_MHz 1649 cpu_info:21:cpu_info21:core_id 1040 cpu_info:21:cpu_info21:cpu_fru hc:///component= cpu_info:21:cpu_info21:cpu_type sparcv9 cpu_info:21:cpu_info21:crtime 185.933775649 cpu_info:21:cpu_info21:current_clock_Hz 1648762500 cpu_info:21:cpu_info21:device_ID 21 cpu_info:21:cpu_info21:fpu_type sparcv9 cpu_info:21:cpu_info21:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:21:cpu_info21:pg_id 10 cpu_info:21:cpu_info21:snaptime 9305222.48385497 cpu_info:21:cpu_info21:state on-line cpu_info:21:cpu_info21:state_begin 1430258903 cpu_info:21:cpu_info21:supported_frequencies_Hz 1648762500 cpu_info:22:cpu_info22:brand SPARC-T3 cpu_info:22:cpu_info22:chip_id 0 cpu_info:22:cpu_info22:class misc cpu_info:22:cpu_info22:clock_MHz 1649 cpu_info:22:cpu_info22:core_id 1040 cpu_info:22:cpu_info22:cpu_fru hc:///component= cpu_info:22:cpu_info22:cpu_type sparcv9 cpu_info:22:cpu_info22:crtime 185.935894125 cpu_info:22:cpu_info22:current_clock_Hz 1648762500 cpu_info:22:cpu_info22:device_ID 22 cpu_info:22:cpu_info22:fpu_type sparcv9 cpu_info:22:cpu_info22:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:22:cpu_info22:pg_id 10 cpu_info:22:cpu_info22:snaptime 9305222.48501202 cpu_info:22:cpu_info22:state on-line cpu_info:22:cpu_info22:state_begin 1430258903 cpu_info:22:cpu_info22:supported_frequencies_Hz 1648762500 cpu_info:23:cpu_info23:brand SPARC-T3 cpu_info:23:cpu_info23:chip_id 0 cpu_info:23:cpu_info23:class misc cpu_info:23:cpu_info23:clock_MHz 1649 cpu_info:23:cpu_info23:core_id 1040 cpu_info:23:cpu_info23:cpu_fru hc:///component= cpu_info:23:cpu_info23:cpu_type sparcv9 cpu_info:23:cpu_info23:crtime 185.938371736 cpu_info:23:cpu_info23:current_clock_Hz 1648762500 cpu_info:23:cpu_info23:device_ID 23 cpu_info:23:cpu_info23:fpu_type sparcv9 cpu_info:23:cpu_info23:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:23:cpu_info23:pg_id 10 cpu_info:23:cpu_info23:snaptime 9305222.4862152 cpu_info:23:cpu_info23:state on-line cpu_info:23:cpu_info23:state_begin 1430258903 cpu_info:23:cpu_info23:supported_frequencies_Hz 1648762500 cpu_info:24:cpu_info24:brand SPARC-T3 cpu_info:24:cpu_info24:chip_id 0 cpu_info:24:cpu_info24:class misc cpu_info:24:cpu_info24:clock_MHz 1649 cpu_info:24:cpu_info24:core_id 1047 cpu_info:24:cpu_info24:cpu_fru hc:///component= cpu_info:24:cpu_info24:cpu_type sparcv9 cpu_info:24:cpu_info24:crtime 185.94063135 cpu_info:24:cpu_info24:current_clock_Hz 1648762500 cpu_info:24:cpu_info24:device_ID 24 cpu_info:24:cpu_info24:fpu_type sparcv9 cpu_info:24:cpu_info24:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:24:cpu_info24:pg_id 11 cpu_info:24:cpu_info24:snaptime 9305222.48737505 cpu_info:24:cpu_info24:state on-line cpu_info:24:cpu_info24:state_begin 1430258903 cpu_info:24:cpu_info24:supported_frequencies_Hz 1648762500 cpu_info:25:cpu_info25:brand SPARC-T3 cpu_info:25:cpu_info25:chip_id 0 cpu_info:25:cpu_info25:class misc cpu_info:25:cpu_info25:clock_MHz 1649 cpu_info:25:cpu_info25:core_id 1047 cpu_info:25:cpu_info25:cpu_fru hc:///component= cpu_info:25:cpu_info25:cpu_type sparcv9 cpu_info:25:cpu_info25:crtime 185.942830876 cpu_info:25:cpu_info25:current_clock_Hz 1648762500 cpu_info:25:cpu_info25:device_ID 25 cpu_info:25:cpu_info25:fpu_type sparcv9 cpu_info:25:cpu_info25:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:25:cpu_info25:pg_id 11 cpu_info:25:cpu_info25:snaptime 9305222.48852791 cpu_info:25:cpu_info25:state on-line cpu_info:25:cpu_info25:state_begin 1430258903 cpu_info:25:cpu_info25:supported_frequencies_Hz 1648762500 cpu_info:26:cpu_info26:brand SPARC-T3 cpu_info:26:cpu_info26:chip_id 0 cpu_info:26:cpu_info26:class misc cpu_info:26:cpu_info26:clock_MHz 1649 cpu_info:26:cpu_info26:core_id 1047 cpu_info:26:cpu_info26:cpu_fru hc:///component= cpu_info:26:cpu_info26:cpu_type sparcv9 cpu_info:26:cpu_info26:crtime 185.945192502 cpu_info:26:cpu_info26:current_clock_Hz 1648762500 cpu_info:26:cpu_info26:device_ID 26 cpu_info:26:cpu_info26:fpu_type sparcv9 cpu_info:26:cpu_info26:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:26:cpu_info26:pg_id 11 cpu_info:26:cpu_info26:snaptime 9305222.48970872 cpu_info:26:cpu_info26:state on-line cpu_info:26:cpu_info26:state_begin 1430258903 cpu_info:26:cpu_info26:supported_frequencies_Hz 1648762500 cpu_info:27:cpu_info27:brand SPARC-T3 cpu_info:27:cpu_info27:chip_id 0 cpu_info:27:cpu_info27:class misc cpu_info:27:cpu_info27:clock_MHz 1649 cpu_info:27:cpu_info27:core_id 1047 cpu_info:27:cpu_info27:cpu_fru hc:///component= cpu_info:27:cpu_info27:cpu_type sparcv9 cpu_info:27:cpu_info27:crtime 185.947281633 cpu_info:27:cpu_info27:current_clock_Hz 1648762500 cpu_info:27:cpu_info27:device_ID 27 cpu_info:27:cpu_info27:fpu_type sparcv9 cpu_info:27:cpu_info27:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:27:cpu_info27:pg_id 11 cpu_info:27:cpu_info27:snaptime 9305222.49087556 cpu_info:27:cpu_info27:state on-line cpu_info:27:cpu_info27:state_begin 1430258903 cpu_info:27:cpu_info27:supported_frequencies_Hz 1648762500 cpu_info:28:cpu_info28:brand SPARC-T3 cpu_info:28:cpu_info28:chip_id 0 cpu_info:28:cpu_info28:class misc cpu_info:28:cpu_info28:clock_MHz 1649 cpu_info:28:cpu_info28:core_id 1047 cpu_info:28:cpu_info28:cpu_fru hc:///component= cpu_info:28:cpu_info28:cpu_type sparcv9 cpu_info:28:cpu_info28:crtime 185.949373558 cpu_info:28:cpu_info28:current_clock_Hz 1648762500 cpu_info:28:cpu_info28:device_ID 28 cpu_info:28:cpu_info28:fpu_type sparcv9 cpu_info:28:cpu_info28:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:28:cpu_info28:pg_id 13 cpu_info:28:cpu_info28:snaptime 9305222.49203402 cpu_info:28:cpu_info28:state on-line cpu_info:28:cpu_info28:state_begin 1430258903 cpu_info:28:cpu_info28:supported_frequencies_Hz 1648762500 cpu_info:29:cpu_info29:brand SPARC-T3 cpu_info:29:cpu_info29:chip_id 0 cpu_info:29:cpu_info29:class misc cpu_info:29:cpu_info29:clock_MHz 1649 cpu_info:29:cpu_info29:core_id 1047 cpu_info:29:cpu_info29:cpu_fru hc:///component= cpu_info:29:cpu_info29:cpu_type sparcv9 cpu_info:29:cpu_info29:crtime 185.951693261 cpu_info:29:cpu_info29:current_clock_Hz 1648762500 cpu_info:29:cpu_info29:device_ID 29 cpu_info:29:cpu_info29:fpu_type sparcv9 cpu_info:29:cpu_info29:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:29:cpu_info29:pg_id 13 cpu_info:29:cpu_info29:snaptime 9305222.49319247 cpu_info:29:cpu_info29:state on-line cpu_info:29:cpu_info29:state_begin 1430258903 cpu_info:29:cpu_info29:supported_frequencies_Hz 1648762500 cpu_info:30:cpu_info30:brand SPARC-T3 cpu_info:30:cpu_info30:chip_id 0 cpu_info:30:cpu_info30:class misc cpu_info:30:cpu_info30:clock_MHz 1649 cpu_info:30:cpu_info30:core_id 1047 cpu_info:30:cpu_info30:cpu_fru hc:///component= cpu_info:30:cpu_info30:cpu_type sparcv9 cpu_info:30:cpu_info30:crtime 185.956749097 cpu_info:30:cpu_info30:current_clock_Hz 1648762500 cpu_info:30:cpu_info30:device_ID 30 cpu_info:30:cpu_info30:fpu_type sparcv9 cpu_info:30:cpu_info30:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:30:cpu_info30:pg_id 13 cpu_info:30:cpu_info30:snaptime 9305222.49447669 cpu_info:30:cpu_info30:state on-line cpu_info:30:cpu_info30:state_begin 1430258903 cpu_info:30:cpu_info30:supported_frequencies_Hz 1648762500 cpu_info:31:cpu_info31:brand SPARC-T3 cpu_info:31:cpu_info31:chip_id 0 cpu_info:31:cpu_info31:class misc cpu_info:31:cpu_info31:clock_MHz 1649 cpu_info:31:cpu_info31:core_id 1047 cpu_info:31:cpu_info31:cpu_fru hc:///component= cpu_info:31:cpu_info31:cpu_type sparcv9 cpu_info:31:cpu_info31:crtime 185.958863381 cpu_info:31:cpu_info31:current_clock_Hz 1648762500 cpu_info:31:cpu_info31:device_ID 31 cpu_info:31:cpu_info31:fpu_type sparcv9 cpu_info:31:cpu_info31:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:31:cpu_info31:pg_id 13 cpu_info:31:cpu_info31:snaptime 9305222.49563934 cpu_info:31:cpu_info31:state on-line cpu_info:31:cpu_info31:state_begin 1430258903 cpu_info:31:cpu_info31:supported_frequencies_Hz 1648762500 cpu_info:32:cpu_info32:brand SPARC-T3 cpu_info:32:cpu_info32:chip_id 0 cpu_info:32:cpu_info32:class misc cpu_info:32:cpu_info32:clock_MHz 1649 cpu_info:32:cpu_info32:core_id 1054 cpu_info:32:cpu_info32:cpu_fru hc:///component= cpu_info:32:cpu_info32:cpu_type sparcv9 cpu_info:32:cpu_info32:crtime 185.961092252 cpu_info:32:cpu_info32:current_clock_Hz 1648762500 cpu_info:32:cpu_info32:device_ID 32 cpu_info:32:cpu_info32:fpu_type sparcv9 cpu_info:32:cpu_info32:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:32:cpu_info32:pg_id 14 cpu_info:32:cpu_info32:snaptime 9305222.4967978 cpu_info:32:cpu_info32:state on-line cpu_info:32:cpu_info32:state_begin 1430258903 cpu_info:32:cpu_info32:supported_frequencies_Hz 1648762500 cpu_info:33:cpu_info33:brand SPARC-T3 cpu_info:33:cpu_info33:chip_id 0 cpu_info:33:cpu_info33:class misc cpu_info:33:cpu_info33:clock_MHz 1649 cpu_info:33:cpu_info33:core_id 1054 cpu_info:33:cpu_info33:cpu_fru hc:///component= cpu_info:33:cpu_info33:cpu_type sparcv9 cpu_info:33:cpu_info33:crtime 185.96330156 cpu_info:33:cpu_info33:current_clock_Hz 1648762500 cpu_info:33:cpu_info33:device_ID 33 cpu_info:33:cpu_info33:fpu_type sparcv9 cpu_info:33:cpu_info33:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:33:cpu_info33:pg_id 14 cpu_info:33:cpu_info33:snaptime 9305222.49796044 cpu_info:33:cpu_info33:state on-line cpu_info:33:cpu_info33:state_begin 1430258903 cpu_info:33:cpu_info33:supported_frequencies_Hz 1648762500 cpu_info:34:cpu_info34:brand SPARC-T3 cpu_info:34:cpu_info34:chip_id 0 cpu_info:34:cpu_info34:class misc cpu_info:34:cpu_info34:clock_MHz 1649 cpu_info:34:cpu_info34:core_id 1054 cpu_info:34:cpu_info34:cpu_fru hc:///component= cpu_info:34:cpu_info34:cpu_type sparcv9 cpu_info:34:cpu_info34:crtime 185.965719082 cpu_info:34:cpu_info34:current_clock_Hz 1648762500 cpu_info:34:cpu_info34:device_ID 34 cpu_info:34:cpu_info34:fpu_type sparcv9 cpu_info:34:cpu_info34:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:34:cpu_info34:pg_id 14 cpu_info:34:cpu_info34:snaptime 9305222.49915942 cpu_info:34:cpu_info34:state on-line cpu_info:34:cpu_info34:state_begin 1430258903 cpu_info:34:cpu_info34:supported_frequencies_Hz 1648762500 cpu_info:35:cpu_info35:brand SPARC-T3 cpu_info:35:cpu_info35:chip_id 0 cpu_info:35:cpu_info35:class misc cpu_info:35:cpu_info35:clock_MHz 1649 cpu_info:35:cpu_info35:core_id 1054 cpu_info:35:cpu_info35:cpu_fru hc:///component= cpu_info:35:cpu_info35:cpu_type sparcv9 cpu_info:35:cpu_info35:crtime 185.967967518 cpu_info:35:cpu_info35:current_clock_Hz 1648762500 cpu_info:35:cpu_info35:device_ID 35 cpu_info:35:cpu_info35:fpu_type sparcv9 cpu_info:35:cpu_info35:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:35:cpu_info35:pg_id 14 cpu_info:35:cpu_info35:snaptime 9305222.50033744 cpu_info:35:cpu_info35:state on-line cpu_info:35:cpu_info35:state_begin 1430258903 cpu_info:35:cpu_info35:supported_frequencies_Hz 1648762500 cpu_info:36:cpu_info36:brand SPARC-T3 cpu_info:36:cpu_info36:chip_id 0 cpu_info:36:cpu_info36:class misc cpu_info:36:cpu_info36:clock_MHz 1649 cpu_info:36:cpu_info36:core_id 1054 cpu_info:36:cpu_info36:cpu_fru hc:///component= cpu_info:36:cpu_info36:cpu_type sparcv9 cpu_info:36:cpu_info36:crtime 185.970185211 cpu_info:36:cpu_info36:current_clock_Hz 1648762500 cpu_info:36:cpu_info36:device_ID 36 cpu_info:36:cpu_info36:fpu_type sparcv9 cpu_info:36:cpu_info36:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:36:cpu_info36:pg_id 16 cpu_info:36:cpu_info36:snaptime 9305222.5014931 cpu_info:36:cpu_info36:state on-line cpu_info:36:cpu_info36:state_begin 1430258903 cpu_info:36:cpu_info36:supported_frequencies_Hz 1648762500 cpu_info:37:cpu_info37:brand SPARC-T3 cpu_info:37:cpu_info37:chip_id 0 cpu_info:37:cpu_info37:class misc cpu_info:37:cpu_info37:clock_MHz 1649 cpu_info:37:cpu_info37:core_id 1054 cpu_info:37:cpu_info37:cpu_fru hc:///component= cpu_info:37:cpu_info37:cpu_type sparcv9 cpu_info:37:cpu_info37:crtime 185.972471376 cpu_info:37:cpu_info37:current_clock_Hz 1648762500 cpu_info:37:cpu_info37:device_ID 37 cpu_info:37:cpu_info37:fpu_type sparcv9 cpu_info:37:cpu_info37:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:37:cpu_info37:pg_id 16 cpu_info:37:cpu_info37:snaptime 9305222.50265574 cpu_info:37:cpu_info37:state on-line cpu_info:37:cpu_info37:state_begin 1430258903 cpu_info:37:cpu_info37:supported_frequencies_Hz 1648762500 cpu_info:38:cpu_info38:brand SPARC-T3 cpu_info:38:cpu_info38:chip_id 0 cpu_info:38:cpu_info38:class misc cpu_info:38:cpu_info38:clock_MHz 1649 cpu_info:38:cpu_info38:core_id 1054 cpu_info:38:cpu_info38:cpu_fru hc:///component= cpu_info:38:cpu_info38:cpu_type sparcv9 cpu_info:38:cpu_info38:crtime 185.974700248 cpu_info:38:cpu_info38:current_clock_Hz 1648762500 cpu_info:38:cpu_info38:device_ID 38 cpu_info:38:cpu_info38:fpu_type sparcv9 cpu_info:38:cpu_info38:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:38:cpu_info38:pg_id 16 cpu_info:38:cpu_info38:snaptime 9305222.50383516 cpu_info:38:cpu_info38:state on-line cpu_info:38:cpu_info38:state_begin 1430258903 cpu_info:38:cpu_info38:supported_frequencies_Hz 1648762500 cpu_info:39:cpu_info39:brand SPARC-T3 cpu_info:39:cpu_info39:chip_id 0 cpu_info:39:cpu_info39:class misc cpu_info:39:cpu_info39:clock_MHz 1649 cpu_info:39:cpu_info39:core_id 1054 cpu_info:39:cpu_info39:cpu_fru hc:///component= cpu_info:39:cpu_info39:cpu_type sparcv9 cpu_info:39:cpu_info39:crtime 185.976951478 cpu_info:39:cpu_info39:current_clock_Hz 1648762500 cpu_info:39:cpu_info39:device_ID 39 cpu_info:39:cpu_info39:fpu_type sparcv9 cpu_info:39:cpu_info39:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:39:cpu_info39:pg_id 16 cpu_info:39:cpu_info39:snaptime 9305222.50499082 cpu_info:39:cpu_info39:state on-line cpu_info:39:cpu_info39:state_begin 1430258903 cpu_info:39:cpu_info39:supported_frequencies_Hz 1648762500 cpu_info:40:cpu_info40:brand SPARC-T3 cpu_info:40:cpu_info40:chip_id 0 cpu_info:40:cpu_info40:class misc cpu_info:40:cpu_info40:clock_MHz 1649 cpu_info:40:cpu_info40:core_id 1061 cpu_info:40:cpu_info40:cpu_fru hc:///component= cpu_info:40:cpu_info40:cpu_type sparcv9 cpu_info:40:cpu_info40:crtime 185.979307514 cpu_info:40:cpu_info40:current_clock_Hz 1648762500 cpu_info:40:cpu_info40:device_ID 40 cpu_info:40:cpu_info40:fpu_type sparcv9 cpu_info:40:cpu_info40:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:40:cpu_info40:pg_id 17 cpu_info:40:cpu_info40:snaptime 9305222.50614788 cpu_info:40:cpu_info40:state on-line cpu_info:40:cpu_info40:state_begin 1430258903 cpu_info:40:cpu_info40:supported_frequencies_Hz 1648762500 cpu_info:41:cpu_info41:brand SPARC-T3 cpu_info:41:cpu_info41:chip_id 0 cpu_info:41:cpu_info41:class misc cpu_info:41:cpu_info41:clock_MHz 1649 cpu_info:41:cpu_info41:core_id 1061 cpu_info:41:cpu_info41:cpu_fru hc:///component= cpu_info:41:cpu_info41:cpu_type sparcv9 cpu_info:41:cpu_info41:crtime 185.981589487 cpu_info:41:cpu_info41:current_clock_Hz 1648762500 cpu_info:41:cpu_info41:device_ID 41 cpu_info:41:cpu_info41:fpu_type sparcv9 cpu_info:41:cpu_info41:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:41:cpu_info41:pg_id 17 cpu_info:41:cpu_info41:snaptime 9305222.50731052 cpu_info:41:cpu_info41:state on-line cpu_info:41:cpu_info41:state_begin 1430258903 cpu_info:41:cpu_info41:supported_frequencies_Hz 1648762500 cpu_info:42:cpu_info42:brand SPARC-T3 cpu_info:42:cpu_info42:chip_id 0 cpu_info:42:cpu_info42:class misc cpu_info:42:cpu_info42:clock_MHz 1649 cpu_info:42:cpu_info42:core_id 1061 cpu_info:42:cpu_info42:cpu_fru hc:///component= cpu_info:42:cpu_info42:cpu_type sparcv9 cpu_info:42:cpu_info42:crtime 185.983932946 cpu_info:42:cpu_info42:current_clock_Hz 1648762500 cpu_info:42:cpu_info42:device_ID 42 cpu_info:42:cpu_info42:fpu_type sparcv9 cpu_info:42:cpu_info42:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:42:cpu_info42:pg_id 17 cpu_info:42:cpu_info42:snaptime 9305222.50847177 cpu_info:42:cpu_info42:state on-line cpu_info:42:cpu_info42:state_begin 1430258903 cpu_info:42:cpu_info42:supported_frequencies_Hz 1648762500 cpu_info:43:cpu_info43:brand SPARC-T3 cpu_info:43:cpu_info43:chip_id 0 cpu_info:43:cpu_info43:class misc cpu_info:43:cpu_info43:clock_MHz 1649 cpu_info:43:cpu_info43:core_id 1061 cpu_info:43:cpu_info43:cpu_fru hc:///component= cpu_info:43:cpu_info43:cpu_type sparcv9 cpu_info:43:cpu_info43:crtime 185.986174395 cpu_info:43:cpu_info43:current_clock_Hz 1648762500 cpu_info:43:cpu_info43:device_ID 43 cpu_info:43:cpu_info43:fpu_type sparcv9 cpu_info:43:cpu_info43:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:43:cpu_info43:pg_id 17 cpu_info:43:cpu_info43:snaptime 9305222.50965119 cpu_info:43:cpu_info43:state on-line cpu_info:43:cpu_info43:state_begin 1430258903 cpu_info:43:cpu_info43:supported_frequencies_Hz 1648762500 cpu_info:44:cpu_info44:brand SPARC-T3 cpu_info:44:cpu_info44:chip_id 0 cpu_info:44:cpu_info44:class misc cpu_info:44:cpu_info44:clock_MHz 1649 cpu_info:44:cpu_info44:core_id 1061 cpu_info:44:cpu_info44:cpu_fru hc:///component= cpu_info:44:cpu_info44:cpu_type sparcv9 cpu_info:44:cpu_info44:crtime 185.988461958 cpu_info:44:cpu_info44:current_clock_Hz 1648762500 cpu_info:44:cpu_info44:device_ID 44 cpu_info:44:cpu_info44:fpu_type sparcv9 cpu_info:44:cpu_info44:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:44:cpu_info44:pg_id 19 cpu_info:44:cpu_info44:snaptime 9305222.51080685 cpu_info:44:cpu_info44:state on-line cpu_info:44:cpu_info44:state_begin 1430258903 cpu_info:44:cpu_info44:supported_frequencies_Hz 1648762500 cpu_info:45:cpu_info45:brand SPARC-T3 cpu_info:45:cpu_info45:chip_id 0 cpu_info:45:cpu_info45:class misc cpu_info:45:cpu_info45:clock_MHz 1649 cpu_info:45:cpu_info45:core_id 1061 cpu_info:45:cpu_info45:cpu_fru hc:///component= cpu_info:45:cpu_info45:cpu_type sparcv9 cpu_info:45:cpu_info45:crtime 185.990886467 cpu_info:45:cpu_info45:current_clock_Hz 1648762500 cpu_info:45:cpu_info45:device_ID 45 cpu_info:45:cpu_info45:fpu_type sparcv9 cpu_info:45:cpu_info45:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:45:cpu_info45:pg_id 19 cpu_info:45:cpu_info45:snaptime 9305222.5119667 cpu_info:45:cpu_info45:state on-line cpu_info:45:cpu_info45:state_begin 1430258903 cpu_info:45:cpu_info45:supported_frequencies_Hz 1648762500 cpu_info:46:cpu_info46:brand SPARC-T3 cpu_info:46:cpu_info46:chip_id 0 cpu_info:46:cpu_info46:class misc cpu_info:46:cpu_info46:clock_MHz 1649 cpu_info:46:cpu_info46:core_id 1061 cpu_info:46:cpu_info46:cpu_fru hc:///component= cpu_info:46:cpu_info46:cpu_type sparcv9 cpu_info:46:cpu_info46:crtime 185.993407398 cpu_info:46:cpu_info46:current_clock_Hz 1648762500 cpu_info:46:cpu_info46:device_ID 46 cpu_info:46:cpu_info46:fpu_type sparcv9 cpu_info:46:cpu_info46:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:46:cpu_info46:pg_id 19 cpu_info:46:cpu_info46:snaptime 9305222.51316568 cpu_info:46:cpu_info46:state on-line cpu_info:46:cpu_info46:state_begin 1430258903 cpu_info:46:cpu_info46:supported_frequencies_Hz 1648762500 cpu_info:47:cpu_info47:brand SPARC-T3 cpu_info:47:cpu_info47:chip_id 0 cpu_info:47:cpu_info47:class misc cpu_info:47:cpu_info47:clock_MHz 1649 cpu_info:47:cpu_info47:core_id 1061 cpu_info:47:cpu_info47:cpu_fru hc:///component= cpu_info:47:cpu_info47:cpu_type sparcv9 cpu_info:47:cpu_info47:crtime 185.995799767 cpu_info:47:cpu_info47:current_clock_Hz 1648762500 cpu_info:47:cpu_info47:device_ID 47 cpu_info:47:cpu_info47:fpu_type sparcv9 cpu_info:47:cpu_info47:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:47:cpu_info47:pg_id 19 cpu_info:47:cpu_info47:snaptime 9305222.51431994 cpu_info:47:cpu_info47:state on-line cpu_info:47:cpu_info47:state_begin 1430258903 cpu_info:47:cpu_info47:supported_frequencies_Hz 1648762500 cpu_info:48:cpu_info48:brand SPARC-T3 cpu_info:48:cpu_info48:chip_id 0 cpu_info:48:cpu_info48:class misc cpu_info:48:cpu_info48:clock_MHz 1649 cpu_info:48:cpu_info48:core_id 1068 cpu_info:48:cpu_info48:cpu_fru hc:///component= cpu_info:48:cpu_info48:cpu_type sparcv9 cpu_info:48:cpu_info48:crtime 185.998159995 cpu_info:48:cpu_info48:current_clock_Hz 1648762500 cpu_info:48:cpu_info48:device_ID 48 cpu_info:48:cpu_info48:fpu_type sparcv9 cpu_info:48:cpu_info48:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:48:cpu_info48:pg_id 20 cpu_info:48:cpu_info48:snaptime 9305222.51549656 cpu_info:48:cpu_info48:state on-line cpu_info:48:cpu_info48:state_begin 1430258903 cpu_info:48:cpu_info48:supported_frequencies_Hz 1648762500 cpu_info:49:cpu_info49:brand SPARC-T3 cpu_info:49:cpu_info49:chip_id 0 cpu_info:49:cpu_info49:class misc cpu_info:49:cpu_info49:clock_MHz 1649 cpu_info:49:cpu_info49:core_id 1068 cpu_info:49:cpu_info49:cpu_fru hc:///component= cpu_info:49:cpu_info49:cpu_type sparcv9 cpu_info:49:cpu_info49:crtime 186.000578915 cpu_info:49:cpu_info49:current_clock_Hz 1648762500 cpu_info:49:cpu_info49:device_ID 49 cpu_info:49:cpu_info49:fpu_type sparcv9 cpu_info:49:cpu_info49:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:49:cpu_info49:pg_id 20 cpu_info:49:cpu_info49:snaptime 9305222.51664943 cpu_info:49:cpu_info49:state on-line cpu_info:49:cpu_info49:state_begin 1430258903 cpu_info:49:cpu_info49:supported_frequencies_Hz 1648762500 cpu_info:50:cpu_info50:brand SPARC-T3 cpu_info:50:cpu_info50:chip_id 0 cpu_info:50:cpu_info50:class misc cpu_info:50:cpu_info50:clock_MHz 1649 cpu_info:50:cpu_info50:core_id 1068 cpu_info:50:cpu_info50:cpu_fru hc:///component= cpu_info:50:cpu_info50:cpu_type sparcv9 cpu_info:50:cpu_info50:crtime 186.002997835 cpu_info:50:cpu_info50:current_clock_Hz 1648762500 cpu_info:50:cpu_info50:device_ID 50 cpu_info:50:cpu_info50:fpu_type sparcv9 cpu_info:50:cpu_info50:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:50:cpu_info50:pg_id 20 cpu_info:50:cpu_info50:snaptime 9305222.51780229 cpu_info:50:cpu_info50:state on-line cpu_info:50:cpu_info50:state_begin 1430258903 cpu_info:50:cpu_info50:supported_frequencies_Hz 1648762500 cpu_info:51:cpu_info51:brand SPARC-T3 cpu_info:51:cpu_info51:chip_id 0 cpu_info:51:cpu_info51:class misc cpu_info:51:cpu_info51:clock_MHz 1649 cpu_info:51:cpu_info51:core_id 1068 cpu_info:51:cpu_info51:cpu_fru hc:///component= cpu_info:51:cpu_info51:cpu_type sparcv9 cpu_info:51:cpu_info51:crtime 186.005381819 cpu_info:51:cpu_info51:current_clock_Hz 1648762500 cpu_info:51:cpu_info51:device_ID 51 cpu_info:51:cpu_info51:fpu_type sparcv9 cpu_info:51:cpu_info51:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:51:cpu_info51:pg_id 20 cpu_info:51:cpu_info51:snaptime 9305222.51896214 cpu_info:51:cpu_info51:state on-line cpu_info:51:cpu_info51:state_begin 1430258903 cpu_info:51:cpu_info51:supported_frequencies_Hz 1648762500 cpu_info:52:cpu_info52:brand SPARC-T3 cpu_info:52:cpu_info52:chip_id 0 cpu_info:52:cpu_info52:class misc cpu_info:52:cpu_info52:clock_MHz 1649 cpu_info:52:cpu_info52:core_id 1068 cpu_info:52:cpu_info52:cpu_fru hc:///component= cpu_info:52:cpu_info52:cpu_type sparcv9 cpu_info:52:cpu_info52:crtime 186.007718292 cpu_info:52:cpu_info52:current_clock_Hz 1648762500 cpu_info:52:cpu_info52:device_ID 52 cpu_info:52:cpu_info52:fpu_type sparcv9 cpu_info:52:cpu_info52:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:52:cpu_info52:pg_id 22 cpu_info:52:cpu_info52:snaptime 9305222.5201206 cpu_info:52:cpu_info52:state on-line cpu_info:52:cpu_info52:state_begin 1430258903 cpu_info:52:cpu_info52:supported_frequencies_Hz 1648762500 cpu_info:53:cpu_info53:brand SPARC-T3 cpu_info:53:cpu_info53:chip_id 0 cpu_info:53:cpu_info53:class misc cpu_info:53:cpu_info53:clock_MHz 1649 cpu_info:53:cpu_info53:core_id 1068 cpu_info:53:cpu_info53:cpu_fru hc:///component= cpu_info:53:cpu_info53:cpu_type sparcv9 cpu_info:53:cpu_info53:crtime 186.010135814 cpu_info:53:cpu_info53:current_clock_Hz 1648762500 cpu_info:53:cpu_info53:device_ID 53 cpu_info:53:cpu_info53:fpu_type sparcv9 cpu_info:53:cpu_info53:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:53:cpu_info53:pg_id 22 cpu_info:53:cpu_info53:snaptime 9305222.52128464 cpu_info:53:cpu_info53:state on-line cpu_info:53:cpu_info53:state_begin 1430258903 cpu_info:53:cpu_info53:supported_frequencies_Hz 1648762500 cpu_info:54:cpu_info54:brand SPARC-T3 cpu_info:54:cpu_info54:chip_id 0 cpu_info:54:cpu_info54:class misc cpu_info:54:cpu_info54:clock_MHz 1649 cpu_info:54:cpu_info54:core_id 1068 cpu_info:54:cpu_info54:cpu_fru hc:///component= cpu_info:54:cpu_info54:cpu_type sparcv9 cpu_info:54:cpu_info54:crtime 186.012468094 cpu_info:54:cpu_info54:current_clock_Hz 1648762500 cpu_info:54:cpu_info54:device_ID 54 cpu_info:54:cpu_info54:fpu_type sparcv9 cpu_info:54:cpu_info54:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:54:cpu_info54:pg_id 22 cpu_info:54:cpu_info54:snaptime 9305222.52246266 cpu_info:54:cpu_info54:state on-line cpu_info:54:cpu_info54:state_begin 1430258903 cpu_info:54:cpu_info54:supported_frequencies_Hz 1648762500 cpu_info:55:cpu_info55:brand SPARC-T3 cpu_info:55:cpu_info55:chip_id 0 cpu_info:55:cpu_info55:class misc cpu_info:55:cpu_info55:clock_MHz 1649 cpu_info:55:cpu_info55:core_id 1068 cpu_info:55:cpu_info55:cpu_fru hc:///component= cpu_info:55:cpu_info55:cpu_type sparcv9 cpu_info:55:cpu_info55:crtime 186.015075664 cpu_info:55:cpu_info55:current_clock_Hz 1648762500 cpu_info:55:cpu_info55:device_ID 55 cpu_info:55:cpu_info55:fpu_type sparcv9 cpu_info:55:cpu_info55:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:55:cpu_info55:pg_id 22 cpu_info:55:cpu_info55:snaptime 9305222.52361692 cpu_info:55:cpu_info55:state on-line cpu_info:55:cpu_info55:state_begin 1430258903 cpu_info:55:cpu_info55:supported_frequencies_Hz 1648762500 cpu_info:56:cpu_info56:brand SPARC-T3 cpu_info:56:cpu_info56:chip_id 0 cpu_info:56:cpu_info56:class misc cpu_info:56:cpu_info56:clock_MHz 1649 cpu_info:56:cpu_info56:core_id 1075 cpu_info:56:cpu_info56:cpu_fru hc:///component= cpu_info:56:cpu_info56:cpu_type sparcv9 cpu_info:56:cpu_info56:crtime 186.01747502 cpu_info:56:cpu_info56:current_clock_Hz 1648762500 cpu_info:56:cpu_info56:device_ID 56 cpu_info:56:cpu_info56:fpu_type sparcv9 cpu_info:56:cpu_info56:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:56:cpu_info56:pg_id 23 cpu_info:56:cpu_info56:snaptime 9305222.52477957 cpu_info:56:cpu_info56:state on-line cpu_info:56:cpu_info56:state_begin 1430258903 cpu_info:56:cpu_info56:supported_frequencies_Hz 1648762500 cpu_info:57:cpu_info57:brand SPARC-T3 cpu_info:57:cpu_info57:chip_id 0 cpu_info:57:cpu_info57:class misc cpu_info:57:cpu_info57:clock_MHz 1649 cpu_info:57:cpu_info57:core_id 1075 cpu_info:57:cpu_info57:cpu_fru hc:///component= cpu_info:57:cpu_info57:cpu_type sparcv9 cpu_info:57:cpu_info57:crtime 186.019972195 cpu_info:57:cpu_info57:current_clock_Hz 1648762500 cpu_info:57:cpu_info57:device_ID 57 cpu_info:57:cpu_info57:fpu_type sparcv9 cpu_info:57:cpu_info57:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:57:cpu_info57:pg_id 23 cpu_info:57:cpu_info57:snaptime 9305222.52599671 cpu_info:57:cpu_info57:state on-line cpu_info:57:cpu_info57:state_begin 1430258903 cpu_info:57:cpu_info57:supported_frequencies_Hz 1648762500 cpu_info:58:cpu_info58:brand SPARC-T3 cpu_info:58:cpu_info58:chip_id 0 cpu_info:58:cpu_info58:class misc cpu_info:58:cpu_info58:clock_MHz 1649 cpu_info:58:cpu_info58:core_id 1075 cpu_info:58:cpu_info58:cpu_fru hc:///component= cpu_info:58:cpu_info58:cpu_type sparcv9 cpu_info:58:cpu_info58:crtime 186.022502907 cpu_info:58:cpu_info58:current_clock_Hz 1648762500 cpu_info:58:cpu_info58:device_ID 58 cpu_info:58:cpu_info58:fpu_type sparcv9 cpu_info:58:cpu_info58:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:58:cpu_info58:pg_id 23 cpu_info:58:cpu_info58:snaptime 9305222.52714958 cpu_info:58:cpu_info58:state on-line cpu_info:58:cpu_info58:state_begin 1430258903 cpu_info:58:cpu_info58:supported_frequencies_Hz 1648762500 cpu_info:59:cpu_info59:brand SPARC-T3 cpu_info:59:cpu_info59:chip_id 0 cpu_info:59:cpu_info59:class misc cpu_info:59:cpu_info59:clock_MHz 1649 cpu_info:59:cpu_info59:core_id 1075 cpu_info:59:cpu_info59:cpu_fru hc:///component= cpu_info:59:cpu_info59:cpu_type sparcv9 cpu_info:59:cpu_info59:crtime 186.024843572 cpu_info:59:cpu_info59:current_clock_Hz 1648762500 cpu_info:59:cpu_info59:device_ID 59 cpu_info:59:cpu_info59:fpu_type sparcv9 cpu_info:59:cpu_info59:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:59:cpu_info59:pg_id 23 cpu_info:59:cpu_info59:snaptime 9305222.52831362 cpu_info:59:cpu_info59:state on-line cpu_info:59:cpu_info59:state_begin 1430258903 cpu_info:59:cpu_info59:supported_frequencies_Hz 1648762500 cpu_info:60:cpu_info60:brand SPARC-T3 cpu_info:60:cpu_info60:chip_id 0 cpu_info:60:cpu_info60:class misc cpu_info:60:cpu_info60:clock_MHz 1649 cpu_info:60:cpu_info60:core_id 1075 cpu_info:60:cpu_info60:cpu_fru hc:///component= cpu_info:60:cpu_info60:cpu_type sparcv9 cpu_info:60:cpu_info60:crtime 186.027181442 cpu_info:60:cpu_info60:current_clock_Hz 1648762500 cpu_info:60:cpu_info60:device_ID 60 cpu_info:60:cpu_info60:fpu_type sparcv9 cpu_info:60:cpu_info60:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:60:cpu_info60:pg_id 25 cpu_info:60:cpu_info60:snaptime 9305222.52947487 cpu_info:60:cpu_info60:state on-line cpu_info:60:cpu_info60:state_begin 1430258903 cpu_info:60:cpu_info60:supported_frequencies_Hz 1648762500 cpu_info:61:cpu_info61:brand SPARC-T3 cpu_info:61:cpu_info61:chip_id 0 cpu_info:61:cpu_info61:class misc cpu_info:61:cpu_info61:clock_MHz 1649 cpu_info:61:cpu_info61:core_id 1075 cpu_info:61:cpu_info61:cpu_fru hc:///component= cpu_info:61:cpu_info61:cpu_type sparcv9 cpu_info:61:cpu_info61:crtime 186.029607348 cpu_info:61:cpu_info61:current_clock_Hz 1648762500 cpu_info:61:cpu_info61:device_ID 61 cpu_info:61:cpu_info61:fpu_type sparcv9 cpu_info:61:cpu_info61:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:61:cpu_info61:pg_id 25 cpu_info:61:cpu_info61:snaptime 9305222.53065289 cpu_info:61:cpu_info61:state on-line cpu_info:61:cpu_info61:state_begin 1430258903 cpu_info:61:cpu_info61:supported_frequencies_Hz 1648762500 cpu_info:62:cpu_info62:brand SPARC-T3 cpu_info:62:cpu_info62:chip_id 0 cpu_info:62:cpu_info62:class misc cpu_info:62:cpu_info62:clock_MHz 1649 cpu_info:62:cpu_info62:core_id 1075 cpu_info:62:cpu_info62:cpu_fru hc:///component= cpu_info:62:cpu_info62:cpu_type sparcv9 cpu_info:62:cpu_info62:crtime 186.032326712 cpu_info:62:cpu_info62:current_clock_Hz 1648762500 cpu_info:62:cpu_info62:device_ID 62 cpu_info:62:cpu_info62:fpu_type sparcv9 cpu_info:62:cpu_info62:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:62:cpu_info62:pg_id 25 cpu_info:62:cpu_info62:snaptime 9305222.53182811 cpu_info:62:cpu_info62:state on-line cpu_info:62:cpu_info62:state_begin 1430258903 cpu_info:62:cpu_info62:supported_frequencies_Hz 1648762500 cpu_info:63:cpu_info63:brand SPARC-T3 cpu_info:63:cpu_info63:chip_id 0 cpu_info:63:cpu_info63:class misc cpu_info:63:cpu_info63:clock_MHz 1649 cpu_info:63:cpu_info63:core_id 1075 cpu_info:63:cpu_info63:cpu_fru hc:///component= cpu_info:63:cpu_info63:cpu_type sparcv9 cpu_info:63:cpu_info63:crtime 186.034794541 cpu_info:63:cpu_info63:current_clock_Hz 1648762500 cpu_info:63:cpu_info63:device_ID 63 cpu_info:63:cpu_info63:fpu_type sparcv9 cpu_info:63:cpu_info63:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:63:cpu_info63:pg_id 25 cpu_info:63:cpu_info63:snaptime 9305222.53301871 cpu_info:63:cpu_info63:state on-line cpu_info:63:cpu_info63:state_begin 1430258903 cpu_info:63:cpu_info63:supported_frequencies_Hz 1648762500 cpu_info:64:cpu_info64:brand SPARC-T3 cpu_info:64:cpu_info64:chip_id 0 cpu_info:64:cpu_info64:class misc cpu_info:64:cpu_info64:clock_MHz 1649 cpu_info:64:cpu_info64:core_id 1082 cpu_info:64:cpu_info64:cpu_fru hc:///component= cpu_info:64:cpu_info64:cpu_type sparcv9 cpu_info:64:cpu_info64:crtime 186.037253985 cpu_info:64:cpu_info64:current_clock_Hz 1648762500 cpu_info:64:cpu_info64:device_ID 64 cpu_info:64:cpu_info64:fpu_type sparcv9 cpu_info:64:cpu_info64:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:64:cpu_info64:pg_id 26 cpu_info:64:cpu_info64:snaptime 9305222.53418415 cpu_info:64:cpu_info64:state on-line cpu_info:64:cpu_info64:state_begin 1430258903 cpu_info:64:cpu_info64:supported_frequencies_Hz 1648762500 cpu_info:65:cpu_info65:brand SPARC-T3 cpu_info:65:cpu_info65:chip_id 0 cpu_info:65:cpu_info65:class misc cpu_info:65:cpu_info65:clock_MHz 1649 cpu_info:65:cpu_info65:core_id 1082 cpu_info:65:cpu_info65:cpu_fru hc:///component= cpu_info:65:cpu_info65:cpu_type sparcv9 cpu_info:65:cpu_info65:crtime 186.039909068 cpu_info:65:cpu_info65:current_clock_Hz 1648762500 cpu_info:65:cpu_info65:device_ID 65 cpu_info:65:cpu_info65:fpu_type sparcv9 cpu_info:65:cpu_info65:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:65:cpu_info65:pg_id 26 cpu_info:65:cpu_info65:snaptime 9305222.53533841 cpu_info:65:cpu_info65:state on-line cpu_info:65:cpu_info65:state_begin 1430258903 cpu_info:65:cpu_info65:supported_frequencies_Hz 1648762500 cpu_info:66:cpu_info66:brand SPARC-T3 cpu_info:66:cpu_info66:chip_id 0 cpu_info:66:cpu_info66:class misc cpu_info:66:cpu_info66:clock_MHz 1649 cpu_info:66:cpu_info66:core_id 1082 cpu_info:66:cpu_info66:cpu_fru hc:///component= cpu_info:66:cpu_info66:cpu_type sparcv9 cpu_info:66:cpu_info66:crtime 186.042333577 cpu_info:66:cpu_info66:current_clock_Hz 1648762500 cpu_info:66:cpu_info66:device_ID 66 cpu_info:66:cpu_info66:fpu_type sparcv9 cpu_info:66:cpu_info66:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:66:cpu_info66:pg_id 26 cpu_info:66:cpu_info66:snaptime 9305222.53649127 cpu_info:66:cpu_info66:state on-line cpu_info:66:cpu_info66:state_begin 1430258903 cpu_info:66:cpu_info66:supported_frequencies_Hz 1648762500 cpu_info:67:cpu_info67:brand SPARC-T3 cpu_info:67:cpu_info67:chip_id 0 cpu_info:67:cpu_info67:class misc cpu_info:67:cpu_info67:clock_MHz 1649 cpu_info:67:cpu_info67:core_id 1082 cpu_info:67:cpu_info67:cpu_fru hc:///component= cpu_info:67:cpu_info67:cpu_type sparcv9 cpu_info:67:cpu_info67:crtime 186.044874071 cpu_info:67:cpu_info67:current_clock_Hz 1648762500 cpu_info:67:cpu_info67:device_ID 67 cpu_info:67:cpu_info67:fpu_type sparcv9 cpu_info:67:cpu_info67:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:67:cpu_info67:pg_id 26 cpu_info:67:cpu_info67:snaptime 9305222.53778388 cpu_info:67:cpu_info67:state on-line cpu_info:67:cpu_info67:state_begin 1430258903 cpu_info:67:cpu_info67:supported_frequencies_Hz 1648762500 cpu_info:68:cpu_info68:brand SPARC-T3 cpu_info:68:cpu_info68:chip_id 0 cpu_info:68:cpu_info68:class misc cpu_info:68:cpu_info68:clock_MHz 1649 cpu_info:68:cpu_info68:core_id 1082 cpu_info:68:cpu_info68:cpu_fru hc:///component= cpu_info:68:cpu_info68:cpu_type sparcv9 cpu_info:68:cpu_info68:crtime 186.047410374 cpu_info:68:cpu_info68:current_clock_Hz 1648762500 cpu_info:68:cpu_info68:device_ID 68 cpu_info:68:cpu_info68:fpu_type sparcv9 cpu_info:68:cpu_info68:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:68:cpu_info68:pg_id 28 cpu_info:68:cpu_info68:snaptime 9305222.53897727 cpu_info:68:cpu_info68:state on-line cpu_info:68:cpu_info68:state_begin 1430258903 cpu_info:68:cpu_info68:supported_frequencies_Hz 1648762500 cpu_info:69:cpu_info69:brand SPARC-T3 cpu_info:69:cpu_info69:chip_id 0 cpu_info:69:cpu_info69:class misc cpu_info:69:cpu_info69:clock_MHz 1649 cpu_info:69:cpu_info69:core_id 1082 cpu_info:69:cpu_info69:cpu_fru hc:///component= cpu_info:69:cpu_info69:cpu_type sparcv9 cpu_info:69:cpu_info69:crtime 186.049833485 cpu_info:69:cpu_info69:current_clock_Hz 1648762500 cpu_info:69:cpu_info69:device_ID 69 cpu_info:69:cpu_info69:fpu_type sparcv9 cpu_info:69:cpu_info69:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:69:cpu_info69:pg_id 28 cpu_info:69:cpu_info69:snaptime 9305222.54013852 cpu_info:69:cpu_info69:state on-line cpu_info:69:cpu_info69:state_begin 1430258903 cpu_info:69:cpu_info69:supported_frequencies_Hz 1648762500 cpu_info:70:cpu_info70:brand SPARC-T3 cpu_info:70:cpu_info70:chip_id 0 cpu_info:70:cpu_info70:class misc cpu_info:70:cpu_info70:clock_MHz 1649 cpu_info:70:cpu_info70:core_id 1082 cpu_info:70:cpu_info70:cpu_fru hc:///component= cpu_info:70:cpu_info70:cpu_type sparcv9 cpu_info:70:cpu_info70:crtime 186.052309698 cpu_info:70:cpu_info70:current_clock_Hz 1648762500 cpu_info:70:cpu_info70:device_ID 70 cpu_info:70:cpu_info70:fpu_type sparcv9 cpu_info:70:cpu_info70:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:70:cpu_info70:pg_id 28 cpu_info:70:cpu_info70:snaptime 9305222.54131234 cpu_info:70:cpu_info70:state on-line cpu_info:70:cpu_info70:state_begin 1430258903 cpu_info:70:cpu_info70:supported_frequencies_Hz 1648762500 cpu_info:71:cpu_info71:brand SPARC-T3 cpu_info:71:cpu_info71:chip_id 0 cpu_info:71:cpu_info71:class misc cpu_info:71:cpu_info71:clock_MHz 1649 cpu_info:71:cpu_info71:core_id 1082 cpu_info:71:cpu_info71:cpu_fru hc:///component= cpu_info:71:cpu_info71:cpu_type sparcv9 cpu_info:71:cpu_info71:crtime 186.054795694 cpu_info:71:cpu_info71:current_clock_Hz 1648762500 cpu_info:71:cpu_info71:device_ID 71 cpu_info:71:cpu_info71:fpu_type sparcv9 cpu_info:71:cpu_info71:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:71:cpu_info71:pg_id 28 cpu_info:71:cpu_info71:snaptime 9305222.54247779 cpu_info:71:cpu_info71:state on-line cpu_info:71:cpu_info71:state_begin 1430258903 cpu_info:71:cpu_info71:supported_frequencies_Hz 1648762500 cpu_info:72:cpu_info72:brand SPARC-T3 cpu_info:72:cpu_info72:chip_id 0 cpu_info:72:cpu_info72:class misc cpu_info:72:cpu_info72:clock_MHz 1649 cpu_info:72:cpu_info72:core_id 1089 cpu_info:72:cpu_info72:cpu_fru hc:///component= cpu_info:72:cpu_info72:cpu_type sparcv9 cpu_info:72:cpu_info72:crtime 186.059253437 cpu_info:72:cpu_info72:current_clock_Hz 1648762500 cpu_info:72:cpu_info72:device_ID 72 cpu_info:72:cpu_info72:fpu_type sparcv9 cpu_info:72:cpu_info72:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:72:cpu_info72:pg_id 29 cpu_info:72:cpu_info72:snaptime 9305222.54363624 cpu_info:72:cpu_info72:state on-line cpu_info:72:cpu_info72:state_begin 1430258903 cpu_info:72:cpu_info72:supported_frequencies_Hz 1648762500 cpu_info:73:cpu_info73:brand SPARC-T3 cpu_info:73:cpu_info73:chip_id 0 cpu_info:73:cpu_info73:class misc cpu_info:73:cpu_info73:clock_MHz 1649 cpu_info:73:cpu_info73:core_id 1089 cpu_info:73:cpu_info73:cpu_fru hc:///component= cpu_info:73:cpu_info73:cpu_type sparcv9 cpu_info:73:cpu_info73:crtime 186.062956578 cpu_info:73:cpu_info73:current_clock_Hz 1648762500 cpu_info:73:cpu_info73:device_ID 73 cpu_info:73:cpu_info73:fpu_type sparcv9 cpu_info:73:cpu_info73:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:73:cpu_info73:pg_id 29 cpu_info:73:cpu_info73:snaptime 9305222.54479609 cpu_info:73:cpu_info73:state on-line cpu_info:73:cpu_info73:state_begin 1430258903 cpu_info:73:cpu_info73:supported_frequencies_Hz 1648762500 cpu_info:74:cpu_info74:brand SPARC-T3 cpu_info:74:cpu_info74:chip_id 0 cpu_info:74:cpu_info74:class misc cpu_info:74:cpu_info74:clock_MHz 1649 cpu_info:74:cpu_info74:core_id 1089 cpu_info:74:cpu_info74:cpu_fru hc:///component= cpu_info:74:cpu_info74:cpu_type sparcv9 cpu_info:74:cpu_info74:crtime 186.066589848 cpu_info:74:cpu_info74:current_clock_Hz 1648762500 cpu_info:74:cpu_info74:device_ID 74 cpu_info:74:cpu_info74:fpu_type sparcv9 cpu_info:74:cpu_info74:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:74:cpu_info74:pg_id 29 cpu_info:74:cpu_info74:snaptime 9305222.54595315 cpu_info:74:cpu_info74:state on-line cpu_info:74:cpu_info74:state_begin 1430258903 cpu_info:74:cpu_info74:supported_frequencies_Hz 1648762500 cpu_info:75:cpu_info75:brand SPARC-T3 cpu_info:75:cpu_info75:chip_id 0 cpu_info:75:cpu_info75:class misc cpu_info:75:cpu_info75:clock_MHz 1649 cpu_info:75:cpu_info75:core_id 1089 cpu_info:75:cpu_info75:cpu_fru hc:///component= cpu_info:75:cpu_info75:cpu_type sparcv9 cpu_info:75:cpu_info75:crtime 186.070164428 cpu_info:75:cpu_info75:current_clock_Hz 1648762500 cpu_info:75:cpu_info75:device_ID 75 cpu_info:75:cpu_info75:fpu_type sparcv9 cpu_info:75:cpu_info75:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:75:cpu_info75:pg_id 29 cpu_info:75:cpu_info75:snaptime 9305222.54710601 cpu_info:75:cpu_info75:state on-line cpu_info:75:cpu_info75:state_begin 1430258903 cpu_info:75:cpu_info75:supported_frequencies_Hz 1648762500 cpu_info:76:cpu_info76:brand SPARC-T3 cpu_info:76:cpu_info76:chip_id 0 cpu_info:76:cpu_info76:class misc cpu_info:76:cpu_info76:clock_MHz 1649 cpu_info:76:cpu_info76:core_id 1089 cpu_info:76:cpu_info76:cpu_fru hc:///component= cpu_info:76:cpu_info76:cpu_type sparcv9 cpu_info:76:cpu_info76:crtime 186.074604005 cpu_info:76:cpu_info76:current_clock_Hz 1648762500 cpu_info:76:cpu_info76:device_ID 76 cpu_info:76:cpu_info76:fpu_type sparcv9 cpu_info:76:cpu_info76:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:76:cpu_info76:pg_id 31 cpu_info:76:cpu_info76:snaptime 9305222.54828683 cpu_info:76:cpu_info76:state on-line cpu_info:76:cpu_info76:state_begin 1430258903 cpu_info:76:cpu_info76:supported_frequencies_Hz 1648762500 cpu_info:77:cpu_info77:brand SPARC-T3 cpu_info:77:cpu_info77:chip_id 0 cpu_info:77:cpu_info77:class misc cpu_info:77:cpu_info77:clock_MHz 1649 cpu_info:77:cpu_info77:core_id 1089 cpu_info:77:cpu_info77:cpu_fru hc:///component= cpu_info:77:cpu_info77:cpu_type sparcv9 cpu_info:77:cpu_info77:crtime 186.078156225 cpu_info:77:cpu_info77:current_clock_Hz 1648762500 cpu_info:77:cpu_info77:device_ID 77 cpu_info:77:cpu_info77:fpu_type sparcv9 cpu_info:77:cpu_info77:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:77:cpu_info77:pg_id 31 cpu_info:77:cpu_info77:snaptime 9305222.54944528 cpu_info:77:cpu_info77:state on-line cpu_info:77:cpu_info77:state_begin 1430258903 cpu_info:77:cpu_info77:supported_frequencies_Hz 1648762500 cpu_info:78:cpu_info78:brand SPARC-T3 cpu_info:78:cpu_info78:chip_id 0 cpu_info:78:cpu_info78:class misc cpu_info:78:cpu_info78:clock_MHz 1649 cpu_info:78:cpu_info78:core_id 1089 cpu_info:78:cpu_info78:cpu_fru hc:///component= cpu_info:78:cpu_info78:cpu_type sparcv9 cpu_info:78:cpu_info78:crtime 186.081686087 cpu_info:78:cpu_info78:current_clock_Hz 1648762500 cpu_info:78:cpu_info78:device_ID 78 cpu_info:78:cpu_info78:fpu_type sparcv9 cpu_info:78:cpu_info78:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:78:cpu_info78:pg_id 31 cpu_info:78:cpu_info78:snaptime 9305222.55061491 cpu_info:78:cpu_info78:state on-line cpu_info:78:cpu_info78:state_begin 1430258903 cpu_info:78:cpu_info78:supported_frequencies_Hz 1648762500 cpu_info:79:cpu_info79:brand SPARC-T3 cpu_info:79:cpu_info79:chip_id 0 cpu_info:79:cpu_info79:class misc cpu_info:79:cpu_info79:clock_MHz 1649 cpu_info:79:cpu_info79:core_id 1089 cpu_info:79:cpu_info79:cpu_fru hc:///component= cpu_info:79:cpu_info79:cpu_type sparcv9 cpu_info:79:cpu_info79:crtime 186.08618715 cpu_info:79:cpu_info79:current_clock_Hz 1648762500 cpu_info:79:cpu_info79:device_ID 79 cpu_info:79:cpu_info79:fpu_type sparcv9 cpu_info:79:cpu_info79:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:79:cpu_info79:pg_id 31 cpu_info:79:cpu_info79:snaptime 9305222.55181809 cpu_info:79:cpu_info79:state on-line cpu_info:79:cpu_info79:state_begin 1430258903 cpu_info:79:cpu_info79:supported_frequencies_Hz 1648762500 cpu_info:80:cpu_info80:brand SPARC-T3 cpu_info:80:cpu_info80:chip_id 0 cpu_info:80:cpu_info80:class misc cpu_info:80:cpu_info80:clock_MHz 1649 cpu_info:80:cpu_info80:core_id 1096 cpu_info:80:cpu_info80:cpu_fru hc:///component= cpu_info:80:cpu_info80:cpu_type sparcv9 cpu_info:80:cpu_info80:crtime 186.089729589 cpu_info:80:cpu_info80:current_clock_Hz 1648762500 cpu_info:80:cpu_info80:device_ID 80 cpu_info:80:cpu_info80:fpu_type sparcv9 cpu_info:80:cpu_info80:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:80:cpu_info80:pg_id 32 cpu_info:80:cpu_info80:snaptime 9305222.5529989 cpu_info:80:cpu_info80:state on-line cpu_info:80:cpu_info80:state_begin 1430258903 cpu_info:80:cpu_info80:supported_frequencies_Hz 1648762500 cpu_info:81:cpu_info81:brand SPARC-T3 cpu_info:81:cpu_info81:chip_id 0 cpu_info:81:cpu_info81:class misc cpu_info:81:cpu_info81:clock_MHz 1649 cpu_info:81:cpu_info81:core_id 1096 cpu_info:81:cpu_info81:cpu_fru hc:///component= cpu_info:81:cpu_info81:cpu_type sparcv9 cpu_info:81:cpu_info81:crtime 186.093385218 cpu_info:81:cpu_info81:current_clock_Hz 1648762500 cpu_info:81:cpu_info81:device_ID 81 cpu_info:81:cpu_info81:fpu_type sparcv9 cpu_info:81:cpu_info81:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:81:cpu_info81:pg_id 32 cpu_info:81:cpu_info81:snaptime 9305222.55415735 cpu_info:81:cpu_info81:state on-line cpu_info:81:cpu_info81:state_begin 1430258903 cpu_info:81:cpu_info81:supported_frequencies_Hz 1648762500 cpu_info:82:cpu_info82:brand SPARC-T3 cpu_info:82:cpu_info82:chip_id 0 cpu_info:82:cpu_info82:class misc cpu_info:82:cpu_info82:clock_MHz 1649 cpu_info:82:cpu_info82:core_id 1096 cpu_info:82:cpu_info82:cpu_fru hc:///component= cpu_info:82:cpu_info82:cpu_type sparcv9 cpu_info:82:cpu_info82:crtime 186.096857787 cpu_info:82:cpu_info82:current_clock_Hz 1648762500 cpu_info:82:cpu_info82:device_ID 82 cpu_info:82:cpu_info82:fpu_type sparcv9 cpu_info:82:cpu_info82:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:82:cpu_info82:pg_id 32 cpu_info:82:cpu_info82:snaptime 9305222.55531301 cpu_info:82:cpu_info82:state on-line cpu_info:82:cpu_info82:state_begin 1430258903 cpu_info:82:cpu_info82:supported_frequencies_Hz 1648762500 cpu_info:83:cpu_info83:brand SPARC-T3 cpu_info:83:cpu_info83:chip_id 0 cpu_info:83:cpu_info83:class misc cpu_info:83:cpu_info83:clock_MHz 1649 cpu_info:83:cpu_info83:core_id 1096 cpu_info:83:cpu_info83:cpu_fru hc:///component= cpu_info:83:cpu_info83:cpu_type sparcv9 cpu_info:83:cpu_info83:crtime 186.10044075 cpu_info:83:cpu_info83:current_clock_Hz 1648762500 cpu_info:83:cpu_info83:device_ID 83 cpu_info:83:cpu_info83:fpu_type sparcv9 cpu_info:83:cpu_info83:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:83:cpu_info83:pg_id 32 cpu_info:83:cpu_info83:snaptime 9305222.55646867 cpu_info:83:cpu_info83:state on-line cpu_info:83:cpu_info83:state_begin 1430258903 cpu_info:83:cpu_info83:supported_frequencies_Hz 1648762500 cpu_info:84:cpu_info84:brand SPARC-T3 cpu_info:84:cpu_info84:chip_id 0 cpu_info:84:cpu_info84:class misc cpu_info:84:cpu_info84:clock_MHz 1649 cpu_info:84:cpu_info84:core_id 1096 cpu_info:84:cpu_info84:cpu_fru hc:///component= cpu_info:84:cpu_info84:cpu_type sparcv9 cpu_info:84:cpu_info84:crtime 186.103991574 cpu_info:84:cpu_info84:current_clock_Hz 1648762500 cpu_info:84:cpu_info84:device_ID 84 cpu_info:84:cpu_info84:fpu_type sparcv9 cpu_info:84:cpu_info84:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:84:cpu_info84:pg_id 34 cpu_info:84:cpu_info84:snaptime 9305222.55762992 cpu_info:84:cpu_info84:state on-line cpu_info:84:cpu_info84:state_begin 1430258903 cpu_info:84:cpu_info84:supported_frequencies_Hz 1648762500 cpu_info:85:cpu_info85:brand SPARC-T3 cpu_info:85:cpu_info85:chip_id 0 cpu_info:85:cpu_info85:class misc cpu_info:85:cpu_info85:clock_MHz 1649 cpu_info:85:cpu_info85:core_id 1096 cpu_info:85:cpu_info85:cpu_fru hc:///component= cpu_info:85:cpu_info85:cpu_type sparcv9 cpu_info:85:cpu_info85:crtime 186.107497679 cpu_info:85:cpu_info85:current_clock_Hz 1648762500 cpu_info:85:cpu_info85:device_ID 85 cpu_info:85:cpu_info85:fpu_type sparcv9 cpu_info:85:cpu_info85:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:85:cpu_info85:pg_id 34 cpu_info:85:cpu_info85:snaptime 9305222.55880235 cpu_info:85:cpu_info85:state on-line cpu_info:85:cpu_info85:state_begin 1430258903 cpu_info:85:cpu_info85:supported_frequencies_Hz 1648762500 cpu_info:86:cpu_info86:brand SPARC-T3 cpu_info:86:cpu_info86:chip_id 0 cpu_info:86:cpu_info86:class misc cpu_info:86:cpu_info86:clock_MHz 1649 cpu_info:86:cpu_info86:core_id 1096 cpu_info:86:cpu_info86:cpu_fru hc:///component= cpu_info:86:cpu_info86:cpu_type sparcv9 cpu_info:86:cpu_info86:crtime 186.112561899 cpu_info:86:cpu_info86:current_clock_Hz 1648762500 cpu_info:86:cpu_info86:device_ID 86 cpu_info:86:cpu_info86:fpu_type sparcv9 cpu_info:86:cpu_info86:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:86:cpu_info86:pg_id 34 cpu_info:86:cpu_info86:snaptime 9305222.55995382 cpu_info:86:cpu_info86:state on-line cpu_info:86:cpu_info86:state_begin 1430258903 cpu_info:86:cpu_info86:supported_frequencies_Hz 1648762500 cpu_info:87:cpu_info87:brand SPARC-T3 cpu_info:87:cpu_info87:chip_id 0 cpu_info:87:cpu_info87:class misc cpu_info:87:cpu_info87:clock_MHz 1649 cpu_info:87:cpu_info87:core_id 1096 cpu_info:87:cpu_info87:cpu_fru hc:///component= cpu_info:87:cpu_info87:cpu_type sparcv9 cpu_info:87:cpu_info87:crtime 186.116544523 cpu_info:87:cpu_info87:current_clock_Hz 1648762500 cpu_info:87:cpu_info87:device_ID 87 cpu_info:87:cpu_info87:fpu_type sparcv9 cpu_info:87:cpu_info87:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:87:cpu_info87:pg_id 34 cpu_info:87:cpu_info87:snaptime 9305222.56116537 cpu_info:87:cpu_info87:state on-line cpu_info:87:cpu_info87:state_begin 1430258903 cpu_info:87:cpu_info87:supported_frequencies_Hz 1648762500 cpu_info:88:cpu_info88:brand SPARC-T3 cpu_info:88:cpu_info88:chip_id 0 cpu_info:88:cpu_info88:class misc cpu_info:88:cpu_info88:clock_MHz 1649 cpu_info:88:cpu_info88:core_id 1103 cpu_info:88:cpu_info88:cpu_fru hc:///component= cpu_info:88:cpu_info88:cpu_type sparcv9 cpu_info:88:cpu_info88:crtime 186.120367841 cpu_info:88:cpu_info88:current_clock_Hz 1648762500 cpu_info:88:cpu_info88:device_ID 88 cpu_info:88:cpu_info88:fpu_type sparcv9 cpu_info:88:cpu_info88:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:88:cpu_info88:pg_id 35 cpu_info:88:cpu_info88:snaptime 9305222.56231964 cpu_info:88:cpu_info88:state on-line cpu_info:88:cpu_info88:state_begin 1430258903 cpu_info:88:cpu_info88:supported_frequencies_Hz 1648762500 cpu_info:89:cpu_info89:brand SPARC-T3 cpu_info:89:cpu_info89:chip_id 0 cpu_info:89:cpu_info89:class misc cpu_info:89:cpu_info89:clock_MHz 1649 cpu_info:89:cpu_info89:core_id 1103 cpu_info:89:cpu_info89:cpu_fru hc:///component= cpu_info:89:cpu_info89:cpu_type sparcv9 cpu_info:89:cpu_info89:crtime 186.124051418 cpu_info:89:cpu_info89:current_clock_Hz 1648762500 cpu_info:89:cpu_info89:device_ID 89 cpu_info:89:cpu_info89:fpu_type sparcv9 cpu_info:89:cpu_info89:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:89:cpu_info89:pg_id 35 cpu_info:89:cpu_info89:snaptime 9305222.56348368 cpu_info:89:cpu_info89:state on-line cpu_info:89:cpu_info89:state_begin 1430258903 cpu_info:89:cpu_info89:supported_frequencies_Hz 1648762500 cpu_info:90:cpu_info90:brand SPARC-T3 cpu_info:90:cpu_info90:chip_id 0 cpu_info:90:cpu_info90:class misc cpu_info:90:cpu_info90:clock_MHz 1649 cpu_info:90:cpu_info90:core_id 1103 cpu_info:90:cpu_info90:cpu_fru hc:///component= cpu_info:90:cpu_info90:cpu_type sparcv9 cpu_info:90:cpu_info90:crtime 186.127595254 cpu_info:90:cpu_info90:current_clock_Hz 1648762500 cpu_info:90:cpu_info90:device_ID 90 cpu_info:90:cpu_info90:fpu_type sparcv9 cpu_info:90:cpu_info90:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:90:cpu_info90:pg_id 35 cpu_info:90:cpu_info90:snaptime 9305222.56470222 cpu_info:90:cpu_info90:state on-line cpu_info:90:cpu_info90:state_begin 1430258903 cpu_info:90:cpu_info90:supported_frequencies_Hz 1648762500 cpu_info:91:cpu_info91:brand SPARC-T3 cpu_info:91:cpu_info91:chip_id 0 cpu_info:91:cpu_info91:class misc cpu_info:91:cpu_info91:clock_MHz 1649 cpu_info:91:cpu_info91:core_id 1103 cpu_info:91:cpu_info91:cpu_fru hc:///component= cpu_info:91:cpu_info91:cpu_type sparcv9 cpu_info:91:cpu_info91:crtime 186.131172628 cpu_info:91:cpu_info91:current_clock_Hz 1648762500 cpu_info:91:cpu_info91:device_ID 91 cpu_info:91:cpu_info91:fpu_type sparcv9 cpu_info:91:cpu_info91:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:91:cpu_info91:pg_id 35 cpu_info:91:cpu_info91:snaptime 9305222.56585928 cpu_info:91:cpu_info91:state on-line cpu_info:91:cpu_info91:state_begin 1430258903 cpu_info:91:cpu_info91:supported_frequencies_Hz 1648762500 cpu_info:92:cpu_info92:brand SPARC-T3 cpu_info:92:cpu_info92:chip_id 0 cpu_info:92:cpu_info92:class misc cpu_info:92:cpu_info92:clock_MHz 1649 cpu_info:92:cpu_info92:core_id 1103 cpu_info:92:cpu_info92:cpu_fru hc:///component= cpu_info:92:cpu_info92:cpu_type sparcv9 cpu_info:92:cpu_info92:crtime 186.135181802 cpu_info:92:cpu_info92:current_clock_Hz 1648762500 cpu_info:92:cpu_info92:device_ID 92 cpu_info:92:cpu_info92:fpu_type sparcv9 cpu_info:92:cpu_info92:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:92:cpu_info92:pg_id 37 cpu_info:92:cpu_info92:snaptime 9305222.56701773 cpu_info:92:cpu_info92:state on-line cpu_info:92:cpu_info92:state_begin 1430258903 cpu_info:92:cpu_info92:supported_frequencies_Hz 1648762500 cpu_info:93:cpu_info93:brand SPARC-T3 cpu_info:93:cpu_info93:chip_id 0 cpu_info:93:cpu_info93:class misc cpu_info:93:cpu_info93:clock_MHz 1649 cpu_info:93:cpu_info93:core_id 1103 cpu_info:93:cpu_info93:cpu_fru hc:///component= cpu_info:93:cpu_info93:cpu_type sparcv9 cpu_info:93:cpu_info93:crtime 186.146467299 cpu_info:93:cpu_info93:current_clock_Hz 1648762500 cpu_info:93:cpu_info93:device_ID 93 cpu_info:93:cpu_info93:fpu_type sparcv9 cpu_info:93:cpu_info93:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:93:cpu_info93:pg_id 37 cpu_info:93:cpu_info93:snaptime 9305222.568172 cpu_info:93:cpu_info93:state on-line cpu_info:93:cpu_info93:state_begin 1430258903 cpu_info:93:cpu_info93:supported_frequencies_Hz 1648762500 cpu_info:94:cpu_info94:brand SPARC-T3 cpu_info:94:cpu_info94:chip_id 0 cpu_info:94:cpu_info94:class misc cpu_info:94:cpu_info94:clock_MHz 1649 cpu_info:94:cpu_info94:core_id 1103 cpu_info:94:cpu_info94:cpu_fru hc:///component= cpu_info:94:cpu_info94:cpu_type sparcv9 cpu_info:94:cpu_info94:crtime 186.150243105 cpu_info:94:cpu_info94:current_clock_Hz 1648762500 cpu_info:94:cpu_info94:device_ID 94 cpu_info:94:cpu_info94:fpu_type sparcv9 cpu_info:94:cpu_info94:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:94:cpu_info94:pg_id 37 cpu_info:94:cpu_info94:snaptime 9305222.56933883 cpu_info:94:cpu_info94:state on-line cpu_info:94:cpu_info94:state_begin 1430258903 cpu_info:94:cpu_info94:supported_frequencies_Hz 1648762500 cpu_info:95:cpu_info95:brand SPARC-T3 cpu_info:95:cpu_info95:chip_id 0 cpu_info:95:cpu_info95:class misc cpu_info:95:cpu_info95:clock_MHz 1649 cpu_info:95:cpu_info95:core_id 1103 cpu_info:95:cpu_info95:cpu_fru hc:///component= cpu_info:95:cpu_info95:cpu_type sparcv9 cpu_info:95:cpu_info95:crtime 186.154034283 cpu_info:95:cpu_info95:current_clock_Hz 1648762500 cpu_info:95:cpu_info95:device_ID 95 cpu_info:95:cpu_info95:fpu_type sparcv9 cpu_info:95:cpu_info95:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:95:cpu_info95:pg_id 37 cpu_info:95:cpu_info95:snaptime 9305222.5705462 cpu_info:95:cpu_info95:state on-line cpu_info:95:cpu_info95:state_begin 1430258903 cpu_info:95:cpu_info95:supported_frequencies_Hz 1648762500 cpu_info:96:cpu_info96:brand SPARC-T3 cpu_info:96:cpu_info96:chip_id 0 cpu_info:96:cpu_info96:class misc cpu_info:96:cpu_info96:clock_MHz 1649 cpu_info:96:cpu_info96:core_id 1110 cpu_info:96:cpu_info96:cpu_fru hc:///component= cpu_info:96:cpu_info96:cpu_type sparcv9 cpu_info:96:cpu_info96:crtime 186.157794718 cpu_info:96:cpu_info96:current_clock_Hz 1648762500 cpu_info:96:cpu_info96:device_ID 96 cpu_info:96:cpu_info96:fpu_type sparcv9 cpu_info:96:cpu_info96:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:96:cpu_info96:pg_id 38 cpu_info:96:cpu_info96:snaptime 9305222.57170186 cpu_info:96:cpu_info96:state on-line cpu_info:96:cpu_info96:state_begin 1430258903 cpu_info:96:cpu_info96:supported_frequencies_Hz 1648762500 cpu_info:97:cpu_info97:brand SPARC-T3 cpu_info:97:cpu_info97:chip_id 0 cpu_info:97:cpu_info97:class misc cpu_info:97:cpu_info97:clock_MHz 1649 cpu_info:97:cpu_info97:core_id 1110 cpu_info:97:cpu_info97:cpu_fru hc:///component= cpu_info:97:cpu_info97:cpu_type sparcv9 cpu_info:97:cpu_info97:crtime 186.162034466 cpu_info:97:cpu_info97:current_clock_Hz 1648762500 cpu_info:97:cpu_info97:device_ID 97 cpu_info:97:cpu_info97:fpu_type sparcv9 cpu_info:97:cpu_info97:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:97:cpu_info97:pg_id 38 cpu_info:97:cpu_info97:snaptime 9305222.57285752 cpu_info:97:cpu_info97:state on-line cpu_info:97:cpu_info97:state_begin 1430258903 cpu_info:97:cpu_info97:supported_frequencies_Hz 1648762500 cpu_info:98:cpu_info98:brand SPARC-T3 cpu_info:98:cpu_info98:chip_id 0 cpu_info:98:cpu_info98:class misc cpu_info:98:cpu_info98:clock_MHz 1649 cpu_info:98:cpu_info98:core_id 1110 cpu_info:98:cpu_info98:cpu_fru hc:///component= cpu_info:98:cpu_info98:cpu_type sparcv9 cpu_info:98:cpu_info98:crtime 186.165764158 cpu_info:98:cpu_info98:current_clock_Hz 1648762500 cpu_info:98:cpu_info98:device_ID 98 cpu_info:98:cpu_info98:fpu_type sparcv9 cpu_info:98:cpu_info98:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:98:cpu_info98:pg_id 38 cpu_info:98:cpu_info98:snaptime 9305222.57402436 cpu_info:98:cpu_info98:state on-line cpu_info:98:cpu_info98:state_begin 1430258903 cpu_info:98:cpu_info98:supported_frequencies_Hz 1648762500 cpu_info:99:cpu_info99:brand SPARC-T3 cpu_info:99:cpu_info99:chip_id 0 cpu_info:99:cpu_info99:class misc cpu_info:99:cpu_info99:clock_MHz 1649 cpu_info:99:cpu_info99:core_id 1110 cpu_info:99:cpu_info99:cpu_fru hc:///component= cpu_info:99:cpu_info99:cpu_type sparcv9 cpu_info:99:cpu_info99:crtime 186.169446338 cpu_info:99:cpu_info99:current_clock_Hz 1648762500 cpu_info:99:cpu_info99:device_ID 99 cpu_info:99:cpu_info99:fpu_type sparcv9 cpu_info:99:cpu_info99:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:99:cpu_info99:pg_id 38 cpu_info:99:cpu_info99:snaptime 9305222.5751856 cpu_info:99:cpu_info99:state on-line cpu_info:99:cpu_info99:state_begin 1430258903 cpu_info:99:cpu_info99:supported_frequencies_Hz 1648762500 cpu_info:100:cpu_info100:brand SPARC-T3 cpu_info:100:cpu_info100:chip_id 0 cpu_info:100:cpu_info100:class misc cpu_info:100:cpu_info100:clock_MHz 1649 cpu_info:100:cpu_info100:core_id 1110 cpu_info:100:cpu_info100:cpu_fru hc:///component= cpu_info:100:cpu_info100:cpu_type sparcv9 cpu_info:100:cpu_info100:crtime 186.17328363 cpu_info:100:cpu_info100:current_clock_Hz 1648762500 cpu_info:100:cpu_info100:device_ID 100 cpu_info:100:cpu_info100:fpu_type sparcv9 cpu_info:100:cpu_info100:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:100:cpu_info100:pg_id 40 cpu_info:100:cpu_info100:snaptime 9305222.57636642 cpu_info:100:cpu_info100:state on-line cpu_info:100:cpu_info100:state_begin 1430258903 cpu_info:100:cpu_info100:supported_frequencies_Hz 1648762500 cpu_info:101:cpu_info101:brand SPARC-T3 cpu_info:101:cpu_info101:chip_id 0 cpu_info:101:cpu_info101:class misc cpu_info:101:cpu_info101:clock_MHz 1649 cpu_info:101:cpu_info101:core_id 1110 cpu_info:101:cpu_info101:cpu_fru hc:///component= cpu_info:101:cpu_info101:cpu_type sparcv9 cpu_info:101:cpu_info101:crtime 186.17700913 cpu_info:101:cpu_info101:current_clock_Hz 1648762500 cpu_info:101:cpu_info101:device_ID 101 cpu_info:101:cpu_info101:fpu_type sparcv9 cpu_info:101:cpu_info101:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:101:cpu_info101:pg_id 40 cpu_info:101:cpu_info101:snaptime 9305222.57756819 cpu_info:101:cpu_info101:state on-line cpu_info:101:cpu_info101:state_begin 1430258903 cpu_info:101:cpu_info101:supported_frequencies_Hz 1648762500 cpu_info:102:cpu_info102:brand SPARC-T3 cpu_info:102:cpu_info102:chip_id 0 cpu_info:102:cpu_info102:class misc cpu_info:102:cpu_info102:clock_MHz 1649 cpu_info:102:cpu_info102:core_id 1110 cpu_info:102:cpu_info102:cpu_fru hc:///component= cpu_info:102:cpu_info102:cpu_type sparcv9 cpu_info:102:cpu_info102:crtime 186.181111931 cpu_info:102:cpu_info102:current_clock_Hz 1648762500 cpu_info:102:cpu_info102:device_ID 102 cpu_info:102:cpu_info102:fpu_type sparcv9 cpu_info:102:cpu_info102:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:102:cpu_info102:pg_id 40 cpu_info:102:cpu_info102:snaptime 9305222.57872385 cpu_info:102:cpu_info102:state on-line cpu_info:102:cpu_info102:state_begin 1430258903 cpu_info:102:cpu_info102:supported_frequencies_Hz 1648762500 cpu_info:103:cpu_info103:brand SPARC-T3 cpu_info:103:cpu_info103:chip_id 0 cpu_info:103:cpu_info103:class misc cpu_info:103:cpu_info103:clock_MHz 1649 cpu_info:103:cpu_info103:core_id 1110 cpu_info:103:cpu_info103:cpu_fru hc:///component= cpu_info:103:cpu_info103:cpu_type sparcv9 cpu_info:103:cpu_info103:crtime 186.184992543 cpu_info:103:cpu_info103:current_clock_Hz 1648762500 cpu_info:103:cpu_info103:device_ID 103 cpu_info:103:cpu_info103:fpu_type sparcv9 cpu_info:103:cpu_info103:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:103:cpu_info103:pg_id 40 cpu_info:103:cpu_info103:snaptime 9305222.57987811 cpu_info:103:cpu_info103:state on-line cpu_info:103:cpu_info103:state_begin 1430258903 cpu_info:103:cpu_info103:supported_frequencies_Hz 1648762500 cpu_info:104:cpu_info104:brand SPARC-T3 cpu_info:104:cpu_info104:chip_id 0 cpu_info:104:cpu_info104:class misc cpu_info:104:cpu_info104:clock_MHz 1649 cpu_info:104:cpu_info104:core_id 1117 cpu_info:104:cpu_info104:cpu_fru hc:///component= cpu_info:104:cpu_info104:cpu_type sparcv9 cpu_info:104:cpu_info104:crtime 186.188854989 cpu_info:104:cpu_info104:current_clock_Hz 1648762500 cpu_info:104:cpu_info104:device_ID 104 cpu_info:104:cpu_info104:fpu_type sparcv9 cpu_info:104:cpu_info104:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:104:cpu_info104:pg_id 41 cpu_info:104:cpu_info104:snaptime 9305222.58126295 cpu_info:104:cpu_info104:state on-line cpu_info:104:cpu_info104:state_begin 1430258903 cpu_info:104:cpu_info104:supported_frequencies_Hz 1648762500 cpu_info:105:cpu_info105:brand SPARC-T3 cpu_info:105:cpu_info105:chip_id 0 cpu_info:105:cpu_info105:class misc cpu_info:105:cpu_info105:clock_MHz 1649 cpu_info:105:cpu_info105:core_id 1117 cpu_info:105:cpu_info105:cpu_fru hc:///component= cpu_info:105:cpu_info105:cpu_type sparcv9 cpu_info:105:cpu_info105:crtime 186.192766344 cpu_info:105:cpu_info105:current_clock_Hz 1648762500 cpu_info:105:cpu_info105:device_ID 105 cpu_info:105:cpu_info105:fpu_type sparcv9 cpu_info:105:cpu_info105:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:105:cpu_info105:pg_id 41 cpu_info:105:cpu_info105:snaptime 9305222.5824228 cpu_info:105:cpu_info105:state on-line cpu_info:105:cpu_info105:state_begin 1430258903 cpu_info:105:cpu_info105:supported_frequencies_Hz 1648762500 cpu_info:106:cpu_info106:brand SPARC-T3 cpu_info:106:cpu_info106:chip_id 0 cpu_info:106:cpu_info106:class misc cpu_info:106:cpu_info106:clock_MHz 1649 cpu_info:106:cpu_info106:core_id 1117 cpu_info:106:cpu_info106:cpu_fru hc:///component= cpu_info:106:cpu_info106:cpu_type sparcv9 cpu_info:106:cpu_info106:crtime 186.197053603 cpu_info:106:cpu_info106:current_clock_Hz 1648762500 cpu_info:106:cpu_info106:device_ID 106 cpu_info:106:cpu_info106:fpu_type sparcv9 cpu_info:106:cpu_info106:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:106:cpu_info106:pg_id 41 cpu_info:106:cpu_info106:snaptime 9305222.58358125 cpu_info:106:cpu_info106:state on-line cpu_info:106:cpu_info106:state_begin 1430258903 cpu_info:106:cpu_info106:supported_frequencies_Hz 1648762500 cpu_info:107:cpu_info107:brand SPARC-T3 cpu_info:107:cpu_info107:chip_id 0 cpu_info:107:cpu_info107:class misc cpu_info:107:cpu_info107:clock_MHz 1649 cpu_info:107:cpu_info107:core_id 1117 cpu_info:107:cpu_info107:cpu_fru hc:///component= cpu_info:107:cpu_info107:cpu_type sparcv9 cpu_info:107:cpu_info107:crtime 186.200927229 cpu_info:107:cpu_info107:current_clock_Hz 1648762500 cpu_info:107:cpu_info107:device_ID 107 cpu_info:107:cpu_info107:fpu_type sparcv9 cpu_info:107:cpu_info107:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:107:cpu_info107:pg_id 41 cpu_info:107:cpu_info107:snaptime 9305222.5847467 cpu_info:107:cpu_info107:state on-line cpu_info:107:cpu_info107:state_begin 1430258903 cpu_info:107:cpu_info107:supported_frequencies_Hz 1648762500 cpu_info:108:cpu_info108:brand SPARC-T3 cpu_info:108:cpu_info108:chip_id 0 cpu_info:108:cpu_info108:class misc cpu_info:108:cpu_info108:clock_MHz 1649 cpu_info:108:cpu_info108:core_id 1117 cpu_info:108:cpu_info108:cpu_fru hc:///component= cpu_info:108:cpu_info108:cpu_type sparcv9 cpu_info:108:cpu_info108:crtime 186.204772906 cpu_info:108:cpu_info108:current_clock_Hz 1648762500 cpu_info:108:cpu_info108:device_ID 108 cpu_info:108:cpu_info108:fpu_type sparcv9 cpu_info:108:cpu_info108:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:108:cpu_info108:pg_id 43 cpu_info:108:cpu_info108:snaptime 9305222.58591214 cpu_info:108:cpu_info108:state on-line cpu_info:108:cpu_info108:state_begin 1430258903 cpu_info:108:cpu_info108:supported_frequencies_Hz 1648762500 cpu_info:109:cpu_info109:brand SPARC-T3 cpu_info:109:cpu_info109:chip_id 0 cpu_info:109:cpu_info109:class misc cpu_info:109:cpu_info109:clock_MHz 1649 cpu_info:109:cpu_info109:core_id 1117 cpu_info:109:cpu_info109:cpu_fru hc:///component= cpu_info:109:cpu_info109:cpu_type sparcv9 cpu_info:109:cpu_info109:crtime 186.208800246 cpu_info:109:cpu_info109:current_clock_Hz 1648762500 cpu_info:109:cpu_info109:device_ID 109 cpu_info:109:cpu_info109:fpu_type sparcv9 cpu_info:109:cpu_info109:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:109:cpu_info109:pg_id 43 cpu_info:109:cpu_info109:snaptime 9305222.58709854 cpu_info:109:cpu_info109:state on-line cpu_info:109:cpu_info109:state_begin 1430258903 cpu_info:109:cpu_info109:supported_frequencies_Hz 1648762500 cpu_info:110:cpu_info110:brand SPARC-T3 cpu_info:110:cpu_info110:chip_id 0 cpu_info:110:cpu_info110:class misc cpu_info:110:cpu_info110:clock_MHz 1649 cpu_info:110:cpu_info110:core_id 1117 cpu_info:110:cpu_info110:cpu_fru hc:///component= cpu_info:110:cpu_info110:cpu_type sparcv9 cpu_info:110:cpu_info110:crtime 186.21284715 cpu_info:110:cpu_info110:current_clock_Hz 1648762500 cpu_info:110:cpu_info110:device_ID 110 cpu_info:110:cpu_info110:fpu_type sparcv9 cpu_info:110:cpu_info110:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:110:cpu_info110:pg_id 43 cpu_info:110:cpu_info110:snaptime 9305222.5882556 cpu_info:110:cpu_info110:state on-line cpu_info:110:cpu_info110:state_begin 1430258903 cpu_info:110:cpu_info110:supported_frequencies_Hz 1648762500 cpu_info:111:cpu_info111:brand SPARC-T3 cpu_info:111:cpu_info111:chip_id 0 cpu_info:111:cpu_info111:class misc cpu_info:111:cpu_info111:clock_MHz 1649 cpu_info:111:cpu_info111:core_id 1117 cpu_info:111:cpu_info111:cpu_fru hc:///component= cpu_info:111:cpu_info111:cpu_type sparcv9 cpu_info:111:cpu_info111:crtime 186.216681648 cpu_info:111:cpu_info111:current_clock_Hz 1648762500 cpu_info:111:cpu_info111:device_ID 111 cpu_info:111:cpu_info111:fpu_type sparcv9 cpu_info:111:cpu_info111:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:111:cpu_info111:pg_id 43 cpu_info:111:cpu_info111:snaptime 9305222.58941964 cpu_info:111:cpu_info111:state on-line cpu_info:111:cpu_info111:state_begin 1430258903 cpu_info:111:cpu_info111:supported_frequencies_Hz 1648762500 cpu_info:112:cpu_info112:brand SPARC-T3 cpu_info:112:cpu_info112:chip_id 0 cpu_info:112:cpu_info112:class misc cpu_info:112:cpu_info112:clock_MHz 1649 cpu_info:112:cpu_info112:core_id 1124 cpu_info:112:cpu_info112:cpu_fru hc:///component= cpu_info:112:cpu_info112:cpu_type sparcv9 cpu_info:112:cpu_info112:crtime 186.220644707 cpu_info:112:cpu_info112:current_clock_Hz 1648762500 cpu_info:112:cpu_info112:device_ID 112 cpu_info:112:cpu_info112:fpu_type sparcv9 cpu_info:112:cpu_info112:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:112:cpu_info112:pg_id 44 cpu_info:112:cpu_info112:snaptime 9305222.59064377 cpu_info:112:cpu_info112:state on-line cpu_info:112:cpu_info112:state_begin 1430258903 cpu_info:112:cpu_info112:supported_frequencies_Hz 1648762500 cpu_info:113:cpu_info113:brand SPARC-T3 cpu_info:113:cpu_info113:chip_id 0 cpu_info:113:cpu_info113:class misc cpu_info:113:cpu_info113:clock_MHz 1649 cpu_info:113:cpu_info113:core_id 1124 cpu_info:113:cpu_info113:cpu_fru hc:///component= cpu_info:113:cpu_info113:cpu_type sparcv9 cpu_info:113:cpu_info113:crtime 186.224940351 cpu_info:113:cpu_info113:current_clock_Hz 1648762500 cpu_info:113:cpu_info113:device_ID 113 cpu_info:113:cpu_info113:fpu_type sparcv9 cpu_info:113:cpu_info113:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:113:cpu_info113:pg_id 44 cpu_info:113:cpu_info113:snaptime 9305222.591819 cpu_info:113:cpu_info113:state on-line cpu_info:113:cpu_info113:state_begin 1430258903 cpu_info:113:cpu_info113:supported_frequencies_Hz 1648762500 cpu_info:114:cpu_info114:brand SPARC-T3 cpu_info:114:cpu_info114:chip_id 0 cpu_info:114:cpu_info114:class misc cpu_info:114:cpu_info114:clock_MHz 1649 cpu_info:114:cpu_info114:core_id 1124 cpu_info:114:cpu_info114:cpu_fru hc:///component= cpu_info:114:cpu_info114:cpu_type sparcv9 cpu_info:114:cpu_info114:crtime 186.228844719 cpu_info:114:cpu_info114:current_clock_Hz 1648762500 cpu_info:114:cpu_info114:device_ID 114 cpu_info:114:cpu_info114:fpu_type sparcv9 cpu_info:114:cpu_info114:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:114:cpu_info114:pg_id 44 cpu_info:114:cpu_info114:snaptime 9305222.59298444 cpu_info:114:cpu_info114:state on-line cpu_info:114:cpu_info114:state_begin 1430258903 cpu_info:114:cpu_info114:supported_frequencies_Hz 1648762500 cpu_info:115:cpu_info115:brand SPARC-T3 cpu_info:115:cpu_info115:chip_id 0 cpu_info:115:cpu_info115:class misc cpu_info:115:cpu_info115:clock_MHz 1649 cpu_info:115:cpu_info115:core_id 1124 cpu_info:115:cpu_info115:cpu_fru hc:///component= cpu_info:115:cpu_info115:cpu_type sparcv9 cpu_info:115:cpu_info115:crtime 186.232733716 cpu_info:115:cpu_info115:current_clock_Hz 1648762500 cpu_info:115:cpu_info115:device_ID 115 cpu_info:115:cpu_info115:fpu_type sparcv9 cpu_info:115:cpu_info115:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:115:cpu_info115:pg_id 44 cpu_info:115:cpu_info115:snaptime 9305222.5941387 cpu_info:115:cpu_info115:state on-line cpu_info:115:cpu_info115:state_begin 1430258903 cpu_info:115:cpu_info115:supported_frequencies_Hz 1648762500 cpu_info:116:cpu_info116:brand SPARC-T3 cpu_info:116:cpu_info116:chip_id 0 cpu_info:116:cpu_info116:class misc cpu_info:116:cpu_info116:clock_MHz 1649 cpu_info:116:cpu_info116:core_id 1124 cpu_info:116:cpu_info116:cpu_fru hc:///component= cpu_info:116:cpu_info116:cpu_type sparcv9 cpu_info:116:cpu_info116:crtime 186.236670225 cpu_info:116:cpu_info116:current_clock_Hz 1648762500 cpu_info:116:cpu_info116:device_ID 116 cpu_info:116:cpu_info116:fpu_type sparcv9 cpu_info:116:cpu_info116:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:116:cpu_info116:pg_id 46 cpu_info:116:cpu_info116:snaptime 9305222.59529995 cpu_info:116:cpu_info116:state on-line cpu_info:116:cpu_info116:state_begin 1430258903 cpu_info:116:cpu_info116:supported_frequencies_Hz 1648762500 cpu_info:117:cpu_info117:brand SPARC-T3 cpu_info:117:cpu_info117:chip_id 0 cpu_info:117:cpu_info117:class misc cpu_info:117:cpu_info117:clock_MHz 1649 cpu_info:117:cpu_info117:core_id 1124 cpu_info:117:cpu_info117:cpu_fru hc:///component= cpu_info:117:cpu_info117:cpu_type sparcv9 cpu_info:117:cpu_info117:crtime 186.240778616 cpu_info:117:cpu_info117:current_clock_Hz 1648762500 cpu_info:117:cpu_info117:device_ID 117 cpu_info:117:cpu_info117:fpu_type sparcv9 cpu_info:117:cpu_info117:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:117:cpu_info117:pg_id 46 cpu_info:117:cpu_info117:snaptime 9305222.59648495 cpu_info:117:cpu_info117:state on-line cpu_info:117:cpu_info117:state_begin 1430258903 cpu_info:117:cpu_info117:supported_frequencies_Hz 1648762500 cpu_info:118:cpu_info118:brand SPARC-T3 cpu_info:118:cpu_info118:chip_id 0 cpu_info:118:cpu_info118:class misc cpu_info:118:cpu_info118:clock_MHz 1649 cpu_info:118:cpu_info118:core_id 1124 cpu_info:118:cpu_info118:cpu_fru hc:///component= cpu_info:118:cpu_info118:cpu_type sparcv9 cpu_info:118:cpu_info118:crtime 186.244717919 cpu_info:118:cpu_info118:current_clock_Hz 1648762500 cpu_info:118:cpu_info118:device_ID 118 cpu_info:118:cpu_info118:fpu_type sparcv9 cpu_info:118:cpu_info118:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:118:cpu_info118:pg_id 46 cpu_info:118:cpu_info118:snaptime 9305222.5976476 cpu_info:118:cpu_info118:state on-line cpu_info:118:cpu_info118:state_begin 1430258903 cpu_info:118:cpu_info118:supported_frequencies_Hz 1648762500 cpu_info:119:cpu_info119:brand SPARC-T3 cpu_info:119:cpu_info119:chip_id 0 cpu_info:119:cpu_info119:class misc cpu_info:119:cpu_info119:clock_MHz 1649 cpu_info:119:cpu_info119:core_id 1124 cpu_info:119:cpu_info119:cpu_fru hc:///component= cpu_info:119:cpu_info119:cpu_type sparcv9 cpu_info:119:cpu_info119:crtime 186.248661415 cpu_info:119:cpu_info119:current_clock_Hz 1648762500 cpu_info:119:cpu_info119:device_ID 119 cpu_info:119:cpu_info119:fpu_type sparcv9 cpu_info:119:cpu_info119:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:119:cpu_info119:pg_id 46 cpu_info:119:cpu_info119:snaptime 9305222.59881723 cpu_info:119:cpu_info119:state on-line cpu_info:119:cpu_info119:state_begin 1430258903 cpu_info:119:cpu_info119:supported_frequencies_Hz 1648762500 cpu_info:120:cpu_info120:brand SPARC-T3 cpu_info:120:cpu_info120:chip_id 0 cpu_info:120:cpu_info120:class misc cpu_info:120:cpu_info120:clock_MHz 1649 cpu_info:120:cpu_info120:core_id 1131 cpu_info:120:cpu_info120:cpu_fru hc:///component= cpu_info:120:cpu_info120:cpu_type sparcv9 cpu_info:120:cpu_info120:crtime 186.252660808 cpu_info:120:cpu_info120:current_clock_Hz 1648762500 cpu_info:120:cpu_info120:device_ID 120 cpu_info:120:cpu_info120:fpu_type sparcv9 cpu_info:120:cpu_info120:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:120:cpu_info120:pg_id 47 cpu_info:120:cpu_info120:snaptime 9305222.59998826 cpu_info:120:cpu_info120:state on-line cpu_info:120:cpu_info120:state_begin 1430258903 cpu_info:120:cpu_info120:supported_frequencies_Hz 1648762500 cpu_info:121:cpu_info121:brand SPARC-T3 cpu_info:121:cpu_info121:chip_id 0 cpu_info:121:cpu_info121:class misc cpu_info:121:cpu_info121:clock_MHz 1649 cpu_info:121:cpu_info121:core_id 1131 cpu_info:121:cpu_info121:cpu_fru hc:///component= cpu_info:121:cpu_info121:cpu_type sparcv9 cpu_info:121:cpu_info121:crtime 186.257104577 cpu_info:121:cpu_info121:current_clock_Hz 1648762500 cpu_info:121:cpu_info121:device_ID 121 cpu_info:121:cpu_info121:fpu_type sparcv9 cpu_info:121:cpu_info121:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:121:cpu_info121:pg_id 47 cpu_info:121:cpu_info121:snaptime 9305222.60114672 cpu_info:121:cpu_info121:state on-line cpu_info:121:cpu_info121:state_begin 1430258903 cpu_info:121:cpu_info121:supported_frequencies_Hz 1648762500 cpu_info:122:cpu_info122:brand SPARC-T3 cpu_info:122:cpu_info122:chip_id 0 cpu_info:122:cpu_info122:class misc cpu_info:122:cpu_info122:clock_MHz 1649 cpu_info:122:cpu_info122:core_id 1131 cpu_info:122:cpu_info122:cpu_fru hc:///component= cpu_info:122:cpu_info122:cpu_type sparcv9 cpu_info:122:cpu_info122:crtime 186.260994971 cpu_info:122:cpu_info122:current_clock_Hz 1648762500 cpu_info:122:cpu_info122:device_ID 122 cpu_info:122:cpu_info122:fpu_type sparcv9 cpu_info:122:cpu_info122:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:122:cpu_info122:pg_id 47 cpu_info:122:cpu_info122:snaptime 9305222.60230238 cpu_info:122:cpu_info122:state on-line cpu_info:122:cpu_info122:state_begin 1430258903 cpu_info:122:cpu_info122:supported_frequencies_Hz 1648762500 cpu_info:123:cpu_info123:brand SPARC-T3 cpu_info:123:cpu_info123:chip_id 0 cpu_info:123:cpu_info123:class misc cpu_info:123:cpu_info123:clock_MHz 1649 cpu_info:123:cpu_info123:core_id 1131 cpu_info:123:cpu_info123:cpu_fru hc:///component= cpu_info:123:cpu_info123:cpu_type sparcv9 cpu_info:123:cpu_info123:crtime 186.264900737 cpu_info:123:cpu_info123:current_clock_Hz 1648762500 cpu_info:123:cpu_info123:device_ID 123 cpu_info:123:cpu_info123:fpu_type sparcv9 cpu_info:123:cpu_info123:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:123:cpu_info123:pg_id 47 cpu_info:123:cpu_info123:snaptime 9305222.60351952 cpu_info:123:cpu_info123:state on-line cpu_info:123:cpu_info123:state_begin 1430258903 cpu_info:123:cpu_info123:supported_frequencies_Hz 1648762500 cpu_info:124:cpu_info124:brand SPARC-T4 cpu_info:124:cpu_info124:chip_id 0 cpu_info:124:cpu_info124:class misc cpu_info:124:cpu_info124:clock_MHz 1649 cpu_info:124:cpu_info124:core_id 1131 cpu_info:124:cpu_info124:cpu_fru hc:///component= cpu_info:124:cpu_info124:cpu_type sparcv9 cpu_info:124:cpu_info124:crtime 186.268767375 cpu_info:124:cpu_info124:current_clock_Hz 1648762500 cpu_info:124:cpu_info124:device_ID 124 cpu_info:124:cpu_info124:fpu_type sparcv9 cpu_info:124:cpu_info124:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:124:cpu_info124:pg_id 49 cpu_info:124:cpu_info124:snaptime 9305222.60468497 cpu_info:124:cpu_info124:state off-line cpu_info:124:cpu_info124:state_begin 1430258903 cpu_info:124:cpu_info124:supported_frequencies_Hz 1648762500 cpu_info:125:cpu_info125:brand SPARC-T4 cpu_info:125:cpu_info125:chip_id 0 cpu_info:125:cpu_info125:class misc cpu_info:125:cpu_info125:clock_MHz 1649 cpu_info:125:cpu_info125:core_id 1131 cpu_info:125:cpu_info125:cpu_fru hc:///component= cpu_info:125:cpu_info125:cpu_type sparcv9 cpu_info:125:cpu_info125:crtime 186.272702486 cpu_info:125:cpu_info125:current_clock_Hz 1648762500 cpu_info:125:cpu_info125:device_ID 125 cpu_info:125:cpu_info125:fpu_type sparcv9 cpu_info:125:cpu_info125:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:125:cpu_info125:pg_id 49 cpu_info:125:cpu_info125:snaptime 9305222.60585879 cpu_info:125:cpu_info125:state off-line cpu_info:125:cpu_info125:state_begin 1430258903 cpu_info:125:cpu_info125:supported_frequencies_Hz 1648762500 cpu_info:126:cpu_info126:brand SPARC-T4 cpu_info:126:cpu_info126:chip_id 0 cpu_info:126:cpu_info126:class misc cpu_info:126:cpu_info126:clock_MHz 1649 cpu_info:126:cpu_info126:core_id 1131 cpu_info:126:cpu_info126:cpu_fru hc:///component= cpu_info:126:cpu_info126:cpu_type sparcv9 cpu_info:126:cpu_info126:crtime 186.27663061 cpu_info:126:cpu_info126:current_clock_Hz 1648762500 cpu_info:126:cpu_info126:device_ID 126 cpu_info:126:cpu_info126:fpu_type sparcv9 cpu_info:126:cpu_info126:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:126:cpu_info126:pg_id 49 cpu_info:126:cpu_info126:snaptime 9305222.60703821 cpu_info:126:cpu_info126:state off-line cpu_info:126:cpu_info126:state_begin 1430258903 cpu_info:126:cpu_info126:supported_frequencies_Hz 1648762500 cpu_info:127:cpu_info127:brand SPARC-T4 cpu_info:127:cpu_info127:chip_id 0 cpu_info:127:cpu_info127:class misc cpu_info:127:cpu_info127:clock_MHz 1649 cpu_info:127:cpu_info127:core_id 1131 cpu_info:127:cpu_info127:cpu_fru hc:///component= cpu_info:127:cpu_info127:cpu_type sparcv9 cpu_info:127:cpu_info127:crtime 186.281711599 cpu_info:127:cpu_info127:current_clock_Hz 1648762500 cpu_info:127:cpu_info127:device_ID 127 cpu_info:127:cpu_info127:fpu_type sparcv9 cpu_info:127:cpu_info127:implementation SPARC-T3 (chipid 0, clock 1649 MHz) cpu_info:127:cpu_info127:pg_id 49 cpu_info:127:cpu_info127:snaptime 9305222.60819247 cpu_info:127:cpu_info127:state off-line cpu_info:127:cpu_info127:state_begin 1430258903 cpu_info:127:cpu_info127:supported_frequencies_Hz 1648762500 END allow(@plugin).to receive(:shell_out).with("kstat -p cpu_info").and_return(mock_shell_out(0, kstatinfo_output, "")) @plugin.run end it "gets the total virtual processor count" do expect(@plugin["cpu"]["total"]).to be(128) end it "gets the total processor count" do expect(@plugin["cpu"]["real"]).to be(1) end it "gets the total core count" do expect(@plugin["cpu"]["cores"]).to be(16) end it "gets the number of threads per core" do expect(@plugin["cpu"]["corethreads"]).to be(8) end it "gets the total number of online cores" do expect(@plugin["cpu"]["cpustates"]["on-line"]).to be(124) end it "gets the total number of offline cores" do expect(@plugin["cpu"]["cpustates"]["off-line"]).to be(4) end describe "per-cpu information" do it "includes processor model names" do expect(@plugin["cpu"]["0"]["model_name"]).to eql("SPARC-T3") expect(@plugin["cpu"]["1"]["model_name"]).to eql("SPARC-T3") expect(@plugin["cpu"]["2"]["model_name"]).to eql("SPARC-T3") expect(@plugin["cpu"]["3"]["model_name"]).to eql("SPARC-T3") expect(@plugin["cpu"]["124"]["model_name"]).to eql("SPARC-T4") expect(@plugin["cpu"]["125"]["model_name"]).to eql("SPARC-T4") expect(@plugin["cpu"]["126"]["model_name"]).to eql("SPARC-T4") expect(@plugin["cpu"]["127"]["model_name"]).to eql("SPARC-T4") end it "includes processor sockets" do expect(@plugin["cpu"]["0"]["socket"]).to eql("0") expect(@plugin["cpu"]["1"]["socket"]).to eql("0") expect(@plugin["cpu"]["2"]["socket"]).to eql("0") expect(@plugin["cpu"]["3"]["socket"]).to eql("0") expect(@plugin["cpu"]["124"]["socket"]).to eql("0") expect(@plugin["cpu"]["125"]["socket"]).to eql("0") expect(@plugin["cpu"]["126"]["socket"]).to eql("0") expect(@plugin["cpu"]["127"]["socket"]).to eql("0") end it "includes processor MHz" do expect(@plugin["cpu"]["0"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["1"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["2"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["3"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["124"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["125"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["126"]["mhz"]).to eql("1649") expect(@plugin["cpu"]["127"]["mhz"]).to eql("1649") end it "includes processor core IDs" do expect(@plugin["cpu"]["0"]["core_id"]).to eql("1026") expect(@plugin["cpu"]["8"]["core_id"]).to eql("1033") expect(@plugin["cpu"]["16"]["core_id"]).to eql("1040") expect(@plugin["cpu"]["24"]["core_id"]).to eql("1047") expect(@plugin["cpu"]["32"]["core_id"]).to eql("1054") expect(@plugin["cpu"]["40"]["core_id"]).to eql("1061") expect(@plugin["cpu"]["48"]["core_id"]).to eql("1068") expect(@plugin["cpu"]["56"]["core_id"]).to eql("1075") expect(@plugin["cpu"]["64"]["core_id"]).to eql("1082") expect(@plugin["cpu"]["72"]["core_id"]).to eql("1089") expect(@plugin["cpu"]["80"]["core_id"]).to eql("1096") expect(@plugin["cpu"]["88"]["core_id"]).to eql("1103") expect(@plugin["cpu"]["96"]["core_id"]).to eql("1110") expect(@plugin["cpu"]["104"]["core_id"]).to eql("1117") expect(@plugin["cpu"]["112"]["core_id"]).to eql("1124") expect(@plugin["cpu"]["120"]["core_id"]).to eql("1131") end it "includes processor architecture" do expect(@plugin["cpu"]["0"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["1"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["2"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["3"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["124"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["125"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["126"]["arch"]).to eql("sparcv9") expect(@plugin["cpu"]["127"]["arch"]).to eql("sparcv9") end it "includes processor FPU type" do expect(@plugin["cpu"]["0"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["1"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["2"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["3"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["124"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["125"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["126"]["fpu_type"]).to eql("sparcv9") expect(@plugin["cpu"]["127"]["fpu_type"]).to eql("sparcv9") end it "includes processor state" do expect(@plugin["cpu"]["0"]["state"]).to eql("on-line") expect(@plugin["cpu"]["1"]["state"]).to eql("on-line") expect(@plugin["cpu"]["2"]["state"]).to eql("on-line") expect(@plugin["cpu"]["3"]["state"]).to eql("on-line") expect(@plugin["cpu"]["124"]["state"]).to eql("off-line") expect(@plugin["cpu"]["125"]["state"]).to eql("off-line") expect(@plugin["cpu"]["126"]["state"]).to eql("off-line") expect(@plugin["cpu"]["127"]["state"]).to eql("off-line") end end end end ohai-16.0.7/spec/unit/plugins/solaris2/dmi_spec.rb000066400000000000000000000112351362624620500217750ustar00rootroot00000000000000# # Author:: Thom May () # Copyright:: Copyright (c) 2015 Chef Software # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" SOLARIS_DMI_OUT = <<~EOS.freeze ID SIZE TYPE 0 64 SMB_TYPE_BIOS (type 0) (BIOS information) Vendor: American Megatrends Inc. Version String: 4701 Release Date: 08/26/2014 Address Segment: 0xf000 ROM Size: 8388608 bytes Image Size: 65536 bytes Characteristics: 0x53f8b9c80 SMB_BIOSFL_PCI (PCI is supported) SMB_BIOSFL_APM (APM is supported) SMB_BIOSFL_FLASH (BIOS is Flash Upgradeable) SMB_BIOSFL_SHADOW (BIOS shadowing is allowed) SMB_BIOSFL_CDBOOT (Boot from CD is supported) SMB_BIOSFL_SELBOOT (Selectable Boot supported) SMB_BIOSFL_ROMSOCK (BIOS ROM is socketed) SMB_BIOSFL_EDD (EDD Spec is supported) SMB_BIOSFL_525_12M (int 0x13 5.25" 1.2M floppy) SMB_BIOSFL_35_720K (int 0x13 3.5" 720K floppy) SMB_BIOSFL_35_288M (int 0x13 3.5" 2.88M floppy) SMB_BIOSFL_I5_PRINT (int 0x5 print screen svcs) SMB_BIOSFL_I9_KBD (int 0x9 8042 keyboard svcs) SMB_BIOSFL_I14_SER (int 0x14 serial svcs) SMB_BIOSFL_I17_PRINTER (int 0x17 printer svcs) 0x100000000 0x400000000 Characteristics Extension Byte 1: 0x3 SMB_BIOSXB1_ACPI (ACPI is supported) SMB_BIOSXB1_USBL (USB legacy is supported) Characteristics Extension Byte 2: 0xd SMB_BIOSXB2_BBOOT (BIOS Boot Specification supported) SMB_BIOSXB2_ETCDIST (Enable Targeted Content Distrib.) SMB_BIOSXB2_UEFI (UEFI Specification supported) Version Number: 0.0 Embedded Ctlr Firmware Version Number: 0.0 ID SIZE TYPE 1 129 SMB_TYPE_SYSTEM (type 1) (system information) Manufacturer: System manufacturer Product: System Product Name Version: System Version Serial Number: System Serial Number UUID: 20b1001e-8c00-0072-5566-10c37b474fc1 Wake-Up Event: 0x6 (power switch) SKU Number: SKU Family: To be filled by O.E.M. ID SIZE TYPE 2 116 SMB_TYPE_BASEBOARD (type 2) (base board) Manufacturer: ASUSTeK COMPUTER INC. Product: P9X79 WS Version: Rev 1.xx Serial Number: 140525831000250 Asset Tag: To be filled by O.E.M. Location Tag: To be filled by O.E.M. Chassis: 3 Flags: 0x9 SMB_BBFL_MOTHERBOARD (board is a motherboard) SMB_BBFL_REPLACABLE (board is field-replacable) Board Type: 0xa (motherboard) ID SIZE TYPE 46 38 SMB_TYPE_OBDEVS (type 10) (on-board devices) Onboard Ethernet Onboard Audio ID SIZE TYPE 3 106 SMB_TYPE_CHASSIS (type 3) (system enclosure or chassis) Manufacturer: Chassis Manufacture Version: Chassis Version Serial Number: Chassis Serial Number Asset Tag: PCS OEM Data: 0x0 SKU number: ^E Lock Present: N Chassis Type: 0x3 (desktop) Boot-Up State: 0x3 (safe) Power Supply State: 0x3 (safe) Thermal State: 0x3 (safe) Chassis Height: 0u Power Cords: 1 Element Records: 0 EOS describe Ohai::System, "Solaris2.X DMI plugin" do before do @plugin = get_plugin("solaris2/dmi") allow(@plugin).to receive(:collect_os).and_return("solaris2") @stdout = SOLARIS_DMI_OUT allow(@plugin).to receive(:shell_out).with("smbios").and_return(mock_shell_out(0, @stdout, "")) end it "runs smbios" do expect(@plugin).to receive(:shell_out).with("smbios").and_return(mock_shell_out(0, @stdout, "")) @plugin.run end { bios: { vendor: "American Megatrends Inc.", release_date: "08/26/2014", }, system: { manufacturer: "System manufacturer", product: "System Product Name", }, chassis: { lock_present: "N", asset_tag: "PCS", }, }.each do |id, data| data.each do |attribute, value| it "has [:dmi][:#{id}][:#{attribute}] set" do @plugin.run expect(@plugin[:dmi][id][attribute]).to eql(value) end end end it "ignores unwanted types" do @plugin.run expect(@plugin[:dmi]).not_to have_key(:on_board_devices) end end ohai-16.0.7/spec/unit/plugins/solaris2/filesystem.rb000066400000000000000000000531141362624620500224000ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "spec_helper" describe Ohai::System, "Solaris2.X filesystem plugin" do let(:plugin) { get_plugin("filesystem") } before do allow(plugin).to receive(:collect_os).and_return("solaris2") end describe "filesystem properties" do let(:plugin_config) { {} } before do @original_plugin_config = Ohai.config[:plugin] Ohai.config[:plugin] = plugin_config allow(plugin).to receive(:shell_out).with("df -Pka").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("df -na").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("mount").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("zfs get -p -H all").and_return(mock_shell_out(0, "", "")) @df_pka = <<~DF_PKA Filesystem 1024-blocks Used Available Capacity Mounted on rpool/ROOT/solaris-0 730451045 2172071 727373448 1% / rpool/ROOT/solaris-0/var 730451045 850302 727373448 1% /var /dev 0 0 0 0% /dev proc 0 0 0 0% /proc ctfs 0 0 0 0% /system/contract mnttab 0 0 0 0% /etc/mnttab objfs 0 0 0 0% /system/object swap 18544280 568 18543712 1% /system/volatile sharefs 0 0 0 0% /etc/dfs/sharetab fd 0 0 0 0% /dev/fd swap 18666120 122408 18543712 1% /tmp rpool/VARSHARE 730451045 1181 727373448 1% /var/share rpool/export 730451045 32 727373448 1% /export rpool/export/home 730451045 182277 727373448 1% /export/home rpool 730451045 31 727373448 1% /rpool rpool/VARSHARE/pkg 730451045 32 727373448 1% /var/share/pkg rpool/VARSHARE/pkg/repositories 730451045 31 727373448 1% /var/share/pkg/repositories rpool/export/home/shian 730451045 37 727373448 1% /export/home/shain rpool/export/home/phild 730451045 38 727373448 1% /export/home/phild r -hosts 0 0 0 0% /net auto_home 0 0 0 0% /home -fedfs 0 0 0 0% /nfs4 DF_PKA @mount = <<~MOUNT / on rpool/ROOT/solaris-0 read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/mountpoint=/zones/servername.chef.internal.dns/root//zone=servername.chef.internal.dns/nozonemod/sharezone=151/dev=4bd0b7e on Fri Feb 2 16:27:36 2018 /var on rpool/ROOT/solaris-0/var read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/mountpoint=/zones/servername.chef.internal.dns/root/var/zone=servername.chef.internal.dns/nozonemod/sharezone=151/dev=4bd0b7f on Fri Feb 2 16:27:36 2018 /dev on /dev read/write/setuid/devices/rstchown/zone=servername.chef.internal.dns/nozonemod/sharezone=151/dev=8f8003a on Fri Feb 2 16:27:36 2018 /proc on proc read/write/setuid/nodevices/rstchown/zone=servername.chef.internal.dns/sharezone=151/dev=8f40096 on Fri Feb 2 16:27:37 2018 /system/contract on ctfs read/write/setuid/nodevices/rstchown/zone=servername.chef.internal.dns/sharezone=151/dev=8fc0097 on Fri Feb 2 16:27:37 2018 /etc/mnttab on mnttab read/write/setuid/nodevices/rstchown/zone=servername.chef.internal.dns/sharezone=151/dev=9000097 on Fri Feb 2 16:27:37 2018 /system/object on objfs read/write/setuid/nodevices/rstchown/zone=servername.chef.internal.dns/sharezone=151/dev=9080097 on Fri Feb 2 16:27:37 2018 /system/volatile on swap read/write/setuid/nodevices/rstchown/xattr/zone=servername.chef.internal.dns/sharezone=151/dev=90406f0 on Fri Feb 2 16:27:37 2018 /etc/dfs/sharetab on sharefs read/write/setuid/nodevices/rstchown/zone=servername.chef.internal.dns/sharezone=151/dev=90c004d on Fri Feb 2 16:27:37 2018 /dev/fd on fd read/write/setuid/nodevices/rstchown/zone=servername.chef.internal.dns/sharezone=151/dev=91c007d on Fri Feb 2 16:27:44 2018 /tmp on swap read/write/setuid/nodevices/rstchown/xattr/zone=servername.chef.internal.dns/sharezone=151/dev=90406f1 on Fri Feb 2 16:27:45 2018 /var/share on rpool/VARSHARE read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b80 on Fri Feb 2 16:27:45 2018 /export on rpool/export read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b81 on Fri Feb 2 16:28:11 2018 /export/home on rpool/export/home read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b82 on Fri Feb 2 16:28:11 2018 /rpool on rpool read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b83 on Fri Feb 2 16:28:11 2018 /var/share/pkg on rpool/VARSHARE/pkg read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b84 on Fri Feb 2 16:28:12 2018 /var/share/pkg/repositories on rpool/VARSHARE/pkg/repositories read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b85 on Fri Feb 2 16:28:12 2018 /export/home/ on rpool/export/home/ read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b8a on Fri Feb 2 16:39:15 2018 /export/home/ on rpool/export/home/ read/write/setuid/nodevices/rstchown/nonbmand/exec/xattr/atime/zone=servername.chef.internal.dns/sharezone=151/dev=4bd0b8b on Fri Feb 2 16:39:16 2018 MOUNT @zfs_get = <<~ZFS_GET data0 type filesystem - data0 creation 1331514391 - data0 used 7926803118480 - data0 available 3666345412208 - data0 referenced 60350619952 - data0 compressratio 1.04x - data0 mounted yes - data0 quota 0 default data0 reservation 0 default data0 recordsize 131072 default data0 mountpoint /data0 default data0 sharenfs rw=192.168.130.0/24,rw=[2001:470:1f05:2c9::]/64,rw=[2001:470:8122:dd40::10] local data0 checksum on default data0 compression off local data0 atime off local data0 devices on default data0 exec on default data0 setuid on default data0 readonly off default data0 zoned off default data0 snapdir hidden default data0 aclinherit restricted default data0 canmount on default data0 xattr on default data0 copies 1 default data0 version 5 - data0 utf8only off - data0 normalization none - data0 casesensitivity sensitive - data0 vscan off default data0 nbmand off default data0 sharesmb off default data0 refquota 0 default data0 refreservation 0 default data0 primarycache all default data0 secondarycache all default data0 usedbysnapshots 157243047152 - data0 usedbydataset 60350619952 - data0 usedbychildren 7709209451376 - data0 usedbyrefreservation 0 - data0 logbias latency default data0 dedup off default data0 mlslabel none default data0 sync standard default data0 refcompressratio 1.29x - data0 written 4183965296 - data0 logicalused 8240006744576 - data0 logicalreferenced 75625359872 - data0 filesystem_limit 18446744073709551615 default data0 snapshot_limit 18446744073709551615 default data0 filesystem_count 18446744073709551615 default data0 snapshot_count 18446744073709551615 default data0 snapdev hidden default data0 acltype off default data0 context none default data0 fscontext none default data0 defcontext none default data0 rootcontext none default data0 relatime off default data0 redundant_metadata all default data0 overlay off default data0@20130228 type snapshot - data0@20130228 creation 1362119670 - data0@20130228 used 0 - data0@20130228 referenced 57161787648 - data0@20130228 compressratio 1.30x - data0@20130228 devices on default data0@20130228 exec on default data0@20130228 setuid on default data0@20130228 xattr on default data0@20130228 version 5 - data0@20130228 utf8only off - data0@20130228 normalization none - data0@20130228 casesensitivity sensitive - data0@20130228 nbmand off default data0@20130228 primarycache all default data0@20130228 secondarycache all default data0@20130228 defer_destroy off - data0@20130228 userrefs 0 - data0@20130228 mlslabel none default data0@20130228 refcompressratio 1.30x - data0@20130228 written 57161787648 - data0@20130228 clones - data0@20130228 logicalused 0 - data0@20130228 logicalreferenced 72138856960 - data0@20130228 acltype off default data0@20130228 context none default data0@20130228 fscontext none default data0@20130228 defcontext none default data0@20130228 rootcontext none default data0@20130301 type snapshot - data0@20130301 creation 1362122621 - data0@20130301 used 0 - data0@20130301 referenced 57161787648 - data0@20130301 compressratio 1.30x - data0@20130301 devices on default data0@20130301 exec on default data0@20130301 setuid on default data0@20130301 xattr on default data0@20130301 version 5 - data0@20130301 utf8only off - data0@20130301 normalization none - data0@20130301 casesensitivity sensitive - data0@20130301 nbmand off default data0@20130301 primarycache all default data0@20130301 secondarycache all default data0@20130301 defer_destroy off - data0@20130301 userrefs 0 - data0@20130301 mlslabel none default data0@20130301 refcompressratio 1.30x - data0@20130301 written 0 - data0@20130301 clones - data0@20130301 logicalused 0 - data0@20130301 logicalreferenced 72138856960 - data0@20130301 acltype off default data0@20130301 context none default data0@20130301 fscontext none default data0@20130301 defcontext none default data0@20130301 rootcontext none default data0@20130310 type snapshot - data0@20130310 creation 1362955150 - data0@20130310 used 281392 - data0@20130310 referenced 57173475232 - data0@20130310 compressratio 1.30x - data0@20130310 devices on default data0@20130310 exec on default data0@20130310 setuid on default data0@20130310 xattr on default data0@20130310 version 5 - data0@20130310 utf8only off - data0@20130310 normalization none - data0@20130310 casesensitivity sensitive - data0@20130310 nbmand off default data0@20130310 primarycache all default data0@20130310 secondarycache all default data0@20130310 defer_destroy off - data0@20130310 userrefs 0 - data0@20130310 mlslabel none default data0@20130310 refcompressratio 1.30x - data0@20130310 written 11968976 - data0@20130310 clones - data0@20130310 logicalused 0 - data0@20130310 logicalreferenced 72164488192 - data0@20130310 acltype off default data0@20130310 context none default data0@20130310 fscontext none default data0@20130310 defcontext none default data0@20130310 rootcontext none default data0@20160311 type snapshot - data0@20160311 creation 1457762233 - data0@20160311 used 155723556528 - data0@20160311 referenced 211890289712 - data0@20160311 compressratio 1.24x - data0@20160311 devices on default data0@20160311 exec on default data0@20160311 setuid on default data0@20160311 xattr on default data0@20160311 version 5 - data0@20160311 utf8only off - data0@20160311 normalization none - data0@20160311 casesensitivity sensitive - data0@20160311 nbmand off default data0@20160311 primarycache all default data0@20160311 secondarycache all default data0@20160311 defer_destroy off - data0@20160311 userrefs 0 - data0@20160311 mlslabel none default data0@20160311 refcompressratio 1.24x - data0@20160311 written 156235945184 - data0@20160311 clones - data0@20160311 logicalused 0 - data0@20160311 logicalreferenced 259598664192 - data0@20160311 acltype off default data0@20160311 context none default data0@20160311 fscontext none default data0@20160311 defcontext none default data0@20160311 rootcontext none default data0/Movies type filesystem - data0/Movies creation 1331530217 - data0/Movies used 642640700304 - data0/Movies available 3666345412208 - data0/Movies referenced 586525311344 - data0/Movies compressratio 1.00x - data0/Movies mounted yes - data0/Movies quota 0 default data0/Movies reservation 0 default data0/Movies recordsize 131072 default data0/Movies mountpoint /data0/Movies default data0/Movies sharenfs sec=sys,rw=192.168.130.0/24,rw=192.168.135.0/24,rw=[2001:470:1f05:2c9::]/64,rw=[2001:470:8122::]/48,rw=[2001:470:8122:dd40::10]local data0/Movies checksum on default data0/Movies compression off inherited from data0 data0/Movies atime off local data0/Movies devices on default data0/Movies exec on default data0/Movies setuid on default data0/Movies readonly off default data0/Movies zoned off default data0/Movies snapdir hidden default data0/Movies aclinherit restricted default data0/Movies canmount on default data0/Movies xattr on default data0/Movies copies 1 default data0/Movies version 5 - data0/Movies utf8only off - data0/Movies normalization none - data0/Movies casesensitivity sensitive - data0/Movies vscan off default data0/Movies nbmand off default data0/Movies sharesmb off local data0/Movies refquota 0 default data0/Movies refreservation 0 default data0/Movies primarycache all default data0/Movies secondarycache all default data0/Movies usedbysnapshots 56115388960 - data0/Movies usedbydataset 586525311344 - data0/Movies usedbychildren 0 - data0/Movies usedbyrefreservation 0 - data0/Movies logbias latency default data0/Movies dedup off default data0/Movies mlslabel none default data0/Movies sync standard default data0/Movies refcompressratio 1.00x - data0/Movies written 197038505024 - data0/Movies logicalused 642795343360 - data0/Movies logicalreferenced 586666194432 - data0/Movies filesystem_limit 18446744073709551615 default data0/Movies snapshot_limit 18446744073709551615 default data0/Movies filesystem_count 18446744073709551615 default data0/Movies snapshot_count 18446744073709551615 default data0/Movies snapdev hidden default data0/Movies acltype off default data0/Movies context none default data0/Movies fscontext none default data0/Movies defcontext none default data0/Movies rootcontext none default data0/Movies relatime off default data0/Movies redundant_metadata all default data0/Movies overlay off default: ZFS_GET end after do Ohai.config[:plugin] = @original_plugin_config end context "reports filesystem data" do before do allow(plugin).to receive(:shell_out) .with("mount") .and_return(mock_shell_out(0, @mount, nil)) allow(plugin).to receive(:shell_out) .with("df -Pka") .and_return(mock_shell_out(0, @df_pka, nil)) # TODO: get this output # allow(plugin).to receive(:shell_out) # .with("df -na") # .and_return(mock_shell_out(0, @df_na, nil)) plugin.run end it "returns kb_used" do expect(plugin[:filesystem]["rpool/VARSHARE"]["kb_used"]).to eq("1181") expect(plugin[:filesystem2]["by_pair"]["rpool/VARSHARE,/var/share"]["kb_used"]).to eq("1181") end it "returns mount" do expect(plugin[:filesystem]["rpool/VARSHARE"]["mount"]).to eq("/var/share") expect(plugin[:filesystem2]["by_pair"]["rpool/VARSHARE,/var/share"]["mount"]).to eq("/var/share") end it "returns mount_opts" do opts = %w{ read write setuid nodevices rstchown nonbmand exec xattr atime zone=servername.chef.internal.dns sharezone=151 dev=4bd0b80 } expect(plugin[:filesystem]["rpool/VARSHARE"]["mount_options"]).to eq(opts) expect(plugin[:filesystem2]["by_pair"]["rpool/VARSHARE,/var/share"]["mount_options"]).to eq(opts) end end context "handles zfs properties" do before do allow(plugin).to receive(:shell_out) .with("zfs get -p -H all") .and_return(mock_shell_out(0, @zfs_get, nil)) plugin.run end it "returns top-level stats" do # old API expect(plugin[:filesystem]["data0"]["fs_type"]).to eq("zfs") expect(plugin[:filesystem]["data0"]["mount"]).to eq("/data0") # new API expect(plugin[:filesystem2]["by_pair"]["data0,/data0"]["fs_type"]).to eq("zfs") expect(plugin[:filesystem2]["by_pair"]["data0,/data0"]["mount"]).to eq("/data0") end it "returns zfs-specific properties" do # old API expect(plugin[:filesystem]["data0"]["zfs_values"]["used"]).to eq("7926803118480") expect(plugin[:filesystem]["data0"]["zfs_sources"]["used"]).to eq("-") # new API expect(plugin[:filesystem2]["by_pair"]["data0,/data0"]["zfs_properties"]["used"]["value"]).to eq("7926803118480") expect(plugin[:filesystem2]["by_pair"]["data0,/data0"]["zfs_properties"]["used"]["source"]).to eq("-") end end end end ohai-16.0.7/spec/unit/plugins/solaris2/hostname_spec.rb000066400000000000000000000026111362624620500230400ustar00rootroot00000000000000# # Author:: Daniel DeLeo # Copyright:: Copyright (c) 2009 Daniel DeLeo # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris2.X hostname plugin" do before do @plugin = get_plugin("hostname") allow(@plugin).to receive(:collect_os).and_return(:solaris2) allow(@plugin).to receive(:resolve_fqdn).and_return("kitteh.inurfridge.eatinurfoodz") allow(@plugin).to receive(:shell_out).with("hostname").and_return(mock_shell_out(0, "kitteh\n", "")) # Socket.stub(:getaddrinfo).and_return( [["AF_INET", 0, "kitteh.inurfridge.eatinurfoodz", "10.1.2.3", 2, 0, 0]] ); end it_should_check_from("solaris2::hostname", "hostname", "hostname", "kitteh") it "gets the fqdn value from #resolve_fqdn" do @plugin.run expect(@plugin["fqdn"]).to eq("kitteh.inurfridge.eatinurfoodz") end end ohai-16.0.7/spec/unit/plugins/solaris2/kernel_spec.rb000066400000000000000000000237661362624620500225200ustar00rootroot00000000000000# # Author:: Daniel DeLeo # Copyright:: Copyright (c) 2009 Daniel DeLeo # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris2.X kernel plugin" do # NOTE: Solaris will report the same module loaded multiple times # with the same ID, Loadaddr, etc. and only the info column different # ignoring it, and removing the data from this fixture. MODINFO = <<-TOOMUCH.freeze Id Loadaddr Size Info Rev Module Name 6 1180000 4623 1 1 specfs (filesystem for specfs) 8 1185df0 38c4 1 1 TS (time sharing sched class) 9 1188f50 8dc - 1 TS_DPTBL (Time sharing dispatch table) 10 1188fe0 3623e 2 1 ufs (filesystem for ufs) 11 11bc7ae 1ef - 1 fssnap_if (File System Snapshot Interface) 12 11bc8f6 1b3a 1 1 rootnex (sun4u root nexus 1.95) 13 11be023 210 57 1 options (options driver) 15 11be6ff 181a 12 1 sad (STREAMS Administrative Driver ') 16 11bfc79 64b 2 1 pseudo (nexus driver for 'pseudo') 17 11c0152 23563 32 1 sd (SCSI Disk Driver 1.447) 18 11e160d 8c49 - 1 scsi (SCSI Bus Utility Routines) 23 12171db 1072b 50 1 glm (GLM SCSI HBA Driver 1.191.) 24 1225816 edcb 111 1 pcipsy (PCI Bus nexus driver 1.214) 26 123e0eb 15b7 - 1 dada ( ATA Bus Utility Routines) 27 123f30a 722 - 1 todmostek (tod module for Mostek M48T59 1.) 28 11e7342 1a902 5 1 procfs (filesystem for proc) 29 12335a1 da0 134 1 power (power button driver v1.10) 30 1234199 15cb 126 1 ebus (ebus nexus driver 1.44) 32 123f9a4 12215 6 1 sockfs (filesystem for sockfs) 34 12365ba 6ae 11 1 clone (Clone Pseudodriver 'clone') 35 1251709 7b1a6 0 1 ip (IP Streams module) 36 1236a10 34f 1 1 ip6 (IP Streams module) 37 12c56af 282d1 2 1 tcp (TCP Streams module) 38 1236ba4 107d - 1 md5 (MD5 Message-Digest Algorithm) 39 1237b6c 365 3 1 tcp6 (TCP Streams module) 40 1201148 a22f 4 1 udp (UDP Streams module) 41 1237d11 365 5 1 udp6 (UDP Streams module) 42 12096ef 86eb 6 1 icmp (ICMP Streams module) 43 1237eb6 351 7 1 icmp6 (ICMP Streams module) 44 123804c 6d5b 8 1 arp (ARP Streams module) 45 1210282 46ba 9 1 timod (transport interface str mod) 47 12152d1 c53 16 1 conskbd (Console kbd Multiplexer driver ) 48 1215b88 1ec2 15 1 wc (Workstation multiplexer Driver ) 49 12e66d4 516c 37 1 su (su driver 1.80) 51 12ed065 4026 10 1 kb (streams module for keyboard) 52 12efe3b 18c0 11 1 ms (streams module for mouse) 53 12f14f7 a87 17 1 consms (Mouse Driver for Sun 'consms' 5) 54 12f1bf6 b9d6 166 1 gfxp (TSI tspci driver %I%) 55 12fb934 d77 14 1 iwscn (Workstation Redirection driver ) 58 1321301 4a4e 1 1 elfexec (exec module for elf) 62 1328758 10bca - 1 usba (USBA: USB Architecture 1.36) 64 1337002 4884 - 1 mpxio (Multipath Interface Library v1.) 68 131ded0 36d9 3 1 fifofs (filesystem for fifo) 69 131248e 6888 - 1 fctl (Sun FC Transport Library v1.14) 71 1345ddc 18cff - 1 usba10 (USBA10: USB 1.0 Architecture 1.) 75 135b92b f0e2 12 1 ldterm (terminal line discipline) 76 1326309 246d 13 1 ttcompat (alt ioctl calls) 77 133b574 8cbb 29 1 zs (Z8530 serial driver V4.128) 78 1343d27 15d0 26 1 ptsl (tty pseudo driver slave 'ptsl' ) 79 12fc4f3 1e77 25 1 ptc (tty pseudo driver control 'ptc') 81 13748db 1d2c 14 1 rts (Routing Socket Streams module) 88 136a112 ac5a 20 1 se (Siemens SAB 82532 ESCC2 1.128) 89 13cf520 4be3 105 1 tl (TPI Local Transport Driver - tl) 90 13d3d1b 48d3 17 1 keysock (PF_KEY Socket Streams module) 91 13d7766 323f 234 1 spdsock (PF_POLICY Socket Streams device) 92 137c3fb 1672 97 1 sysmsg (System message redirection (fan) 93 12fe1ba 82c 0 1 cn (Console redirection driver 5.57) 94 7814fba6 4b5 2 1 intpexec (exec mod for interp) 95 12fe826 2cb 42 1 pipe (pipe(2) syscall) 96 137d2dd 112d 13 1 mm (memory driver 1.68) 97 13da515 ea79 7 1 hme (10/100Mb Ethernet Driver v1.167) 98 78058000 2e313 85 1 md (Solaris Volume Manager base mod) 99 13e6c82 127bc 226 1 rpcmod (RPC syscall) 100 13f6ab6 1f99 - 1 tlimod (KTLI misc module) 101 13f89a9 54e8 - 1 md_stripe (Solaris Volume Manager stripes ) 102 78086000 13316 - 1 md_mirror (Solaris Volume Manager mirrors ) 103 78084c17 1669 15 1 mntfs (mount information file system) 105 78098156 fe0 12 1 fdfs (filesystem for fd) 106 7809a000 46d7 201 1 doorfs (doors) 107 7809e3c4 16e2 4 1 namefs (filesystem for namefs) 108 780a0000 15ef2 11 1 tmpfs (filesystem for tmpfs) 109 78098ca6 1054 90 1 kstat (kernel statistics driver 1.18) 110 1375e9f 3aa9 88 1 devinfo (DEVINFO Driver 1.48) 111 13fda05 25b9 38 1 openeepr (OPENPROM/NVRAM Driver v1.14) 112 780a5886 9c7 21 1 log (streams log driver) 113 780bc000 2c080 106 1 nfs (NFS syscall, client, and common) 114 780ea000 4e43 - 1 rpcsec (kernel RPC security module.) 115 780f4000 8667 - 1 klmmod (lock mgr common module) 116 780f0000 354c 2 1 FX (Fixed priority sched class) 117 137e232 2ae - 1 FX_DPTBL (Fixed priority dispatch table) 118 780fc000 668b 17 1 autofs (filesystem for autofs) 119 780eeaab 1bba 104 1 random (random number device v1.8) 120 12eb400 1b66 - 1 sha1 (SHA1 Message-Digest Algorithm) 122 780f2788 13b8 - 1 bootdev (bootdev misc module 1.18) 124 78124000 579e 127 1 pm (power management driver v1.104) 125 781106aa 10b7 207 1 pset (processor sets) 126 7812a000 289d 52 1 shmsys (System V shared memory) 127 1216e2a 3dc - 1 ipc (common ipc code) 128 7812e000 ee14 - 1 md_raid (Solaris Volume Manager raid mod) 129 7813e000 d0cd - 1 md_trans (Solaris Volume Manager trans mo) 130 7814c000 2a03 - 1 md_hotspares (Solaris Volume Manager hot spar) 131 7814ab55 1004 - 1 md_notify (Solaris Volume Manager notifica) 132 7809f7f6 903 22 1 sy (Indirect driver for tty 'sy' 1.) 133 780e541c d34 23 1 ptm (Master streams driver 'ptm' 1.4) 134 7812c76d d36 24 1 pts (Slave Stream Pseudo Terminal dr) 135 7814e728 1617 19 1 ptem (pty hardware emulator) 136 780e5eb8 2a5 20 1 redirmod (redirection module) 137 78150000 6b71 91 1 vol (Volume Management Driver, 1.93) 138 13285ad 2cf 21 1 connld (Streams-based pipes) 139 137e27a 109 3 1 IA (interactive scheduling class) 140 7813c544 1b10 22 1 hwc (streams module for hardware cur) 141 78156871 170f 23 1 bufmod (streams buffer mod) 142 1325c4c 838 72 1 ksyms (kernel symbols driver 1.25) 143 12fea22 14864 33 1 st (SCSI tape Driver 1.238) 144 1379790 2a12 53 1 semsys (System V semaphore facility) 145 12138e4 15e4 4 1 RT (realtime scheduling class) 146 121719e 28c - 1 RT_DPTBL (realtime dispatch table) TOOMUCH before do @plugin = get_plugin("kernel") allow(@plugin).to receive(:collect_os).and_return(:solaris2) allow(@plugin).to receive(:init_kernel).and_return({}) allow(@plugin).to receive(:shell_out).with("uname -s").and_return(mock_shell_out(0, "SunOS\n", "")) allow(@plugin).to receive(:shell_out).with("modinfo").and_return(mock_shell_out(0, MODINFO, "")) @release = StringIO.new(" Oracle Solaris 10 1/13 s10s_u11wos_24a SPARC\n Assembled 17 January 2013") allow(File).to receive(:open).with("/etc/release").and_yield(@release) end it "gives the Solaris update version information" do @release = StringIO.new(" Solaris 10 10/08 s10s_u6wos_07b SPARC\n Use is subject to license terms.\n Assembled 27 October 2008") allow(File).to receive(:open).with("/etc/release").and_yield(@release) @plugin.run expect(@plugin[:kernel][:update]).to eq("10 10/08 s10s_u6wos_07") end it "gives the Oracle Solaris update version information" do @release = StringIO.new(" Oracle Solaris 10 1/13 s10s_u11wos_24a SPARC\n Assembled 17 January 2013") allow(File).to receive(:open).with("/etc/release").and_yield(@release) @plugin.run expect(@plugin[:kernel][:update]).to eq("10 1/13 s10s_u11wos_24") end it "gives the Solaris 11 update version information" do @release = StringIO.new(" Oracle Solaris 11.3 SPARC\n Assembled 25 July 2016") allow(File).to receive(:open).with("/etc/release").and_yield(@release) @plugin.run expect(@plugin[:kernel][:update]).to eq("11.3") end it_should_check_from_deep_mash("solaris2::kernel", "kernel", "os", "uname -s", [0, "SunOS\n", ""]) it "gives excruciating detail about kernel modules" do @plugin.run expect(@plugin[:kernel][:modules]).to have(107).modules # Teh daterz # Id Loadaddr Size Info Rev Module Name # 6 1180000 4623 1 1 specfs (filesystem for specfs) teh_daterz = { "id" => 6, "loadaddr" => "1180000", "size" => 17955, "description" => "filesystem for specfs" } expect(@plugin[:kernel][:modules].keys).to include("specfs") expect(@plugin[:kernel][:modules].keys).not_to include("Module") expect(@plugin[:kernel][:modules]["specfs"]).to eq(teh_daterz) end end ohai-16.0.7/spec/unit/plugins/solaris2/memory_spec.rb000066400000000000000000000027541362624620500225420ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris2.X memory plugin" do before do @plugin = get_plugin("solaris2/memory") allow(@plugin).to receive(:collect_os).and_return("solaris2") allow(@plugin).to receive(:shell_out).with("prtconf | grep Memory").and_return(mock_shell_out(0, "Memory size: 8194 Megabytes\n", "")) @swap_s = "total: 112230656k bytes allocated + 357865576k reserved = 470096232k used, 47057688k available\n" allow(@plugin).to receive(:shell_out).with("swap -s").and_return(mock_shell_out(0, @swap_s, "")) end it "gets the total memory" do @plugin.run expect(@plugin[:memory][:total]).to eql("#{8194 * 1024}kB") end it "gets total swap" do @plugin.run expect(@plugin[:memory][:swap][:total]).to eql("#{(470096232 + 47057688)}kB" ) end it "gets free swap" do @plugin.run expect(@plugin[:memory][:swap][:free]).to eql("47057688kB") end end ohai-16.0.7/spec/unit/plugins/solaris2/network_spec.rb000066400000000000000000000231311362624620500227130ustar00rootroot00000000000000# # Author:: Daniel DeLeo # Copyright:: Copyright (c) 2010-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris2.X network plugin" do before do @solaris_arp_rn = <<~ARP_RN Net to Media Table: IPv4 Device IP Address Mask Flags Phys Addr ------ -------------------- --------------- ----- --------------- rtls0 172.31.4.1 255.255.255.255 00:14:69:81:0b:c0 rtls0 172.31.4.44 255.255.255.255 00:0c:29:c4:9a:11 rtls0 172.31.5.16 255.255.255.255 de:ad:be:ef:3b:ba rtls0 172.31.4.16 255.255.255.255 d8:d3:85:65:39:40 rtls0 172.31.4.12 255.255.255.255 d8:d3:85:bb:43:b0 rtls0 172.31.4.115 255.255.255.255 52:54:00:0d:b7:5b rtls0 172.31.4.126 255.255.255.255 52:54:00:2d:93:0c rtls0 172.31.4.125 255.255.255.255 02:08:20:2e:29:8d rtls0 172.31.4.121 255.255.255.255 52:54:00:25:8a:3f rtls0 172.31.4.103 255.255.255.255 SP 52:54:00:7f:22:e7 rtls0 172.31.4.102 255.255.255.255 02:08:20:88:38:18 rtls0 172.31.4.106 255.255.255.255 02:08:20:6d:cc:aa rtls0 172.31.4.83 255.255.255.255 02:08:20:05:8e:75 rtls0 172.31.4.82 255.255.255.255 52:54:00:2d:93:0c rtls0 172.31.4.81 255.255.255.255 02:08:20:37:80:87 rtls0 224.0.0.0 240.0.0.0 SM 01:00:5e:00:00:00 ARP_RN @solaris_ifconfig = <<~ENDIFCONFIG ipmp0: flags=108000000843 mtu 1500 inet 10.10.130.103 netmask fffffe00 broadcast 10.10.131.255 groupname ipmp0 lo0:3: flags=2001000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 e1000g0:3: flags=201000843 mtu 1500 index 3 inet 72.2.115.28 netmask ffffff80 broadcast 72.2.115.127 e1000g2:1: flags=201000843 mtu 1500 index 4 inet 10.2.115.28 netmask ffffff80 broadcast 10.2.115.127 inet6 2001:0db8:3c4d:55:a00:20ff:fe8e:f3ad/64 net0: flags=40201000843 mtu 1500 index 2 inet 37.153.96.148 netmask fffffe00 broadcast 37.153.97.255 ether 90:b8:d0:16:9b:97 net1:1: flags=100001000843 mtu 1500 index 2 inet 10.16.125.36 netmask fffffe00 broadcast 10.16.125.255 ether 90:b8:d0:16:9b:97 ip.tun0: flags=2200851 mtu 1480 index 3 inet tunnel src 109.146.85.57 tunnel dst 109.146.85.212 tunnel security settings --> use 'ipsecconf -ln -i ip.tun1' tunnel hop limit 60 inet6 fe80::6d92:5539/10 --> fe80::6d92:55d4 ip.tun0:1: flags=2200851 mtu 1480 index 3 inet6 2::45/128 --> 2::46 lo0: flags=1000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 eri0: flags=1004843 mtu 1500 index 2 inet 172.17.128.208 netmask ffffff00 broadcast 172.17.128.255 ip6.tun0: flags=10008d1 mtu 1460 index 3 inet6 tunnel src fe80::1 tunnel dst fe80::2 tunnel security settings --> use 'ipsecconf -ln -i ip.tun1' tunnel hop limit 60 tunnel encapsulation limit 4 inet 10.0.0.208 --> 10.0.0.210 netmask ff000000 qfe1: flags=2000841 mtu 1500 index 3 usesrc vni0 inet6 fe80::203:baff:fe17:4be0/10 ether 0:3:ba:17:4b:e0 vni0: flags=2002210041 mtu 1460 index 5 srcof qfe1 inet6 fe80::203:baff:fe17:4444/128 ENDIFCONFIG @solaris_netstat_rn = <<~NETSTAT_RN Routing Table: IPv4 Destination Gateway Flags Ref Use Interface -------------------- -------------------- ----- ----- ---------- --------- default 10.13.37.1 UG 1 0 e1000g0 10.13.37.0 10.13.37.157 U 1 2 e1000g0 127.0.0.1 127.0.0.1 UH 1 35 lo0 Routing Table: IPv6 Destination/Mask Gateway Flags Ref Use If --------------------------- --------------------------- ----- --- ------- ----- fe80::/10 fe80::250:56ff:fe13:3757 U 1 0 e1000g0 ::1 ::1 UH 1 0 lo0 NETSTAT_RN @solaris_route_get = <<~ROUTE_GET route to: default destination: default mask: default gateway: 10.13.37.1 interface: e1000g0 index 3 flags: recvpipe sendpipe ssthresh rtt,ms rttvar,ms hopcount mtu expire 0 0 0 0 0 0 1500 0 ROUTE_GET @solaris11_route_get = <<~ROUTE_GET route to: default destination: default mask: default gateway: 10.13.37.1 interface: net1 index 2 flags: recvpipe sendpipe ssthresh rtt,ms rttvar,ms hopcount mtu expire 0 0 0 0 0 0 1500 0 ROUTE_GET @ifconfig_lines = @solaris_ifconfig.split("\n") @plugin = get_plugin("solaris2/network") allow(@plugin).to receive(:collect_os).and_return(:solaris2) @plugin[:network] = Mash.new allow(@plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, @solaris_route_get, "")) allow(@plugin).to receive(:shell_out).with("arp -an").and_return(mock_shell_out(0, @solaris_arp_rn, "")) allow(@plugin).to receive(:shell_out).with("route -v -n get default").and_return(mock_shell_out(0, @solaris_route_get, "")) end describe "gathering IP layer address info" do before do @stdout = double("Pipe, stdout, cmd=`route get default`", read: @solaris_route_get) allow(@plugin).to receive(:shell_out).with("route -v -n get default").and_return(mock_shell_out(0, @solaris_route_get, "")) allow(@plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, @solaris_ifconfig, "")) @plugin.run end it "completes the run" do expect(@plugin["network"]).not_to be_nil end it "detects the interfaces" do expect(@plugin["network"]["interfaces"].keys.sort).to eq(["e1000g0:3", "e1000g2:1", "eri0", "ip.tun0", "ip.tun0:1", "ip6.tun0", "ipmp0", "lo0", "lo0:3", "net0", "net1:1", "qfe1", "vni0"]) end it "detects the ip addresses of the interfaces" do expect(@plugin["network"]["interfaces"]["e1000g0:3"]["addresses"].keys).to include("72.2.115.28") end it "detects the encapsulation type of the interfaces" do expect(@plugin["network"]["interfaces"]["e1000g0:3"]["encapsulation"]).to eq("Ethernet") end it "detects the L3PROTECT network flag" do expect(@plugin["network"]["interfaces"]["net0"]["flags"]).to include("L3PROTECT") end it "detects an interface with no index number" do expect(@plugin["network"]["interfaces"]["ipmp0"]["index"]).to eq(nil) expect(@plugin["network"]["interfaces"]["ipmp0"]["mtu"]).to eq("1500") end end describe "gathering solaris 11 zone IP layer address info" do before do @stdout = double("Pipe, stdout, cmd=`route get default`", read: @solaris11_route_get) allow(@plugin).to receive(:shell_out).with("route -v -n get default").and_return(mock_shell_out(0, @solaris11_route_get, "")) allow(@plugin).to receive(:shell_out).with("ifconfig -a").and_return(mock_shell_out(0, @solaris_ifconfig, "")) @plugin.run end it "finds the flags for a PHYSRUNNING interface" do expect(@plugin[:network][:interfaces]["net1:1"][:flags]).to eq(%w{ UP BROADCAST RUNNING MULTICAST IPv4 PHYSRUNNING }) end it "finds the default interface for a solaris 11 zone" do expect(@plugin[:network][:default_interface]).to eq("net1:1") end end # TODO: specs for the arp -an stuff, check that it correctly adds the MAC addr to the right iface, etc. describe "setting the node's default IP address attribute" do before do @stdout = double("Pipe, stdout, cmd=`route get default`", read: @solaris_route_get) allow(@plugin).to receive(:shell_out).with("route -v -n get default").and_return(mock_shell_out(0, @solaris_route_get, "")) @plugin.run end it "finds the default interface by asking which iface has the default route" do expect(@plugin[:network][:default_interface]).to eq("e1000g0") end end end ohai-16.0.7/spec/unit/plugins/solaris2/platform_spec.rb000066400000000000000000000060761362624620500230570ustar00rootroot00000000000000# # Author:: Trevor O () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris plugin platform" do before do @plugin = get_plugin("solaris2/platform") allow(@plugin).to receive(:collect_os).and_return(:solaris2) allow(@plugin).to receive(:shell_out).with("/sbin/uname -X") end describe "on SmartOS" do before do @uname_x = <<~UNAME_X System = SunOS Node = node.example.com Release = 5.11 KernelID = joyent_20120130T201844Z Machine = i86pc BusType = Serial = Users = OEM# = 0 Origin# = 1 NumCPU = 16 UNAME_X allow(File).to receive(:exist?).with("/sbin/uname").and_return(true) allow(@plugin).to receive(:shell_out).with("/sbin/uname -X").and_return(mock_shell_out(0, @uname_x, "")) @release = StringIO.new(" SmartOS 20120130T201844Z x86_64\n") allow(File).to receive(:open).with("/etc/release").and_yield(@release) end it "runs uname and set platform and build" do @plugin.run expect(@plugin[:platform_build]).to eq("joyent_20120130T201844Z") end it "sets the platform" do @plugin.run expect(@plugin[:platform]).to eq("smartos") end it "sets the platform_version" do @plugin.run expect(@plugin[:platform_version]).to eq("5.11") end end describe "on Solaris 11" do before do @uname_x = <<~UNAME_X System = SunOS Node = node.example.com Release = 5.11 KernelID = 11.1 Machine = i86pc BusType = Serial = Users = OEM# = 0 Origin# = 1 NumCPU = 1 UNAME_X allow(File).to receive(:exist?).with("/sbin/uname").and_return(true) allow(@plugin).to receive(:shell_out).with("/sbin/uname -X").and_return(mock_shell_out(0, @uname_x, "")) @release = StringIO.new(" Oracle Solaris 11.1 X86\n") allow(File).to receive(:open).with("/etc/release").and_yield(@release) end it "runs uname and set platform and build" do @plugin.run expect(@plugin[:platform_build]).to eq("11.1") end it "sets the platform" do @plugin.run expect(@plugin[:platform]).to eq("solaris2") end it "sets the platform_version" do @plugin.run expect(@plugin[:platform_version]).to eq("5.11") end end end ohai-16.0.7/spec/unit/plugins/solaris2/virtualization_spec.rb000066400000000000000000000074331362624620500243150ustar00rootroot00000000000000# # Author:: Sean Walbran () # Copyright:: Copyright (c) 2009-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Solaris virtualization platform" do let(:plugin) { get_plugin("solaris2/virtualization") } before do @psrinfo_pv = <<~PSRINFO_PV The physical processor has 1 virtual processor (0) x86 (GenuineIntel family 6 model 2 step 3 clock 2667 MHz) Intel Pentium(r) Pro PSRINFO_PV allow(plugin).to receive(:collect_os).and_return(:solaris2) # default to all requested Files not existing allow(File).to receive(:exist?).with("/usr/sbin/psrinfo").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/smbios").and_return(false) allow(File).to receive(:exist?).with("/usr/sbin/zoneadm").and_return(false) allow(plugin).to receive(:shell_out).with("/usr/sbin/smbios").and_return(mock_shell_out(0, "", "")) allow(plugin).to receive(:shell_out).with("#{Ohai.abs_path( "/usr/sbin/psrinfo" )} -pv").and_return(mock_shell_out(0, "", "")) end describe "when we are checking for kvm" do before do expect(File).to receive(:exist?).with("/usr/sbin/psrinfo").and_return(true) end it "runs psrinfo -pv" do expect(plugin).to receive(:shell_out).with("#{Ohai.abs_path( "/usr/sbin/psrinfo" )} -pv") plugin.run end it "sets kvm guest if psrinfo -pv contains QEMU Virtual CPU" do allow(plugin).to receive(:shell_out).with("#{Ohai.abs_path( "/usr/sbin/psrinfo" )} -pv").and_return(mock_shell_out(0, "QEMU Virtual CPU", "")) plugin.run expect(plugin[:virtualization][:system]).to eq("kvm") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:kvm]).to eq("guest") end it "does not set virtualization if kvm isn't there" do expect(plugin).to receive(:shell_out).with("#{Ohai.abs_path( "/usr/sbin/psrinfo" )} -pv").and_return(mock_shell_out(0, @psrinfo_pv, "")) plugin.run expect(plugin[:virtualization][:systems]).to eq({}) end end describe "when we are parsing DMI data" do it "sets virtualization attributes if the appropriate DMI data is present" do plugin[:dmi] = { system: { manufacturer: "Amazon EC2", product: "c5n.large", version: nil, }, } plugin.run expect(plugin[:virtualization][:system]).to eq("amazonec2") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:amazonec2]).to eq("guest") end it "sets empty virtualization attributes if nothing is detected" do plugin[:dmi] = { system: { manufacturer: "Supermicro", product: "X10SLH-N6-ST031", version: "0123456789", }, } plugin.run expect(plugin[:virtualization]).to eq({ "systems" => {} }) end end it "does not set virtualization if no tests match" do plugin.run expect(plugin[:virtualization][:systems]).to eq({}) end end ohai-16.0.7/spec/unit/plugins/ssh_host_keys_spec.rb000066400000000000000000000124661362624620500223620ustar00rootroot00000000000000# # Author:: Bryan McLellan # Copyright:: Copyright (c) 2012-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "ssh_host_key plugin" do before do @plugin = get_plugin("ssh_host_key") @plugin[:keys] = Mash.new allow(File).to receive(:exist?).with("/etc/ssh/sshd_config").and_return(true) allow(File).to receive(:open).with("/etc/ssh/sshd_config").and_yield(sshd_config_file) allow(File).to receive(:exist?).and_return(true) allow(File).to receive(:exist?).with("/etc/ssh/ssh_host_dsa_key.pub").and_return(true) allow(File).to receive(:exist?).with("/etc/ssh/ssh_host_rsa_key.pub").and_return(true) allow(File).to receive(:exist?).with("/etc/ssh/ssh_host_ecdsa_key.pub").and_return(true) allow(File).to receive(:exist?).with("/etc/ssh/ssh_host_ed25519_key.pub").and_return(true) # Ensure we can still use IO.read io_read = IO.method(:read) allow(IO).to receive(:read) { |file| io_read.call(file) } # Return fake public key files so we don't have to go digging for them in unit tests @dsa_key = "ssh-dss AAAAB3NzaC1kc3MAAACBAMHlT02xN8kietxPfhcb98xHueTzKCOTz6dZlP/dmKILHrQOAExuSEeNiA2uvmhHNVQvs/cBsRiDxgSKux3ie2q8+MB6vHCiSpSkoPjrL75iT57YDilCB4/sytt6IJpj+H42wRDWTX0/QRybMHUvmnmEL0cwZXykSvrIum0BKB6hAAAAFQDsi6WUCClhtZIiTY9uh8eAre+SbQAAAIEAgNnuw0uEuqtcVif+AYd/bCZvL9FPqg7DrmTkamNEcVinhUGwsPGJTLJf+o5ens1X4RzQoi1R6Y6zCTL2FN/hZgINJNO0z9BN402wWrZmQd+Vb1U5DyDtveuvipqyQS+fm9neRwdLuv36Fc9f9nkZ7YHpkGPJp+yJpG4OoeREhwgAAACBAIf9kKLf2XiXnlByzlJ2Naa55d/hp2E059VKCRsBS++xFKYKvSqjnDQBFiMtAUhb8EdTyBGyalqOgqogDQVtwHfTZWZwqHAhry9aM06y92Eu/xSey4tWjKeknOsnRe640KC4zmKDBRTrjjkuAdrKPN9k3jl+OCc669JHlIfo6kqf oppa" @rsa_key = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuhcVXV+nNapkyUC5p4TH1ymRxUjtMBKqYWmwyI29gVFnUNeHkKFHWon0KFeGJP2Rm8BfTiZa9ER9e8pRr4Nd+z1C1o0kVoxEEfB9tpSdTlpk1GG83D94l57fij8THRVIwuCEosViUlg1gDgC4SpxbqfdBkUN2qyf6JDOh7t2QpYh7berpDEWeBpb7BKdLEDT57uw7ijKzSNyaXqq8KkB9I+UFrRwpuos4W7ilX+PQ+mWLi2ZZJfTYZMxxVS+qJwiDtNxGCRwTOQZG03kI7eLBZG+igupr0uD4o6qeftPOr0kxgjoPU4nEKvYiGq8Rqd2vYrhiaJHLk9QB6xStQvS3Q== oppa" @ecdsa_key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBx8VgvxmHxs/sIn/ATh0iUcuz1I2Xc0e1ejXCGHBMZ98IE3FBt1ezlqCpNMcHVV2skQQ8vyLbKxzweyZuNSDU8= oppa" @ed25519_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFYGnIM5K5JaRxbMCqz8cPMmLp57ZoJQvA5Tlj18EO6H djb" allow(IO).to receive(:read).with("/etc/ssh/ssh_host_dsa_key.pub").and_return(@dsa_key) allow(IO).to receive(:read).with("/etc/ssh/ssh_host_rsa_key.pub").and_return(@rsa_key) allow(IO).to receive(:read).with("/etc/ssh/ssh_host_ecdsa_key.pub").and_return(@ecdsa_key) allow(IO).to receive(:read).with("/etc/ssh/ssh_host_ed25519_key.pub").and_return(@ed25519_key) end shared_examples "loads keys" do it "reads the key and sets the dsa attribute correctly" do @plugin.run expect(@plugin[:keys][:ssh][:host_dsa_public]).to eql(@dsa_key.split[1]) expect(@plugin[:keys][:ssh][:host_dsa_type]).to be_nil end it "reads the key and sets the rsa attribute correctly" do @plugin.run expect(@plugin[:keys][:ssh][:host_rsa_public]).to eql(@rsa_key.split[1]) expect(@plugin[:keys][:ssh][:host_rsa_type]).to be_nil end it "reads the key and sets the ecdsa attribute correctly" do @plugin.run expect(@plugin[:keys][:ssh][:host_ecdsa_public]).to eql(@ecdsa_key.split[1]) expect(@plugin[:keys][:ssh][:host_ecdsa_type]).to eql(@ecdsa_key.split[0]) end it "reads the key and sets the ed25519 attribute correctly" do @plugin.run expect(@plugin[:keys][:ssh][:host_ed25519_public]).to eql(@ed25519_key.split[1]) expect(@plugin[:keys][:ssh][:host_ed25519_type]).to be_nil end end context "when an sshd_config exists" do let :sshd_config_file do <<~EOS # HostKeys for protocol version 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key EOS end it_behaves_like "loads keys" end context "when an sshd_config exists with commented entries" do let :sshd_config_file do <<~EOS # HostKeys for protocol version 2 #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key #HostKey /etc/ssh/ssh_host_ecdsa_key #HostKey /etc/ssh/ssh_host_ed25519_key EOS end it_behaves_like "loads keys" end context "when an sshd_config can not be found" do let :sshd_config_file do nil end before do allow(File).to receive(:exist?).with("/etc/ssh/sshd_config").and_return(false) allow(File).to receive(:exist?).with("/etc/sshd_config").and_return(false) end it_behaves_like "loads keys" end end ohai-16.0.7/spec/unit/plugins/sysconf_spec.rb000066400000000000000000000616131362624620500211570ustar00rootroot00000000000000# # Author:: Davide Cavalca # Copyright:: Copyright (c) 2016 Facebook # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "sysconf plugin", :unix_only do let(:plugin) { get_plugin("sysconf") } it "populates sysconf if getconf is found" do getconf_out = <<~GETCONF_OUT LINK_MAX 65000 _POSIX_LINK_MAX 65000 MAX_CANON 255 _POSIX_MAX_CANON 255 MAX_INPUT 255 _POSIX_MAX_INPUT 255 NAME_MAX 255 _POSIX_NAME_MAX 255 PATH_MAX 4096 _POSIX_PATH_MAX 4096 PIPE_BUF 4096 _POSIX_PIPE_BUF 4096 SOCK_MAXBUF _POSIX_ASYNC_IO _POSIX_CHOWN_RESTRICTED 1 _POSIX_NO_TRUNC 1 _POSIX_PRIO_IO _POSIX_SYNC_IO _POSIX_VDISABLE 0 ARG_MAX 2097152 ATEXIT_MAX 2147483647 CHAR_BIT 8 CHAR_MAX 127 CHAR_MIN -128 CHILD_MAX 63672 CLK_TCK 100 INT_MAX 2147483647 INT_MIN -2147483648 IOV_MAX 1024 LOGNAME_MAX 256 LONG_BIT 64 MB_LEN_MAX 16 NGROUPS_MAX 65536 NL_ARGMAX 4096 NL_LANGMAX 2048 NL_MSGMAX 2147483647 NL_NMAX 2147483647 NL_SETMAX 2147483647 NL_TEXTMAX 2147483647 NSS_BUFLEN_GROUP 1024 NSS_BUFLEN_PASSWD 1024 NZERO 20 OPEN_MAX 1024 PAGESIZE 4096 PAGE_SIZE 4096 PASS_MAX 8192 PTHREAD_DESTRUCTOR_ITERATIONS 4 PTHREAD_KEYS_MAX 1024 PTHREAD_STACK_MIN 16384 PTHREAD_THREADS_MAX SCHAR_MAX 127 SCHAR_MIN -128 SHRT_MAX 32767 SHRT_MIN -32768 SSIZE_MAX 32767 TTY_NAME_MAX 32 TZNAME_MAX 6 UCHAR_MAX 255 UINT_MAX 4294967295 UIO_MAXIOV 1024 ULONG_MAX 18446744073709551615 USHRT_MAX 65535 WORD_BIT 32 _AVPHYS_PAGES 2101393 _NPROCESSORS_CONF 8 _NPROCESSORS_ONLN 8 _PHYS_PAGES 4096040 _POSIX_ARG_MAX 2097152 _POSIX_ASYNCHRONOUS_IO 200809 _POSIX_CHILD_MAX 63672 _POSIX_FSYNC 200809 _POSIX_JOB_CONTROL 1 _POSIX_MAPPED_FILES 200809 _POSIX_MEMLOCK 200809 _POSIX_MEMLOCK_RANGE 200809 _POSIX_MEMORY_PROTECTION 200809 _POSIX_MESSAGE_PASSING 200809 _POSIX_NGROUPS_MAX 65536 _POSIX_OPEN_MAX 1024 _POSIX_PII _POSIX_PII_INTERNET _POSIX_PII_INTERNET_DGRAM _POSIX_PII_INTERNET_STREAM _POSIX_PII_OSI _POSIX_PII_OSI_CLTS _POSIX_PII_OSI_COTS _POSIX_PII_OSI_M _POSIX_PII_SOCKET _POSIX_PII_XTI _POSIX_POLL _POSIX_PRIORITIZED_IO 200809 _POSIX_PRIORITY_SCHEDULING 200809 _POSIX_REALTIME_SIGNALS 200809 _POSIX_SAVED_IDS 1 _POSIX_SELECT _POSIX_SEMAPHORES 200809 _POSIX_SHARED_MEMORY_OBJECTS 200809 _POSIX_SSIZE_MAX 32767 _POSIX_STREAM_MAX 16 _POSIX_SYNCHRONIZED_IO 200809 _POSIX_THREADS 200809 _POSIX_THREAD_ATTR_STACKADDR 200809 _POSIX_THREAD_ATTR_STACKSIZE 200809 _POSIX_THREAD_PRIORITY_SCHEDULING 200809 _POSIX_THREAD_PRIO_INHERIT 200809 _POSIX_THREAD_PRIO_PROTECT 200809 _POSIX_THREAD_ROBUST_PRIO_INHERIT _POSIX_THREAD_ROBUST_PRIO_PROTECT _POSIX_THREAD_PROCESS_SHARED 200809 _POSIX_THREAD_SAFE_FUNCTIONS 200809 _POSIX_TIMERS 200809 TIMER_MAX _POSIX_TZNAME_MAX 6 _POSIX_VERSION 200809 _T_IOV_MAX _XOPEN_CRYPT 1 _XOPEN_ENH_I18N 1 _XOPEN_LEGACY 1 _XOPEN_REALTIME 1 _XOPEN_REALTIME_THREADS 1 _XOPEN_SHM 1 _XOPEN_UNIX 1 _XOPEN_VERSION 700 _XOPEN_XCU_VERSION 4 _XOPEN_XPG2 1 _XOPEN_XPG3 1 _XOPEN_XPG4 1 BC_BASE_MAX 99 BC_DIM_MAX 2048 BC_SCALE_MAX 99 BC_STRING_MAX 1000 CHARCLASS_NAME_MAX 2048 COLL_WEIGHTS_MAX 255 EQUIV_CLASS_MAX EXPR_NEST_MAX 32 LINE_MAX 2048 POSIX2_BC_BASE_MAX 99 POSIX2_BC_DIM_MAX 2048 POSIX2_BC_SCALE_MAX 99 POSIX2_BC_STRING_MAX 1000 POSIX2_CHAR_TERM 200809 POSIX2_COLL_WEIGHTS_MAX 255 POSIX2_C_BIND 200809 POSIX2_C_DEV 200809 POSIX2_C_VERSION 200809 POSIX2_EXPR_NEST_MAX 32 POSIX2_FORT_DEV POSIX2_FORT_RUN _POSIX2_LINE_MAX 2048 POSIX2_LINE_MAX 2048 POSIX2_LOCALEDEF 200809 POSIX2_RE_DUP_MAX 32767 POSIX2_SW_DEV 200809 POSIX2_UPE POSIX2_VERSION 200809 RE_DUP_MAX 32767 PATH /bin:/usr/bin CS_PATH /bin:/usr/bin LFS_CFLAGS LFS_LDFLAGS LFS_LIBS LFS_LINTFLAGS LFS64_CFLAGS -D_LARGEFILE64_SOURCE LFS64_LDFLAGS LFS64_LIBS LFS64_LINTFLAGS -D_LARGEFILE64_SOURCE _XBS5_WIDTH_RESTRICTED_ENVS XBS5_LP64_OFF64 XBS5_WIDTH_RESTRICTED_ENVS XBS5_LP64_OFF64 _XBS5_ILP32_OFF32 XBS5_ILP32_OFF32_CFLAGS XBS5_ILP32_OFF32_LDFLAGS XBS5_ILP32_OFF32_LIBS XBS5_ILP32_OFF32_LINTFLAGS _XBS5_ILP32_OFFBIG XBS5_ILP32_OFFBIG_CFLAGS XBS5_ILP32_OFFBIG_LDFLAGS XBS5_ILP32_OFFBIG_LIBS XBS5_ILP32_OFFBIG_LINTFLAGS _XBS5_LP64_OFF64 1 XBS5_LP64_OFF64_CFLAGS -m64 XBS5_LP64_OFF64_LDFLAGS -m64 XBS5_LP64_OFF64_LIBS XBS5_LP64_OFF64_LINTFLAGS _XBS5_LPBIG_OFFBIG XBS5_LPBIG_OFFBIG_CFLAGS XBS5_LPBIG_OFFBIG_LDFLAGS XBS5_LPBIG_OFFBIG_LIBS XBS5_LPBIG_OFFBIG_LINTFLAGS _POSIX_V6_ILP32_OFF32 POSIX_V6_ILP32_OFF32_CFLAGS POSIX_V6_ILP32_OFF32_LDFLAGS POSIX_V6_ILP32_OFF32_LIBS POSIX_V6_ILP32_OFF32_LINTFLAGS _POSIX_V6_WIDTH_RESTRICTED_ENVS POSIX_V6_LP64_OFF64 POSIX_V6_WIDTH_RESTRICTED_ENVS POSIX_V6_LP64_OFF64 _POSIX_V6_ILP32_OFFBIG POSIX_V6_ILP32_OFFBIG_CFLAGS POSIX_V6_ILP32_OFFBIG_LDFLAGS POSIX_V6_ILP32_OFFBIG_LIBS POSIX_V6_ILP32_OFFBIG_LINTFLAGS _POSIX_V6_LP64_OFF64 1 POSIX_V6_LP64_OFF64_CFLAGS -m64 POSIX_V6_LP64_OFF64_LDFLAGS -m64 POSIX_V6_LP64_OFF64_LIBS POSIX_V6_LP64_OFF64_LINTFLAGS _POSIX_V6_LPBIG_OFFBIG POSIX_V6_LPBIG_OFFBIG_CFLAGS POSIX_V6_LPBIG_OFFBIG_LDFLAGS POSIX_V6_LPBIG_OFFBIG_LIBS POSIX_V6_LPBIG_OFFBIG_LINTFLAGS _POSIX_V7_ILP32_OFF32 POSIX_V7_ILP32_OFF32_CFLAGS POSIX_V7_ILP32_OFF32_LDFLAGS POSIX_V7_ILP32_OFF32_LIBS POSIX_V7_ILP32_OFF32_LINTFLAGS _POSIX_V7_WIDTH_RESTRICTED_ENVS POSIX_V7_LP64_OFF64 POSIX_V7_WIDTH_RESTRICTED_ENVS POSIX_V7_LP64_OFF64 _POSIX_V7_ILP32_OFFBIG POSIX_V7_ILP32_OFFBIG_CFLAGS POSIX_V7_ILP32_OFFBIG_LDFLAGS POSIX_V7_ILP32_OFFBIG_LIBS POSIX_V7_ILP32_OFFBIG_LINTFLAGS _POSIX_V7_LP64_OFF64 1 POSIX_V7_LP64_OFF64_CFLAGS -m64 POSIX_V7_LP64_OFF64_LDFLAGS -m64 POSIX_V7_LP64_OFF64_LIBS POSIX_V7_LP64_OFF64_LINTFLAGS _POSIX_V7_LPBIG_OFFBIG POSIX_V7_LPBIG_OFFBIG_CFLAGS POSIX_V7_LPBIG_OFFBIG_LDFLAGS POSIX_V7_LPBIG_OFFBIG_LIBS POSIX_V7_LPBIG_OFFBIG_LINTFLAGS _POSIX_ADVISORY_INFO 200809 _POSIX_BARRIERS 200809 _POSIX_BASE _POSIX_C_LANG_SUPPORT _POSIX_C_LANG_SUPPORT_R _POSIX_CLOCK_SELECTION 200809 _POSIX_CPUTIME 200809 _POSIX_THREAD_CPUTIME 200809 _POSIX_DEVICE_SPECIFIC _POSIX_DEVICE_SPECIFIC_R _POSIX_FD_MGMT _POSIX_FIFO _POSIX_PIPE _POSIX_FILE_ATTRIBUTES _POSIX_FILE_LOCKING _POSIX_FILE_SYSTEM _POSIX_MONOTONIC_CLOCK 200809 _POSIX_MULTI_PROCESS _POSIX_SINGLE_PROCESS _POSIX_NETWORKING _POSIX_READER_WRITER_LOCKS 200809 _POSIX_SPIN_LOCKS 200809 _POSIX_REGEXP 1 _REGEX_VERSION _POSIX_SHELL 1 _POSIX_SIGNALS _POSIX_SPAWN 200809 _POSIX_SPORADIC_SERVER _POSIX_THREAD_SPORADIC_SERVER _POSIX_SYSTEM_DATABASE _POSIX_SYSTEM_DATABASE_R _POSIX_TIMEOUTS 200809 _POSIX_TYPED_MEMORY_OBJECTS _POSIX_USER_GROUPS _POSIX_USER_GROUPS_R POSIX2_PBS POSIX2_PBS_ACCOUNTING POSIX2_PBS_LOCATE POSIX2_PBS_TRACK POSIX2_PBS_MESSAGE SYMLOOP_MAX STREAM_MAX 16 AIO_LISTIO_MAX AIO_MAX AIO_PRIO_DELTA_MAX 20 DELAYTIMER_MAX 2147483647 HOST_NAME_MAX 64 LOGIN_NAME_MAX 256 MQ_OPEN_MAX MQ_PRIO_MAX 32768 _POSIX_DEVICE_IO _POSIX_TRACE _POSIX_TRACE_EVENT_FILTER _POSIX_TRACE_INHERIT _POSIX_TRACE_LOG RTSIG_MAX 32 SEM_NSEMS_MAX SEM_VALUE_MAX 2147483647 SIGQUEUE_MAX 63672 FILESIZEBITS 64 POSIX_ALLOC_SIZE_MIN 4096 POSIX_REC_INCR_XFER_SIZE POSIX_REC_MAX_XFER_SIZE POSIX_REC_MIN_XFER_SIZE 4096 POSIX_REC_XFER_ALIGN 4096 SYMLINK_MAX GNU_LIBC_VERSION glibc 2.24 GNU_LIBPTHREAD_VERSION NPTL 2.24 POSIX2_SYMLINKS 1 LEVEL1_ICACHE_SIZE 32768 LEVEL1_ICACHE_ASSOC 8 LEVEL1_ICACHE_LINESIZE 64 LEVEL1_DCACHE_SIZE 32768 LEVEL1_DCACHE_ASSOC 8 LEVEL1_DCACHE_LINESIZE 64 LEVEL2_CACHE_SIZE 262144 LEVEL2_CACHE_ASSOC 4 LEVEL2_CACHE_LINESIZE 64 LEVEL3_CACHE_SIZE 8388608 LEVEL3_CACHE_ASSOC 16 LEVEL3_CACHE_LINESIZE 64 LEVEL4_CACHE_SIZE 0 LEVEL4_CACHE_ASSOC 0 LEVEL4_CACHE_LINESIZE 0 IPV6 200809 RAW_SOCKETS 200809 _POSIX_IPV6 200809 _POSIX_RAW_SOCKETS 200809 GETCONF_OUT allow(plugin).to receive(:which).with("getconf").and_return("/usr/bin/getconf") allow(plugin).to receive(:shell_out).with("/usr/bin/getconf -a").and_return(mock_shell_out(0, getconf_out, "")) allow(plugin).to receive(:collect_os).and_return(:linux) plugin.run expect(plugin[:sysconf].to_hash).to eq({ "LINK_MAX" => 65000, "_POSIX_LINK_MAX" => 65000, "MAX_CANON" => 255, "_POSIX_MAX_CANON" => 255, "MAX_INPUT" => 255, "_POSIX_MAX_INPUT" => 255, "NAME_MAX" => 255, "_POSIX_NAME_MAX" => 255, "PATH_MAX" => 4096, "_POSIX_PATH_MAX" => 4096, "PIPE_BUF" => 4096, "_POSIX_PIPE_BUF" => 4096, "SOCK_MAXBUF" => nil, "_POSIX_ASYNC_IO" => nil, "_POSIX_CHOWN_RESTRICTED" => 1, "_POSIX_NO_TRUNC" => 1, "_POSIX_PRIO_IO" => nil, "_POSIX_SYNC_IO" => nil, "_POSIX_VDISABLE" => 0, "ARG_MAX" => 2097152, "ATEXIT_MAX" => 2147483647, "CHAR_BIT" => 8, "CHAR_MAX" => 127, "CHAR_MIN" => -128, "CHILD_MAX" => 63672, "CLK_TCK" => 100, "INT_MAX" => 2147483647, "INT_MIN" => -2147483648, "IOV_MAX" => 1024, "LOGNAME_MAX" => 256, "LONG_BIT" => 64, "MB_LEN_MAX" => 16, "NGROUPS_MAX" => 65536, "NL_ARGMAX" => 4096, "NL_LANGMAX" => 2048, "NL_MSGMAX" => 2147483647, "NL_NMAX" => 2147483647, "NL_SETMAX" => 2147483647, "NL_TEXTMAX" => 2147483647, "NSS_BUFLEN_GROUP" => 1024, "NSS_BUFLEN_PASSWD" => 1024, "NZERO" => 20, "OPEN_MAX" => 1024, "PAGESIZE" => 4096, "PAGE_SIZE" => 4096, "PASS_MAX" => 8192, "PTHREAD_DESTRUCTOR_ITERATIONS" => 4, "PTHREAD_KEYS_MAX" => 1024, "PTHREAD_STACK_MIN" => 16384, "PTHREAD_THREADS_MAX" => nil, "SCHAR_MAX" => 127, "SCHAR_MIN" => -128, "SHRT_MAX" => 32767, "SHRT_MIN" => -32768, "SSIZE_MAX" => 32767, "TTY_NAME_MAX" => 32, "TZNAME_MAX" => 6, "UCHAR_MAX" => 255, "UINT_MAX" => 4294967295, "UIO_MAXIOV" => 1024, "ULONG_MAX" => 18446744073709551615, "USHRT_MAX" => 65535, "WORD_BIT" => 32, "_AVPHYS_PAGES" => 2101393, "_NPROCESSORS_CONF" => 8, "_NPROCESSORS_ONLN" => 8, "_PHYS_PAGES" => 4096040, "_POSIX_ARG_MAX" => 2097152, "_POSIX_ASYNCHRONOUS_IO" => 200809, "_POSIX_CHILD_MAX" => 63672, "_POSIX_FSYNC" => 200809, "_POSIX_JOB_CONTROL" => 1, "_POSIX_MAPPED_FILES" => 200809, "_POSIX_MEMLOCK" => 200809, "_POSIX_MEMLOCK_RANGE" => 200809, "_POSIX_MEMORY_PROTECTION" => 200809, "_POSIX_MESSAGE_PASSING" => 200809, "_POSIX_NGROUPS_MAX" => 65536, "_POSIX_OPEN_MAX" => 1024, "_POSIX_PII" => nil, "_POSIX_PII_INTERNET" => nil, "_POSIX_PII_INTERNET_DGRAM" => nil, "_POSIX_PII_INTERNET_STREAM" => nil, "_POSIX_PII_OSI" => nil, "_POSIX_PII_OSI_CLTS" => nil, "_POSIX_PII_OSI_COTS" => nil, "_POSIX_PII_OSI_M" => nil, "_POSIX_PII_SOCKET" => nil, "_POSIX_PII_XTI" => nil, "_POSIX_POLL" => nil, "_POSIX_PRIORITIZED_IO" => 200809, "_POSIX_PRIORITY_SCHEDULING" => 200809, "_POSIX_REALTIME_SIGNALS" => 200809, "_POSIX_SAVED_IDS" => 1, "_POSIX_SELECT" => nil, "_POSIX_SEMAPHORES" => 200809, "_POSIX_SHARED_MEMORY_OBJECTS" => 200809, "_POSIX_SSIZE_MAX" => 32767, "_POSIX_STREAM_MAX" => 16, "_POSIX_SYNCHRONIZED_IO" => 200809, "_POSIX_THREADS" => 200809, "_POSIX_THREAD_ATTR_STACKADDR" => 200809, "_POSIX_THREAD_ATTR_STACKSIZE" => 200809, "_POSIX_THREAD_PRIORITY_SCHEDULING" => 200809, "_POSIX_THREAD_PRIO_INHERIT" => 200809, "_POSIX_THREAD_PRIO_PROTECT" => 200809, "_POSIX_THREAD_ROBUST_PRIO_INHERIT" => nil, "_POSIX_THREAD_ROBUST_PRIO_PROTECT" => nil, "_POSIX_THREAD_PROCESS_SHARED" => 200809, "_POSIX_THREAD_SAFE_FUNCTIONS" => 200809, "_POSIX_TIMERS" => 200809, "TIMER_MAX" => nil, "_POSIX_TZNAME_MAX" => 6, "_POSIX_VERSION" => 200809, "_T_IOV_MAX" => nil, "_XOPEN_CRYPT" => 1, "_XOPEN_ENH_I18N" => 1, "_XOPEN_LEGACY" => 1, "_XOPEN_REALTIME" => 1, "_XOPEN_REALTIME_THREADS" => 1, "_XOPEN_SHM" => 1, "_XOPEN_UNIX" => 1, "_XOPEN_VERSION" => 700, "_XOPEN_XCU_VERSION" => 4, "_XOPEN_XPG2" => 1, "_XOPEN_XPG3" => 1, "_XOPEN_XPG4" => 1, "BC_BASE_MAX" => 99, "BC_DIM_MAX" => 2048, "BC_SCALE_MAX" => 99, "BC_STRING_MAX" => 1000, "CHARCLASS_NAME_MAX" => 2048, "COLL_WEIGHTS_MAX" => 255, "EQUIV_CLASS_MAX" => nil, "EXPR_NEST_MAX" => 32, "LINE_MAX" => 2048, "POSIX2_BC_BASE_MAX" => 99, "POSIX2_BC_DIM_MAX" => 2048, "POSIX2_BC_SCALE_MAX" => 99, "POSIX2_BC_STRING_MAX" => 1000, "POSIX2_CHAR_TERM" => 200809, "POSIX2_COLL_WEIGHTS_MAX" => 255, "POSIX2_C_BIND" => 200809, "POSIX2_C_DEV" => 200809, "POSIX2_C_VERSION" => 200809, "POSIX2_EXPR_NEST_MAX" => 32, "POSIX2_FORT_DEV" => nil, "POSIX2_FORT_RUN" => nil, "_POSIX2_LINE_MAX" => 2048, "POSIX2_LINE_MAX" => 2048, "POSIX2_LOCALEDEF" => 200809, "POSIX2_RE_DUP_MAX" => 32767, "POSIX2_SW_DEV" => 200809, "POSIX2_UPE" => nil, "POSIX2_VERSION" => 200809, "RE_DUP_MAX" => 32767, "PATH" => "/bin:/usr/bin", "CS_PATH" => "/bin:/usr/bin", "LFS_CFLAGS" => nil, "LFS_LDFLAGS" => nil, "LFS_LIBS" => nil, "LFS_LINTFLAGS" => nil, "LFS64_CFLAGS" => "-D_LARGEFILE64_SOURCE", "LFS64_LDFLAGS" => nil, "LFS64_LIBS" => nil, "LFS64_LINTFLAGS" => "-D_LARGEFILE64_SOURCE", "_XBS5_WIDTH_RESTRICTED_ENVS" => "XBS5_LP64_OFF64", "XBS5_WIDTH_RESTRICTED_ENVS" => "XBS5_LP64_OFF64", "_XBS5_ILP32_OFF32" => nil, "XBS5_ILP32_OFF32_CFLAGS" => nil, "XBS5_ILP32_OFF32_LDFLAGS" => nil, "XBS5_ILP32_OFF32_LIBS" => nil, "XBS5_ILP32_OFF32_LINTFLAGS" => nil, "_XBS5_ILP32_OFFBIG" => nil, "XBS5_ILP32_OFFBIG_CFLAGS" => nil, "XBS5_ILP32_OFFBIG_LDFLAGS" => nil, "XBS5_ILP32_OFFBIG_LIBS" => nil, "XBS5_ILP32_OFFBIG_LINTFLAGS" => nil, "_XBS5_LP64_OFF64" => 1, "XBS5_LP64_OFF64_CFLAGS" => "-m64", "XBS5_LP64_OFF64_LDFLAGS" => "-m64", "XBS5_LP64_OFF64_LIBS" => nil, "XBS5_LP64_OFF64_LINTFLAGS" => nil, "_XBS5_LPBIG_OFFBIG" => nil, "XBS5_LPBIG_OFFBIG_CFLAGS" => nil, "XBS5_LPBIG_OFFBIG_LDFLAGS" => nil, "XBS5_LPBIG_OFFBIG_LIBS" => nil, "XBS5_LPBIG_OFFBIG_LINTFLAGS" => nil, "_POSIX_V6_ILP32_OFF32" => nil, "POSIX_V6_ILP32_OFF32_CFLAGS" => nil, "POSIX_V6_ILP32_OFF32_LDFLAGS" => nil, "POSIX_V6_ILP32_OFF32_LIBS" => nil, "POSIX_V6_ILP32_OFF32_LINTFLAGS" => nil, "_POSIX_V6_WIDTH_RESTRICTED_ENVS" => "POSIX_V6_LP64_OFF64", "POSIX_V6_WIDTH_RESTRICTED_ENVS" => "POSIX_V6_LP64_OFF64", "_POSIX_V6_ILP32_OFFBIG" => nil, "POSIX_V6_ILP32_OFFBIG_CFLAGS" => nil, "POSIX_V6_ILP32_OFFBIG_LDFLAGS" => nil, "POSIX_V6_ILP32_OFFBIG_LIBS" => nil, "POSIX_V6_ILP32_OFFBIG_LINTFLAGS" => nil, "_POSIX_V6_LP64_OFF64" => 1, "POSIX_V6_LP64_OFF64_CFLAGS" => "-m64", "POSIX_V6_LP64_OFF64_LDFLAGS" => "-m64", "POSIX_V6_LP64_OFF64_LIBS" => nil, "POSIX_V6_LP64_OFF64_LINTFLAGS" => nil, "_POSIX_V6_LPBIG_OFFBIG" => nil, "POSIX_V6_LPBIG_OFFBIG_CFLAGS" => nil, "POSIX_V6_LPBIG_OFFBIG_LDFLAGS" => nil, "POSIX_V6_LPBIG_OFFBIG_LIBS" => nil, "POSIX_V6_LPBIG_OFFBIG_LINTFLAGS" => nil, "_POSIX_V7_ILP32_OFF32" => nil, "POSIX_V7_ILP32_OFF32_CFLAGS" => nil, "POSIX_V7_ILP32_OFF32_LDFLAGS" => nil, "POSIX_V7_ILP32_OFF32_LIBS" => nil, "POSIX_V7_ILP32_OFF32_LINTFLAGS" => nil, "_POSIX_V7_WIDTH_RESTRICTED_ENVS" => "POSIX_V7_LP64_OFF64", "POSIX_V7_WIDTH_RESTRICTED_ENVS" => "POSIX_V7_LP64_OFF64", "_POSIX_V7_ILP32_OFFBIG" => nil, "POSIX_V7_ILP32_OFFBIG_CFLAGS" => nil, "POSIX_V7_ILP32_OFFBIG_LDFLAGS" => nil, "POSIX_V7_ILP32_OFFBIG_LIBS" => nil, "POSIX_V7_ILP32_OFFBIG_LINTFLAGS" => nil, "_POSIX_V7_LP64_OFF64" => 1, "POSIX_V7_LP64_OFF64_CFLAGS" => "-m64", "POSIX_V7_LP64_OFF64_LDFLAGS" => "-m64", "POSIX_V7_LP64_OFF64_LIBS" => nil, "POSIX_V7_LP64_OFF64_LINTFLAGS" => nil, "_POSIX_V7_LPBIG_OFFBIG" => nil, "POSIX_V7_LPBIG_OFFBIG_CFLAGS" => nil, "POSIX_V7_LPBIG_OFFBIG_LDFLAGS" => nil, "POSIX_V7_LPBIG_OFFBIG_LIBS" => nil, "POSIX_V7_LPBIG_OFFBIG_LINTFLAGS" => nil, "_POSIX_ADVISORY_INFO" => 200809, "_POSIX_BARRIERS" => 200809, "_POSIX_BASE" => nil, "_POSIX_C_LANG_SUPPORT" => nil, "_POSIX_C_LANG_SUPPORT_R" => nil, "_POSIX_CLOCK_SELECTION" => 200809, "_POSIX_CPUTIME" => 200809, "_POSIX_THREAD_CPUTIME" => 200809, "_POSIX_DEVICE_SPECIFIC" => nil, "_POSIX_DEVICE_SPECIFIC_R" => nil, "_POSIX_FD_MGMT" => nil, "_POSIX_FIFO" => nil, "_POSIX_PIPE" => nil, "_POSIX_FILE_ATTRIBUTES" => nil, "_POSIX_FILE_LOCKING" => nil, "_POSIX_FILE_SYSTEM" => nil, "_POSIX_MONOTONIC_CLOCK" => 200809, "_POSIX_MULTI_PROCESS" => nil, "_POSIX_SINGLE_PROCESS" => nil, "_POSIX_NETWORKING" => nil, "_POSIX_READER_WRITER_LOCKS" => 200809, "_POSIX_SPIN_LOCKS" => 200809, "_POSIX_REGEXP" => 1, "_REGEX_VERSION" => nil, "_POSIX_SHELL" => 1, "_POSIX_SIGNALS" => nil, "_POSIX_SPAWN" => 200809, "_POSIX_SPORADIC_SERVER" => nil, "_POSIX_THREAD_SPORADIC_SERVER" => nil, "_POSIX_SYSTEM_DATABASE" => nil, "_POSIX_SYSTEM_DATABASE_R" => nil, "_POSIX_TIMEOUTS" => 200809, "_POSIX_TYPED_MEMORY_OBJECTS" => nil, "_POSIX_USER_GROUPS" => nil, "_POSIX_USER_GROUPS_R" => nil, "POSIX2_PBS" => nil, "POSIX2_PBS_ACCOUNTING" => nil, "POSIX2_PBS_LOCATE" => nil, "POSIX2_PBS_TRACK" => nil, "POSIX2_PBS_MESSAGE" => nil, "SYMLOOP_MAX" => nil, "STREAM_MAX" => 16, "AIO_LISTIO_MAX" => nil, "AIO_MAX" => nil, "AIO_PRIO_DELTA_MAX" => 20, "DELAYTIMER_MAX" => 2147483647, "HOST_NAME_MAX" => 64, "LOGIN_NAME_MAX" => 256, "MQ_OPEN_MAX" => nil, "MQ_PRIO_MAX" => 32768, "_POSIX_DEVICE_IO" => nil, "_POSIX_TRACE" => nil, "_POSIX_TRACE_EVENT_FILTER" => nil, "_POSIX_TRACE_INHERIT" => nil, "_POSIX_TRACE_LOG" => nil, "RTSIG_MAX" => 32, "SEM_NSEMS_MAX" => nil, "SEM_VALUE_MAX" => 2147483647, "SIGQUEUE_MAX" => 63672, "FILESIZEBITS" => 64, "POSIX_ALLOC_SIZE_MIN" => 4096, "POSIX_REC_INCR_XFER_SIZE" => nil, "POSIX_REC_MAX_XFER_SIZE" => nil, "POSIX_REC_MIN_XFER_SIZE" => 4096, "POSIX_REC_XFER_ALIGN" => 4096, "SYMLINK_MAX" => nil, "GNU_LIBC_VERSION" => "glibc 2.24", "GNU_LIBPTHREAD_VERSION" => "NPTL 2.24", "POSIX2_SYMLINKS" => 1, "LEVEL1_ICACHE_SIZE" => 32768, "LEVEL1_ICACHE_ASSOC" => 8, "LEVEL1_ICACHE_LINESIZE" => 64, "LEVEL1_DCACHE_SIZE" => 32768, "LEVEL1_DCACHE_ASSOC" => 8, "LEVEL1_DCACHE_LINESIZE" => 64, "LEVEL2_CACHE_SIZE" => 262144, "LEVEL2_CACHE_ASSOC" => 4, "LEVEL2_CACHE_LINESIZE" => 64, "LEVEL3_CACHE_SIZE" => 8388608, "LEVEL3_CACHE_ASSOC" => 16, "LEVEL3_CACHE_LINESIZE" => 64, "LEVEL4_CACHE_SIZE" => 0, "LEVEL4_CACHE_ASSOC" => 0, "LEVEL4_CACHE_LINESIZE" => 0, "IPV6" => 200809, "RAW_SOCKETS" => 200809, "_POSIX_IPV6" => 200809, "_POSIX_RAW_SOCKETS" => 200809, }) end it "does not populate sysconf if getconf is not found" do allow(plugin).to receive(:which).with("getconf").and_return(false) plugin.run expect(plugin[:sysconf]).to be(nil) end end ohai-16.0.7/spec/unit/plugins/timezone_spec.rb000066400000000000000000000016711362624620500213230ustar00rootroot00000000000000# # Author:: John Bellone () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "timezone plugin" do before do @plugin = get_plugin("timezone") allow(Time).to receive_message_chain(:now, :getlocal, :zone) { "ZZZ" } end it "gets the local timezone" do @plugin.run expect(@plugin["time"]["timezone"]).to eq("ZZZ") end end ohai-16.0.7/spec/unit/plugins/vbox_host_spec.rb000066400000000000000000000011771362624620500215050ustar00rootroot00000000000000# Author:: "Joshua Colson" # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ohai-16.0.7/spec/unit/plugins/virtualbox_spec.rb000066400000000000000000000475251362624620500217000ustar00rootroot00000000000000# Author:: Tim Smith () # Copyright:: Copyright (c) 2015-2019 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" vbox_list_vms_stdout = <<~EOF "ubuntu-18.04-amd64_1549746024485_35372" {6294f16b-4f05-4430-afb9-773bdb237aec} EOF vbox_vminfo_stdout = <<~EOF name="ubuntu-18.04-amd64_1549746024485_35372" groups="/" ostype="Ubuntu (64-bit)" UUID="6294f16b-4f05-4430-afb9-773bdb237aec" CfgFile="/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/ubuntu-18.04-amd64_1549746024485_35372.vbox" SnapFldr="/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Snapshots" LogFldr="/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Logs" hardwareuuid="6294f16b-4f05-4430-afb9-773bdb237aec" memory=1024 pagefusion="off" vram=8 cpuexecutioncap=100 hpet="off" chipset="piix3" firmware="BIOS" cpus=1 pae="on" longmode="on" triplefaultreset="off" apic="on" x2apic="on" cpuid-portability-level=0 bootmenu="messageandmenu" boot1="disk" boot2="dvd" boot3="none" boot4="none" acpi="on" ioapic="on" biosapic="apic" biossystemtimeoffset=0 rtcuseutc="off" hwvirtex="on" nestedpaging="on" largepages="on" vtxvpid="on" vtxux="on" paravirtprovider="default" effparavirtprovider="kvm" VMState="poweroff" VMStateChangeTime="2019-02-09T21:00:33.575000000" monitorcount=1 accelerate3d="off" accelerate2dvideo="off" teleporterenabled="off" teleporterport=0 teleporteraddress="" teleporterpassword="" tracing-enabled="off" tracing-allow-vm-access="off" tracing-config="" autostart-enabled="off" autostart-delay=0 defaultfrontend="" storagecontrollername0="IDE Controller" storagecontrollertype0="PIIX4" storagecontrollerinstance0="0" storagecontrollermaxportcount0="2" storagecontrollerportcount0="2" storagecontrollerbootable0="on" storagecontrollername1="SATA Controller" storagecontrollertype1="IntelAhci" storagecontrollerinstance1="0" storagecontrollermaxportcount1="30" storagecontrollerportcount1="1" storagecontrollerbootable1="on" "IDE Controller-0-0"="none" "IDE Controller-0-1"="none" "IDE Controller-1-0"="none" "IDE Controller-1-1"="none" "SATA Controller-0-0"="/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Snapshots/{1c182745-4b09-41a1-a147-d3ced46f72f6}.vmdk" "SATA Controller-ImageUUID-0-0"="1c182745-4b09-41a1-a147-d3ced46f72f6" natnet1="nat" macaddress1="080027E5FA8F" cableconnected1="on" nic1="nat" nictype1="82540EM" nicspeed1="0" mtu="0" sockSnd="64" sockRcv="64" tcpWndSnd="64" tcpWndRcv="64" nic2="none" nic3="none" nic4="none" nic5="none" nic6="none" nic7="none" nic8="none" hidpointing="ps2mouse" hidkeyboard="ps2kbd" uart1="off" uart2="off" uart3="off" uart4="off" lpt1="off" lpt2="off" audio="pulse" audio_in="false" audio_out="false" clipboard="disabled" draganddrop="disabled" vrde="on" vrdeport=-1 vrdeports="5947" vrdeaddress="127.0.0.1" vrdeauthtype="null" vrdemulticon="off" vrdereusecon="off" vrdevideochannel="off" vrdeproperty[TCP/Ports]="5947" vrdeproperty[TCP/Address]="127.0.0.1" usb="off" ehci="off" xhci="off" GuestMemoryBalloon=0 SnapshotName="base" SnapshotUUID="085cbbec-70cd-4864-9208-5d938dcabb71" CurrentSnapshotName="base" CurrentSnapshotUUID="085cbbec-70cd-4864-9208-5d938dcabb71" CurrentSnapshotNode="SnapshotName" EOF vbox_list_hdds_stdout = <<~EOF UUID: ebb6dca0-879f-480b-a50e-9efe330bd021 Parent UUID: base State: locked read Type: normal (base) Location: /virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/ubuntu-18.04-amd64-disk001.vmdk Storage format: VMDK Capacity: 65536 MBytes Encryption: disabled UUID: 1c182745-4b09-41a1-a147-d3ced46f72f6 Parent UUID: ebb6dca0-879f-480b-a50e-9efe330bd021 State: created Type: normal (differencing) Location: /virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Snapshots/{1c182745-4b09-41a1-a147-d3ced46f72f6}.vmdk Storage format: VMDK Capacity: 65536 MBytes Encryption: disabled EOF vbox_list_dvds_stdout = <<~EOF UUID: 897aa7bc-1ec1-4e13-a16d-101d3716c72d State: created Type: normal (base) Location: /tmp/test.dvd Storage format: RAW Capacity: 100 MBytes Encryption: disabled EOF vbox_list_hostdvds_stdout = <<~EOF UUID: 00445644-0000-0000-2f64-65762f737230 Name: /dev/sr0 EOF vbox_list_hostfloppies_stdout = <<~EOF EOF vbox_list_hostonlyifs_stdout = <<~EOF Name: vboxnet0 GUID: 786f6276-656e-4074-8000-0a0027000000 DHCP: Disabled IPAddress: 192.168.33.1 NetworkMask: 255.255.255.0 IPV6Address: IPV6NetworkMaskPrefixLength: 0 HardwareAddress: 0a:00:27:00:00:00 MediumType: Ethernet Wireless: No Status: Down VBoxNetworkName: HostInterfaceNetworking-vboxnet0 Name: vboxnet1 GUID: 786f6276-656e-4174-8000-0a0027000001 DHCP: Disabled IPAddress: 192.168.19.1 NetworkMask: 255.255.255.0 IPV6Address: fe80::800:27ff:fe00:1 IPV6NetworkMaskPrefixLength: 64 HardwareAddress: 0a:00:27:00:00:01 MediumType: Ethernet Wireless: No Status: Up VBoxNetworkName: HostInterfaceNetworking-vboxnet1 EOF vbox_list_bridgedifs_stdout = <<~EOF Name: eno1 GUID: 316f6e65-0000-4000-8000-309c233b62a9 DHCP: Disabled IPAddress: 10.143.72.133 NetworkMask: 255.255.255.224 IPV6Address: fe80::9226:82e9:1101:60e6 IPV6NetworkMaskPrefixLength: 64 HardwareAddress: 30:9c:23:3b:62:a9 MediumType: Ethernet Wireless: No Status: Up VBoxNetworkName: HostInterfaceNetworking-eno1 EOF vbox_list_dhcpservers_stdout = <<~EOF NetworkName: HostInterfaceNetworking-vboxnet0 IP: 192.168.56.100 NetworkMask: 255.255.255.0 lowerIPAddress: 192.168.56.101 upperIPAddress: 192.168.56.254 Enabled: Yes NetworkName: HostInterfaceNetworking-vboxnet1 IP: 192.168.19.2 NetworkMask: 255.255.255.0 lowerIPAddress: 192.168.19.3 upperIPAddress: 192.168.19.254 Enabled: Yes EOF # output of: VBoxManage list --sorted natnets vbox_list_natnets_stdout = <<~EOF NetworkName: NatNetwork IP: 10.0.2.1 Network: 10.0.2.0/24 IPv6 Enabled: No IPv6 Prefix: fd17:625c:f037:2::/64 DHCP Enabled: Yes Enabled: Yes loopback mappings (ipv4) 127.0.0.1=2 EOF expected_output = { "guests" => { "ubuntu-18.04-amd64_1549746024485_35372" => { "groups" => "/", "ostype" => "Ubuntu (64-bit)", "uuid" => "6294f16b-4f05-4430-afb9-773bdb237aec", "cfgfile" => "/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/ubuntu-18.04-amd64_1549746024485_35372.vbox", "snapfldr" => "/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Snapshots", "logfldr" => "/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Logs", "hardwareuuid" => "6294f16b-4f05-4430-afb9-773bdb237aec", "memory" => "1024", "pagefusion" => "off", "vram" => "8", "cpuexecutioncap" => "100", "hpet" => "off", "chipset" => "piix3", "firmware" => "BIOS", "cpus" => "1", "pae" => "on", "longmode" => "on", "triplefaultreset" => "off", "apic" => "on", "x2apic" => "on", "cpuid-portability-level" => "0", "bootmenu" => "messageandmenu", "boot1" => "disk", "boot2" => "dvd", "boot3" => "none", "boot4" => "none", "acpi" => "on", "ioapic" => "on", "biosapic" => "apic", "biossystemtimeoffset" => "0", "rtcuseutc" => "off", "hwvirtex" => "on", "nestedpaging" => "on", "largepages" => "on", "vtxvpid" => "on", "vtxux" => "on", "paravirtprovider" => "default", "effparavirtprovider" => "kvm", "vmstate" => "poweroff", "vmstatechangetime" => "2019-02-09T21:00:33.575000000", "monitorcount" => "1", "accelerate3d" => "off", "accelerate2dvideo" => "off", "teleporterenabled" => "off", "teleporterport" => "0", "teleporteraddress" => "", "teleporterpassword" => "", "tracing-enabled" => "off", "tracing-allow-vm-access" => "off", "tracing-config" => "", "autostart-enabled" => "off", "autostart-delay" => "0", "defaultfrontend" => "", "storagecontrollername0" => "IDE Controller", "storagecontrollertype0" => "PIIX4", "storagecontrollerinstance0" => "0", "storagecontrollermaxportcount0" => "2", "storagecontrollerportcount0" => "2", "storagecontrollerbootable0" => "on", "storagecontrollername1" => "SATA Controller", "storagecontrollertype1" => "IntelAhci", "storagecontrollerinstance1" => "0", "storagecontrollermaxportcount1" => "30", "storagecontrollerportcount1" => "1", "storagecontrollerbootable1" => "on", "ide controller-0-0" => "none", "ide controller-0-1" => "none", "ide controller-1-0" => "none", "ide controller-1-1" => "none", "sata controller-0-0" => "/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Snapshots/{1c182745-4b09-41a1-a147-d3ced46f72f6}.vmdk", "sata controller-imageuuid-0-0" => "1c182745-4b09-41a1-a147-d3ced46f72f6", "natnet1" => "nat", "macaddress1" => "080027E5FA8F", "cableconnected1" => "on", "nic1" => "nat", "nictype1" => "82540EM", "nicspeed1" => "0", "mtu" => "0", "socksnd" => "64", "sockrcv" => "64", "tcpwndsnd" => "64", "tcpwndrcv" => "64", "nic2" => "none", "nic3" => "none", "nic4" => "none", "nic5" => "none", "nic6" => "none", "nic7" => "none", "nic8" => "none", "hidpointing" => "ps2mouse", "hidkeyboard" => "ps2kbd", "uart1" => "off", "uart2" => "off", "uart3" => "off", "uart4" => "off", "lpt1" => "off", "lpt2" => "off", "audio" => "pulse", "audio_in" => "false", "audio_out" => "false", "clipboard" => "disabled", "draganddrop" => "disabled", "vrde" => "on", "vrdeport" => "-1", "vrdeports" => "5947", "vrdeaddress" => "127.0.0.1", "vrdeauthtype" => "null", "vrdemulticon" => "off", "vrdereusecon" => "off", "vrdevideochannel" => "off", "vrdeproperty[tcp/ports]" => "5947", "vrdeproperty[tcp/address]" => "127.0.0.1", "usb" => "off", "ehci" => "off", "xhci" => "off", "guestmemoryballoon" => "0", "snapshotname" => "base", "snapshotuuid" => "085cbbec-70cd-4864-9208-5d938dcabb71", "currentsnapshotname" => "base", "currentsnapshotuuid" => "085cbbec-70cd-4864-9208-5d938dcabb71", "currentsnapshotnode" => "SnapshotName" } }, "hdds" => { "/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/ubuntu-18.04-amd64-disk001.vmdk" => { "uuid" => "ebb6dca0-879f-480b-a50e-9efe330bd021", "parent uuid" => "base", "state" => "locked read", "type" => "normal (base)", "storage format" => "VMDK", "capacity" => "65536 MBytes", "encryption" => "disabled" }, "/virtual/machines/ubuntu-18.04-amd64_1549746024485_35372/Snapshots/{1c182745-4b09-41a1-a147-d3ced46f72f6}.vmdk" => { "uuid" => "1c182745-4b09-41a1-a147-d3ced46f72f6", "parent uuid" => "ebb6dca0-879f-480b-a50e-9efe330bd021", "state" => "created", "type" => "normal (differencing)", "storage format" => "VMDK", "capacity" => "65536 MBytes", "encryption" => "disabled" } }, "dvds" => { "/tmp/test.dvd" => { "uuid" => "897aa7bc-1ec1-4e13-a16d-101d3716c72d", "state" => "created", "type" => "normal (base)", "storage format" => "RAW", "capacity" => "100 MBytes", "encryption" => "disabled" } }, "hostdvds" => { "/dev/sr0" => { "uuid" => "00445644-0000-0000-2f64-65762f737230" } }, "hostfloppies" => {}, "hostonlyifs" => { "vboxnet0" => { "guid" => "786f6276-656e-4074-8000-0a0027000000", "dhcp" => "Disabled", "ipaddress" => "192.168.33.1", "networkmask" => "255.255.255.0", "ipv6address" => "", "ipv6networkmaskprefixlength" => "0", "hardwareaddress" => "0a:00:27:00:00:00", "mediumtype" => "Ethernet", "wireless" => "No", "status" => "Down", "vboxnetworkname" => "HostInterfaceNetworking-vboxnet0" }, "vboxnet1" => { "guid" => "786f6276-656e-4174-8000-0a0027000001", "dhcp" => "Disabled", "ipaddress" => "192.168.19.1", "networkmask" => "255.255.255.0", "ipv6address" => "fe80::800:27ff:fe00:1", "ipv6networkmaskprefixlength" => "64", "hardwareaddress" => "0a:00:27:00:00:01", "mediumtype" => "Ethernet", "wireless" => "No", "status" => "Up", "vboxnetworkname" => "HostInterfaceNetworking-vboxnet1" } }, "bridgedifs" => { "eno1" => { "guid" => "316f6e65-0000-4000-8000-309c233b62a9", "dhcp" => "Disabled", "ipaddress" => "10.143.72.133", "networkmask" => "255.255.255.224", "ipv6address" => "fe80::9226:82e9:1101:60e6", "ipv6networkmaskprefixlength" => "64", "hardwareaddress" => "30:9c:23:3b:62:a9", "mediumtype" => "Ethernet", "wireless" => "No", "status" => "Up", "vboxnetworkname" => "HostInterfaceNetworking-eno1" } }, "dhcpservers" => { "HostInterfaceNetworking-vboxnet0" => { "ip" => "192.168.56.100", "networkmask" => "255.255.255.0", "loweripaddress" => "192.168.56.101", "upperipaddress" => "192.168.56.254", "enabled" => "Yes" }, "HostInterfaceNetworking-vboxnet1" => { "ip" => "192.168.19.2", "networkmask" => "255.255.255.0", "loweripaddress" => "192.168.19.3", "upperipaddress" => "192.168.19.254", "enabled" => "Yes" } }, "natnets" => { "NatNetwork" => { "ip" => "10.0.2.1", "network" => "10.0.2.0/24", "ipv6 enabled" => "No", "ipv6 prefix" => "fd17:625c:f037:2::/64", "dhcp enabled" => "Yes", "enabled" => "Yes" } } } vbox_output = <<~EOF Oracle VM VirtualBox Guest Additions Command Line Management Interface Version 5.0.2 (C) 2008-2015 Oracle Corporation All rights reserved. Name: /VirtualBox/GuestInfo/OS/Product, value: Linux, timestamp: 1448390422246549000, flags: Name: /VirtualBox/GuestInfo/Net/0/V4/IP, value: 10.0.2.15, timestamp: 1448390422248366000, flags: Name: /VirtualBox/HostInfo/GUI/LanguageID, value: en_US, timestamp: 1448390412061749000, flags: Name: /VirtualBox/GuestInfo/Net/0/MAC, value: 080027FBB38C, timestamp: 1448390422248652000, flags: Name: /VirtualBox/GuestInfo/OS/ServicePack, value: , timestamp: 1448390422246976000, flags: Name: /VirtualBox/HostInfo/VBoxVerExt, value: 5.0.10, timestamp: 1448390411701508000, flags: TRANSIENT, RDONLYGUEST Name: /VirtualBox/GuestInfo/Net/0/V4/Netmask, value: 255.255.255.0, timestamp: 1448390422248569000, flags: Name: /VirtualBox/GuestInfo/OS/Version, value: #36~14.04.1-Ubuntu SMP Thu Oct 8 10:21:08 UTC 2015, timestamp: 1448390422246810000, flags: Name: /VirtualBox/GuestAdd/VersionExt, value: 5.0.2, timestamp: 1448390422247220000, flags: Name: /VirtualBox/GuestAdd/Revision, value: 102096, timestamp: 1448390422247266000, flags: Name: /VirtualBox/HostGuest/SysprepExec, value: , timestamp: 1448390411701168000, flags: TRANSIENT, RDONLYGUEST Name: /VirtualBox/GuestInfo/OS/LoggedInUsers, value: 1, timestamp: 1448390452251425000, flags: TRANSIENT, TRANSRESET Name: /VirtualBox/GuestInfo/Net/0/Status, value: Up, timestamp: 1448390422248755000, flags: Name: /VirtualBox/GuestInfo/Net/0/Name, value: eth0, timestamp: 1448390422248814000, flags: Name: /VirtualBox/HostGuest/SysprepArgs, value: , timestamp: 1448390411701220000, flags: TRANSIENT, RDONLYGUEST Name: /VirtualBox/GuestAdd/Version, value: 5.0.2, timestamp: 1448390422247066000, flags: Name: /VirtualBox/HostInfo/VBoxRev, value: 104061, timestamp: 1448390411701536000, flags: TRANSIENT, RDONLYGUEST Name: /VirtualBox/GuestInfo/Net/0/V4/Broadcast, value: 10.0.2.255, timestamp: 1448390422248498000, flags: Name: /VirtualBox/HostInfo/VBoxVer, value: 5.0.10, timestamp: 1448390411701485000, flags: TRANSIENT, RDONLYGUEST Name: /VirtualBox/GuestInfo/OS/LoggedInUsersList, value: tim, timestamp: 1448390452251274000, flags: TRANSIENT, TRANSRESET Name: /VirtualBox/GuestInfo/Net/Count, value: 1, timestamp: 1448391352440445000, flags: Name: /VirtualBox/GuestInfo/OS/Release, value: 3.19.0-31-generic, timestamp: 1448390422246638000, flags: Name: /VirtualBox/GuestInfo/OS/NoLoggedInUsers, value: false, timestamp: 1448390452251532000, flags: TRANSIENT, TRANSRESET EOF describe Ohai::System, "plugin virtualbox" do let(:plugin) { get_plugin("virtualbox") } before do plugin[:virtualization] = Mash.new plugin[:virtualization][:systems] = Mash.new end context "when not on a virtualbox guest" do it "does not set the virtualbox attribute" do plugin[:virtualization][:systems][:vmware] = "host" plugin.run expect(plugin).not_to have_key(:virtualbox) end end context "when on a vbox guest" do context "when VBoxControl shellout fails" do it "does not set the virtualbox attribute" do plugin[:virtualization][:systems][:vbox] = "guest" allow(plugin).to receive(:shell_out).with("VBoxControl guestproperty enumerate").and_return(mock_shell_out(1, "", "")) plugin.run expect(plugin).not_to have_key(:virtualbox) end end context "when VBoxControl shellout succeeds" do before do plugin[:virtualization][:systems][:vbox] = "guest" allow(plugin).to receive(:shell_out).with("VBoxControl guestproperty enumerate").and_return(mock_shell_out(0, vbox_output, "")) plugin.run end it "sets the host version" do expect(plugin[:virtualbox][:host][:version]).to eql("5.0.10") end it "sets the host revision" do expect(plugin[:virtualbox][:host][:revision]).to eql("104061") end it "sets the host language" do expect(plugin[:virtualbox][:host][:language]).to eql("en_US") end it "sets the guest additions version" do expect(plugin[:virtualbox][:guest][:guest_additions_version]).to eql("5.0.2") end it "sets the guest additions revision" do expect(plugin[:virtualbox][:guest][:guest_additions_revision]).to eql("102096") end end end context "when on a vbox host" do context "when the host has virtualbox installed" do it "creates a vbox attribute with accurate data" do plugin[:virtualization][:systems][:vbox] = "host" allow(plugin).to receive(:which).with("VBoxManage").and_return("/usr/bin/VBoxManage") allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted vms").and_return(mock_shell_out(0, vbox_list_vms_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage showvminfo 6294f16b-4f05-4430-afb9-773bdb237aec --machinereadable").and_return(mock_shell_out(0, vbox_vminfo_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted hdds").and_return(mock_shell_out(0, vbox_list_hdds_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted dvds").and_return(mock_shell_out(0, vbox_list_dvds_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted hostdvds").and_return(mock_shell_out(0, vbox_list_hostdvds_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted hostfloppies").and_return(mock_shell_out(0, vbox_list_hostfloppies_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted hostonlyifs").and_return(mock_shell_out(0, vbox_list_hostonlyifs_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted bridgedifs").and_return(mock_shell_out(0, vbox_list_bridgedifs_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted dhcpservers").and_return(mock_shell_out(0, vbox_list_dhcpservers_stdout, "")) allow(plugin).to receive(:shell_out).with("VBoxManage list --sorted natnets").and_return(mock_shell_out(0, vbox_list_natnets_stdout, "")) plugin.run expect(plugin).to have_key(:virtualbox) expect(plugin[:virtualbox]).to eq(expected_output) end end end end ohai-16.0.7/spec/unit/plugins/vmware_spec.rb000066400000000000000000000071231362624620500207700ustar00rootroot00000000000000# # Author:: "Christopher M. Luciano" # Copyright (C) 2015 IBM Corp. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" describe Ohai::System, "plugin vmware" do let(:plugin) { get_plugin("vmware") } let(:path) { "/usr/bin/vmware-toolbox-cmd" } before do allow(plugin).to receive(:collect_os).and_return(:linux) end context "when on vmware guest with toolbox installed" do before do allow(File).to receive(:exist?).with("/usr/bin/vmware-toolbox-cmd").and_return(true) allow(plugin).to receive(:shell_out).with("#{path} stat speed").and_return(mock_shell_out(0, "2000 MHz", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat hosttime").and_return(mock_shell_out(0, "04 Jun 2015 19:21:16", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat sessionid").and_return(mock_shell_out(0, "0x0000000000000000", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat balloon").and_return(mock_shell_out(0, "0 MB", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat swap").and_return(mock_shell_out(0, "0 MB", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat memlimit").and_return(mock_shell_out(0, "4000000000 MB", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat memres").and_return(mock_shell_out(0, "0 MB", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat cpures").and_return(mock_shell_out(0, "0 MHz", nil)) allow(plugin).to receive(:shell_out).with("#{path} stat cpulimit").and_return(mock_shell_out(0, "4000000000 MB", nil)) allow(plugin).to receive(:shell_out).with("#{path} upgrade status").and_return(mock_shell_out(0, "VMware Tools are up-to-date.", nil)) allow(plugin).to receive(:shell_out).with("#{path} timesync status").and_return(mock_shell_out(0, "Disabled", nil)) plugin[:virtualization] = Mash.new plugin[:virtualization][:systems] = Mash.new plugin[:virtualization][:systems][:vmware] = Mash.new plugin.run end it "gets the speed" do expect(plugin[:vmware][:speed]).to eq("2000 MHz") end it "gets the hosttime" do expect(plugin[:vmware][:hosttime]).to eq("04 Jun 2015 19:21:16") end it "gets tools update status" do expect(plugin[:vmware][:upgrade]).to eq("VMware Tools are up-to-date.") end end context "when on vmware guest without toolbox" do it "does not create a vmware attribute" do plugin[:virtualization] = Mash.new plugin[:virtualization][:systems] = Mash.new plugin[:virtualization][:systems][:vmware] = Mash.new allow(File).to receive(:exist?).with("/usr/bin/vmware-toolbox-cmd").and_return(false) plugin.run expect(plugin).not_to have_key(:vmware) end end context "when on vbox guest" do it "does not create a vmware attribute" do plugin[:virtualization] = Mash.new plugin[:virtualization][:systems] = Mash.new plugin[:virtualization][:systems][:vbox] = Mash.new plugin.run expect(plugin).not_to have_key(:vmware) end end end ohai-16.0.7/spec/unit/plugins/windows/000077500000000000000000000000001362624620500176175ustar00rootroot00000000000000ohai-16.0.7/spec/unit/plugins/windows/cpu_spec.rb000066400000000000000000000074001362624620500217460ustar00rootroot00000000000000# # Author:: Salim Alam () # Copyright:: Copyright (c) 2015 Chef Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" shared_examples "a cpu" do |cpu_no| describe "cpu #{cpu_no}" do it "sets physical_id to CPU#{cpu_no}" do expect(@plugin[:cpu][cpu_no.to_s][:physical_id]).to eq("CPU#{cpu_no}") end it "sets mhz to 2793" do expect(@plugin[:cpu][cpu_no.to_s][:mhz]).to eq("2793") end it "sets vendor_id to GenuineIntel" do expect(@plugin[:cpu][cpu_no.to_s][:vendor_id]).to eq("GenuineIntel") end it "sets model_name to Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz" do expect(@plugin[:cpu][cpu_no.to_s][:model_name]) .to eq("Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz") end it "sets description to Intel64 Family 6 Model 70 Stepping 1" do expect(@plugin[:cpu][cpu_no.to_s][:description]) .to eq("Intel64 Family 6 Model 70 Stepping 1") end it "sets model to 17921" do expect(@plugin[:cpu][cpu_no.to_s][:model]).to eq("17921") end it "sets family to 2" do expect(@plugin[:cpu][cpu_no.to_s][:family]).to eq("2") end it "sets stepping to 9" do expect(@plugin[:cpu][cpu_no.to_s][:stepping]).to eq(9) end it "sets cache_size to 64 KB" do expect(@plugin[:cpu][cpu_no.to_s][:cache_size]).to eq("64 KB") end end end describe Ohai::System, "Windows cpu plugin" do before do @plugin = get_plugin("cpu") allow(@plugin).to receive(:collect_os).and_return(:windows) @double_wmi_instance = instance_double(WmiLite::Wmi) @processors = [{ "description" => "Intel64 Family 6 Model 70 Stepping 1", "name" => "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz", "deviceid" => "CPU0", "family" => 2, "manufacturer" => "GenuineIntel", "maxclockspeed" => 2793, "numberofcores" => 1, "numberoflogicalprocessors" => 2, "revision" => 17_921, "stepping" => 9, "l2cachesize" => 64 }, { "description" => "Intel64 Family 6 Model 70 Stepping 1", "name" => "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz", "deviceid" => "CPU1", "family" => 2, "manufacturer" => "GenuineIntel", "maxclockspeed" => 2793, "numberofcores" => 1, "numberoflogicalprocessors" => 2, "revision" => 17_921, "stepping" => 9, "l2cachesize" => 64 }] allow(WmiLite::Wmi).to receive(:new).and_return(@double_wmi_instance) allow(@double_wmi_instance).to receive(:instances_of) .with("Win32_Processor") .and_return(@processors) @plugin.run end it "sets total cpu to 2" do expect(@plugin[:cpu][:total]).to eq(4) end it "sets real cpu to 2" do expect(@plugin[:cpu][:real]).to eq(2) end it "sets 2 distinct cpus numbered 0 and 1" do expect(@plugin[:cpu]).to have_key("0") expect(@plugin[:cpu]).to have_key("1") end it_behaves_like "a cpu", 0 it_behaves_like "a cpu", 1 end ohai-16.0.7/spec/unit/plugins/windows/filesystem_spec.rb000066400000000000000000000272241362624620500233510ustar00rootroot00000000000000# # Author:: Nimesh Pathi # Copyright:: Copyright (c) 2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "wmi-lite/wmi" describe Ohai::System, "Windows Filesystem Plugin", :windows_only do let(:plugin) { get_plugin("filesystem") } let(:success) { true } let(:logical_disks_instances) do [ { "caption" => "C:", "deviceid" => "C:", "size" => "10000000", "filesystem" => "NTFS", "drivetype" => 3, "description" => "Local Fixed Disk", "freespace" => "100000", "name" => "C:", # omit "volumename"; it will be added in (some) tests below }, { "caption" => "D:", "deviceid" => "D:", "size" => "10000000", "filesystem" => "FAT32", "drivetype" => 2, "description" => "Removable Disk", "freespace" => "100000", "name" => "D:", # omit "volumename"; it will be added in (some) tests below }, ] end let(:encryptable_volume_instances) do [ { "conversionstatus" => 0, "driveletter" => "C:", }, { "conversionstatus" => 2, "driveletter" => "D:", }, ] end let(:wmi_exception) do namespace = "Exception while testing" exception = WIN32OLERuntimeError.new(namespace) WmiLite::WmiException.new(exception, :ConnectServer, @namespace) end before do allow(plugin).to receive(:collect_os).and_return(:windows) end describe "the plugin" do context "when there are no volume names" do before do allow(plugin).to receive(:logical_info).and_return(plugin.logical_properties(logical_disks_instances)) allow(plugin).to receive(:encryptable_info).and_return(plugin.encryption_properties(encryptable_volume_instances)) plugin.run end it "returns space information" do { "kb_size" => 10000, "kb_available" => 100, "kb_used" => 9900, "percent_used" => 99, }.each do |k, v| expect(plugin[:filesystem]["C:"][k]).to eq(v) expect(plugin[:filesystem]["D:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"][",C:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"][",D:"][k]).to eq(v) end end it "returns disk information" do { "fs_type" => "ntfs", "drive_type" => 3, "drive_type_string" => "local", "drive_type_human" => "Local Fixed Disk", "volume_name" => "", "encryption_status" => "FullyDecrypted", }.each do |k, v| expect(plugin[:filesystem]["C:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"][",C:"][k]).to eq(v) end { "fs_type" => "fat32", "drive_type" => 2, "drive_type_string" => "removable", "drive_type_human" => "Removable Disk", "volume_name" => "", "encryption_status" => "EncryptionInProgress", }.each do |k, v| expect(plugin[:filesystem]["D:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"][",D:"][k]).to eq(v) end end end context "when there are volume names" do before do ldi = logical_disks_instances ldi.each_with_index { |d, i| d["volumename"] = "Volume #{i}" } allow(plugin).to receive(:logical_info).and_return(plugin.logical_properties(ldi)) allow(plugin).to receive(:encryptable_info).and_return(plugin.encryption_properties(encryptable_volume_instances)) plugin.run end it "returns space information" do { "kb_size" => 10000, "kb_available" => 100, "kb_used" => 9900, "percent_used" => 99, }.each do |k, v| expect(plugin[:filesystem]["C:"][k]).to eq(v) expect(plugin[:filesystem]["D:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"]["volume 0,C:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"]["volume 1,D:"][k]).to eq(v) end end it "returns disk information" do { "fs_type" => "ntfs", "drive_type" => 3, "drive_type_string" => "local", "drive_type_human" => "Local Fixed Disk", "volume_name" => "Volume 0", "encryption_status" => "FullyDecrypted", }.each do |k, v| expect(plugin[:filesystem]["C:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"]["volume 0,C:"][k]).to eq(v) end { "fs_type" => "fat32", "drive_type" => 2, "drive_type_string" => "removable", "drive_type_human" => "Removable Disk", "volume_name" => "Volume 1", "encryption_status" => "EncryptionInProgress", }.each do |k, v| expect(plugin[:filesystem]["D:"][k]).to eq(v) expect(plugin[:filesystem2]["by_pair"]["volume 1,D:"][k]).to eq(v) end end end end describe "#logical_properties" do let(:disks) { logical_disks_instances } let(:logical_props) { %i{kb_size kb_available kb_used percent_used mount fs_type drive_type drive_type_string drive_type_human volume_name device} } it "Returns a mash" do expect(plugin.logical_properties(disks)).to be_a(Mash) end it "Returns an empty mash when blank array is passed" do expect(plugin.logical_properties([])).to be_a(Mash) expect(plugin.logical_properties([])).to be_empty end it "Returns properties without values when there is no disk information" do data = plugin.logical_properties([{}]) expect(data[","].symbolize_keys.keys).to eq(logical_props) expect(data[","]["kb_used"]).to eq(0) expect(data[","]["fs_type"]).to be_empty end it "Refines required logical properties out of given instance" do data = plugin.logical_properties(disks) expect(data[",C:"].symbolize_keys.keys).to eq(logical_props) expect(data[",D:"].symbolize_keys.keys).to eq(logical_props) end it "Calculates logical properties out of given instance" do data = plugin.logical_properties(disks) expect(data[",C:"]["kb_used"]).to eq(data[",D:"]["kb_used"]).and eq(9900) expect(data[",C:"]["percent_used"]).to eq(data[",D:"]["percent_used"]).and eq(99) expect(data[",C:"]["fs_type"]).to eq("ntfs") expect(data[",D:"]["fs_type"]).to eq("fat32") end end describe "#logical_info" do it "Returns an empty mash when wmi namespace does not exists" do allow(WmiLite::Wmi).to receive(:new).and_raise(wmi_exception) expect(plugin.logical_info).to be_a(Mash) expect(plugin.logical_info).to be_empty end it "Returns an empty mash when Win32_LogicalDisk could not be processed" do allow(WmiLite::Wmi).to receive(:new).and_return(success) allow(success) .to receive(:instances_of) .with("Win32_LogicalDisk") .and_raise(wmi_exception) expect(plugin.logical_info).to be_a(Mash) expect(plugin.logical_info).to be_empty end it "Returns a Mash loaded with logical details" do allow(WmiLite::Wmi).to receive(:new).and_return(success) allow(success) .to receive(:instances_of) .with("Win32_LogicalDisk") .and_return(logical_disks_instances) expect(plugin.logical_info).to be_a(Mash) expect(plugin.logical_info).not_to be_empty end end describe "#encryption_properties" do let(:disks) { encryptable_volume_instances } let(:encryption_props) { [:encryption_status] } it "Returns a mash" do expect(plugin.encryption_properties(disks)).to be_a(Mash) end it "Returns an empty mash when blank array is passed" do expect(plugin.encryption_properties([])).to be_a(Mash) expect(plugin.encryption_properties([])).to be_empty end it "Returns properties without values when there is no disk information" do data = plugin.encryption_properties([{}]) expect(data[nil].symbolize_keys.keys).to eq(encryption_props) expect(data[nil]["encryption_status"]).to be_empty end it "Refines required encryption properties out of given instance" do data = plugin.encryption_properties(disks) expect(data["C:"].symbolize_keys.keys).to eq(encryption_props) expect(data["D:"].symbolize_keys.keys).to eq(encryption_props) end it "Calculates encryption properties out of given instance" do data = plugin.encryption_properties(disks) expect(data["C:"]["encryption_status"]).to eq("FullyDecrypted") expect(data["D:"]["encryption_status"]).to eq("EncryptionInProgress") end end describe "#encryptable_info" do it "Returns an empty mash when wmi namespace does not exists" do allow(WmiLite::Wmi).to receive(:new).and_raise(wmi_exception) expect(plugin.encryptable_info).to be_a(Mash) expect(plugin.encryptable_info).to be_empty end it "Returns an empty mash when Win32_EncryptableVolume could not be processed" do allow(WmiLite::Wmi).to receive(:new).and_return(success) allow(success) .to receive(:instances_of) .with("Win32_EncryptableVolume") .and_raise(wmi_exception) expect(plugin.encryptable_info).to be_a(Mash) expect(plugin.encryptable_info).to be_empty end it "Returns a Mash loaded with encryption details" do allow(WmiLite::Wmi).to receive(:new).and_return(success) allow(success) .to receive(:instances_of) .with("Win32_EncryptableVolume") .and_return(encryptable_volume_instances) expect(plugin.encryptable_info).to be_a(Mash) expect(plugin.encryptable_info).not_to be_empty end end describe "#merge_info" do let(:logical_info) do { "dev1,drive1" => { "mount" => "drive1", "x" => 10, "y" => "test1" }, "dev2,drive2" => { "mount" => "drive2", "x" => 20, "z" => "test2" }, "dev2,drive3" => { "mount" => "drive3", "x" => 20, "z" => "test3" } } end let(:encryption_info) do { "drive1" => { "k" => 10, "l" => "test1" }, "drive2" => { "l" => 20, "m" => "test2" } } end let(:logical_info2) { { ",drive1" => { "mount" => "drive1", "o" => 10, "p" => "test1" } } } let(:encryption_info2) { { "drive2" => { "q" => 10, "r" => "test1" } } } it "Merges all the various properties of filesystems" do expect(plugin.merge_info(logical_info, encryption_info)).to eq( "dev1,drive1" => { "mount" => "drive1", "x" => 10, "y" => "test1", "k" => 10, "l" => "test1" }, "dev2,drive2" => { "mount" => "drive2", "x" => 20, "z" => "test2", "l" => 20, "m" => "test2" }, "dev2,drive3" => { "mount" => "drive3", "x" => 20, "z" => "test3" } ) end it "Does not affect any core information after processing" do expect(plugin.merge_info(logical_info2, encryption_info2)).to eq( ",drive1" => { "mount" => "drive1", "o" => 10, "p" => "test1" }, ",drive2" => { "q" => 10, "r" => "test1" } ) expect(logical_info2).to eq(",drive1" => { "mount" => "drive1", "o" => 10, "p" => "test1" }) expect(encryption_info2).to eq("drive2" => { "q" => 10, "r" => "test1" }) end end end ohai-16.0.7/spec/unit/plugins/windows/fips_spec.rb000066400000000000000000000030231362624620500221150ustar00rootroot00000000000000# # Author:: Matt Wrock () # Copyright:: Copyright (c) 2016-2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "openssl" describe Ohai::System, "plugin fips" do subject do plugin.run plugin["fips"]["kernel"]["enabled"] end let(:enabled) { 0 } let(:plugin) { get_plugin("windows/fips") } let(:openssl_test_mode) { false } before do allow(plugin).to receive(:collect_os).and_return(:windows) end around do |ex| $FIPS_TEST_MODE = openssl_test_mode ex.run ensure $FIPS_TEST_MODE = false end context "with OpenSSL.fips_mode == false" do before { allow(OpenSSL).to receive(:fips_mode).and_return(false) } it "does not set fips plugin" do expect(subject).to be(false) end end context "with OpenSSL.fips_mode == true" do before { allow(OpenSSL).to receive(:fips_mode).and_return(true) } it "sets fips plugin" do expect(subject).to be(true) end end end ohai-16.0.7/spec/unit/plugins/windows/kernel_spec.rb000066400000000000000000000067321362624620500224460ustar00rootroot00000000000000# # Copyright:: Copyright (c) 2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Windows kernel plugin", :windows_only do let(:plugin) { get_plugin("kernel") } before do require "wmi-lite/wmi" # Mock a Win32_OperatingSystem OLE32 WMI object caption = double("WIN32OLE", name: "Caption") version = double("WIN32OLE", name: "Version") build_number = double("WIN32OLE", name: "BuildNumber") csd_version = double("WIN32OLE", name: "CsdVersion") os_type = double("WIN32OLE", name: "OsType") product_type = double("WIN32OLE", name: "ProductType") operating_system_sku = double("WIN32OLE", name: "OperatingSystemSKU") os_properties = [ caption, version, build_number, csd_version, os_type, product_type, operating_system_sku ] os = double( "WIN32OLE", properties_: os_properties) allow(os).to receive(:invoke).with(build_number.name).and_return("7601") allow(os).to receive(:invoke).with(csd_version.name).and_return("Service Pack 1") allow(os).to receive(:invoke).with(os_type.name).and_return(18) allow(os).to receive(:invoke).with(caption.name).and_return("Microsoft Windows 7 Ultimate") allow(os).to receive(:invoke).with(version.name).and_return("6.1.7601") allow(os).to receive(:invoke).with(product_type.name).and_return(1) allow(os).to receive(:invoke).with(operating_system_sku.name).and_return(48) os_wmi = WmiLite::Wmi::Instance.new(os) expect_any_instance_of(WmiLite::Wmi).to receive(:first_of).with("Win32_OperatingSystem").and_return(os_wmi) system_type = double("WIN32OLE", name: "SystemType") pc_system_type = double("WIN32OLE", name: "PCSystemType") free_virtual_memory = double("WIN32OLE", name: "FreeVirtualMemory") cs_properties = [ system_type, pc_system_type, free_virtual_memory] cs = double("WIN32OLE", properties_: cs_properties) allow(cs).to receive(:invoke).with(system_type.name).and_return("x64-based PC") allow(cs).to receive(:invoke).with(pc_system_type.name).and_return(2) allow(cs).to receive(:invoke).with(free_virtual_memory.name).and_return("Why would you want this data here?") cs_wmi = WmiLite::Wmi::Instance.new(cs) expect_any_instance_of(WmiLite::Wmi).to receive(:first_of).with("Win32_ComputerSystem").and_return(cs_wmi) plugin.run end it "sets the correct system information" do expect(plugin[:kernel][:name]).to eq("Microsoft Windows 7 Ultimate") expect(plugin[:kernel][:release]).to eq("6.1.7601") expect(plugin[:kernel][:version]).to eq("6.1.7601 Service Pack 1 Build 7601") expect(plugin[:kernel][:os]).to eq("WINNT") expect(plugin[:kernel][:machine]).to eq("x86_64") expect(plugin[:kernel][:system_type]).to eq("Mobile") expect(plugin[:kernel][:product_type]).to eq("Workstation") expect(plugin[:kernel][:server_core]).to eq(false) expect(plugin[:kernel]).not_to have_key(:free_virtual_memory) end end ohai-16.0.7/spec/unit/plugins/windows/memory_spec.rb000066400000000000000000000030661362624620500224730ustar00rootroot00000000000000# # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Windows memory plugin", :windows_only do before do require "wmi-lite/wmi" @plugin = get_plugin("windows/memory") mock_os = { "TotalVisibleMemorySize" => "10485760", "FreePhysicalMemory" => "5242880", "SizeStoredInPagingFiles" => "20971520", "FreeSpaceInPagingFiles" => "15728640", } expect_any_instance_of(WmiLite::Wmi).to receive(:first_of).with("Win32_OperatingSystem").and_return(mock_os) end it "gets total memory" do @plugin.run expect(@plugin["memory"]["total"]).to eql("10485760kB") end it "gets free memory" do @plugin.run expect(@plugin["memory"]["free"]).to eql("5242880kB") end it "gets total swap" do @plugin.run expect(@plugin["memory"]["swap"]["total"]).to eql("20971520kB") end it "gets free memory" do @plugin.run expect(@plugin["memory"]["swap"]["free"]).to eql("15728640kB") end end ohai-16.0.7/spec/unit/plugins/windows/network_spec.rb000066400000000000000000000116121362624620500226500ustar00rootroot00000000000000# # Author:: Nimesh Pathi # Copyright:: Copyright (c) 2018 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ipaddress" describe Ohai::System, "Windows Network Plugin" do let(:plugin) { get_plugin("windows/network") } before do allow(plugin).to receive(:collect_os).and_return(:windows) end describe "#interface_code" do let(:interface_idx) { 1 } let(:index) { 2 } context "when interface index is given" do it "Returns a valid string having hexadecimal interface_index" do index = nil expect(plugin.interface_code(interface_idx, index)).to eq("0x1") end end context "when interface index is not given" do it "Returns a valid string having hexadecimal index" do interface_idx = nil expect(plugin.interface_code(interface_idx, index)).to eq("0x2") end end end describe "#prefer_ipv4" do let(:inet4) { "192.168.1.1" } let(:inet6) { "fe80::2fe:c8ff:fef5:c88f" } context "when Array is not passed" do it "Returns nil" do expect(plugin.prefer_ipv4("Invalid")).to be_nil end end context "when no address is passed in Array" do it "Returns nil" do expect(plugin.prefer_ipv4([])).to be_nil end end context "preferred chances of IPV4 address" do it "Returns the address when only IPV4 address is passed" do expect(plugin.prefer_ipv4([inet4])).to eq(inet4) end it "returns the address when IPV6 is also present at latter place" do expect(plugin.prefer_ipv4([inet4, inet6])).to eq(inet4) end it "returns the address when IPV6 is also present at former place" do expect(plugin.prefer_ipv4([inet6, inet4])).to eq(inet4) end end context "Preferred chances of IPV6 address" do it "returns the address when only IPV6 address is passed" do expect(plugin.prefer_ipv4([inet4])).to eq(inet4) end it "does not return the address if IPV4 is also present at former place" do expect(plugin.prefer_ipv4([inet4, inet6])).not_to eq(inet6) end it "does not return the address if IPV4 is also present at latter place" do expect(plugin.prefer_ipv4([inet6, inet4])).not_to eq(inet6) end end end describe "#favored_default_route_windows" do let(:interface1) do { "index" => 1, "interface_index" => 1, "ip_connection_metric" => 10, "default_ip_gateway" => ["fe80::2fe:c8ff:fef5:c88f", "192.168.1.1"] } end let(:iface_config) { { 1 => interface1 } } context "when a hash is not passed" do it "returns nil" do expect(plugin.favored_default_route_windows("Invalid")).to be_nil end end context "when no interface is passed in Hash" do it "returns nil" do expect(plugin.favored_default_route_windows({})).to be_nil end end context "when an interface configuration is passed" do context "without default_ip_gateway" do it "returns nil" do interface1["default_ip_gateway"] = nil expect(plugin.favored_default_route_windows(iface_config)).to be_nil end end context "with default_ip_gateway" do it "returns a hash with details" do expect(plugin.favored_default_route_windows(iface_config)).to be_a(Hash) expect(plugin.favored_default_route_windows(iface_config)).not_to be_empty end it "returns the default_gateway in IPV4 format" do expect(plugin.favored_default_route_windows(iface_config)).to include(default_ip_gateway: "192.168.1.1") end end end context "when multiple interfaces are passed" do let(:interface2) do { "index" => 2, "interface_index" => 3, "ip_connection_metric" => 20, "default_ip_gateway" => ["192.168.1.2"] } end let(:iface_config) do { 1 => interface1, 2 => interface2 } end it "returns the default route as least metric interface" do expect(plugin.favored_default_route_windows(iface_config)).to include(interface_index: 1) end it "returns its default_gateway in IPV4 format" do expect(plugin.favored_default_route_windows(iface_config)).to include(default_ip_gateway: "192.168.1.1") end end end end ohai-16.0.7/spec/unit/plugins/windows/system_enclosure_spec.rb000066400000000000000000000034541362624620500245670ustar00rootroot00000000000000# # Author:: Stuart Preston () # Copyright:: Copyright (c) 2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "System Enclosure", :windows_only do before do require "wmi-lite/wmi" @plugin = get_plugin("windows/system_enclosure") manufacturer = double("WIN32OLE", name: "manufacturer", value: "My Fake Manufacturer") serialnumber = double("WIN32OLE", name: "serialnumber", value: "1234123412341234") property_map = [ manufacturer, serialnumber ] wmi_ole_object = double( "WIN32OLE", properties_: property_map) allow(wmi_ole_object).to receive(:invoke).with(manufacturer.name).and_return(manufacturer.value) allow(wmi_ole_object).to receive(:invoke).with(serialnumber.name).and_return(serialnumber.value) wmi_object = WmiLite::Wmi::Instance.new(wmi_ole_object) expect_any_instance_of(WmiLite::Wmi).to receive(:first_of).with(("Win32_SystemEnclosure")).and_return(wmi_object) end it "returns the manufacturer" do @plugin.run expect(@plugin["system_enclosure"]["manufacturer"]).to eql("My Fake Manufacturer") end it "returns a serial number" do @plugin.run expect(@plugin["system_enclosure"]["serialnumber"]).to eql("1234123412341234") end end ohai-16.0.7/spec/unit/plugins/windows/uptime_spec.rb000066400000000000000000000024401362624620500224610ustar00rootroot00000000000000# # Author:: Aliasgar Batterywala () # Copyright:: Copyright (c) 2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Windows plugin uptime" do let(:plugin) { get_plugin("uptime") } let(:wmi) { double("wmi", { first_of: "" }) } before do allow(WmiLite::Wmi).to receive(:new).and_return(wmi) allow(plugin).to receive(:collect_os).and_return(:windows) end it "uses Win32_OperatingSystem WMI class to fetch the system's uptime" do expect(wmi).to receive(:first_of).with("Win32_OperatingSystem") expect(Time).to receive(:new) expect(Time).to receive(:parse) expect(plugin).to receive(:seconds_to_human) plugin.run end end ohai-16.0.7/spec/unit/plugins/windows/virtualization_spec.rb000066400000000000000000000070371362624620500242510ustar00rootroot00000000000000# # Author:: Pavel Yudin () # Author:: Tim Smith () # Copyright:: Copyright (c) 2015 Pavel Yudin # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "Windows virtualization platform" do let(:plugin) { get_plugin("windows/virtualization") } let(:wmi) { double("WmiLite::Wmi") } before do allow(WmiLite::Wmi).to receive(:new).and_return(wmi) allow(plugin).to receive(:collect_os).and_return(:windows) end describe "it sets virtualization guest status from Win32_ComputerSystemProduct data" do it "system is vmware" do allow(wmi).to receive(:first_of).with("Win32_ComputerSystemProduct").and_return( { "caption" => "Computer System Product", "description" => "Computer System Product", "identifyingnumber" => "ec2d6aad-f59b-a10d-5784-ca9b7ba4f727", "name" => "HVM domU", "skunumber" => nil, "uuid" => "EC2D6AAD-F59B-A10D-5784-CA9B7BA4F727", "vendor" => "Xen", "version" => "4.2.amazon" } ) plugin.run expect(plugin[:virtualization][:system]).to eq("xen") expect(plugin[:virtualization][:role]).to eq("guest") expect(plugin[:virtualization][:systems][:xen]).to eq("guest") end end context "when running on a hardware system" do it "does not set virtualization attributes" do allow(wmi).to receive(:first_of).with("Win32_ComputerSystemProduct").and_return({ "caption" => "Computer System Product", "description" => "Computer System Product", "identifyingnumber" => "0123456789", "name" => "X10SLH-N6-ST031", "skunumber" => nil, "uuid" => "00000000-0000-0000-0000-0CC47A8F7618", "vendor" => "Supermicro", "version" => "0123456789" }) plugin.run expect(plugin[:virtualization]).to eq("systems" => {}) end end end ohai-16.0.7/spec/unit/plugins/zpools_spec.rb000066400000000000000000000216641362624620500210230ustar00rootroot00000000000000# License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" describe Ohai::System, "zpools plugin" do let(:plugin) { get_plugin("zpools") } context "when on Linux" do let(:zpool_status_tank) do <<-EOST pool: tank state: ONLINE scan: scrub repaired 0 in 0h0m with 0 errors on Fri Jun 6 14:43:40 2014 config: NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 raidz2-0 ONLINE 0 0 0 sdc ONLINE 0 0 0 sdd ONLINE 0 0 0 sde ONLINE 0 0 0 sdf ONLINE 0 0 0 sdg ONLINE 0 0 0 sdh ONLINE 0 0 0 raidz2-1 ONLINE 0 0 0 sdi ONLINE 0 0 0 sdj ONLINE 0 0 0 sdk ONLINE 0 0 0 sdl ONLINE 0 0 0 sdm ONLINE 0 0 0 sdn ONLINE 0 0 0 EOST end let(:zpool_out) do <<~EOZO rpool 109G 66.2G 42.8G 60% 1.00x ONLINE - tank 130T 4.91M 130T 0% 1.00x ONLINE - EOZO end let(:zpool_status_rpool) do <<-EOSR pool: rpool state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM rpool ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 sda ONLINE 0 0 0 sdb ONLINE 0 0 0 errors: No known data errors EOSR end before do allow(plugin).to receive(:platform_family).and_return("rhel") allow(plugin).to receive(:collect_os).and_return(:linux) allow(plugin).to receive(:shell_out).with("zpool list -H -o name,size,alloc,free,cap,dedup,health,version").and_return(mock_shell_out(0, zpool_out, "")) allow(plugin).to receive(:shell_out).with("zpool status rpool").and_return(mock_shell_out(0, zpool_status_rpool, "")) allow(plugin).to receive(:shell_out).with("zpool status tank").and_return(mock_shell_out(0, zpool_status_tank, "")) end it "Has entries for both zpools" do plugin.run expect(plugin[:zpools][:rpool]).to be expect(plugin[:zpools][:tank]).to be end it "Has the correct pool size" do plugin.run expect(plugin[:zpools][:rpool][:pool_size]).to match("109G") expect(plugin[:zpools][:tank][:pool_size]).to match("130T") end it "Has the correct pool allocated size" do plugin.run expect(plugin[:zpools][:rpool][:pool_allocated]).to match("66.2G") expect(plugin[:zpools][:tank][:pool_allocated]).to match("4.91M") end it "Has the correct pool free size" do plugin.run expect(plugin[:zpools][:rpool][:pool_free]).to match("42.8G") expect(plugin[:zpools][:tank][:pool_free]).to match("130T") end it "Has the correct capacity_used" do plugin.run expect(plugin[:zpools][:rpool][:capacity_used]).to match("60%") expect(plugin[:zpools][:tank][:capacity_used]).to match("0%") end it "Has the correct dedup_factor" do plugin.run expect(plugin[:zpools][:rpool][:dedup_factor]).to match("1.00x") expect(plugin[:zpools][:tank][:dedup_factor]).to match("1.00x") end it "Has the correct health" do plugin.run expect(plugin[:zpools][:rpool][:health]).to match("ONLINE") expect(plugin[:zpools][:tank][:health]).to match("ONLINE") end it "Has the correct number of devices" do plugin.run expect(plugin[:zpools][:rpool][:devices].keys.size).to match(2) expect(plugin[:zpools][:tank][:devices].keys.size).to match(12) end it "Won't have a version number" do plugin.run expect(plugin[:zpools][:rpool][:zpool_version]).to be_nil expect(plugin[:zpools][:tank][:zpool_version]).to be_nil end end context "when on Solaris2" do let(:zpool_status_tank) do <<~EOST pool: tank state: ONLINE scan: scrub repaired 0 in 0h0m with 0 errors on Fri Jun 6 14:43:40 2014 config: NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 raidz2-0 ONLINE 0 0 0 c1t50014EE209D1DBA9d0 ONLINE 0 0 0 c1t50014EE20A0ECED2d0 ONLINE 0 0 0 c1t50014EE20A106BFFd0 ONLINE 0 0 0 c1t50014EE20A1423E8d0 ONLINE 0 0 0 c1t50014EE20A145447d0 ONLINE 0 0 0 c1t50014EE20A29EE56d0 ONLINE 0 0 0 raidz2-1 ONLINE 0 0 0 c1t50014EE20A2B984Cd0 ONLINE 0 0 0 c1t50014EE20A2BBC78d0 ONLINE 0 0 0 c1t50014EE20A2BDCA9d0 ONLINE 0 0 0 c1t50014EE25F697DC4d0 ONLINE 0 0 0 c1t50014EE25F698BECd0 ONLINE 0 0 0 c1t50014EE25F6998DAd0 ONLINE 0 0 0 EOST end let(:zpool_out) do <<~EOZO rpool 109G 66.2G 42.8G 60% 1.00x ONLINE 34 tank 130T 4.91M 130T 0% 1.00x ONLINE 34 EOZO end let(:zpool_status_rpool) do <<~EOSR pool: rpool state: ONLINE scan: resilvered 65.6G in 0h8m with 0 errors on Fri Jun 6 14:22:40 2014 config: NAME STATE READ WRITE CKSUM rpool ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c3t5d0s0 ONLINE 0 0 0 c3t4d0s0 ONLINE 0 0 0 errors: No known data errors EOSR end before do allow(plugin).to receive(:platform_family).and_return("solaris2") allow(plugin).to receive(:collect_os).and_return(:solaris2) allow(plugin).to receive(:shell_out).with("zpool list -H -o name,size,alloc,free,cap,dedup,health,version").and_return(mock_shell_out(0, zpool_out, "")) allow(plugin).to receive(:shell_out).with("su adm -c \"zpool status rpool\"").and_return(mock_shell_out(0, zpool_status_rpool, "")) allow(plugin).to receive(:shell_out).with("su adm -c \"zpool status tank\"").and_return(mock_shell_out(0, zpool_status_tank, "")) end it "Has entries for both zpools" do plugin.run expect(plugin[:zpools][:rpool]).to be expect(plugin[:zpools][:tank]).to be end it "Has the correct pool size" do plugin.run expect(plugin[:zpools][:rpool][:pool_size]).to match("109G") expect(plugin[:zpools][:tank][:pool_size]).to match("130T") end it "Has the correct pool allocated size" do plugin.run expect(plugin[:zpools][:rpool][:pool_allocated]).to match("66.2G") expect(plugin[:zpools][:tank][:pool_allocated]).to match("4.91M") end it "Has the correct pool free size" do plugin.run expect(plugin[:zpools][:rpool][:pool_free]).to match("42.8G") expect(plugin[:zpools][:tank][:pool_free]).to match("130T") end it "Has the correct capacity_used" do plugin.run expect(plugin[:zpools][:rpool][:capacity_used]).to match("60%") expect(plugin[:zpools][:tank][:capacity_used]).to match("0%") end it "Has the correct dedup_factor" do plugin.run expect(plugin[:zpools][:rpool][:dedup_factor]).to match("1.00x") expect(plugin[:zpools][:tank][:dedup_factor]).to match("1.00x") end it "Has the correct health" do plugin.run expect(plugin[:zpools][:rpool][:health]).to match("ONLINE") expect(plugin[:zpools][:tank][:health]).to match("ONLINE") end it "Has the correct number of devices" do plugin.run expect(plugin[:zpools][:rpool][:devices].keys.size).to match(2) expect(plugin[:zpools][:tank][:devices].keys.size).to match(12) end it "Has a version number" do plugin.run expect(plugin[:zpools][:rpool][:zpool_version]).to match("34") expect(plugin[:zpools][:tank][:zpool_version]).to match("34") end end end ohai-16.0.7/spec/unit/provides_map_spec.rb000066400000000000000000000176761362624620500205140ustar00rootroot00000000000000# # Author:: Daniel DeLeo () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); you # may not use this file except in compliance with the License. You may # obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or # implied. # See the License for the specific language governing permissions and # limitations under the License # require "spec_helper" describe Ohai::ProvidesMap do let(:ohai_system) { Ohai::System.new } let(:provides_map) { described_class.new } let(:plugin_1) { Ohai::DSL::Plugin.new(ohai_system.data, ohai_system.logger) } let(:plugin_2) { Ohai::DSL::Plugin.new(ohai_system.data, ohai_system.logger) } let(:plugin_3) { Ohai::DSL::Plugin.new(ohai_system.data, ohai_system.logger) } let(:plugin_4) { Ohai::DSL::Plugin.new(ohai_system.data, ohai_system.logger) } describe "when looking up providing plugins for a single attribute" do describe "when the attribute does not exist" do it "raises Ohai::Exceptions::AttributeNotFound error" do expect { provides_map.find_providers_for(["single"]) }.to raise_error(Ohai::Exceptions::AttributeNotFound, "No such attribute: 'single'") end end describe "when the attribute does not have a provider" do it "raises Ohai::Exceptions::ProviderNotFound error" do provides_map.set_providers_for(plugin_1, ["first/second"]) expect { provides_map.find_providers_for(["first"]) }.to raise_error(Ohai::Exceptions::ProviderNotFound, "Cannot find plugin providing attribute: 'first'") end end describe "when only one plugin provides the attribute" do before do provides_map.set_providers_for(plugin_1, ["single"]) end it "returns the provider" do expect(provides_map.find_providers_for(["single"])).to eq([plugin_1]) end end describe "when multiple plugins provide the attribute" do before do provides_map.set_providers_for(plugin_1, ["single"]) provides_map.set_providers_for(plugin_2, ["single"]) end it "returns all providers" do expect(provides_map.find_providers_for(["single"])).to eq([plugin_1, plugin_2]) end end end describe "when looking up providing plugins for multiple attributes" do describe "when a different plugin provides each attribute" do before do provides_map.set_providers_for(plugin_1, ["one"]) provides_map.set_providers_for(plugin_2, ["two"]) end it "returns each provider" do expect(provides_map.find_providers_for(%w{one two})).to eq([plugin_1, plugin_2]) end end describe "when one plugin provides both requested attributes" do before do provides_map.set_providers_for(plugin_1, ["one"]) provides_map.set_providers_for(plugin_1, ["one_again"]) end it "returns unique providers" do expect(provides_map.find_providers_for(%w{one one_again})).to eq([plugin_1]) end end end describe "when looking up providers for multi-level attributes" do describe "when the full attribute exists in the map" do before do provides_map.set_providers_for(plugin_1, ["top/middle/bottom"]) end it "collects the provider" do expect(provides_map.find_providers_for(["top/middle/bottom"])).to eq([plugin_1]) end end end describe "when setting multi-level attributes" do describe "when the attribute contains //" do it "raises an Ohai::Exceptions::AttributeSyntaxError" do expect { provides_map.set_providers_for(plugin_1, ["this/plugin//is/bad"]) }.to raise_error(Ohai::Exceptions::AttributeSyntaxError, "Attribute contains duplicate '/' characters: this/plugin//is/bad") end end describe "when the attribute has a trailing slash" do it "raises an Ohai::Exceptions::AttributeSyntaxError" do expect { provides_map.set_providers_for(plugin_1, ["this/plugin/is/bad/"]) }.to raise_error(Ohai::Exceptions::AttributeSyntaxError, "Attribute contains a trailing '/': this/plugin/is/bad/") end end end describe "when looking for providers of attributes specified in CLI" do before do provides_map.set_providers_for(plugin_1, ["cat/whiskers"]) provides_map.set_providers_for(plugin_2, ["cat/paws", "cat/paws/toes"]) provides_map.set_providers_for(plugin_3, ["cat/mouth/teeth"]) end it "finds providers for subattributes if any exists when the attribute doesn't have a provider" do providers = provides_map.deep_find_providers_for(["cat"]) expect(providers).to have(3).plugins expect(providers).to include(plugin_1) expect(providers).to include(plugin_2) expect(providers).to include(plugin_3) end it "finds providers for the first parent attribute when the attribute or any subattributes doesn't have a provider" do providers = provides_map.deep_find_providers_for(["cat/paws/front"]) expect(providers).to eq([plugin_2]) end end describe "when looking for the closest providers" do describe "and the full attribute is provided" do before do provides_map.set_providers_for(plugin_1, ["do/not/eat/metal"]) end it "returns the provider of the full attribute" do expect(provides_map.find_closest_providers_for(["do/not/eat/metal"])).to eql([plugin_1]) end end describe "and the full attribute is not provided" do before do provides_map.set_providers_for(plugin_1, ["do/not/eat"]) end it "does not raise error if a parent attribute is provided" do expect { provides_map.find_closest_providers_for(["do/not/eat/plastic"]) }.not_to raise_error end it "returns the providers of the closest parent attribute" do provides_map.set_providers_for(plugin_2, ["do/not"]) # set a less-specific parent expect(provides_map.find_closest_providers_for(["do/not/eat/glass"])).to eql([plugin_1]) end it "raises error if the least-specific parent is not an attribute" do expect { provides_map.find_closest_providers_for(["please/eat/your/vegetables"]) }.to raise_error(Ohai::Exceptions::AttributeNotFound, "No such attribute: 'please/eat/your/vegetables'") end it "raises error if no parent attribute has a provider" do expect { provides_map.find_closest_providers_for(["do/not"]) }.to raise_error(Ohai::Exceptions::ProviderNotFound, "Cannot find plugin providing attribute: 'do/not'") end end end describe "when listing all plugins" do before do provides_map.set_providers_for(plugin_1, ["one"]) provides_map.set_providers_for(plugin_2, ["two"]) provides_map.set_providers_for(plugin_3, ["stub/three"]) provides_map.set_providers_for(plugin_4, ["foo/bar/four", "also/this/four"]) end it "finds all the plugins providing attributes" do all_plugins = provides_map.all_plugins expect(all_plugins).to have(4).plugins expect(all_plugins).to include(plugin_1) expect(all_plugins).to include(plugin_2) expect(all_plugins).to include(plugin_3) expect(all_plugins).to include(plugin_4) end describe "with an attribute filter" do it "finds plugins with a single level of attribute" do expect(provides_map.all_plugins("one")).to eq([plugin_1]) end it "finds plugins with an exact match for multiple levels of attribute" do expect(provides_map.all_plugins("stub/three")).to eq([plugin_3]) end it "finds plugins that provide subattributes of the requested path" do expect(provides_map.all_plugins("stub")).to eq([plugin_3]) expect(provides_map.all_plugins("foo/bar")).to eq([plugin_4]) end end end end ohai-16.0.7/spec/unit/runner_spec.rb000066400000000000000000000300141362624620500173120ustar00rootroot00000000000000# # Author:: Claire McQuin () # Copyright:: Copyright (c) 2013-2019, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); you # may not use this file except in compliance with the License. You may # obtain a copy of the license at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or # implied. # See the License for the specific language governing permissions and # limitations under the License # require "spec_helper" describe Ohai::Runner, "run_plugin" do let(:safe_run) { true } before do @ohai = Ohai::System.new @runner = described_class.new(@ohai, safe_run) end describe "when running an invalid plugin" do it "raises error" do expect { @runner.run_plugin(double("Ohai::NotPlugin")) }.to raise_error(Ohai::Exceptions::InvalidPlugin) end end describe "when running a plugin" do let(:plugin) { double("Ohai::DSL::Plugin", is_a?: true, version: version, name: :Test, has_run?: has_run, dependencies: [ ]) } let(:version) { :version7 } let(:has_run) { false } describe "version 7" do it "calls run_v7_plugin" do expect(@runner).to receive(:run_v7_plugin) @runner.run_plugin(plugin) end describe "if the plugin has run before" do let(:has_run) { true } it "does not run the plugin" do expect(plugin).not_to receive(:safe_run) @runner.run_plugin(plugin) end end end describe "invalid version" do let(:version) { :versionBla } it "raises error" do expect { @runner.run_plugin(plugin) }.to raise_error(Ohai::Exceptions::InvalidPlugin) end end end describe "when running a plugin with no dependencies, Ohai::Runner" do let(:plugin) do klass = Ohai.plugin(:Test) do provides("thing") collect_data do thing(Mash.new) end end klass.new(@ohai.data, @ohai.logger) end it "runs the plugin" do @runner.run_plugin(plugin) expect(plugin.has_run?).to be true end it "adds plugin data to Ohai::System.data" do @runner.run_plugin(plugin) expect(@ohai.data).to have_key(:thing) expect(@ohai.data[:thing]).to eql({}) end end describe "when running a plugin with one dependency" do describe "when the dependency does not exist" do before do klass = Ohai.plugin(:Test) do provides("thing") depends("other_thing") collect_data do thing(other_thing) end end @plugin = klass.new(@ohai.data, @ohai.logger) end it "raises Ohai::Excpetions::AttributeNotFound" do expect { @runner.run_plugin(@plugin) }.to raise_error(Ohai::Exceptions::AttributeNotFound) end it "does not run the plugin" do expect { @runner.run_plugin(@plugin) }.to raise_error(Ohai::Exceptions::AttributeNotFound) expect(@plugin.has_run?).to be false end end describe "when the dependency has a single provider" do before do klass1 = Ohai.plugin(:Thing) do provides("thing") collect_data do thing("thang") end end klass2 = Ohai.plugin(:Other) do provides("other") depends("thing") collect_data do other(thing) end end @plugins = [] [klass1, klass2].each do |klass| @plugins << klass.new(@ohai.data, @ohai.logger) end @plugin1, @plugin2 = @plugins @ohai.provides_map.set_providers_for(@plugin1, ["thing"]) end it "runs the plugins" do @runner.run_plugin(@plugin2) @plugins.each do |plugin| expect(plugin.has_run?).to be true end end end describe "when the dependency has multiple providers" do before do klass1 = Ohai.plugin(:Thing) do provides("thing") collect_data do thing(Mash.new) end end klass2 = Ohai.plugin(:Other) do provides("other") depends("thing") collect_data do other(thing) end end @plugins = [] [klass1, klass1, klass2].each do |klass| @plugins << klass.new(@ohai.data, @ohai.logger) end @plugin1, @plugin2, @plugin3 = @plugins @ohai.provides_map.set_providers_for(@plugin1, ["thing"]) @ohai.provides_map.set_providers_for(@plugin2, ["thing"]) end it "runs the plugins" do @runner.run_plugin(@plugin3) @plugins.each do |plugin| expect(plugin.has_run?).to be true end end end end describe "when running a plugin with many dependencies" do before do @ohai = Ohai::System.new @runner = described_class.new(@ohai, true) klass1 = Ohai.plugin(:One) do provides("one") collect_data do one(1) end end klass2 = Ohai.plugin(:Two) do provides("two") collect_data do two(2) end end klass3 = Ohai.plugin(:Three) do provides("three") depends("one", "two") collect_data do three(3) end end @plugins = [] [klass1, klass2, klass3].each do |klass| @plugins << klass.new(@ohai.data, @ohai.logger) end @plugin1, @plugin2, @plugin3 = @plugins @ohai.provides_map.set_providers_for(@plugin1, %w{one two}) @ohai.provides_map.set_providers_for(@plugin2, %w{one two}) end it "runs the plugins" do @runner.run_plugin(@plugin3) @plugins.each do |plugin| expect(plugin.has_run?).to be true end end end describe "when a cycle is detected" do let(:runner) { described_class.new(@ohai, true) } context "when there are no edges in the cycle (A->A)" do let(:plugin_class) do Ohai.plugin(:Thing) do provides("thing") depends("thing") collect_data do thing(other) end end end let(:plugin) { plugin_class.new(@ohai.data, @ohai.logger) } it "ignores the cycle" do @ohai.provides_map.set_providers_for(plugin, ["thing"]) runner.run_plugin(plugin) # should not raise end end context "when there is one edge in the cycle (A->B and B->A)" do before do klass1 = Ohai.plugin(:Thing) do # rubocop disable Lint/UselessAssignment provides("thing") depends("other") collect_data do thing(other) end end klass2 = Ohai.plugin(:Other) do provides("other") depends("thing") collect_data do other(thing) end end @plugins = [] [klass1, klass2].each_with_index do |klass, idx| @plugins << klass.new(@ohai.data, @ohai.logger) end @plugin1, @plugin2 = @plugins end it "raises Ohai::Exceptions::DependencyCycle" do allow(runner).to receive(:fetch_plugins).with(["thing"]).and_return([@plugin1]) allow(runner).to receive(:fetch_plugins).with(["other"]).and_return([@plugin2]) expected_error_string = "Dependency cycle detected. Please refer to the following plugins: Thing, Other" expect { runner.run_plugin(@plugin1) }.to raise_error(Ohai::Exceptions::DependencyCycle, expected_error_string) end end end describe "when A depends on B and C, and B depends on C" do before do @ohai = Ohai::System.new @runner = described_class.new(@ohai, true) klass_a = Ohai.plugin(:A) do provides("A") depends("B", "C") collect_data {} end klass_b = Ohai.plugin(:B) do provides("B") depends("C") collect_data {} end klass_c = Ohai.plugin(:C) do provides("C") collect_data {} end @plugins = [] [klass_a, klass_b, klass_c].each do |klass| @plugins << klass.new(@ohai.data, @ohai.logger) end @plugin_a, @plugin_b, @plugin_c = @plugins end it "does not detect a cycle when B is the first provider returned" do @ohai.provides_map.set_providers_for(@plugin_a, ["A"]) @ohai.provides_map.set_providers_for(@plugin_b, ["B"]) @ohai.provides_map.set_providers_for(@plugin_c, ["C"]) expect(Ohai::Log).not_to receive(:error).with(/DependencyCycleError/) @runner.run_plugin(@plugin_a) @plugins.each do |plugin| expect(plugin.has_run?).to be true end end it "does not detect a cycle when C is the first provider returned" do @ohai.provides_map.set_providers_for(@plugin_a, ["A"]) @ohai.provides_map.set_providers_for(@plugin_c, ["C"]) @ohai.provides_map.set_providers_for(@plugin_b, ["B"]) expect(Ohai::Log).not_to receive(:error).with(/DependencyCycleError/) @runner.run_plugin(@plugin_a) @plugins.each do |plugin| expect(plugin.has_run?).to be true end end end end describe Ohai::Runner, "fetch_plugins" do before do @provides_map = Ohai::ProvidesMap.new @data = Mash.new @ohai = double("Ohai::System", data: @data, provides_map: @provides_map, logger: Ohai::Log.with_child) @runner = described_class.new(@ohai, true) end it "collects the provider" do plugin = Ohai::DSL::Plugin.new(@ohai.data, @ohai.logger) @ohai.provides_map.set_providers_for(plugin, ["top/middle/bottom"]) dependency_providers = @runner.fetch_plugins(["top/middle/bottom"]) expect(dependency_providers).to eql([plugin]) end describe "when the attribute is not provided by any plugin" do describe "and some parent attribute has providers" do it "returns the providers for the parent" do plugin = Ohai::DSL::Plugin.new(@ohai.data, @ohai.logger) @provides_map.set_providers_for(plugin, ["test/attribute"]) expect(@runner.fetch_plugins(["test/attribute/too_far"])).to eql([plugin]) end end describe "and no parent attribute has providers" do it "raises Ohai::Exceptions::AttributeNotFound exception" do # provides map is empty expect { @runner.fetch_plugins(["false/attribute"]) }.to raise_error(Ohai::Exceptions::AttributeNotFound, "No such attribute: 'false/attribute'") end end end it "returns unique providers" do plugin = Ohai::DSL::Plugin.new(@ohai.data, @ohai.logger) @provides_map.set_providers_for(plugin, ["test", "test/too_far/way_too_far"]) expect(@runner.fetch_plugins(["test", "test/too_far/way_too_far"])).to eql([plugin]) end end describe Ohai::Runner, "#get_cycle" do before do @ohai = Ohai::System.new @runner = described_class.new(@ohai, true) klass1 = Ohai.plugin(:One) do provides("one") depends("two") collect_data do one(two) end end klass2 = Ohai.plugin(:Two) do provides("two") depends("one") collect_data do two(one) end end klass3 = Ohai.plugin(:Three) do provides("three") depends("two") collect_data do three(two) end end plugins = [] [klass1, klass2, klass3].each_with_index do |klass, idx| plugins << klass.new(@ohai.data, @ohai.logger) end @plugin1, @plugin2, @plugin3 = plugins end it "returns the sources for the plugins in the cycle, when given an exact cycle" do cycle = [@plugin1, @plugin2] cycle_start = @plugin1 cycle_names = @runner.get_cycle(cycle, cycle_start) expect(cycle_names).to eql([@plugin1.name, @plugin2.name]) end it "returns the sources for only the plugins in the cycle, when there are plugins before the cycle begins" do cycle = [@plugin3, @plugin1, @plugin2] cycle_start = @plugin1 cycle_names = @runner.get_cycle(cycle, cycle_start) expect(cycle_names).to eql([@plugin1.name, @plugin2.name]) end end ohai-16.0.7/spec/unit/system_spec.rb000066400000000000000000000277171362624620500173450ustar00rootroot00000000000000# # Author:: Adam Jacob () # Author:: Claire McQuin () # Copyright:: Copyright (c) 2008-2017, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "ohai/mixin/os" describe "Ohai::System" do extend IntegrationSupport let(:ohai_external) {} let(:ohai) { Ohai::System.new({ invoked_from_cli: true }) } describe "#initialize" do it "returns an Ohai::System object" do expect(ohai).to be_a_kind_of(Ohai::System) end it "sets @attributes to a ProvidesMap" do expect(ohai.provides_map).to be_a_kind_of(Ohai::ProvidesMap) end it "merges provided configuration options into the ohai config context" do config = { disabled_plugins: %i{Foo Baz}, directory: ["/some/extra/plugins"], critical_plugins: %i{Foo Bar}, } Ohai::System.new(config) config.each do |option, value| expect(Ohai.config[option]).to eq(value) end end context "when a single directory is configured as a string" do let(:directory) { "/some/fantastic/plugins" } it "adds directory to plugin_path" do Ohai.config[:directory] = directory Ohai::System.new({ invoked_from_cli: true }) expect(Ohai.config[:plugin_path]).to include("/some/fantastic/plugins") end end context "when multiple directories are configured" do let(:directory) { ["/some/fantastic/plugins", "/some/other/plugins"] } it "adds directories to plugin_path" do Ohai.config[:directory] = directory Ohai::System.new({ invoked_from_cli: true }) expect(Ohai.config[:plugin_path]).to include("/some/fantastic/plugins") expect(Ohai.config[:plugin_path]).to include("/some/other/plugins") end end context "when testing the intializer that does way too much" do it "configures logging" do log_level = :debug Ohai.config[:log_level] = log_level expect(Ohai::Log).to receive(:level=).with(log_level) Ohai::System.new({ invoked_from_cli: true }) end it "resolves log_level when set to :auto" do expect(Ohai::Log).to receive(:level=).with(:info) Ohai::System.new({ invoked_from_cli: true }) end context "when called externally" do it "does not configure logging" do log_level = :debug Ohai.config[:log_level] = log_level expect(Ohai::Log).not_to receive(:level=).with(log_level) Ohai::System.new end it "does not resolve log_level when set to :auto" do expect(Ohai::Log).not_to receive(:level=).with(:info) Ohai::System.new end end end end when_plugins_directory "contains directories inside" do with_plugin("repo1/zoo.rb", <<~EOF) Ohai.plugin(:Zoo) do provides 'seals' end EOF with_plugin("repo1/lake.rb", <<~EOF) Ohai.plugin(:Nature) do provides 'fish' end EOF with_plugin("repo2/nature.rb", <<~EOF) Ohai.plugin(:Nature) do provides 'crabs' end EOF with_plugin("repo2/mountain.rb", <<~EOF) Ohai.plugin(:Nature) do provides 'bear' end EOF before do Ohai.config[:plugin_path] = [ path_to("repo1"), path_to("repo2") ] end it "load_plugins() should load all the plugins" do ohai.load_plugins expect(ohai.provides_map.map.keys).to include("seals") expect(ohai.provides_map.map.keys).to include("crabs") expect(Ohai::NamedPlugin.const_get(:Zoo)).to eq(Ohai::NamedPlugin::Zoo) expect(Ohai::NamedPlugin.const_get(:Nature)).to eq(Ohai::NamedPlugin::Nature) end end describe "when running plugins" do when_plugins_directory "contains a v7 plugins with :default and platform specific blocks" do with_plugin("message.rb", <<~EOF) Ohai.plugin(:Message) do provides 'message' collect_data(:default) do message("default") end collect_data(:#{Ohai::Mixin::OS.collect_os}) do message("platform_specific_message") end end EOF it "collects platform specific" do Ohai.config[:plugin_path] = [ path_to(".") ] ohai.all_plugins expect(ohai.data[:message]).to eq("platform_specific_message") end end when_plugins_directory "contains v7 plugins only" do with_plugin("zoo.rb", <<~EOF) Ohai.plugin(:Zoo) do provides 'zoo' collect_data(:default) do zoo("animals") end end EOF with_plugin("park.rb", <<~EOF) Ohai.plugin(:Park) do provides 'park' collect_data(:default) do park("plants") end end EOF with_plugin("fails.rb", <<~EOF) Ohai.plugin(:Fails) do provides 'fails' collect_data(:default) do fail 'thing' end end EOF with_plugin("optional.rb", <<~EOF) Ohai.plugin(:Optional) do provides 'optional' optional true collect_data(:default) do optional("canteloupe") end end EOF it "collects data from all the plugins" do Ohai.config[:plugin_path] = [ path_to(".") ] ohai.all_plugins expect(ohai.data[:zoo]).to eq("animals") expect(ohai.data[:park]).to eq("plants") expect(ohai.data[:zoo]).to be_frozen expect(ohai.data[:park]).to be_frozen end it "writes an error to Ohai::Log" do Ohai.config[:plugin_path] = [ path_to(".") ] # Make sure the stubbing of runner is not overriden with reset_system during test allow(ohai).to receive(:reset_system) allow(ohai.instance_variable_get("@runner")).to receive(:run_plugin).and_raise(Ohai::Exceptions::AttributeNotFound) expect(ohai.logger).to receive(:error).with(/Encountered error while running plugins/) expect { ohai.all_plugins }.to raise_error(Ohai::Exceptions::AttributeNotFound) end describe "when using :disabled_plugins" do before do Ohai.config[:disabled_plugins] = [ :Zoo ] end after do Ohai.config[:disabled_plugins] = [ ] end it "does not run disabled plugins" do Ohai.config[:plugin_path] = [ path_to(".") ] ohai.all_plugins expect(ohai.data[:zoo]).to be_nil expect(ohai.data[:park]).to eq("plants") end end describe "when using :critical_plugins" do # if called from cli is true, we'll exit these tests let(:ohai) { Ohai::System.new } before do Ohai.config[:critical_plugins] = [ :Fails ] end after do Ohai.config[:critical_plugins] = [] end it "fails when critical plugins fail" do Ohai.config[:plugin_path] = [ path_to(".") ] expect { ohai.all_plugins }.to raise_error(Ohai::Exceptions::CriticalPluginFailure, "The following Ohai plugins marked as critical failed: [:Fails]. Failing Chef run.") end end describe "when using :optional_plugins" do it "does not run optional plugins by default" do Ohai.config[:plugin_path] = [ path_to(".") ] ohai.all_plugins expect(ohai.data[:optional]).to be_nil end it "runs optional plugins when specifically enabled" do Ohai.config[:optional_plugins] = [ :Optional ] Ohai.config[:plugin_path] = [ path_to(".") ] ohai.all_plugins expect(ohai.data[:optional]).to eq("canteloupe") end it "runs optional plugins when all plugins are enabled" do Ohai.config[:run_all_plugins] = true Ohai.config[:plugin_path] = [ path_to(".") ] ohai.all_plugins expect(ohai.data[:optional]).to eq("canteloupe") end end end end describe "when Chef OHAI resource executes :reload action" do when_plugins_directory "contains a random plugin" do with_plugin("random.rb", <<-E) Ohai.plugin(:Random) do provides 'random' collect_data do random rand(1 << 32) end end E before do Ohai.config[:plugin_path] = [ path_to(".") ] end it "reruns the plugin providing the desired attributes" do ohai.all_plugins initial_value = ohai.data["random"] ohai.all_plugins updated_value = ohai.data["random"] expect(initial_value).not_to eq(updated_value) end end end describe "when running ohai for specific attributes" do when_plugins_directory "contains v7 plugins" do with_plugin("languages.rb", <<-E) Ohai.plugin(:Languages) do provides 'languages' collect_data do languages Mash.new end end E with_plugin("english.rb", <<-E) Ohai.plugin(:English) do provides 'languages/english' depends 'languages' collect_data do languages[:english] = Mash.new languages[:english][:version] = 2014 end end E with_plugin("french.rb", <<-E) Ohai.plugin(:French) do provides 'languages/french' depends 'languages' collect_data do languages[:french] = Mash.new languages[:french][:version] = 2012 end end E before do Ohai.config[:plugin_path] = [ path_to(".") ] end it "runs all the plugins when a top level attribute is specified" do ohai.all_plugins("languages") expect(ohai.data[:languages][:english][:version]).to eq(2014) expect(ohai.data[:languages][:french][:version]).to eq(2012) end it "runs the first parent when a non-existent child is specified" do ohai.all_plugins("languages/english/version") expect(ohai.data[:languages][:english][:version]).to eq(2014) expect(ohai.data[:languages][:french]).to be_nil end it "is able to run multiple plugins" do ohai.all_plugins(["languages/english", "languages/french"]) expect(ohai.data[:languages][:english][:version]).to eq(2014) expect(ohai.data[:languages][:french][:version]).to eq(2012) end end end describe "when loading a specific plugin path" do when_plugins_directory "contains v7 plugins" do with_plugin("my_cookbook/canteloupe.rb", <<-E) Ohai.plugin(:Canteloupe) do provides 'canteloupe' collect_data do canteloupe Mash.new end end E with_plugin("english/english.rb", <<-E) Ohai.plugin(:English) do provides 'canteloupe/english' depends 'canteloupe' collect_data do canteloupe[:english] = Mash.new canteloupe[:english][:version] = 2014 end end E with_plugin("french/french.rb", <<-E) Ohai.plugin(:French) do provides 'canteloupe/french' depends 'canteloupe' collect_data do canteloupe[:french] = Mash.new canteloupe[:french][:version] = 2012 end end E it "runs all the plugins" do ohai.run_additional_plugins(@plugins_directory) expect(ohai.data[:canteloupe][:english][:version]).to eq(2014) expect(ohai.data[:canteloupe][:french][:version]).to eq(2012) end end end end ohai-16.0.7/spec/unit/util/000077500000000000000000000000001362624620500154215ustar00rootroot00000000000000ohai-16.0.7/spec/unit/util/file_helper_spec.rb000066400000000000000000000030431362624620500212360ustar00rootroot00000000000000# Author:: Bryan McLellan # # Copyright:: Copyright (c) 2014-2016 Chef Software, Inc. # # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "spec_helper" require "ohai/util/file_helper" class FileHelperMock include Ohai::Util::FileHelper end describe "Ohai::Util::FileHelper" do let(:file_helper) { FileHelperMock.new } before do allow(file_helper).to receive(:name).and_return("Fakeclass") logger = instance_double("Mixlib::Log::Child", trace: nil, debug: nil, warn: nil) allow(file_helper).to receive(:logger).and_return(logger) allow(File).to receive(:executable?).and_return(false) end describe "which" do it "returns the path to an executable that is in the path" do allow(File).to receive(:executable?).with("/usr/bin/skyhawk").and_return(true) expect(file_helper.which("skyhawk")).to eql "/usr/bin/skyhawk" end it "returns false if the executable is not in the path" do expect(file_helper.which("the_cake")).to be false end end end ohai-16.0.7/spec/unit/util/ip_helper_spec.rb000066400000000000000000000071241362624620500207330ustar00rootroot00000000000000# # Author:: Stafford Brunk () # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "ipaddress" require "spec_helper" require "ohai/util/ip_helper" class IpHelperMock include Ohai::Util::IpHelper end describe "Ohai::Util::IpHelper" do let(:ip_helper) { IpHelperMock.new } shared_examples "ip address types" do context "with an IPv4 address" do context "that is private" do let(:address) { "10.128.142.89" } it "identifies the address as private" do expect(ip_helper.private_address?(address)).to be_truthy end end context "that is public" do let(:address) { "74.125.224.72" } it "identifies the address as public" do expect(ip_helper.private_address?(address)).to be_falsey end end end context "with an IPv6 address" do context "that is an RFC 4193 unique local address" do let(:address) { "fdf8:f53b:82e4::53" } it "identifies the address as a unique local address" do expect(ip_helper.private_address?(address)).to be_truthy end end context "that is a RFC 4291 Link-Local unicast address" do let(:address) { "FE80::0202:B3FF:FE1E:8329" } it "does identify the address as a link-local address" do expect(ip_helper.private_address?(address)).to be_truthy end end end end describe "private_address?" do include_examples "ip address types" end describe "unique_local_address?" do include_examples "ip address types" end describe "public_address?" do let(:address) { "10.128.142.89" } before do allow(ip_helper).to receive(:private_address?) end it "calls #private_address?" do expect(ip_helper).to receive(:private_address?) ip_helper.public_address?(address) end it "returns the inverse of #private_address?" do expect(ip_helper.public_address?(address)).to equal !ip_helper.private_address?(address) end end describe "loopback?" do context "with an IPv4 address" do context "that is a loopback address" do let(:address) { "127.0.0.1" } it "identifies the address as a loopback address" do expect(ip_helper.loopback?(address)).to be_truthy end end context "that is not a loopback address" do let(:address) { "1.2.3.4" } it "does not identify the address as a loopback address" do expect(ip_helper.loopback?(address)).to be_falsey end end end context "with an IPv6 address" do context "that is a loopback address" do let(:address) { "0:0:0:0:0:0:0:1" } it "identifies the address as a loopback address" do expect(ip_helper.loopback?(address)).to be_truthy end end context "that is not a loopback address" do let(:address) { "2400:6180:0000:00D0:0000:0000:0009:7001" } it "does not identify the address as a loopback address" do expect(ip_helper.loopback?(address)).to be_falsey end end end end end