File Coverage

blib/lib/urpm/parallel_ssh.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package urpm::parallel_ssh;
2              
3              
4             #- Copyright (C) 2002, 2003, 2004, 2005 MandrakeSoft SA
5             #- Copyright (C) 2005-2010 Mandriva SA
6             #- Copyright (C) 2011-2017 Mageia
7              
8 1     1   2606 use strict;
  1         4  
  1         45  
9 1     1   9 use urpm::util 'dirname';
  1         3  
  1         63  
10 1     1   46 use urpm::msg;
  0            
  0            
11             use urpm::parallel;
12              
13             our @ISA = 'urpm::parallel';
14              
15             sub _localhost { $_[0] eq 'localhost' }
16             sub _ssh { &_localhost ? '' : "ssh $_[0] " }
17             sub _host { &_localhost ? '' : "$_[0]:" }
18              
19             sub _scp {
20             my ($urpm, $host, @para) = @_;
21             my $dest = pop @para;
22              
23             $urpm->{log}("parallel_ssh: scp " . join(' ', @para) . " $host:$dest");
24             system('scp', @para, _host($host) . $dest) == 0
25             or $urpm->{fatal}(1, N("scp failed on host %s (%d)", $host, $? >> 8));
26             }
27              
28             sub copy_to_dir {
29             my ($parallel, $urpm, @para) = @_;
30             my $dir = pop @para;
31              
32             foreach my $host (keys %{$parallel->{nodes}}) {
33             if (_localhost($host)) {
34             if (my @f = grep { dirname($_) ne $dir } @para) {
35             $urpm->{log}("parallel_ssh: cp @f $urpm->{cachedir}/rpms");
36             system('cp', @f, $dir) == 0
37             or $urpm->{fatal}(1, N("cp failed on host %s (%d)", $host, $? >> 8));
38             }
39             } else {
40             _scp($urpm, $host, @para, $dir);
41             }
42             }
43             }
44              
45             sub propagate_file {
46             my ($parallel, $urpm, $file) = @_;
47             foreach (grep { !_localhost($_) } keys %{$parallel->{nodes}}) {
48             _scp($urpm, $_, '-q', $file, $file);
49             }
50             }
51              
52             sub _ssh_urpm {
53             my ($urpm, $node, $cmd, $para) = @_;
54              
55             $cmd ne 'urpme' && _localhost($node) and $para = "--nolock $para";
56              
57             # it doesn't matter for urpmq, and previous version of urpmq didn't handle it:
58             $cmd ne 'urpmq' and $para = "--no-locales $para";
59              
60             $urpm->{log}("parallel_ssh: $node: $cmd $para");
61             _ssh($node) . " $cmd $para";
62             }
63             sub _ssh_urpm_popen {
64             my ($urpm, $node, $cmd, $para) = @_;
65              
66             my $command = _ssh_urpm($urpm, $node, $cmd, $para);
67             open(my $fh, "$command |") or $urpm->{fatal}(1, "Can't fork ssh: $!");
68             $fh;
69             }
70              
71             sub urpm_popen {
72             my ($parallel, $urpm, $cmd, $para, $do) = @_;
73              
74             my @errors;
75              
76             foreach my $node (keys %{$parallel->{nodes}}) {
77             my $fh = _ssh_urpm_popen($urpm, $node, $cmd, $para);
78              
79             while (my $s = <$fh>) {
80             chomp $s;
81             $urpm->{debug}("parallel_ssh: $node: received: $s") if $urpm->{debug};
82             $do->($node, $s) and last;
83             }
84             close $fh or push @errors, N("%s failed on host %s (maybe it does not have a good version of urpmi?) (exit code: %d)", $cmd, $node, $? >> 8);
85             $urpm->{debug}("parallel_ssh: $node: $cmd finished") if $urpm->{debug};
86             }
87              
88             @errors;
89             }
90              
91             sub run_urpm_command {
92             my ($parallel, $urpm, $cmd, $para) = @_;
93              
94             foreach my $node (keys %{$parallel->{nodes}}) {
95             system(_ssh_urpm($urpm, $node, $cmd, $para));
96             }
97             }
98              
99             #- allow to bootstrap from urpmi code directly (namespace is urpm).
100              
101             package urpm;
102              
103             no warnings 'redefine';
104              
105             sub handle_parallel_options {
106             my (undef, $options) = @_;
107             my ($id, @nodes) = split /:/, $options;
108              
109             if ($id =~ /^ssh(?:\(([^\)]*)\))?$/) {
110             my %nodes; @nodes{@nodes} = undef;
111             return bless {
112             media => $1,
113             nodes => \%nodes,
114             }, "urpm::parallel_ssh";
115             }
116             return undef;
117             }
118              
119             1;