diff options
-rw-r--r-- | Discover.pm | 73 | ||||
-rw-r--r-- | mdkonline.pm | 230 | ||||
-rw-r--r-- | mdvonline_agent.pl | 73 |
3 files changed, 252 insertions, 124 deletions
diff --git a/Discover.pm b/Discover.pm index 7fc3f110..8b0e220c 100644 --- a/Discover.pm +++ b/Discover.pm @@ -58,14 +58,6 @@ sub init }; # -sub trim { - my $s = shift; - $s =~ s/^\s+//; - $s =~ s/\s+$//; - return $s; -}; - -# sub commify_series { (@_ == 0) ? '' : (@_ == 1) ? $_[0] : @@ -84,17 +76,10 @@ sub search { my @domains = (); my @services = (); - if( ! defined $resolv ) { - logerr "No config found from /etc/resolv.conf ."; - return 0; - } + ! defined $resolv and logerr "No config found from /etc/resolv.conf.", return 0; - if( defined $resolv->{domain} ) { - @domains = $resolv->{domain}; - } - if( defined $resolv->{search} ) { - push( @domains, @{$resolv->{search}} ); - } + defined $resolv->{domain} and @domains = $resolv->{domain}; + defined $resolv->{search} and push( @domains, @{$resolv->{search}} ); @domains = uniq(@domains); for my $domain ( @domains ) { @@ -107,15 +92,13 @@ sub search { @{$resolv->{nameserver}} = qw(localhost); # will try each nameserver listed - for my $ns ( @{$resolv->{nameserver}} ) { + foreach my $ns ( @{$resolv->{nameserver}} ) { # for each possible service/domain - for my $serv ( @services ) { + foreach my $serv ( @services ) { logsay "trying ns $ns, service $serv"; my $ret = $this->find_service( $ns, $serv ); - if( $ret ) { - logsay "search is over: a service has been found."; - return $ret; - } + + $ret and logsay "service found", return $ret; } } logwarn "no dns-declared service found"; @@ -125,6 +108,7 @@ sub search { # NOTE. here it is suppposed that for a given Service instance (PTR), # there is only _one_ SRV record and _one_ TXT record matches. # If there are more, no particular behaviour is expected as for now. +# NOTE. replace this code with a wrapper around dig? sub find_service { my ($this, $nameserver, $service) = @_; my $return; @@ -149,10 +133,9 @@ sub find_service { if( $query ) { # TODO better parsing of the struct my $rr = $query->{answer}[0]; - if( ! defined $rr ) { - logerr "not expected format found in PTR record."; - return 0; - } + + ! defined $rr and logerr "not expected format found in PTR record.", return 0; + $instanceName = $rr->ptrdname; $instanceName =~ s/\\032/ /g; logsay "found '$instanceName'"; @@ -186,10 +169,8 @@ sub find_service { my $rr = $query->{answer}[0]; logsay "yes: " . join(', ', $rr->char_str_list() ); $return->{config} = $this->parse_txt_config( $rr->char_str_list() ); - if( ! defined $return->{config} ) { - logwarn "But no config found."; - return 0; - } + + ! defined $return->{config} and logwarn "But no config found.", return 0; } else { logwarn "No matching TXT record found."; @@ -199,31 +180,39 @@ sub find_service { return $return; }; -# translate the txt records into a properly formatted hash. +# translate the txt record* into a properly formatted hash. +# +# * consists of a list of 'key=value' strings; handled strings are: +# txtvers=n (integer) +# conf=a,b (string: name of the config,integer: set time) +# update=p (string: path to update server) +# service=s (string: path to service resource) +# user=s (string: default user name to use) +# pass=s (string: default password to use) +# auto=b (TRUE|FALSE: whether to act automatically or not) +# mobile=b (TRUE|FALSE: whether to act as a mobile agent or not) +# sub parse_txt_config { my ($this, @config) = @_; my $retconfig; - for my $line ( @config ) { - my @line = split('=', $line); - my $key = $line[0]; - shift(@line); + foreach my $line ( @config ) { + # TODO match these with a regexp + my @line = split('=', $line); + my $key = shift(@line); my $value = join('=', @line); - #print "key: $key\tvalue: $value\n"; switch( $key ) { case 'txtvers' { $retconfig->{txtvers} = $value; } case 'conf' { my @co = split(',', $value); $retconfig->{conf} = { 'name' => $co[0], 'time' => $co[1] }; } - case 'update' { - my @up = split(',', $value); - $retconfig->{update} = { 'type' => $up[0], 'path' => $up[1] }; - } + case 'update' { $retconfig->{update} = $value; } case 'service' { $retconfig->{service} = $value; } case 'user' { $retconfig->{user} = $value; } case 'pass' { $retconfig->{pass} = $value; } case 'auto' { $retconfig->{auto} = 1; } + case 'mobile' { $retconfig->{mobile} = 1; } else {} } } diff --git a/mdkonline.pm b/mdkonline.pm index 37dcc8a6..cc24f287 100644 --- a/mdkonline.pm +++ b/mdkonline.pm @@ -12,13 +12,16 @@ use Net::HTTPS; use HTTP::Request::Common; use HTTP::Request; use SOAP::Lite; +use Switch; +use Log::Agent; # use settings from main file +use Error qw(:try); #For debugging use Data::Dumper; my $release_file = find { -f $_ } '/etc/mandriva-release', '/etc/mandrakelinux-release', '/etc/mandrake-release', '/etc/redhat-release'; -#my $uri = 'https://localhost/~romain/online3/htdocs/soap'; -my $uri = 'https://online.mandriva.com/soap'; +my $uri = 'https://localhost/~romain/online3/htdocs/soap'; +#my $uri = 'https://online.mandriva.com/soap'; my $serviceProxy = $uri; my $onlineProxy = $uri; @@ -31,43 +34,121 @@ sub is_proxy () { my $s = is_proxy() ? SOAP::Lite->uri($uri)->proxy($serviceProxy, proxy => [ 'http' => $ENV{http_proxy} ], agent => $useragent) : SOAP::Lite->uri($uri)->proxy($serviceProxy, agent => $useragent); # +sub get_configuration { + my $in = shift; + my $config_file = '/etc/sysconfig/mdkonline'; + my %conf; + my $ret; + + logsay "checking configuration"; + try { + # check local config file + if( ! ( -e $config_file ) || ! ( -s $config_file ) ) { + logsay "checking dns service"; + %conf = get_conf_from_dns(); + print "from dns:\n",Dumper(%conf),"\n"; + if( %conf ) { + + } + else { throw( ) } + if( %conf eq undef ) { + logwarn "found none"; + } else { + logsay "found one"; + } + } + else { + # found one + logsay "found $config_file"; + %conf = getVarsFromSh($config_file); + if( defined $conf{MACHINE} && ! defined $conf{VERSION} ) { + # old (v2) config + logsay "old (v2) conf found; trying to upgrade to v3"; + $ret = upgrade_to_v3(); + print "\n", $ret, "\n"; + if( $ret eq 1 ) { + logsay "succeeded; reloading configuration"; + # reload config + %conf = getVarsFromSh($config_file); + } + else { + logsay "failed. stop."; + # TODO what do we do now? email warning? support? forget it? + %conf = undef; + } + } + } + } + catch Error with { + my $ex = shift; + print Dumper($ex); + } + finally { + + }; + + # now, a valid working config file is loaded + if( defined $conf{MOBILE} && $conf{MOBILE} eq 'TRUE' ) { + logsay "checking for mobile options"; + # client is mobile: we check for any dns-declared local option + # (like, a local update mirror) + # TODO set precedence rules. user may not want/have the right to + # follow local network rules (security of the update process). + # depends on host config, and on server commands. + my $sd = new Discovery; + my $info = $sd->search(); + if( $info ) { + # TODO + } + else {} # nothing to do + } + %conf; +} + +# update current configuration values with those passed as argument +sub save_config { + + my $params = shift; + my %current = getVarsFromSh('/etc/sysconfig/mdkonline'); + + print Dumper($params); + + defined $params->{customer_id} and $current{CUSTOMER_ID} = $params->{customer_id}; + defined $params->{host_id} and $current{HOST_ID} = $params->{host_id}; + defined $params->{host_key} and $current{HOST_KEY} = $params->{host_key}; + defined $params->{host_name} and $current{HOST_NAME} = $params->{host_name}; + ! defined $current{VERSION} and $current{VERSION} = 3; + defined $params->{country} and $current{COUNTRY} = $params->{country}; + defined $params->{mobile} and $current{MOBILE} = $params->{mobile}; + defined $params->{auto} and $current{AUTO} = $params->{auto}; + $current{DATE_SET} = chomp_(`LC_ALL=C date`); + + print Dumper(%current); + print setVarsInSh( '/etc/sysconfig/mdkonline', %current ); + %current; +}; + +# sub upgrade_to_v3 { my $oldconffile = '/root/.MdkOnline/mdkupdate'; if( ( -e $oldconffile ) && ( -s $oldconffile ) ) { my %old = getVarsFromSh('/root/.MdkOnline/mdkupdate'); if( $old{LOGIN} ne '' && $old{PASS} ne '' && $old{MACHINE} ne '' ) { my $res = mdkonline::soap_recover_service($old{LOGIN},'{md5}'.$old{PASS},$old{MACHINE},$old{COUNTRY}); - print Dumper($res); - print 'code is: ' . $res->{code} . "\n"; - print Dumper($res->{data}); if( $res->{code} eq '0' || $res->{code} == 0 ) { #logsay "succeeded to register anew to service; configuring local host."; - my $dateset = chomp_(`LC_ALL=C date`); - my $auto = 'FALSE'; - my $mobile = 'FALSE'; - my $country = 'FR'; - my $service = 'https://online.mandriva.com/service'; - # TODO set config file differently: set vars in a hash - # and setVarsInSh() to save it (nicer in order to handle optional vars) - output '/etc/sysconfig/mdkonline', - qq(# automatically generated file. Please don't edit. -# use mdvonline_wizard instead. -VERSION=3 -DATESET=$dateset -SERVICE=$service -CUSTOMER_ID=$res->{data}->{customer_id} -HOST_ID=$res->{data}->{host_id} -HOST_KEY=$res->{data}->{host_key} -HOST_NAME=$res->{data}->{host_name} -HOST_GROUPS= -COUNTRY=$country -MOBILE=$mobile -AUTO=$auto -); + my $cd = $res->{data}; + $cd->{auto} = 'FALSE'; + $cd->{mobile} = 'FALSE'; + $cd->{country} = ''; + $cd->{service} = 'https://online.mandriva.com/service'; + + mdkonline::save_config( $res->{data} ); return 1; } else { - #logwarn "failed to recover service; answer was: " . $res->{message} . "(" . $res->{code} . ")"; + $res->{code} eq '1' and logwarn "this host may be already registered"; + logwarn "failed to recover service; answer was: " . $res->{message} . "(" . $res->{code} . ")"; } } else { @@ -79,9 +160,88 @@ AUTO=$auto # no config file found; #logwarn "no config file has been found (" . $oldconffile . ")"; } - return 0; + return undef; }; +sub register_from_dns { + my $dnsconf = shift; + + my $user = $dnsconf->{user}->{name} || ''; + my $pass = $dnsconf->{user}->{pass} || ''; + my $hostname = chomp_(`hostname`); + my $hostinfo = ''; + my $country = ''; # FIXME + # TODO change SOAP proxy to the one indicated at $dnsconf->{service} before + # TODO wrap all soap calls into an object so we can update the proxy on the fly? + my $res = mdkonline::soap_register_host( $user, $pass, $hostname, $hostinfo, $country ); + if( $res->{code} eq 0 ) { + $res->{data}->{service} = $dnsconf->{service}; + return mdkonline::save_config( $res->{data} ); + } + return undef; +} + +sub get_conf_from_dns { + my $sd = new Discover; + my $info = $sd->search(); + my $ret; + if( $info ) { + logsay "found service"; + if( defined $info->{user}->{name} && defined $info->{user}->{pass} + && $info->{user}->{name} ne '' && $info->{user}->{pass} ne '' ) { + print Dumper($info); + # TODO check service certificate + $ret = mdkonline::register_from_dns( $info ); + if( $ret ) { + return $ret; + } + else { + logsay "failed to register to dns declared service"; + } + } + else { + logsay "does not permit automatic registration (no user info)"; + } + } + else { + logsay "no service info found"; + } + return; +} + +# +sub run_and_return_task { + my $task = shift; + my $ret; + + if( $task->{command} ne 'none' ) { +# switch( $task->{command} ) { +# case 'update' { +# #$task->{mirror} +# #$task->{packages} +# } +# case 'upload_config' { +# # +# } +# case 'set_params' { +# #$task->{params} +# } +# case 'none' { +# logsay "nothing to do"; +# } +# else { +# logwarn "unknown task " . $task->{command}; +# } +# } +# # TODO soap_return_task_result(); + } + else { + $ret = 1; + } + $ret; +}; + + sub md5file { require Digest::MD5; my @md5 = map { @@ -121,7 +281,12 @@ sub soap_create_account { sub soap_authenticate_user { my $auth = $s->authenticateUser(@_)->result(); - $auth + $auth; +} + +sub soap_register_host { + my $auth = $s->registerHost(@_)->result(); + $auth; } sub soap_recover_service { @@ -134,6 +299,11 @@ sub soap_get_task { $auth; } +sub soap_return_task_result { + my $auth = $s->setTaskResult(@_)->result(); + $auth; +} + sub get_from_URL { my ($link, $agent_name) = @_; my $ua = LWP::UserAgent->new; diff --git a/mdvonline_agent.pl b/mdvonline_agent.pl index 04709444..3b8ebfb2 100644 --- a/mdvonline_agent.pl +++ b/mdvonline_agent.pl @@ -27,7 +27,9 @@ use POSIX; use lib qw(/usr/lib/libDrakX /usr/lib/libDrakX/drakfirsttime); use common; use mdkonline; +use Switch; use Data::Dumper; +use Error qw(:try); # DNS service discovery use Discover; @@ -45,65 +47,32 @@ logconfig( -priority => [ -display => '[$priority]' ], ); -# TODO set this in mdkonline.pm ? -my $conffile = '/etc/sysconfig/mdkonline'; -my $service = 'https://localhost/~romain/online3/htdocs/service'; +logsay "=================="; +mdkonline::is_running('mdvonline_agent') and die "mdvonline_agent already running\n"; +require_root_capability(); -# script starts here -mdkonline::is_running('mdvonline_agent') - and die "mdvonline_agent already running\n"; +my %conf = mdkonline::get_configuration(); +print Dumper(%conf); -#require_root_capability(); +! defined %conf and logwarn "no configuration set", exit 0; -my %conf; -my $ret = 0; +logsay "checking for tasks"; +print Dumper(%conf); +my $answer = mdkonline::soap_get_task( $conf{HOST_ID}, $conf{HOST_KEY} ); -# 1. check configuration (local) or set from dns if any -if( ( -e $conffile ) && ( -s $conffile ) ) { - %conf = getVarsFromSh($conffile); +print Dumper($answer); - if( defined $conf{MACHINE} && ! defined $conf{VERSION} ) { #|| $conf{VERSION} lt 3 ) { - logsay "old configuration detected: trying to migrate to new scheme"; - $ret = mdkonline::upgrade_to_v3(); - if( $ret eq 1 ) { logsay "succeeded"; } - else { logsay "failed"; } +if( $answer->{code} eq 0 ) { + if( $answer->{data}->{command} eq 'none' ) { + logsay "nothing to do"; } else { - if( defined $conf{MOBILE} && $conf{MOBILE} eq 'TRUE' ) { - # TODO check dns service for a specific update server - # if there is one, it may supersedes default conf update server - # or the one provided by the Online server? - } - $ret = 1; + logsay "got something"; + my $res = mdkonline::run_and_return_task( $answer->{data} ); } + exit 1; } else { - logsay "no configuration file found"; - logsay "starting dns service discovery"; - my $sd = new Discover; - my $serviceinfo = $sd->search(); - if ( $serviceinfo ) { - logsay "found service with info"; - print Dumper($serviceinfo); - # TODO check service certificate - # TODO register to service - # TODO set config file - $ret = 0; - } - else { - #print Dumper($sd); - logsay "no service found"; - $ret = 0; - } - $ret = 0; -} - -if( $ret eq 1 ) { - # 2. now check and run task - print "checking for somethign to do.\n"; - my $task = mdkonline::soap_get_task( $conf{HOST_ID}, $conf{HOST_KEY} ); - print Dumper($task); -} - -logsay "done"; -$ret;
\ No newline at end of file + logwarn "something went wrong " . $answer->{message} . " (".$answer->{code}.")"; + exit 0; +}
\ No newline at end of file |