1####################################################################################################################################
2# HostTest.pm - Encapsulate a docker host for testing
3####################################################################################################################################
4package pgBackRestTest::Common::HostTest;
5
6####################################################################################################################################
7# Perl includes
8####################################################################################################################################
9use strict;
10use warnings FATAL => qw(all);
11use Carp qw(confess);
12
13use Cwd qw(abs_path);
14use Exporter qw(import);
15    our @EXPORT = qw();
16
17use pgBackRestDoc::Common::Log;
18use pgBackRestDoc::Common::String;
19
20use pgBackRestTest::Common::ExecuteTest;
21
22####################################################################################################################################
23# new
24####################################################################################################################################
25sub new
26{
27    my $class = shift;          # Class name
28
29    # Create the class hash
30    my $self = {};
31    bless $self, $class;
32
33    # Assign function parameters, defaults, and log debug info
34    (
35        my $strOperation,
36        $self->{strName},
37        $self->{strContainer},
38        $self->{strImage},
39        $self->{strUser},
40        $self->{strOS},
41        $self->{stryMount},
42        $self->{strOption},
43        $self->{strParam},
44        $self->{bHostUpdate},
45    ) =
46        logDebugParam
47        (
48            __PACKAGE__ . '->new', \@_,
49            {name => 'strName', trace => true},
50            {name => 'strContainer', trace => true},
51            {name => 'strImage', trace => true},
52            {name => 'strUser', trace => true},
53            {name => 'strOS', trace => true},
54            {name => 'stryMount', required => false, trace => true},
55            {name => 'strOption', required => false, trace => true},
56            {name => 'strParam', required => false, trace => true},
57            {name => 'bHostUpdate', required => false, trace => true, default => true},
58        );
59
60    executeTest("docker rm -f $self->{strContainer}", {bSuppressError => true});
61
62    executeTest("docker run -itd -h $self->{strName} --name=$self->{strContainer}" .
63                (defined($self->{strOption}) ? ' ' . $self->{strOption} : '') .
64                (defined($self->{stryMount}) ? ' -v ' . join(' -v ', @{$self->{stryMount}}) : '') .
65                " $self->{strImage} " . (defined($self->{strParam}) ? ' ' . $self->{strParam} : ''),
66                {bSuppressStdErr => true});
67
68    # Get IP Address
69    $self->{strIP} = trim(executeTest("docker inspect --format '\{\{ .NetworkSettings.IPAddress \}\}' $self->{strContainer}"));
70    $self->{bActive} = true;
71
72    # Return from function and log return values if any
73    return logDebugReturn
74    (
75        $strOperation,
76        {name => 'self', value => $self, trace => true}
77    );
78}
79
80####################################################################################################################################
81# remove
82####################################################################################################################################
83sub remove
84{
85    my $self = shift;
86
87    # Assign function parameters, defaults, and log debug info
88    my ($strOperation) = logDebugParam(__PACKAGE__ . '->remove');
89
90    if ($self->{bActive})
91    {
92        executeTest("docker rm -f $self->{strContainer}", {bSuppressError => true});
93        $self->{bActive} = false;
94    }
95
96    # Return from function and log return values if any
97    return logDebugReturn($strOperation);
98}
99
100
101####################################################################################################################################
102# execute
103####################################################################################################################################
104sub execute
105{
106    my $self = shift;
107
108    # Assign function parameters, defaults, and log debug info
109    my
110    (
111        $strOperation,
112        $strCommand,
113        $oParam,
114        $strUser,
115        $bLoadEnv,
116        $bBashWrap,
117    ) =
118        logDebugParam
119        (
120            __PACKAGE__ . '->execute', \@_,
121            {name => 'strCommand'},
122            {name => 'oParam', required => false},
123            {name => 'strUser', required => false},
124            {name => 'bLoadEnv', optional => true, default => true},
125            {name => 'bBashWrap', optional => true, default => true},
126        );
127
128    # Set the user
129    if (!defined($strUser))
130    {
131        $strUser = $self->{strUser};
132    }
133
134    $strCommand =~ s/'/'\\''/g;
135
136    my $oExec = new pgBackRestTest::Common::ExecuteTest(
137        "docker exec -u ${strUser} $self->{strContainer}" .
138        ($bBashWrap ? " bash" . ($bLoadEnv ? ' -l' : '') . " -c '${strCommand}'" : " ${strCommand}"), $oParam);
139
140    # Return from function and log return values if any
141    return logDebugReturn
142    (
143        $strOperation,
144        {name => 'oExec', value => $oExec, trace => true}
145    );
146}
147
148####################################################################################################################################
149# executeSimple
150####################################################################################################################################
151sub executeSimple
152{
153    my $self = shift;
154
155    # Assign function parameters, defaults, and log debug info
156    my
157    (
158        $strOperation,
159        $strCommand,
160        $oParam,
161        $strUser,
162        $bLoadEnv,
163        $bBashWrap,
164    ) =
165        logDebugParam
166        (
167            __PACKAGE__ . '->executeSimple', \@_,
168            {name => 'strCommand', trace => true},
169            {name => 'oParam', required=> false, trace => true},
170            {name => 'strUser', required => false, trace => true},
171            {name => 'bLoadEnv', optional => true, default => true, trace => true},
172            {name => 'bBashWrap', optional => true, default => true},
173        );
174
175    my $oExec = $self->execute($strCommand, $oParam, $strUser, {bLoadEnv => $bLoadEnv});
176    $oExec->begin();
177    $oExec->end();
178
179    # Return from function and log return values if any
180    return logDebugReturn
181    (
182        $strOperation,
183        {name => 'strOutLog', value => $oExec->{strOutLog}, trace => true}
184    );
185}
186
187####################################################################################################################################
188# copyTo
189####################################################################################################################################
190sub copyTo
191{
192    my $self = shift;
193
194    # Assign function parameters, defaults, and log debug info
195    my
196    (
197        $strOperation,
198        $strSource,
199        $strDestination,
200        $strOwner,
201        $strMode
202    ) =
203        logDebugParam
204        (
205            __PACKAGE__ . '->copyTo', \@_,
206            {name => 'strSource'},
207            {name => 'strDestination'},
208            {name => 'strOwner', required => false},
209            {name => 'strMode', required => false}
210        );
211
212    executeTest("docker cp ${strSource} $self->{strContainer}:${strDestination}");
213
214    if (defined($strOwner))
215    {
216        $self->executeSimple("chown ${strOwner} ${strDestination}", undef, 'root');
217    }
218
219    if (defined($strMode))
220    {
221        $self->executeSimple("chmod ${strMode} ${strDestination}", undef, 'root');
222    }
223
224    # Return from function and log return values if any
225    return logDebugReturn($strOperation);
226}
227
228####################################################################################################################################
229# copyFrom
230####################################################################################################################################
231sub copyFrom
232{
233    my $self = shift;
234
235    # Assign function parameters, defaults, and log debug info
236    my
237    (
238        $strOperation,
239        $strSource,
240        $strDestination
241    ) =
242        logDebugParam
243        (
244            __PACKAGE__ . '->copyFrom', \@_,
245            {name => 'strSource'},
246            {name => 'strDestination'}
247        );
248
249    executeTest("docker cp $self->{strContainer}:${strSource} ${strDestination}");
250
251    # Return from function and log return values if any
252    return logDebugReturn($strOperation);
253}
254
255####################################################################################################################################
256# hostUpdateGet
257####################################################################################################################################
258sub hostUpdateGet
259{
260    my $self = shift;
261
262    return $self->{bHostUpdate};
263}
264
265####################################################################################################################################
266# ipGet
267####################################################################################################################################
268sub ipGet
269{
270    my $self = shift;
271
272    return $self->{strIP};
273}
274
275####################################################################################################################################
276# nameGet
277####################################################################################################################################
278sub nameGet
279{
280    my $self = shift;
281
282    return $self->{strName};
283}
284
285####################################################################################################################################
286# nameTest
287####################################################################################################################################
288sub nameTest
289{
290    my $self = shift;
291    my $strName = shift;
292
293    return $self->{strName} eq $strName;
294}
295
296####################################################################################################################################
297# userGet
298####################################################################################################################################
299sub userGet
300{
301    my $self = shift;
302
303    return $self->{strUser};
304}
305
306####################################################################################################################################
307# Getters
308####################################################################################################################################
309sub container {shift->{strContainer}}
310
3111;
312