facter 3.11.4.cfacter.20180821 → 3.11.5.cfacter.20181022

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/ext/facter/facter/CMakeLists.txt +1 -1
  3. data/ext/facter/facter/Gemfile +13 -0
  4. data/ext/facter/facter/Rakefile +9 -0
  5. data/ext/facter/facter/acceptance/lib/facter/acceptance/base_fact_utils.rb +3 -1
  6. data/ext/facter/facter/acceptance/tests/facts/dmi.rb +1 -1
  7. data/ext/facter/facter/appveyor.yml +14 -17
  8. data/ext/facter/facter/exe/facter.cc +2 -1
  9. data/ext/facter/facter/lib/Doxyfile +1 -1
  10. data/ext/facter/facter/lib/inc/facter/ruby/ruby.hpp +11 -0
  11. data/ext/facter/facter/lib/inc/internal/facts/linux/os_osrelease.hpp +98 -0
  12. data/ext/facter/facter/lib/src/facts/collection.cc +2 -0
  13. data/ext/facter/facter/lib/src/facts/linux/operating_system_resolver.cc +5 -8
  14. data/ext/facter/facter/lib/src/facts/windows/dmi_resolver.cc +3 -2
  15. data/ext/facter/facter/lib/src/facts/windows/kernel_resolver.cc +21 -41
  16. data/ext/facter/facter/lib/src/facts/windows/operating_system_resolver.cc +23 -1
  17. data/ext/facter/facter/lib/src/ruby/ruby.cc +35 -3
  18. data/ext/facter/facter/lib/tests/CMakeLists.txt +9 -25
  19. data/ext/facter/facter/lib/tests/facts/collection.cc +1 -1
  20. data/ext/facter/facter/locales/FACTER.pot +23 -7
  21. data/ext/facter/leatherman/CMakeLists.txt +1 -1
  22. data/ext/facter/leatherman/ruby/inc/leatherman/ruby/api.hpp +4 -0
  23. data/ext/facter/leatherman/ruby/src/api.cc +1 -0
  24. data/ext/facter/leatherman/windows/inc/leatherman/windows/wmi.hpp +5 -0
  25. metadata +4 -4
  26. data/ext/facter/facter/lib/inc/internal/facts/linux/os_coreos.hpp +0 -56
  27. data/ext/facter/facter/lib/inc/internal/facts/linux/os_cumulus.hpp +0 -56
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bcbeadda3a08eb363825fbaa0dbc28aa0ea7d722
4
- data.tar.gz: 0ceba75967ddc26ded11b2349024518dfe99ab55
3
+ metadata.gz: a4a4e2fb925fbcdc4a6df9f5059c352c21537d00
4
+ data.tar.gz: e2fa7aed4bc3b820555b69ec88c4fc1732b72932
5
5
  SHA512:
6
- metadata.gz: be5fb3cf4c2f375c26cc4a0442a03aaa51459295c8851d8155328bcb5a287ec2fb2323a6267d175b4ec087619510932f53a65eb916c5178ea006ac0e1445b73a
7
- data.tar.gz: f43786a9d453221a5bca2808ceb375aacca08044a0bcc487602cdc0f9c8b52b5d35f670d1161ea1d66f7afed5ffbc6873855ee629a18d39f5d95683983d7641d
6
+ metadata.gz: ab739721a51ceeed3d9e91be204b99cc028b7f1cb412714b216fc082d3cd5ec7b6110776586e45fd6a30bbe9cdd897cff3f448282896743ac712739d9d917b7a
7
+ data.tar.gz: 4c1ff6d9e83af0f0b7a0f346f2a3e95f5adb5885f8f56f7d137d16fe7e00398b23b8ddac455e942586d71f20ce339cce9413e8ed16be44e8b906a264671ebe31
@@ -1,5 +1,5 @@
1
1
  cmake_minimum_required(VERSION 3.2.2)
2
- project(FACTER VERSION 3.11.4)
2
+ project(FACTER VERSION 3.11.5)
3
3
 
4
4
  # Set this early, so it's available. AIX gets weird, man.
5
5
  if("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
@@ -0,0 +1,13 @@
1
+ source ENV['GEM_SOURCE'] || 'https://artifactory.delivery.puppetlabs.net/artifactory/api/gems/rubygems/'
2
+
3
+ def location_for(place, fake_version = nil)
4
+ if place =~ /^(git[:@][^#]*)#(.*)/
5
+ [fake_version, { :git => $1, :branch => $2, :require => false }].compact
6
+ elsif place =~ /^file:\/\/(.*)/
7
+ ['>= 0', { :path => File.expand_path($1), :require => false }]
8
+ else
9
+ [place, { :require => false }]
10
+ end
11
+ end
12
+
13
+ gem 'packaging', *location_for(ENV['PACKAGING_LOCATION'] || '~> 0.99')
@@ -6,3 +6,12 @@ Dir['tasks/**/*.rake'].each { |t| load t }
6
6
 
7
7
  require 'packaging'
8
8
  Pkg::Util::RakeUtils.load_packaging_tasks
9
+
10
+ namespace :package do
11
+ task :bootstrap do
12
+ puts 'Bootstrap is no longer needed, using packaging-as-a-gem'
13
+ end
14
+ task :implode do
15
+ puts 'Implode is no longer needed, using packaging-as-a-gem'
16
+ end
17
+ end
@@ -523,11 +523,13 @@ module Facter
523
523
  elsif agent['platform'] =~ /2008/
524
524
  os_version = '2008 R2'
525
525
  elsif agent['platform'] =~ /2012/
526
- os_version = '2012 R2'
526
+ os_version = agent['platform'] =~ /R2/ ? '2012 R2' : '2012'
527
527
  elsif agent['platform'] =~ /-10/
528
528
  os_version = '10'
529
529
  elsif agent['platform'] =~ /2016/
530
530
  os_version = '2016'
531
+ elsif agent['platform'] =~ /2019/
532
+ os_version = '2019'
531
533
  else
532
534
  fail_test "Unknown Windows version #{agent['platform']}"
533
535
  end
@@ -15,13 +15,13 @@ test_name "C96148: verify dmi facts" do
15
15
  expected_facts = {
16
16
  'dmi.manufacturer' => /\w+/,
17
17
  'dmi.product.name' => /\w+/,
18
+ 'dmi.product.uuid' => /[-0-9A-Fa-f]+/,
18
19
  }
19
20
  unless agent['platform'] =~ /windows/
20
21
  expected_facts.merge!({'dmi.bios.release_date' => /\d+\/\d+\/\d+/,
21
22
  'dmi.bios.vendor' => /\w+/,
22
23
  'dmi.bios.version' => /\d+/,
23
24
  'dmi.chassis.type' => /\w+/,
24
- 'dmi.product.uuid' => /[-0-9A-Fa-f]+/,
25
25
  })
26
26
  end
27
27
  unless agent['platform'] =~ /windows|cisco|aarch64|el-/
@@ -1,27 +1,21 @@
1
1
  version: 3.1.0.{build}
2
2
  clone_depth: 10
3
3
  environment:
4
- LEATHERMAN_VERSION: 0.99.0
5
- CPPHOCON_VERSION: 0.1.4
4
+ LEATHERMAN_VERSION: 1.4.4
5
+ CPPHOCON_VERSION: 0.1.8
6
6
 
7
7
  init:
8
8
  - |
9
- choco install mingw-w64 -y -Version 4.8.3 -source https://www.myget.org/F/puppetlabs
9
+ choco install -y mingw-w64 -Version 5.2.0 -source https://www.myget.org/F/puppetlabs
10
+ choco install -y cmake -Version 3.2.2 -source https://www.myget.org/F/puppetlabs
10
11
  choco install -y gettext -Version 0.19.6 -source https://www.myget.org/F/puppetlabs
12
+ choco install -y pl-toolchain-x64 -Version 2015.12.01.1 -source https://www.myget.org/F/puppetlabs
13
+ choco install -y pl-boost-x64 -Version 1.58.0.2 -source https://www.myget.org/F/puppetlabs
14
+ choco install -y pl-openssl-x64 -Version 1.0.24.1 -source https://www.myget.org/F/puppetlabs
15
+ choco install -y pl-curl-x64 -Version 7.46.0.1 -source https://www.myget.org/F/puppetlabs
16
+ choco install -y pl-yaml-cpp-x64 -Version 0.5.1.2 -source https://www.myget.org/F/puppetlabs
11
17
  cmake --version
12
18
  - ps: |
13
- $env:PATH = $env:PATH.Replace("Git\bin", "Git\cmd")
14
- $env:PATH = $env:PATH.Replace("Git\usr\bin", "Git\cmd")
15
-
16
- wget 'https://s3.amazonaws.com/kylo-pl-bucket/boost_1_57_0-x86_64_mingw-w64_4.8.3_win32_seh.7z' -OutFile "$env:temp\boost.7z"
17
- 7z.exe x $env:temp\boost.7z -oC:\tools | FIND /V "ing "
18
-
19
- wget 'https://s3.amazonaws.com/kylo-pl-bucket/yaml-cpp-0.5.1-x86_64_mingw-w64_4.8.3_win32_seh.7z' -OutFile "$env:temp\yaml-cpp.7z"
20
- 7z.exe x $env:temp\yaml-cpp.7z -oC:\tools | FIND /V "ing "
21
-
22
- wget 'https://s3.amazonaws.com/kylo-pl-bucket/curl-7.42.1-x86_64_mingw-w64_4.8.3_win32_seh.7z' -OutFile "$env:temp\curl-7.42.1-x86_64_mingw-w64_4.8.3_win32_seh.7z"
23
- 7z.exe x "$env:temp\curl-7.42.1-x86_64_mingw-w64_4.8.3_win32_seh.7z" -oC:\tools | FIND /V "ing "
24
-
25
19
  wget "https://github.com/puppetlabs/leatherman/releases/download/$env:LEATHERMAN_VERSION/leatherman.7z" -OutFile "$env:temp\leatherman.7z"
26
20
  7z.exe x $env:temp\leatherman.7z -oC:\tools | FIND /V "ing "
27
21
 
@@ -29,12 +23,15 @@ init:
29
23
  7z.exe x $env:temp\cpp-hocon.7z -oC:\tools | FIND /V "ing "
30
24
 
31
25
  install:
32
- - SET PATH=C:\Ruby21-x64\bin;C:\tools\mingw64\bin;C:\Program Files\gettext-iconv;%PATH%
26
+ # Minimize environment polution; previously we were linking against the wrong OpenSSL DLLs.
27
+ # Include Ruby and Powershell for unit tests.
28
+ - SET PATH=C:\tools\pl-build-tools\bin;C:\tools\mingw64\bin;C:\ProgramData\chocolatey\bin;C:\Ruby22-x64\bin;C:\Program Files\7-Zip;C:\Windows\system32;C:\Windows;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\gettext-iconv
29
+ - ps: rm -r C:\OpenSSL-Win64
33
30
  - bundle install --jobs 4 --retry 2 --gemfile=lib/Gemfile --quiet
34
31
 
35
32
  build_script:
36
33
  - ps: |
37
- cmake -G "MinGW Makefiles" -DBOOST_ROOT="C:\tools\boost_1_57_0-x86_64_mingw-w64_4.8.3_win32_seh" -DYAMLCPP_ROOT="C:\tools\yaml-cpp-0.5.1-x86_64_mingw-w64_4.8.3_win32_seh" -DBOOST_STATIC=ON -DCURL_STATIC=ON -DCMAKE_INSTALL_PREFIX="C:\Program Files\FACTER" -DCMAKE_PREFIX_PATH="C:\tools\leatherman;C:\tools\curl-7.42.1-x86_64_mingw-w64_4.8.3_win32_seh;C:\tools\cpp-hocon" .
34
+ cmake -G "MinGW Makefiles" -DCMAKE_TOOLCHAIN_FILE="C:\tools\pl-build-tools\pl-build-toolchain.cmake" -DCMAKE_PREFIX_PATH="C:\tools\leatherman;C:\tools\cpp-hocon" -DCMAKE_INSTALL_PREFIX="C:\Program Files\FACTER" -DBOOST_STATIC=ON .
38
35
  mingw32-make -j2
39
36
 
40
37
  test_script:
@@ -332,7 +332,8 @@ int main(int argc, char **argv)
332
332
  if (vm.count("custom-dir")) {
333
333
  custom_directories = vm["custom-dir"].as<vector<string>>();
334
334
  }
335
- facter::ruby::load_custom_facts(facts, vm.count("puppet"), custom_directories);
335
+ bool redirect_ruby_stdout = vm.count("json") || vm.count("yaml");
336
+ facter::ruby::load_custom_facts(facts, vm.count("puppet"), redirect_ruby_stdout, custom_directories);
336
337
  }
337
338
 
338
339
  if (!vm["no-external-facts"].as<bool>()) {
@@ -38,7 +38,7 @@ PROJECT_NAME = facter
38
38
  # could be handy for archiving the generated documentation or if some version
39
39
  # control system is used.
40
40
 
41
- PROJECT_NUMBER = 3.11.4
41
+ PROJECT_NUMBER = 3.11.5
42
42
 
43
43
  # Using the PROJECT_BRIEF tag one can provide an optional one line description
44
44
  # for a project that appears at the top of each page and should give viewer a
@@ -21,6 +21,17 @@ namespace facter { namespace ruby {
21
21
  */
22
22
  LIBFACTER_EXPORT bool initialize(bool include_stack_trace = false);
23
23
 
24
+ /**
25
+ * Loads custom facts into the given collection.
26
+ * Important: this function should be called from main().
27
+ * Calling this function from an arbitrary stack depth may result in segfaults during Ruby GC.
28
+ * @param facts The collection to populate with custom facts.
29
+ * @param initialize_puppet Whether puppet should be loaded to find additional facts.
30
+ * @param redirect_stdout Whether Ruby's stdout should be redirected to stderr
31
+ * @param paths The paths to search for custom facts.
32
+ */
33
+ LIBFACTER_EXPORT void load_custom_facts(facter::facts::collection& facts, bool initialize_puppet, bool redirect_stdout, std::vector<std::string> const& paths = {});
34
+
24
35
  /**
25
36
  * Loads custom facts into the given collection.
26
37
  * Important: this function should be called from main().
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @file
3
+ * Declares the Linux operating system query helper based on /etc/os-release.
4
+ */
5
+ #pragma once
6
+
7
+ #include <internal/facts/linux/os_linux.hpp>
8
+ #include <facter/facts/os.hpp>
9
+ #include <facter/facts/os_family.hpp>
10
+ #include <boost/regex.hpp>
11
+ #include <iostream>
12
+ using namespace std;
13
+
14
+ namespace facter { namespace facts { namespace linux {
15
+
16
+ /**
17
+ * Responsible for determining the name/family/release of Freedesktop-compliant operating systems.
18
+ */
19
+ struct os_osrelease : os_linux
20
+ {
21
+ /**
22
+ * Constructs os_release based on details from /etc/os-release.
23
+ */
24
+ os_osrelease() : os_linux({"ID", "VERSION_ID"}) {}
25
+
26
+ /**
27
+ * Returns the release name based on the ID field from /etc/os-release
28
+ * (which has fewer variations to check for than the NAME field)
29
+ * @param distro_id Unused.
30
+ * @return Returns the OS name.
31
+ */
32
+ virtual std::string get_name(std::string const& distro_id) const override
33
+ {
34
+ auto val = _release_info.find("ID");
35
+ if (val != _release_info.end()) {
36
+ auto& id = val->second;
37
+
38
+ if (id == "coreos") {
39
+ return os::coreos;
40
+ } else if (id == "cumulus-linux") {
41
+ return os::cumulus;
42
+ } else if (id == "opensuse" || id == "opensuse-leap") {
43
+ return os::open_suse;
44
+ } else if (id == "sled") {
45
+ return os::suse_enterprise_desktop;
46
+ } else if (id == "sles") {
47
+ return os::suse_enterprise_server;
48
+ }
49
+ }
50
+ return std::string();
51
+ }
52
+
53
+ /**
54
+ * Returns the release family based on the ID field from /etc/os-release
55
+ * (which has fewer variations to check for than the NAME field)
56
+ * @param name Unused.
57
+ * @return Returns the OS family.
58
+ */
59
+ virtual std::string get_family(std::string const& name) const override
60
+ {
61
+ auto val = _release_info.find("ID");
62
+ if (val != _release_info.end()) {
63
+ auto& id = val->second;
64
+
65
+ if (id == "coreos") {
66
+ return os_family::coreos;
67
+ } else if (id == "cumulus-linux") {
68
+ return os_family::debian;
69
+ } else if (id == "opensuse" || id == "opensuse-leap" || id == "sled" || id == "sles") {
70
+ return os_family::suse;
71
+ }
72
+ }
73
+ return std::string();
74
+ }
75
+
76
+ /**
77
+ * Returns the OS release version based on the VERSION_ID field from /etc/os-release.
78
+ * @param name Unused.
79
+ * @param distro_release Unused.
80
+ * @return Returns the release version.
81
+ */
82
+ virtual std::string get_release(std::string const& name, std::string const& distro_release) const override
83
+ {
84
+ auto val = _release_info.find("VERSION_ID");
85
+ if (val != _release_info.end()) {
86
+ if (boost::regex_match(val->second, boost::regex("^\\d+$"))) {
87
+ // FACT-1880: when VERSION_ID doesn't specify a point-release,
88
+ // return the major version with ".0" appended so that
89
+ // os.release.minor always returns a value.
90
+ return val->second + ".0";
91
+ }
92
+ return val->second;
93
+ }
94
+ return std::string();
95
+ }
96
+ };
97
+
98
+ }}} // namespace facter::facts::linux
@@ -309,6 +309,8 @@ namespace facter { namespace facts {
309
309
  {
310
310
  resolve_facts();
311
311
 
312
+ // We intentionally are using find_if with no return value as a "map until" construct.
313
+ // cppcheck-suppress ignoredReturnValue
312
314
  find_if(begin(_facts), end(_facts), [&func](map<string, unique_ptr<value>>::value_type const& it) {
313
315
  return !func(it.first, it.second.get());
314
316
  });
@@ -2,8 +2,7 @@
2
2
  #include <internal/facts/linux/release_file.hpp>
3
3
  #include <internal/facts/linux/os_linux.hpp>
4
4
  #include <internal/facts/linux/os_cisco.hpp>
5
- #include <internal/facts/linux/os_coreos.hpp>
6
- #include <internal/facts/linux/os_cumulus.hpp>
5
+ #include <internal/facts/linux/os_osrelease.hpp>
7
6
  #include <facter/facts/os.hpp>
8
7
  #include <facter/facts/scalar_value.hpp>
9
8
  #include <facter/facts/map_value.hpp>
@@ -29,13 +28,11 @@ namespace facter { namespace facts { namespace linux {
29
28
 
30
29
  static unique_ptr<os_linux> get_os()
31
30
  {
32
- auto release_info = os_linux::key_value_file(release_file::os, {"NAME", "CISCO_RELEASE_INFO", "ID"});
33
- auto const& name = release_info["NAME"];
31
+ auto release_info = os_linux::key_value_file(release_file::os, {"ID", "CISCO_RELEASE_INFO"});
34
32
  auto const& id = release_info["ID"];
35
- if (name == "Cumulus Linux") {
36
- return unique_ptr<os_linux>(new os_cumulus());
37
- } else if (name == "CoreOS" || id == "coreos") {
38
- return unique_ptr<os_linux>(new os_coreos());
33
+ if (id == "coreos" || id == "cumulus-linux" || id == "opensuse" ||
34
+ id == "opensuse-leap" || id== "sled" || id == "sles") {
35
+ return unique_ptr<os_linux>(new os_osrelease());
39
36
  } else {
40
37
  auto const& cisco = release_info["CISCO_RELEASE_INFO"];
41
38
  boost::system::error_code ec;
@@ -17,11 +17,12 @@ namespace facter { namespace facts { namespace windows {
17
17
  {
18
18
  data result;
19
19
 
20
- auto vals = _wmi->query(wmi::computersystemproduct, {wmi::name});
20
+ auto vals = _wmi->query(wmi::computersystemproduct, {wmi::name, wmi::uuid});
21
21
  if (vals.empty()) {
22
- LOG_DEBUG("WMI query returned no results for {1} with value {2}.", wmi::computersystemproduct, wmi::name);
22
+ LOG_DEBUG("WMI query returned no results for {1} with values {2} and {3}.", wmi::computersystemproduct, wmi::name, wmi::uuid);
23
23
  } else {
24
24
  result.product_name = wmi::get(vals, wmi::name);
25
+ result.uuid = wmi::get(vals, wmi::uuid);
25
26
  }
26
27
 
27
28
  vals = _wmi->query(wmi::bios, {wmi::manufacturer, wmi::serialnumber});
@@ -1,60 +1,42 @@
1
+ #include <leatherman/dynamic_library/dynamic_library.hpp>
1
2
  #include <internal/facts/windows/kernel_resolver.hpp>
2
- #include <leatherman/windows/system_error.hpp>
3
- #include <leatherman/windows/windows.hpp>
4
3
  #include <facter/facts/os.hpp>
5
4
  #include <leatherman/logging/logging.hpp>
5
+
6
6
  #include <boost/optional.hpp>
7
- #include <boost/algorithm/string/trim.hpp>
8
7
  #include <boost/format.hpp>
9
- #include <boost/nowide/convert.hpp>
8
+ #include <windows.h>
9
+ #include <ntstatus.h>
10
10
 
11
11
  using namespace std;
12
- using namespace leatherman::windows;
12
+ using namespace leatherman::dynamic_library;
13
+ using RtlGetVersionPtr = NTSTATUS (WINAPI *)(PRTL_OSVERSIONINFOW);
13
14
 
14
15
  namespace facter { namespace facts { namespace windows {
15
16
 
16
17
  static boost::optional<string> get_release()
17
18
  {
18
- // GetVersionEx requires the manifest is correct, and is essentially deprecated.
19
- // Another method of getting the OS version can be found at
20
- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms724429(v=vs.85).aspx
21
- // and is what we use here.
22
- auto fileName = L"Kernel32.dll";
23
- auto fileVerSize = GetFileVersionInfoSizeW(fileName, nullptr);
24
- if (fileVerSize == 0) {
25
- return boost::none;
19
+ dynamic_library ntoskrnl;
20
+ if (! ntoskrnl.load("ntoskrnl.exe")) {
21
+ return boost::none;
26
22
  }
27
23
 
28
- vector<wchar_t> buffer(fileVerSize);
29
- if (!GetFileVersionInfoW(fileName, 0, fileVerSize, buffer.data())) {
30
- return boost::none;
24
+ auto rtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(
25
+ ntoskrnl.find_symbol("RtlGetVersion"));
26
+ if (! rtlGetVersion) {
27
+ return boost::none;
31
28
  }
32
29
 
33
- struct LANGANDCODEPAGE {
34
- WORD wLanguage, wCodePage;
35
- } *lpTranslate;
36
- UINT cbTranslate;
37
-
38
- if (!VerQueryValueW(buffer.data(), L"\\VarFileinfo\\Translation",
39
- reinterpret_cast<LPVOID*>(&lpTranslate), &cbTranslate)) {
40
- return boost::none;
41
- }
42
-
43
- // Use the 1st language found, as ProductVersion should be language-independent.
44
- wstring subBlock = str(boost::wformat(L"\\StringFileInfo\\%04x%04x\\ProductVersion")
45
- % lpTranslate->wLanguage % lpTranslate->wCodePage);
46
-
47
- wchar_t *version;
48
- UINT versionLen;
49
- if (!VerQueryValueW(buffer.data(), subBlock.c_str(), reinterpret_cast<LPVOID*>(&version), &versionLen)) {
50
- return boost::none;
30
+ OSVERSIONINFOW versionInfo;
31
+ if (rtlGetVersion(&versionInfo) != STATUS_SUCCESS) {
32
+ LOG_DEBUG("failed to get the OS version information from RtlGetVersion");
33
+ return boost::none;
51
34
  }
52
35
 
53
- // Strip the last (file version) token to get just the OS version.
54
- wstring versionStrW(version, versionLen);
55
- auto versionStr = boost::nowide::narrow(versionStrW);
56
- boost::trim_right_if(versionStr, [](char c) { return c != '.'; }); // Remove everything after '.'
57
- boost::trim_right_if(versionStr, [](char c) { return c == '.'; }); // Remove '.'
36
+ auto versionStr = (boost::format("%1%.%2%.%3%")
37
+ % versionInfo.dwMajorVersion
38
+ % versionInfo.dwMinorVersion
39
+ % versionInfo.dwBuildNumber).str();
58
40
 
59
41
  return versionStr;
60
42
  }
@@ -67,8 +49,6 @@ namespace facter { namespace facts { namespace windows {
67
49
  if (release) {
68
50
  result.release = move(*release);
69
51
  result.version = result.release;
70
- } else {
71
- LOG_DEBUG("failed to retrieve kernel facts: {1}", leatherman::windows::system_error());
72
52
  }
73
53
 
74
54
  result.name = os::windows;
@@ -2,7 +2,9 @@
2
2
  #include <leatherman/windows/system_error.hpp>
3
3
  #include <leatherman/windows/wmi.hpp>
4
4
  #include <leatherman/windows/windows.hpp>
5
+ #include <facter/facts/fact.hpp>
5
6
  #include <facter/facts/collection.hpp>
7
+ #include <facter/facts/scalar_value.hpp>
6
8
  #include <facter/facts/os_family.hpp>
7
9
  #include <leatherman/logging/logging.hpp>
8
10
  #include <leatherman/util/regex.hpp>
@@ -10,6 +12,7 @@
10
12
  #include <winnt.h>
11
13
  #include <Shlobj.h>
12
14
  #include <map>
15
+ #include <string>
13
16
  #include <boost/filesystem.hpp>
14
17
 
15
18
  using namespace std;
@@ -101,7 +104,26 @@ namespace facter { namespace facts { namespace windows {
101
104
  auto version = result.release.substr(0, lastDot);
102
105
  bool consumerrel = (wmi::get(vals, wmi::producttype) == "1");
103
106
  if (version == "10.0") {
104
- result.release = consumerrel ? "10" : "2016";
107
+ // Calculate the build number to distinguish between
108
+ // Windows Server 2016 and 2019. Note that the kernel
109
+ // version is written as <major>.<minor>.<build_number>
110
+ auto kernel_version_fact = facts.get<string_value>(fact::kernel_version);
111
+ if (! kernel_version_fact) {
112
+ LOG_DEBUG("Could not resolve the OS release and OS major version facts from the kernel version fact");
113
+ return result;
114
+ }
115
+ auto kernel_version = kernel_version_fact->value();
116
+ auto build_number_as_str = kernel_version.substr(
117
+ kernel_version.find_last_of('.') + 1);
118
+ auto build_number = stol(build_number_as_str);
119
+
120
+ if (consumerrel) {
121
+ result.release = "10";
122
+ } else if (build_number >= 17623L) {
123
+ result.release = "2019";
124
+ } else {
125
+ result.release = "2016";
126
+ }
105
127
  } else if (version == "6.3") {
106
128
  result.release = consumerrel ? "8.1" : "2012 R2";
107
129
  } else if (version == "6.2") {
@@ -30,6 +30,27 @@ static const char load_puppet[] =
30
30
  " end\n"
31
31
  "end\n";
32
32
 
33
+ // This struct redirects stdout to stderr in the ruby runtime for the
34
+ // duration of its lifetime. We use this to ensure that any custom
35
+ // facts writing to stdout during their initialization or execution
36
+ // won't corrupt json/yaml output from the facter executable.
37
+ struct RbStdoutGuard {
38
+ VALUE old_stdout;
39
+ api& ruby;
40
+
41
+ RbStdoutGuard(api& ruby) :ruby(ruby) {
42
+ LOG_DEBUG("Redirecting ruby's stdout to stderr");
43
+ auto rb_stderr = ruby.rb_gv_get("$stderr");
44
+ old_stdout = ruby.rb_gv_get("$stdout");
45
+ ruby.rb_gv_set("$stdout", rb_stderr);
46
+ }
47
+
48
+ ~RbStdoutGuard() {
49
+ LOG_DEBUG("Restoring Ruby's stdout");
50
+ ruby.rb_gv_set("$stdout", old_stdout);
51
+ }
52
+ };
53
+
33
54
  namespace facter { namespace ruby {
34
55
 
35
56
  bool initialize(bool include_stack_trace)
@@ -48,7 +69,7 @@ namespace facter { namespace ruby {
48
69
  return true;
49
70
  }
50
71
 
51
- void load_custom_facts(collection& facts, bool initialize_puppet, vector<string> const& paths)
72
+ void load_custom_facts(collection& facts, bool initialize_puppet, bool redirect_stdout, vector<string> const& paths)
52
73
  {
53
74
  #ifdef _WIN32
54
75
  // Initialize WSA before resolving custom facts. The Ruby runtime does this only when running
@@ -67,12 +88,23 @@ namespace facter { namespace ruby {
67
88
  }
68
89
  }
69
90
  mod.search(paths);
70
- mod.resolve_facts();
91
+ if (redirect_stdout) {
92
+ // Redirect stdout->stderr for custom facts.
93
+ RbStdoutGuard stdout_guard{ruby};
94
+ mod.resolve_facts();
95
+ } else {
96
+ mod.resolve_facts();
97
+ }
71
98
  }
72
99
 
73
100
  void load_custom_facts(collection& facts, vector<string> const& paths)
74
101
  {
75
- load_custom_facts(facts, false, paths);
102
+ load_custom_facts(facts, false, false, paths);
103
+ }
104
+
105
+ void load_custom_facts(collection& facts, bool initialize_puppet, vector<string> const& paths)
106
+ {
107
+ load_custom_facts(facts, initialize_puppet, false, paths);
76
108
  }
77
109
 
78
110
  value const* lookup(value const* value, vector<string>::iterator segment, vector<string>::iterator end) {
@@ -40,6 +40,7 @@ set(LIBFACTER_TESTS_COMMON_SOURCES
40
40
  "logging/logging.cc"
41
41
  "log_capture.cc"
42
42
  "main.cc"
43
+ "mock_server.cc"
43
44
  "util/string.cc"
44
45
  "fixtures.cc"
45
46
  "collection_fixture.cc"
@@ -127,37 +128,20 @@ include_directories(
127
128
  ${CPPHOCON_INCLUDE_DIRS}
128
129
  )
129
130
 
130
- # On EL 4, we run into a linking error when trying to create libraries or
131
- # executables that link in a static library with code using threads. As I
132
- # described in https://gcc.gnu.org/ml/gcc-help/2015-08/msg00035.html, we get
133
- # the error undefined reference to symbol '__tls_get_addr@@GLIBC_2.3'.
134
- # Build mock_server as a separate shared library to avoid this error.
135
131
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
136
- add_library(mock-server SHARED mock_server.cc)
137
- target_link_libraries(mock-server PRIVATE
138
- ${Boost_THREAD_LIBRARY}
139
- ${Boost_SYSTEM_LIBRARY}
140
- ${LIBFACTER_TESTS_PLATFORM_LIBRARIES})
132
+ if (WIN32)
133
+ # On Windows with GCC 5.2, Boost.System emits warnings that aren't correctly
134
+ # suppressed by pragmas. Explicitly skip them.
135
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-variable")
136
+ endif()
141
137
 
142
138
  add_executable(libfacter_test $<TARGET_OBJECTS:libfactersrc>
143
139
  ${LIBFACTER_TESTS_COMMON_SOURCES}
144
140
  ${LIBFACTER_TESTS_PLATFORM_SOURCES}
145
141
  ${LIBFACTER_TESTS_CATEGORY_SOURCES})
146
- # On Windows, mock-server comes after Boost libraries to avoid double
147
- # definition of boost::system::system_category() on Windows. On Linux, it
148
- # comes before to avoid picking up incomplete Boost.Asio symbols included
149
- # by Boost.Log in Leatherman logging.
150
- if (WIN32)
151
- target_link_libraries(libfacter_test
152
- ${LIBS}
153
- ${LIBFACTER_TESTS_PLATFORM_LIBRARIES}
154
- mock-server)
155
- else()
156
- target_link_libraries(libfacter_test
157
- mock-server
158
- ${LIBS}
159
- ${LIBFACTER_TESTS_PLATFORM_LIBRARIES})
160
- endif()
142
+ target_link_libraries(libfacter_test
143
+ ${LIBS}
144
+ ${LIBFACTER_TESTS_PLATFORM_LIBRARIES})
161
145
 
162
146
  if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND BOOST_STATIC AND LEATHERMAN_USE_LOCALES)
163
147
  target_link_libraries(libfacter_test iconv)
@@ -67,7 +67,7 @@ struct multi_resolver : facter::facts::resolver
67
67
 
68
68
  struct temp_variable
69
69
  {
70
- temp_variable(string name, string const& value) :
70
+ temp_variable(string&& name, string const& value) :
71
71
  _name(move(name))
72
72
  {
73
73
  environment::set(_name, value);
@@ -6,7 +6,7 @@
6
6
  #, fuzzy
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: FACTER 3.11.4\n"
9
+ "Project-Id-Version: FACTER 3.11.5\n"
10
10
  "Report-Msgid-Bugs-To: docs@puppet.com\n"
11
11
  "POT-Creation-Date: \n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
@@ -1225,11 +1225,6 @@ msgstr ""
1225
1225
  msgid "failed adding platform facts that require WMI: {1}"
1226
1226
  msgstr ""
1227
1227
 
1228
- #. debug
1229
- #: lib/src/facts/windows/dmi_resolver.cc
1230
- msgid "WMI query returned no results for {1} with value {2}."
1231
- msgstr ""
1232
-
1233
1228
  #. debug
1234
1229
  #: lib/src/facts/windows/dmi_resolver.cc
1235
1230
  msgid "WMI query returned no results for {1} with values {2} and {3}."
@@ -1242,7 +1237,11 @@ msgstr ""
1242
1237
 
1243
1238
  #. debug
1244
1239
  #: lib/src/facts/windows/kernel_resolver.cc
1245
- msgid "failed to retrieve kernel facts: {1}"
1240
+ msgid "failed to get the OS version information from RtlGetVersion"
1241
+ msgstr ""
1242
+
1243
+ #: lib/src/facts/windows/kernel_resolver.cc
1244
+ msgid "%1%.%2%.%3%"
1246
1245
  msgstr ""
1247
1246
 
1248
1247
  #. debug
@@ -1290,6 +1289,13 @@ msgstr ""
1290
1289
  msgid "error finding SYSTEMROOT: {1}"
1291
1290
  msgstr ""
1292
1291
 
1292
+ #. debug
1293
+ #: lib/src/facts/windows/operating_system_resolver.cc
1294
+ msgid ""
1295
+ "Could not resolve the OS release and OS major version facts from the kernel "
1296
+ "version fact"
1297
+ msgstr ""
1298
+
1293
1299
  #. debug
1294
1300
  #: lib/src/facts/windows/processor_resolver.cc
1295
1301
  msgid "WMI processor Name, Architecture query returned no results."
@@ -1525,6 +1531,16 @@ msgstr ""
1525
1531
  msgid "timeout= is not supported for custom facts and will be ignored."
1526
1532
  msgstr ""
1527
1533
 
1534
+ #. debug
1535
+ #: lib/src/ruby/ruby.cc
1536
+ msgid "Redirecting ruby's stdout to stderr"
1537
+ msgstr ""
1538
+
1539
+ #. debug
1540
+ #: lib/src/ruby/ruby.cc
1541
+ msgid "Restoring Ruby's stdout"
1542
+ msgstr ""
1543
+
1528
1544
  #. warning
1529
1545
  #: lib/src/ruby/ruby.cc
1530
1546
  msgid "Could not load puppet; some facts may be unavailable: {1}"
@@ -1,5 +1,5 @@
1
1
  cmake_minimum_required(VERSION 3.2.2)
2
- project(leatherman VERSION 1.4.2)
2
+ project(leatherman VERSION 1.4.4)
3
3
 
4
4
  if (WIN32)
5
5
  link_libraries("-Wl,--nxcompat -Wl,--dynamicbase")
@@ -207,6 +207,10 @@ namespace leatherman { namespace ruby {
207
207
  * See MRI documentation.
208
208
  */
209
209
  VALUE (* const rb_gv_get)(char const*);
210
+ /**
211
+ * See MRI documentation.
212
+ */
213
+ VALUE (* const rb_gv_set)(char const*, VALUE);
210
214
  /**
211
215
  * See MRI documentation.
212
216
  */
@@ -51,6 +51,7 @@ namespace leatherman { namespace ruby {
51
51
  LOAD_SYMBOL(rb_define_singleton_method),
52
52
  LOAD_SYMBOL(rb_class_new_instance),
53
53
  LOAD_SYMBOL(rb_gv_get),
54
+ LOAD_SYMBOL(rb_gv_set),
54
55
  LOAD_SYMBOL(rb_eval_string),
55
56
  LOAD_SYMBOL(rb_funcall),
56
57
  LOAD_ALIASED_SYMBOL(rb_funcallv, rb_funcall2),
@@ -43,6 +43,11 @@ namespace leatherman { namespace windows {
43
43
  */
44
44
  constexpr static char const* computersystemproduct = "Win32_ComputerSystemProduct";
45
45
 
46
+ /**
47
+ * Identifier for the WMI property UUID
48
+ */
49
+ constexpr static char const* uuid = "UUID";
50
+
46
51
  /**
47
52
  * Identifier for the WMI class Win32_OperatingSystem
48
53
  */
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facter
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.4.cfacter.20180821
4
+ version: 3.11.5.cfacter.20181022
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-08-21 00:00:00.000000000 Z
12
+ date: 2018-10-22 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: info@puppet.com
@@ -181,6 +181,7 @@ files:
181
181
  - ext/facter/facter/CMakeLists.txt
182
182
  - ext/facter/facter/CONTRIBUTING.md
183
183
  - ext/facter/facter/Extensibility.md
184
+ - ext/facter/facter/Gemfile
184
185
  - ext/facter/facter/LICENSE
185
186
  - ext/facter/facter/MAINTAINERS
186
187
  - ext/facter/facter/README.md
@@ -393,9 +394,8 @@ files:
393
394
  - ext/facter/facter/lib/inc/internal/facts/linux/networking_resolver.hpp
394
395
  - ext/facter/facter/lib/inc/internal/facts/linux/operating_system_resolver.hpp
395
396
  - ext/facter/facter/lib/inc/internal/facts/linux/os_cisco.hpp
396
- - ext/facter/facter/lib/inc/internal/facts/linux/os_coreos.hpp
397
- - ext/facter/facter/lib/inc/internal/facts/linux/os_cumulus.hpp
398
397
  - ext/facter/facter/lib/inc/internal/facts/linux/os_linux.hpp
398
+ - ext/facter/facter/lib/inc/internal/facts/linux/os_osrelease.hpp
399
399
  - ext/facter/facter/lib/inc/internal/facts/linux/processor_resolver.hpp
400
400
  - ext/facter/facter/lib/inc/internal/facts/linux/release_file.hpp
401
401
  - ext/facter/facter/lib/inc/internal/facts/linux/uptime_resolver.hpp
@@ -1,56 +0,0 @@
1
- /**
2
- * @file
3
- * Declares the CoreOS Linux operating system query helper.
4
- */
5
- #pragma once
6
-
7
- #include <internal/facts/linux/os_linux.hpp>
8
- #include <facter/facts/os.hpp>
9
- #include <facter/facts/os_family.hpp>
10
-
11
- namespace facter { namespace facts { namespace linux {
12
-
13
- /**
14
- * Responsible for determining the name/family/release of CoreOS operating systems.
15
- */
16
- struct os_coreos : os_linux
17
- {
18
- /**
19
- * Constructs the os_cumulus and reads /etc/os-release to gather relevant details.
20
- */
21
- os_coreos() : os_linux({"VERSION_ID"}) {}
22
-
23
- /**
24
- * Returns the release name.
25
- * @param distro_id Unused.
26
- * @return Returns "CoreOS".
27
- */
28
- virtual std::string get_name(std::string const& distro_id) const override
29
- {
30
- return os::coreos;
31
- }
32
-
33
- /**
34
- * Returns the release family.
35
- * @param name Unused.
36
- * @return Returns "CoreOS".
37
- */
38
- virtual std::string get_family(std::string const& name) const override
39
- {
40
- return os_family::coreos;
41
- }
42
-
43
- /**
44
- * Finds VERSION_ID from the release file contents and returns it as the release.
45
- * @param name Unused.
46
- * @param distro_release Unused.
47
- * @return Returns the release version.
48
- */
49
- virtual std::string get_release(std::string const& name, std::string const& distro_release) const override
50
- {
51
- auto val = _release_info.find("VERSION_ID");
52
- return (val != _release_info.end()) ? val->second : std::string();
53
- }
54
- };
55
-
56
- }}} // namespace facter::facts::linux
@@ -1,56 +0,0 @@
1
- /**
2
- * @file
3
- * Declares the Cumulus Linux operating system query helper.
4
- */
5
- #pragma once
6
-
7
- #include <internal/facts/linux/os_linux.hpp>
8
- #include <facter/facts/os.hpp>
9
- #include <facter/facts/os_family.hpp>
10
-
11
- namespace facter { namespace facts { namespace linux {
12
-
13
- /**
14
- * Responsible for determining the name/family/release of Cumulus operating systems.
15
- */
16
- struct os_cumulus : os_linux
17
- {
18
- /**
19
- * Constructs the os_cumulus and reads /etc/os-release to gather relevant details.
20
- */
21
- os_cumulus() : os_linux({"VERSION_ID"}) {}
22
-
23
- /**
24
- * Returns the release name.
25
- * @param distro_id Unused.
26
- * @return Returns "CumulusLinux".
27
- */
28
- virtual std::string get_name(std::string const& distro_id) const override
29
- {
30
- return os::cumulus;
31
- }
32
-
33
- /**
34
- * Returns the release family.
35
- * @param name Unused.
36
- * @return Returns "Debian".
37
- */
38
- virtual std::string get_family(std::string const& name) const override
39
- {
40
- return os_family::debian;
41
- }
42
-
43
- /**
44
- * Finds VERSION_ID from the release file contents and returns it as the release.
45
- * @param name Unused.
46
- * @param distro_release Unused.
47
- * @return Returns the release version.
48
- */
49
- virtual std::string get_release(std::string const& name, std::string const& distro_release) const override
50
- {
51
- auto val = _release_info.find("VERSION_ID");
52
- return (val != _release_info.end()) ? val->second : std::string();
53
- }
54
- };
55
-
56
- }}} // namespace facter::facts::linux