facter 3.11.3.cfacter.20180716 → 3.11.4.cfacter.20180821

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59604eb95692d9fe7a11d3c65c28f32a4b807e11
4
- data.tar.gz: e11014d9bfff774641b5fe5c75f81c831671bbe1
3
+ metadata.gz: bcbeadda3a08eb363825fbaa0dbc28aa0ea7d722
4
+ data.tar.gz: 0ceba75967ddc26ded11b2349024518dfe99ab55
5
5
  SHA512:
6
- metadata.gz: dee599e4596509d648066b32ade20990dbe4d430c6a7b8364f3ee75423827e65a6194f871541301a05aed4c28b0e1f79c0590c3d1eabb0f7f12749b91389c6ff
7
- data.tar.gz: 68e4ab3e73b07dbba067e591582199a996a6fd2b58c5f887e010e0dbb4c220d31bed3d7da7eae085c1800233aa96791fb80fa34a6d2c91b9a94de1c17ce8324d
6
+ metadata.gz: be5fb3cf4c2f375c26cc4a0442a03aaa51459295c8851d8155328bcb5a287ec2fb2323a6267d175b4ec087619510932f53a65eb916c5178ea006ac0e1445b73a
7
+ data.tar.gz: f43786a9d453221a5bca2808ceb375aacca08044a0bcc487602cdc0f9c8b52b5d35f670d1161ea1d66f7afed5ffbc6873855ee629a18d39f5d95683983d7641d
@@ -1,5 +1,5 @@
1
1
  cmake_minimum_required(VERSION 3.2.2)
2
- project(FACTER VERSION 3.11.3)
2
+ project(FACTER VERSION 3.11.4)
3
3
 
4
4
  # Set this early, so it's available. AIX gets weird, man.
5
5
  if("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
@@ -4,39 +4,5 @@ $LOAD_PATH << File.join(RAKE_ROOT, 'tasks')
4
4
  require 'rake'
5
5
  Dir['tasks/**/*.rake'].each { |t| load t }
6
6
 
7
- build_defs_file = File.join(RAKE_ROOT, 'ext', 'build_defaults.yaml')
8
- if File.exist?(build_defs_file)
9
- begin
10
- require 'yaml'
11
- @build_defaults ||= YAML.load_file(build_defs_file)
12
- rescue Exception => e
13
- STDERR.puts "Unable to load yaml from #{build_defs_file}:"
14
- raise e
15
- end
16
- @packaging_url = @build_defaults['packaging_url']
17
- @packaging_repo = @build_defaults['packaging_repo']
18
- raise "Could not find packaging url in #{build_defs_file}" if @packaging_url.nil?
19
- raise "Could not find packaging repo in #{build_defs_file}" if @packaging_repo.nil?
20
-
21
- namespace :package do
22
- desc "Bootstrap packaging automation, e.g. clone into packaging repo"
23
- task :bootstrap do
24
- if File.exist?(File.join(RAKE_ROOT, "ext", @packaging_repo))
25
- puts "It looks like you already have ext/#{@packaging_repo}. If you don't like it, blow it away with package:implode."
26
- else
27
- cd File.join(RAKE_ROOT, 'ext') do
28
- %x{git clone #{@packaging_url}}
29
- end
30
- end
31
- end
32
- desc "Remove all cloned packaging automation"
33
- task :implode do
34
- rm_rf File.join(RAKE_ROOT, "ext", @packaging_repo)
35
- end
36
- end
37
- end
38
-
39
- begin
40
- load File.join(RAKE_ROOT, 'ext', 'packaging', 'packaging.rake')
41
- rescue LoadError
42
- end
7
+ require 'packaging'
8
+ Pkg::Util::RakeUtils.load_packaging_tasks
@@ -1,6 +1,4 @@
1
1
  ---
2
- packaging_url: 'git@github.com:puppetlabs/packaging --branch=master'
3
- packaging_repo: 'packaging'
4
2
  deb_build_mirrors:
5
3
  - deb http://pl-build-tools.delivery.puppetlabs.net/debian __DIST__ main
6
4
  packager: 'puppetlabs'
@@ -91,6 +91,7 @@ if (UNIX)
91
91
  "src/facts/posix/cache.cc"
92
92
  "src/util/posix/scoped_addrinfo.cc"
93
93
  "src/util/posix/scoped_descriptor.cc"
94
+ "src/util/posix/utmpx_file.cc"
94
95
  "src/util/config/posix/config.cc"
95
96
  )
96
97
  if (OPENSSL_FOUND)
@@ -120,6 +121,7 @@ if (AIX)
120
121
  "src/facts/aix/disk_resolver.cc"
121
122
  "src/facts/aix/filesystem_resolver.cc"
122
123
  "src/facts/aix/kernel_resolver.cc"
124
+ "src/facts/aix/load_average_resolver.cc"
123
125
  "src/facts/aix/memory_resolver.cc"
124
126
  "src/facts/aix/networking_resolver.cc"
125
127
  "src/facts/aix/operating_system_resolver.cc"
@@ -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.3
41
+ PROJECT_NUMBER = 3.11.4
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
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @file
3
+ * Declares the AIX load average fact resolver.
4
+ */
5
+ #pragma once
6
+
7
+ #include "../resolvers/load_average_resolver.hpp"
8
+
9
+ namespace facter { namespace facts { namespace aix {
10
+
11
+ /**
12
+ * Responsible for resolving the load average facts.
13
+ */
14
+ struct load_average_resolver : resolvers::load_average_resolver
15
+ {
16
+ protected:
17
+ /**
18
+ * Gets the load averages (for 1, 5 and 15 minutes period).
19
+ * @return The load averages.
20
+ */
21
+ virtual boost::optional<std::tuple<double, double, double>> get_load_averages() override;
22
+ };
23
+
24
+ }}} // namespace facter::facts::aix
@@ -117,7 +117,18 @@ namespace facter { namespace util { namespace aix {
117
117
  * @return true if the iterators are not equal
118
118
  */
119
119
  bool operator != (const iterator& rhs) {
120
- return _data != rhs._data && _owner != rhs._owner;
120
+ return _owner != rhs._owner || _data != rhs._data;
121
+ }
122
+
123
+ /**
124
+ * equality comparison.
125
+ * @param rhs the other iterator to compare to
126
+ * @return true if the iterators are equal
127
+ */
128
+ bool operator == (const iterator& rhs) {
129
+ // We could do !(*this != rhs) here, but it's better to inline
130
+ // the expression for performance reasons. It's simple enough.
131
+ return _owner == rhs._owner && _data == rhs._data;
121
132
  }
122
133
 
123
134
  /**
@@ -150,6 +161,14 @@ namespace facter { namespace util { namespace aix {
150
161
  return *_data;
151
162
  }
152
163
 
164
+ /**
165
+ * arrow operator
166
+ * @return a pointer to the held ODM data structure
167
+ */
168
+ const T* operator->() const{
169
+ return _data;
170
+ }
171
+
153
172
  /**
154
173
  * Destructor. Frees any held ODM data.
155
174
  */
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @file
3
+ * Declares an interface for querying the contents of the utmpx file
4
+ */
5
+ #pragma once
6
+
7
+ #include <utmpx.h>
8
+
9
+ namespace facter { namespace util { namespace posix {
10
+
11
+ /**
12
+ * Class representing a utmpx file. We create only one instance at a time since
13
+ * the utmpx API calls deal with global state. See https://linux.die.net/man/3/getutxid
14
+ * for the documentation.
15
+ */
16
+ class utmpx_file {
17
+ public:
18
+ /**
19
+ * Constructs a utmpx_file instance. We only do this if no other utmpx_file instance exists,
20
+ * which we can determine by querying the 'instance_exists' static variable. Otherwise,
21
+ * we throw an std::logic_error.
22
+ */
23
+ utmpx_file();
24
+
25
+ /// deleted copy constructor
26
+ utmpx_file(const utmpx_file&) = delete;
27
+
28
+ /// deleted assignment operator
29
+ /// @return nothing
30
+ utmpx_file& operator=(const utmpx_file&) = delete;
31
+
32
+ /**
33
+ * Destroys our utmpx_file instance. Here, we also set `instance_exists` to false so that another
34
+ * utmpx_file instance can be created.
35
+ */
36
+ ~utmpx_file();
37
+
38
+ /**
39
+ * Returns a pointer to the utmpx entry corresponding to the passed-in query. Make sure
40
+ * that the calling instance does not go out of scope after invoking this method, otherwise
41
+ * the data in the returned utmpx entry will be garbage. Note that this will move the
42
+ * underlying utmpx file pointer forward, so be sure to call reset() if you want subsequent
43
+ * calls to this routine to always start from the beginning of the utmpx file.
44
+ * @param query the utmpx query. See https://www.systutorials.com/docs/linux/man/5-utmpx/
45
+ * @return pointer to the utmpx entry satisfying the query
46
+ */
47
+ const utmpx* query(utmpx const& query) const;
48
+
49
+ /**
50
+ * Resets the utmpx file.
51
+ */
52
+ void reset() const;
53
+
54
+ private:
55
+ static bool instance_exists; // set to true if a utmpx_file instance exists, false otherwise
56
+ };
57
+ }}} // namespace facter::util::posix
@@ -2,6 +2,7 @@
2
2
  #include <internal/facts/aix/disk_resolver.hpp>
3
3
  #include <internal/facts/aix/filesystem_resolver.hpp>
4
4
  #include <internal/facts/aix/kernel_resolver.hpp>
5
+ #include <internal/facts/aix/load_average_resolver.hpp>
5
6
  #include <internal/facts/aix/memory_resolver.hpp>
6
7
  #include <internal/facts/aix/networking_resolver.hpp>
7
8
  #include <internal/facts/aix/operating_system_resolver.hpp>
@@ -19,6 +20,7 @@ namespace facter { namespace facts {
19
20
  add(make_shared<aix::disk_resolver>());
20
21
  add(make_shared<aix::filesystem_resolver>());
21
22
  add(make_shared<aix::kernel_resolver>());
23
+ add(make_shared<aix::load_average_resolver>());
22
24
  add(make_shared<aix::memory_resolver>());
23
25
  add(make_shared<aix::networking_resolver>());
24
26
  add(make_shared<aix::operating_system_resolver>());
@@ -0,0 +1,50 @@
1
+ #include <internal/facts/aix/load_average_resolver.hpp>
2
+ #include <leatherman/logging/logging.hpp>
3
+ #include <leatherman/locale/locale.hpp>
4
+
5
+ #include <sys/inttypes.h>
6
+ #include <sys/kinfo.h>
7
+
8
+ // Mark string for translation (alias for leatherman::locale::format)
9
+ using leatherman::locale::_;
10
+
11
+ using namespace std;
12
+
13
+ /**
14
+ * This system call lets us query the kernel directly for system
15
+ * information. We use it to get our current load averages.
16
+ *
17
+ * @param info the info we're retrieving from the kernel.
18
+ * @param buf the buffer that we'll store the information in
19
+ * @param buf_size a pointer to the variable containing the size of the buffer in bytes
20
+ * @param arg no idea what this param. represents. we will usually set this to 0.
21
+ * @return 0 if we successfully retrieve the information, else a negative value
22
+ */
23
+ extern "C" int getkerninfo(int info, char* buf, int* buf_size, int32long64_t arg);
24
+
25
+ // Converts the given integer average into a load average.
26
+ static double to_load_avg(double average) {
27
+ // 65536 is the load average scale on AIX machines.
28
+ return average / 65536;
29
+ }
30
+
31
+ namespace facter { namespace facts { namespace aix {
32
+
33
+ boost::optional<tuple<double, double, double> > load_average_resolver::get_load_averages()
34
+ {
35
+ // This approach was adapted from screen-4.6.2's loadav.c file. See
36
+ // https://www.mail-archive.com/opensuse-commit@opensuse.org/msg122486.html
37
+ array<long long, 3> averages;
38
+ int buf_size = averages.size() * sizeof(long long);
39
+ int rc = getkerninfo(KINFO_GET_AVENRUN, reinterpret_cast<char*>(averages.data()), &buf_size, 0);
40
+ if (rc < 0) {
41
+ LOG_DEBUG(_("failed to retrieve the load averages"));
42
+ return boost::none;
43
+ }
44
+
45
+ return make_tuple(
46
+ to_load_avg(averages[0]),
47
+ to_load_avg(averages[1]),
48
+ to_load_avg(averages[2]));
49
+ }
50
+ }}} // namespace facter::facts::aix
@@ -1,6 +1,7 @@
1
1
  #include <internal/facts/aix/memory_resolver.hpp>
2
2
  #include <internal/util/aix/odm.hpp>
3
3
 
4
+ #include <leatherman/logging/logging.hpp>
4
5
  #include <sys/vminfo.h>
5
6
  #include <sys/cfgodm.h>
6
7
  #include <sys/limits.h>
@@ -9,6 +10,15 @@
9
10
  using namespace std;
10
11
  using namespace facter::util::aix;
11
12
 
13
+ // This routine is useful to encapsulate knowledge of the PAGE_SIZE
14
+ // in one place and to also handle implicit conversions of numeric
15
+ // values to uint64_t, which is what we use to represent bytes. Otherwise,
16
+ // we risk accidentally capturing an overflowed value in our computed
17
+ // memory facts.
18
+ static uint64_t pages_to_bytes(uint64_t num_pages) {
19
+ return num_pages * PAGE_SIZE;
20
+ }
21
+
12
22
  namespace facter { namespace facts { namespace aix {
13
23
  memory_resolver::data memory_resolver::collect_data(collection& facts)
14
24
  {
@@ -19,8 +29,8 @@ namespace facter { namespace facts { namespace aix {
19
29
  if (res < 0) {
20
30
  throw system_error(errno, system_category());
21
31
  }
22
- result.mem_total = info.memsizepgs * PAGE_SIZE;
23
- result.mem_free = info.numfrb * PAGE_SIZE;
32
+ result.mem_total = pages_to_bytes(info.memsizepgs);
33
+ result.mem_free = pages_to_bytes(info.numfrb);
24
34
 
25
35
  auto cu_at_query = odm_class<CuAt>::open("CuAt").query("value=paging and attribute=type");
26
36
  for (auto& cu_at : cu_at_query) {
@@ -33,14 +43,19 @@ namespace facter { namespace facts { namespace aix {
33
43
  // swapqry the things that have an attribute we
34
44
  // expect, but ignore any errno values that look like
35
45
  // "this just wasn't a good device to query"
46
+ // ENXIO: No such device address.
36
47
  if (errno != ENODEV &&
37
48
  errno != ENOENT &&
38
- errno != ENOTBLK) {
39
- throw system_error(errno, system_category());
49
+ errno != ENOTBLK &&
50
+ errno != ENXIO) {
51
+ throw system_error(errno, system_category(), device);
52
+ } else {
53
+ LOG_DEBUG("cannot use device {1}: error is {2}", device, errno);
40
54
  }
41
55
  }
42
- result.swap_total += info.size * PAGE_SIZE;
43
- result.swap_free += info.free * PAGE_SIZE;
56
+
57
+ result.swap_total += pages_to_bytes(info.size);
58
+ result.swap_free += pages_to_bytes(info.free);
44
59
  }
45
60
 
46
61
  return result;
@@ -1,43 +1,72 @@
1
1
  #include <internal/facts/aix/operating_system_resolver.hpp>
2
+ #include <internal/util/aix/odm.hpp>
3
+ #include <facter/facts/collection.hpp>
4
+ #include <facter/facts/fact.hpp>
2
5
  #include <facter/facts/os.hpp>
3
- #include <leatherman/execution/execution.hpp>
4
- #include <leatherman/file_util/file.hpp>
6
+ #include <facter/facts/array_value.hpp>
7
+ #include <facter/facts/map_value.hpp>
8
+ #include <facter/facts/scalar_value.hpp>
5
9
  #include <leatherman/logging/logging.hpp>
6
- #include <leatherman/util/regex.hpp>
7
10
 
8
11
  #include <boost/algorithm/string.hpp>
12
+ #include <odmi.h>
13
+ #include <sys/cfgodm.h>
9
14
 
10
15
  using namespace std;
11
- using namespace leatherman::util;
12
- using namespace leatherman::file_util;
13
- using namespace boost;
14
- namespace execution = leatherman::execution;
16
+ using namespace facter::util::aix;
15
17
 
18
+ // This routine's meant to be a general utility function that replicates the behavior of
19
+ // lsattr -El <object> -a <field>. Although it's only used to get the modelname of the
20
+ // sys0 device, we still would like to have it here in case we ever need to separate it
21
+ // out to an AIX utils file to query other attributes. Part of what lsattr does is check
22
+ // PdAt if we don't have an entry for the object's attribute in CuAt, even though it is very
23
+ // unlikely that sys0.modelname will not have a CuAt entry. That is why we have the extra code
24
+ // in here.
16
25
  static string getattr(string object, string field)
17
26
  {
18
- string result;
19
-
20
- execution::each_line(
21
- "/usr/sbin/lsattr", {"-El", object, "-a", field},
22
- [&](string& line) {
23
- if (!line.empty()) {
24
- vector<string> tokens;
25
- boost::split(tokens, line, boost::is_space(), boost::token_compress_on);
26
- if (tokens.size() < 2) {
27
- return true;
28
- }
29
- result = tokens[1];
30
- return false;
31
- }
32
- return true;
33
- },
34
- nullptr,
35
- 0);
36
-
37
- if (result == "") {
38
- LOG_WARNING("Could not get a value from lsattr -El {1} -a {2}", object, field);
27
+ // High-level logic here is:
28
+ // * Check if there's an entry for our object's field attribute in CuAt (the device-specific
29
+ // attribute entry).
30
+ //
31
+ // * Else, check for the field attribute's default value in PdAt. We do this by first
32
+ // figuring out the PdDv type from the CuDv entry for the object, then use our PdDv type
33
+ // to query the field's default value in PdAt.
34
+ string query = (boost::format("name = %1% AND attribute = %2%") % object % field).str();
35
+ auto cuat_query = odm_class<CuAt>::open("CuAt").query(query);
36
+
37
+ // This is a more verbose way of saying that we only expect our query to have one element
38
+ auto cuat_ref = cuat_query.begin();
39
+ if (cuat_ref != cuat_query.end()) {
40
+ auto value = string(cuat_ref->value);
41
+ if (value.empty()) {
42
+ LOG_DEBUG("Could not get a value from the ODM for {1}'s '{2}' attribute.", object, field);
43
+ }
44
+ return value;
45
+ }
46
+
47
+ // Get the PdDv type from the CuDv entry
48
+ query = (boost::format("name = %1%") % object).str();
49
+ auto cudv_query = odm_class<CuDv>::open("CuDv").query(query);
50
+ auto cudv_ref = cudv_query.begin();
51
+ if (cudv_ref == cudv_query.end()) {
52
+ LOG_DEBUG("Could not get a value from the ODM for {1}'s '{2}' attribute: There is no CuDv entry for {1}.", object, field);
53
+ return "";
39
54
  }
40
- return result;
55
+ auto pddv_type = cudv_ref->PdDvLn_Lvalue;
56
+
57
+ query = (boost::format("uniquetype = %1% AND attribute = %2%") % pddv_type % field).str();
58
+ auto pdat_query = odm_class<PdAt>::open("PdAt").query(query);
59
+ auto pdat_ref = pdat_query.begin();
60
+ if (pdat_ref != pdat_query.end()) {
61
+ auto value = string(pdat_ref->deflt);
62
+ if (value.empty()) {
63
+ LOG_DEBUG("Could not get a value from the ODM for {1}'s '{2}' attribute.", object, field);
64
+ }
65
+ return value;
66
+ }
67
+
68
+ LOG_DEBUG("Could not get a value from the ODM for {1}'s '{2}' attribute: There is no PdAt entry for {1} with {2}.", object, field);
69
+ return "";
41
70
  }
42
71
 
43
72
  namespace facter { namespace facts { namespace aix {
@@ -53,9 +82,18 @@ namespace facter { namespace facts { namespace aix {
53
82
  boost::split(tokens, result.release, boost::is_any_of("-"));
54
83
  result.major = tokens[0];
55
84
 
56
- result.architecture = getattr("proc0", "type");
85
+ // Get the hardware
57
86
  result.hardware = getattr("sys0", "modelname");
58
87
 
88
+ // Now get the architecture. We use processor.models[0] for this information.
89
+ auto processors = facts.get<map_value>(fact::processors);
90
+ auto models = processors ? processors->get<array_value>("models") : nullptr;
91
+ if (! models || models->empty()) {
92
+ LOG_DEBUG("Could not get a value for the OS architecture. Your machine does not have any processors!");
93
+ } else {
94
+ result.architecture = models->get<string_value>(0)->value();
95
+ }
96
+
59
97
  return result;
60
98
  }
61
99
  }}}
@@ -148,7 +148,7 @@ namespace facter { namespace facts { namespace linux {
148
148
  "throw"
149
149
  };
150
150
 
151
- auto parse_route_line = [&known_route_types](string& line, std::vector<route>& routes) {
151
+ auto parse_route_line = [&known_route_types](string& line, int family, std::vector<route>& routes) {
152
152
  vector<boost::iterator_range<string::iterator>> parts;
153
153
  boost::split(parts, line, boost::is_space(), boost::token_compress_on);
154
154
 
@@ -181,6 +181,18 @@ namespace facter { namespace facts { namespace linux {
181
181
 
182
182
  route r;
183
183
  r.destination.assign(parts[dst_idx].begin(), parts[dst_idx].end());
184
+
185
+ // Check if we queried for the IPV6 routing tables. If yes, then check if our
186
+ // destination address is missing a ':'. If yes, then IPV6 is disabled since
187
+ // IPV6 addresses have a ':' in them. Our ip command has mistakenly outputted IPV4
188
+ // information. This is bogus data that we want to flush.
189
+ //
190
+ // See FACT-1475 for more details.
191
+ if (family == AF_INET6 && r.destination.find(':') == string::npos) {
192
+ routes = {};
193
+ return false;
194
+ }
195
+
184
196
  // Iterate over key/value pairs and add the ones we care
185
197
  // about to our routes entries
186
198
  for (size_t i = dst_idx+1; i < parts.size(); i += 2) {
@@ -197,10 +209,10 @@ namespace facter { namespace facts { namespace linux {
197
209
  };
198
210
 
199
211
  lth_exe::each_line(ip_command, { "route", "show" }, [this, &parse_route_line](string& line) {
200
- return parse_route_line(line, this->routes4);
212
+ return parse_route_line(line, AF_INET, this->routes4);
201
213
  });
202
214
  lth_exe::each_line(ip_command, { "-6", "route", "show" }, [this, &parse_route_line](string& line) {
203
- return parse_route_line(line, this->routes6);
215
+ return parse_route_line(line, AF_INET6, this->routes6);
204
216
  });
205
217
  }
206
218
 
@@ -61,11 +61,13 @@ namespace facter { namespace facts { namespace linux {
61
61
 
62
62
  operating_system_resolver::selinux_data operating_system_resolver::collect_selinux_data()
63
63
  {
64
+ static string SELINUX_CONFIG_FILE("/etc/selinux/config");
65
+
64
66
  selinux_data result;
65
67
  result.supported = true;
66
68
 
67
69
  string mountpoint = get_selinux_mountpoint();
68
- result.enabled = !mountpoint.empty();
70
+ result.enabled = !mountpoint.empty() && exists(SELINUX_CONFIG_FILE);
69
71
  if (!result.enabled) {
70
72
  return result;
71
73
  }
@@ -87,7 +89,7 @@ namespace facter { namespace facts { namespace linux {
87
89
  // Parse the SELinux config for mode and policy
88
90
  static boost::regex mode_regex("(?m)^SELINUX=(\\w+)$");
89
91
  static boost::regex policy_regex("(?m)^SELINUXTYPE=(\\w+)$");
90
- lth_file::each_line("/etc/selinux/config", [&](string& line) {
92
+ lth_file::each_line(SELINUX_CONFIG_FILE, [&](string& line) {
91
93
  if (re_search(line, mode_regex, &result.config_mode)) {
92
94
  return true;
93
95
  }
@@ -1,10 +1,19 @@
1
1
  #include <internal/facts/posix/uptime_resolver.hpp>
2
+ #include <internal/util/posix/utmpx_file.hpp>
2
3
  #include <leatherman/util/regex.hpp>
3
4
  #include <leatherman/execution/execution.hpp>
5
+ #include <leatherman/logging/logging.hpp>
6
+ #include <leatherman/locale/locale.hpp>
7
+
8
+ #include <ctime>
9
+
10
+ // Mark string for translation (alias for leatherman::locale::format)
11
+ using leatherman::locale::_;
4
12
 
5
13
  using namespace std;
6
14
  using namespace leatherman::util;
7
15
  using namespace leatherman::execution;
16
+ using namespace facter::util::posix;
8
17
 
9
18
  namespace facter { namespace facts { namespace posix {
10
19
 
@@ -43,6 +52,16 @@ namespace facter { namespace facts { namespace posix {
43
52
 
44
53
  int64_t uptime_resolver::get_uptime()
45
54
  {
55
+ LOG_DEBUG(_("Attempting to calculate the uptime from the utmpx file"));
56
+ utmpx query;
57
+ query.ut_type = BOOT_TIME;
58
+ utmpx_file file;
59
+ auto ent = file.query(query);
60
+ if (ent) {
61
+ return time(NULL) - ent->ut_tv.tv_sec;
62
+ }
63
+ LOG_DEBUG(_("Could not calculate the uptime from the utmpx file"));
64
+
46
65
  auto exec = execute("uptime");
47
66
  if (!exec.success) {
48
67
  return -1;
@@ -0,0 +1,36 @@
1
+ #include <internal/util/posix/utmpx_file.hpp>
2
+ #include <leatherman/locale/locale.hpp>
3
+ #include <leatherman/logging/logging.hpp>
4
+
5
+ // Mark string for translation (alias for leatherman::locale::format)
6
+ using leatherman::locale::_;
7
+
8
+ using namespace std;
9
+
10
+ namespace facter { namespace util { namespace posix {
11
+
12
+ bool utmpx_file::instance_exists = false;
13
+
14
+ utmpx_file::utmpx_file() {
15
+ if (utmpx_file::instance_exists) {
16
+ throw logic_error(_("only one utmpx_file instance can exist at a time!"));
17
+ }
18
+
19
+ utmpx_file::instance_exists = true;
20
+ reset();
21
+ }
22
+
23
+ utmpx_file::~utmpx_file() {
24
+ endutxent();
25
+ utmpx_file::instance_exists = false;
26
+ }
27
+
28
+ const utmpx* utmpx_file::query(utmpx const& query) const {
29
+ LOG_DEBUG(_("Reading the utmpx file ..."));
30
+ return getutxid(&query);
31
+ }
32
+
33
+ void utmpx_file::reset() const {
34
+ setutxent();
35
+ }
36
+ }}} // namespace facter::util::posix
@@ -6,7 +6,7 @@
6
6
  #, fuzzy
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: FACTER 3.11.3\n"
9
+ "Project-Id-Version: FACTER 3.11.4\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"
@@ -316,6 +316,15 @@ msgstr ""
316
316
  msgid "querylv returned success but we got a null LV. WTF?"
317
317
  msgstr ""
318
318
 
319
+ #: lib/src/facts/aix/load_average_resolver.cc
320
+ msgid "failed to retrieve the load averages"
321
+ msgstr ""
322
+
323
+ #. debug
324
+ #: lib/src/facts/aix/memory_resolver.cc
325
+ msgid "cannot use device {1}: error is {2}"
326
+ msgstr ""
327
+
319
328
  #: lib/src/facts/aix/networking_resolver.cc
320
329
  msgid "getkerninfo call was unsuccessful"
321
330
  msgstr ""
@@ -352,9 +361,42 @@ msgstr ""
352
361
  msgid "got an unknown RT_IFLIST message: {1}"
353
362
  msgstr ""
354
363
 
355
- #. warning
356
364
  #: lib/src/facts/aix/operating_system_resolver.cc
357
- msgid "Could not get a value from lsattr -El {1} -a {2}"
365
+ msgid "name = %1% AND attribute = %2%"
366
+ msgstr ""
367
+
368
+ #. debug
369
+ #: lib/src/facts/aix/operating_system_resolver.cc
370
+ msgid "Could not get a value from the ODM for {1}'s '{2}' attribute."
371
+ msgstr ""
372
+
373
+ #: lib/src/facts/aix/operating_system_resolver.cc
374
+ msgid "name = %1%"
375
+ msgstr ""
376
+
377
+ #. debug
378
+ #: lib/src/facts/aix/operating_system_resolver.cc
379
+ msgid ""
380
+ "Could not get a value from the ODM for {1}'s '{2}' attribute: There is no "
381
+ "CuDv entry for {1}."
382
+ msgstr ""
383
+
384
+ #: lib/src/facts/aix/operating_system_resolver.cc
385
+ msgid "uniquetype = %1% AND attribute = %2%"
386
+ msgstr ""
387
+
388
+ #. debug
389
+ #: lib/src/facts/aix/operating_system_resolver.cc
390
+ msgid ""
391
+ "Could not get a value from the ODM for {1}'s '{2}' attribute: There is no "
392
+ "PdAt entry for {1} with {2}."
393
+ msgstr ""
394
+
395
+ #. debug
396
+ #: lib/src/facts/aix/operating_system_resolver.cc
397
+ msgid ""
398
+ "Could not get a value for the OS architecture. Your machine does not have "
399
+ "any processors!"
358
400
  msgstr ""
359
401
 
360
402
  #. debug
@@ -959,6 +1001,14 @@ msgstr ""
959
1001
  msgid "strftime failed: timezone is unavailable."
960
1002
  msgstr ""
961
1003
 
1004
+ #: lib/src/facts/posix/uptime_resolver.cc
1005
+ msgid "Attempting to calculate the uptime from the utmpx file"
1006
+ msgstr ""
1007
+
1008
+ #: lib/src/facts/posix/uptime_resolver.cc
1009
+ msgid "Could not calculate the uptime from the utmpx file"
1010
+ msgstr ""
1011
+
962
1012
  #. debug
963
1013
  #: lib/src/facts/posix/xen_resolver.cc
964
1014
  msgid "failure executing {1}: {2}"
@@ -1493,6 +1543,14 @@ msgstr ""
1493
1543
  msgid "a block is unexpected when passing a String"
1494
1544
  msgstr ""
1495
1545
 
1546
+ #: lib/src/util/posix/utmpx_file.cc
1547
+ msgid "only one utmpx_file instance can exist at a time!"
1548
+ msgstr ""
1549
+
1550
+ #: lib/src/util/posix/utmpx_file.cc
1551
+ msgid "Reading the utmpx file ..."
1552
+ msgstr ""
1553
+
1496
1554
  #: lib/src/util/solaris/k_stat.cc
1497
1555
  msgid "kstat_open failed"
1498
1556
  msgstr ""
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.3.cfacter.20180716
4
+ version: 3.11.4.cfacter.20180821
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-07-16 00:00:00.000000000 Z
12
+ date: 2018-08-21 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: info@puppet.com
@@ -360,6 +360,7 @@ files:
360
360
  - ext/facter/facter/lib/inc/internal/facts/aix/disk_resolver.hpp
361
361
  - ext/facter/facter/lib/inc/internal/facts/aix/filesystem_resolver.hpp
362
362
  - ext/facter/facter/lib/inc/internal/facts/aix/kernel_resolver.hpp
363
+ - ext/facter/facter/lib/inc/internal/facts/aix/load_average_resolver.hpp
363
364
  - ext/facter/facter/lib/inc/internal/facts/aix/memory_resolver.hpp
364
365
  - ext/facter/facter/lib/inc/internal/facts/aix/networking_resolver.hpp
365
366
  - ext/facter/facter/lib/inc/internal/facts/aix/operating_system_resolver.hpp
@@ -485,6 +486,7 @@ files:
485
486
  - ext/facter/facter/lib/inc/internal/util/posix/scoped_addrinfo.hpp
486
487
  - ext/facter/facter/lib/inc/internal/util/posix/scoped_bio.hpp
487
488
  - ext/facter/facter/lib/inc/internal/util/posix/scoped_descriptor.hpp
489
+ - ext/facter/facter/lib/inc/internal/util/posix/utmpx_file.hpp
488
490
  - ext/facter/facter/lib/inc/internal/util/scoped_file.hpp
489
491
  - ext/facter/facter/lib/inc/internal/util/solaris/k_stat.hpp
490
492
  - ext/facter/facter/lib/inc/internal/util/solaris/scoped_kstat.hpp
@@ -501,6 +503,7 @@ files:
501
503
  - ext/facter/facter/lib/src/facts/aix/disk_resolver.cc
502
504
  - ext/facter/facter/lib/src/facts/aix/filesystem_resolver.cc
503
505
  - ext/facter/facter/lib/src/facts/aix/kernel_resolver.cc
506
+ - ext/facter/facter/lib/src/facts/aix/load_average_resolver.cc
504
507
  - ext/facter/facter/lib/src/facts/aix/memory_resolver.cc
505
508
  - ext/facter/facter/lib/src/facts/aix/networking_resolver.cc
506
509
  - ext/facter/facter/lib/src/facts/aix/operating_system_resolver.cc
@@ -641,6 +644,7 @@ files:
641
644
  - ext/facter/facter/lib/src/util/posix/scoped_addrinfo.cc
642
645
  - ext/facter/facter/lib/src/util/posix/scoped_bio.cc
643
646
  - ext/facter/facter/lib/src/util/posix/scoped_descriptor.cc
647
+ - ext/facter/facter/lib/src/util/posix/utmpx_file.cc
644
648
  - ext/facter/facter/lib/src/util/scoped_file.cc
645
649
  - ext/facter/facter/lib/src/util/solaris/k_stat.cc
646
650
  - ext/facter/facter/lib/src/util/solaris/scoped_kstat.cc