package Tapper::Remote::Config; BEGIN { $Tapper::Remote::Config::AUTHORITY = 'cpan:AMD'; } { $Tapper::Remote::Config::VERSION = '4.1.0'; } use strict; use warnings; use Getopt::Long; use Moose; use Net::TFTP; use Socket; # for inet_aton and gethostbyname use Sys::Hostname; use YAML::Syck; sub get_tapper_host { my ($host, $port); # try kernel command line open my $FH,'<','/proc/cmdline'; my $cmd_line = <$FH>; close $FH; ($host,undef,$port) = $cmd_line =~ m/tapper_host\s*=\s*(\w+)(:(\d+))?/; return($host,$port) if $host; if (my ($ip) = $cmd_line =~ m/tapper_ip\s*=\s*(\S+)/) { my $iaddr = inet_aton($ip); $host = gethostbyaddr($iaddr, AF_INET); ($port) = $cmd_line =~ m/tapper_port\s*=\s*(\d+)/; return($host,$port) if $host; } # try %ENV if ($ENV{TAPPER_MCP_SERVER}) { $host = $ENV{TAPPER_MCP_SERVER}; $port = $ENV{TAPPER_MCP_PORT}; return ($host, $port); } # try multicast } sub gethostname { my ($self) = @_; my $hostname = Sys::Hostname::hostname(); if ($hostname =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { ($hostname) = gethostbyaddr(inet_aton($hostname), AF_INET) or ( print("Can't get hostname: $!") and exit 1); $hostname =~ s/^(\w+?)\..+$/$1/; system("hostname", "$hostname"); } elsif ($hostname =~ m/^([^\.]+)\./) { $hostname = $1; } return $hostname; } sub get_local_data { my ($self, $state) = @_; # logger will usually be initialised by caller my $tmpcfg={}; my $config_file_name = '/etc/tapper'; $config_file_name = $ENV{TAPPER_CONFIG} if $ENV{TAPPER_CONFIG}; my $hostname = $self->gethostname(); my ($server, $port, $help); Getopt::Long::GetOptions("host=s" => \$server, "port=s" => \$port, "config=s" => \$config_file_name, "help|h" => \$help,); die "Usage: $0 [--host=host --port=port --config=file]\n" if $help; if ($state eq 'install' or (not -e $config_file_name)) { ($server, $port) = $self->get_tapper_host() if not $server; my $tftp = Net::TFTP->new($server); $tftp->get("$hostname-$state", $config_file_name) or return("Can't get local data.",$tftp->error); $tmpcfg->{server} = $server; $tmpcfg->{port} = $port; $tmpcfg->{hostname} = $hostname; } my $config = YAML::Syck::LoadFile($config_file_name) or return ("Can't parse config received from server"); $config->{filename} = $config_file_name; $config->{hostname} = $hostname unless $config->{hostname}; %$config=(%$config, %$tmpcfg); return $config; } 1; __END__ =pod =encoding utf-8 =head1 NAME Tapper::Remote::Config =head1 SYNOPSIS use Tapper::Remote::Config; =head1 NAME Tapper::Remote::Config - Get configuration from Tapper host =head1 FUNCTIONS =head2 get_tapper_host Get hostname of tapper MCP host from kernel boot parameters. @returnlist ($host,port) - string, int - hostname and port of MCP server =head2 gethostname This function returns the host name of the machine. When NFS root is used together with DHCP the hostname set in the kernel usually equals the IP address received from DHCP as a string. In this case the kernel hostname is set to the DNS hostname associated to this IP address. @return hostname of the machine as set in the kernel =head2 get_local_data Get local data needed for all tools running locally on NFS. The function tries to get the MCP host and fetches the config from there. This reduces any need for configuration outside MCP host and thus allows to use unchanged NFS root file systems for both testing and production, with different MCP servers and so on. @param string - state @return success - hash reference containing the config @return error - error string =head1 AUTHOR AMD OSRC Tapper Team =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2012 by Advanced Micro Devices, Inc.. This is free software, licensed under: The (two-clause) FreeBSD License =cut