Skip to content

Commit

Permalink
Fixes #166: inventory the local timezone name and offset to UTC
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthieu CERDA committed Oct 12, 2016
1 parent a2f11cb commit c2a0892
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 6 deletions.
11 changes: 6 additions & 5 deletions Makefile.PL
Expand Up @@ -32,10 +32,10 @@ recommends 'IO::Socket::SSL' => '1.14';
recommends 'LWP::Protocol::https' => '0';

if ($OSNAME ne 'MSWin32') {
recommends 'Proc::Daemon' => '0';
recommends 'Proc::PID::File' => '0';
recommends 'Proc::Daemon' => '0';
recommends 'Proc::PID::File' => '0';
} else {
recommends 'Win32::Daemon' => '0';
recommends 'Win32::Daemon' => '0';
recommends 'Win32::Unicode::File' => '0';
}

Expand All @@ -59,8 +59,9 @@ test_requires 'Net::SNMP' => '0';
test_requires 'Parallel::ForkManager' => '0';

# Inventory
recommends 'Parse::EDID' => '0';
recommends 'Net::CUPS' => 0.60 if $OSNAME ne 'MSWin32';
recommends 'Parse::EDID' => '0';
recommends 'Net::CUPS' => 0.60 if $OSNAME ne 'MSWin32';
recommends 'DateTime' => '0';

# Deploy
recommends 'Archive::Extract' => '0';
Expand Down
1 change: 1 addition & 0 deletions README
Expand Up @@ -40,6 +40,7 @@ Optional Perl modules:

* Net::CUPS, for printers detection
* Parse::EDID, for EDID data parsing
* DateTime, for reliable timezone name extraction

Optional programs:

Expand Down
2 changes: 1 addition & 1 deletion lib/FusionInventory/Agent/Inventory.pm
Expand Up @@ -25,7 +25,7 @@ my %fields = (
VMNAME VMHOSTSERIAL/ ],
OPERATINGSYSTEM => [ qw/KERNEL_NAME KERNEL_VERSION NAME VERSION FULL_NAME
SERVICE_PACK INSTALL_DATE FQDN DNS_DOMAIN
SSH_KEY ARCH BOOT_TIME/ ],
SSH_KEY ARCH BOOT_TIME TIMEZONE/ ],
ACCESSLOG => [ qw/USERID LOGDATE/ ],

ANTIVIRUS => [ qw/COMPANY ENABLED GUID NAME UPTODATE VERSION
Expand Down
96 changes: 96 additions & 0 deletions lib/FusionInventory/Agent/Task/Inventory/Generic/Timezone.pm
@@ -0,0 +1,96 @@
package FusionInventory::Agent::Task::Inventory::Generic::Timezone;

use strict;
use warnings;

use English qw(-no_match_vars);
use UNIVERSAL::require;

use POSIX;
use Time::Local;

use FusionInventory::Agent::Tools;

my $seen;

sub isEnabled {

# No specific dependencies necessary
return 1;
}

sub doInventory {
my (%params) = @_;

my $inventory = $params{inventory};
my $logger = $params{logger};

# Compute a timezone offset like '+0200' using the difference between UTC and local time
# Might require merging with detectLocalTimeOffset (macOS inventory) in the future

## Get the local time
my @t = localtime(time);

## Compute the time offset in seconds between local and UTC time (relative and absolute)
my $utc_offset_seconds = timegm(@t) - timelocal(@t);
my $utc_offset_seconds_abs = abs($utc_offset_seconds);

## Offset sign is minus if $utc_offset_seconds is negative, plus otherwise.
my $offset_sign = $utc_offset_seconds < 0 ? '-' : '+';

## Format the offset string: sign + H (XX) + M (XX)
my $tz_offset =
strftime( $offset_sign . "\%H\%M", gmtime($utc_offset_seconds_abs) );

# Assume by default that the offset is empty (safe default in case something goes wrong below)
my $tz_name = '';

# Timezone name extraction will use one of the following sources:
# * DateTime::TimeZone and DateTime::TimeZone::Local::{Win32,Unix} => 'Europe/Paris'
# * tzutil (Win 7+, Win 2008+) => 'Romance Standard Time'
# * strftime '%Z' => 'CEST'
#
# strftime will not be used on Windows, as it returns unpredictable localized TZ names. It means
# that if reliable timezone name extraction is wanted, DateTime::TimeZone MUST be used.
if (
( DateTime::TimeZone->require() )
&& ( $OSNAME eq 'MSWin32'
? DateTime::TimeZone::Local::Win32->require()
: DateTime::TimeZone::Local::Unix->require() )
)
{
$logger->debug("Using DateTime::TimeZone to get the timezone name");
$tz_name = DateTime::TimeZone->new( name => 'local' )->name();
}
elsif ( ( $OSNAME eq 'MSWin32' ) || ( canRun('tzutil') ) ) {

$logger->debug("Using tzutil to get the timezone name");

my $handle = getFileHandle(
logger => $logger,
command => 'tzutil /g',
);

while ( my $line = <$handle> ) {
$tz_name = $line;
}
close $handle;

}
elsif ( $OSNAME ne 'MSWin32' ) {
$logger->debug("Using strftime to get the timezone name");
$tz_name = strftime( "%Z", localtime() );
}

$inventory->setOperatingSystem(
{
TIMEZONE => {
NAME => $tz_name,
OFFSET => $tz_offset,
}
}
);

}

1;

0 comments on commit c2a0892

Please sign in to comment.