File Coverage

backend/amt.pm
Criterion Covered Total %
statement 121 121 100.0
total 121 121 100.0


line stmt code
1   # Copyright 2018-2021 SUSE LLC
2   # SPDX-License-Identifier: GPL-2.0-or-later
3    
4    
5   use Mojo::Base 'backend::baseclass', -signatures;
6 1 use autodie ':all';
  1  
  1  
7 1 use Time::HiRes qw(sleep gettimeofday);
  1  
  1  
8 1 use Data::Dumper;
  1  
  1  
9 1 require Carp;
  1  
  1  
10   use bmwqemu ();
11 1 use IPC::Run ();
  1  
  1  
12 1 require IPC::System::Simple;
  1  
  1  
13    
14   # xml namespaces
15   my $IPS = "http://intel.com/wbem/wscim/1/ips-schema/1";
16   my $CIM = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2";
17   my $AMT = "http://intel.com/wbem/wscim/1/amt-schema/1";
18   my $XSD = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd";
19   my $ADR = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
20    
21   # AMT requirements: exactly 8 chars, at least on lowecase letter, uppercase
22   # letter, digit, and special
23   my $vnc_password = 'we4kP@ss';
24    
25   defined $bmwqemu::vars{AMT_HOSTNAME} or die 'Need variable AMT_HOSTNAME';
26 1 defined $bmwqemu::vars{AMT_PASSWORD} or die 'Need variable AMT_PASSWORD';
  1  
  1  
27 1  
28 1 # use env to avoid leaking password to logs
29   $ENV{'WSMAN_USER'} = 'admin';
30   $ENV{'WSMAN_PASS'} = $bmwqemu::vars{AMT_PASSWORD};
31 1  
32 1 backend::baseclass::handle_deprecate_backend('AMT');
33   return $class->SUPER::new;
34 1 }
35 1  
36   return ('wsman', '-h', $bmwqemu::vars{AMT_HOSTNAME}, '-P', '16992');
37   }
38 18  
  18  
  18  
39 18 my @cmd = $self->wsman_cmdline();
40   push(@cmd, split(/ /, $cmd));
41    
42 17 my ($stdout, $stderr, $ret);
  17  
  17  
  17  
  17  
43 17 bmwqemu::diag("AMT cmd: @cmd");
44 17 $ret = IPC::Run::run(\@cmd, \$stdin, \$stdout, \$stderr);
45   chomp $stdout;
46 17 chomp $stderr;
47 17  
48 17 die join(' ', @cmd) . ": $stderr" unless ($ret);
49 17 bmwqemu::diag("AMT: $stdout");
50 17 return $stdout;
51   }
52 17  
53 17 # enable SOL + IDE-r
54 17 $self->wsman("invoke -a RequestStateChange $AMT/AMT_RedirectionService -k RequestedState=32771");
55   }
56    
57   # is turning it off first necessary?
58 1 #$self->wsman("invoke -a RequestStateChange $CIM/CIM_KVMRedirectionSAP -k RequestedState=3");
  1  
  1  
59 1 $self->wsman("put $IPS/IPS_KVMRedirectionSettingData -k RFBPassword=$vnc_password");
60   $self->wsman("put $IPS/IPS_KVMRedirectionSettingData -k Is5900PortEnabled=true");
61   $self->wsman("put $IPS/IPS_KVMRedirectionSettingData -k OptInPolicy=false");
62 1 $self->wsman("put $IPS/IPS_KVMRedirectionSettingData -k SessionTimeout=0");
  1  
  1  
63   $self->wsman("invoke -a RequestStateChange $CIM/CIM_KVMRedirectionSAP -k RequestedState=2");
64   }
65 1  
66 1 my $stdout = $self->wsman("get $CIM/CIM_AssociatedPowerManagementService");
67 1  
68 1 return ($stdout =~ m/:PowerState>(\d+)</)[0];
69 1 }
70    
71   my $cmd_stdin = "
72 2 <p:RequestPowerStateChange_INPUT xmlns:p=\"$CIM/CIM_PowerManagementService\">
  2  
  2  
73 2 <p:PowerState>$power_state</p:PowerState>
74   <p:ManagedElement>
75 2 <a:Address xmlns:a=\"$ADR\">$ADR/role/anonymous</a:Address>
76   <r:ReferenceParameters xmlns:r=\"$ADR\">
77   <u:ResourceURI xmlns:u=\"$XSD\">$CIM/CIM_ComputerSystem</u:ResourceURI>
78 3 <s:SelectorSet xmlns:s=\"$XSD\">
  3  
  3  
  3  
79 3 <s:Selector Name=\"Name\">ManagedSystem</s:Selector>
80   </s:SelectorSet>
81   </r:ReferenceParameters>
82   </p:ManagedElement>
83   </p:RequestPowerStateChange_INPUT>
84   ";
85   my $stdout = $self->wsman("-J - invoke -a RequestPowerStateChange $CIM/CIM_PowerManagementService", $cmd_stdin);
86    
87   return ($stdout =~ m/:ReturnValue>(\d+)</);
88   }
89    
90   my $amt_bootdev = 'Intel(r) AMT: Force ' . ({
91   cddvd => 'CD/DVD Boot',
92   hdd => 'Hard-drive Boot',
93 3 pxe => 'PXE Boot',
94   }->{$bootdev} or die "Unsupported boot device $bootdev");
95 3  
96   # reset boot configuration to known state
97   my $keys = "-k BIOSPause=false -k BootMediaIndex=0";
98 2 $keys = "$keys -k ConfigurationDataReset=false -k FirmwareVerbosity=0 ";
  2  
  2  
  2  
99   $keys = "$keys -k ForcedProgressEvents=false -k LockKeyboard=false ";
100   $keys = "$keys -k LockPowerButton=false -k LockResetButton=false ";
101   $keys = "$keys -k LockSleepButton=false -k ReflashBIOS=false";
102   $keys = "$keys -k UseSafeMode=false -k UserPasswordBypass=false";
103 2 $keys = "$keys -k IDERBootDevice=0 -k UseIDER=false -k UseSOL=false";
104   $keys = "$keys -k BIOSSetup=false";
105   $self->wsman("put $AMT/AMT_BootSettingData $keys");
106 2  
107 2 # set requested boot device
108 2 my $cmd_stdin = "
109 2 <p:ChangeBootOrder_INPUT xmlns:p=\"$CIM/CIM_BootConfigSetting\">
110 2 <p:Source>
111 2 <a:Address xmlns:a=\"$ADR\">$ADR/role/anonymous</a:Address>
112 2 <r:ReferenceParameters xmlns:r=\"$ADR\">
113 2 <u:ResourceURI xmlns:u=\"$XSD\">$CIM/CIM_BootSourceSetting</u:ResourceURI>
114 2 <s:SelectorSet xmlns:s=\"$XSD\">
115   <s:Selector Name=\"InstanceID\">$amt_bootdev</s:Selector>
116   </s:SelectorSet>
117 2 </r:ReferenceParameters>
118   </p:Source>
119   </p:ChangeBootOrder_INPUT>";
120    
121   my $stdout = $self->wsman("-J - invoke -a ChangeBootOrder $CIM/CIM_BootConfigSetting", $cmd_stdin);
122    
123   # TODO: setting idercd/iderfd/sol/bios/idersolcd/idersolfd/biossol require
124   # one more call to AMT_BootSettingData here
125    
126   if (!($stdout =~ m/:ReturnValue>0</)) {
127   die "ChangeBootOrder failed";
128   }
129    
130 2 $cmd_stdin = "
131   <p:SetBootConfigRole_INPUT xmlns:p=\"$CIM/CIM_BootService\">
132   <p:BootConfigSetting>
133   <a:Address xmlns:a=\"$ADR\">$ADR/role/anonymous</a:Address>
134   <r:ReferenceParameters xmlns:r=\"$ADR\">
135 2 <u:ResourceURI xmlns:u=\"$XSD\">$CIM/CIM_BootConfigSetting</u:ResourceURI>
136 1 <s:SelectorSet xmlns:s=\"$XSD\">
137   <s:Selector Name=\"InstanceID\">Intel(r) AMT: Boot Configuration 0</s:Selector>
138   </s:SelectorSet>
139 1 </r:ReferenceParameters>
140   </p:BootConfigSetting>
141   <p:Role>1</p:Role>
142   </p:SetBootConfigRole_INPUT>";
143    
144   $stdout = $self->wsman("-J - invoke -a SetBootConfigRole $CIM/CIM_BootService", $cmd_stdin);
145   die 'SetBootConfigRole failed' unless $stdout =~ m/:ReturnValue>0</;
146   }
147    
148   $self->set_power_state($self->is_shutdown() ? 2 : 5);
149   }
150    
151   $self->select_next_boot('pxe');
152   $self->restart_host;
153 1 sleep(5);
154 1 $self->truncate_serial_file;
155   my $sol = $testapi::distri->add_console('sol', 'amt-sol');
156   $sol->backend($self);
157 1  
  1  
  1  
158 1 my $vnc = $testapi::distri->add_console(
159   'sut',
160   'vnc-base',
161 1 {
  1  
  1  
162 1 hostname => $bmwqemu::vars{AMT_HOSTNAME},
163 1 password => $vnc_password,
164 1 connect_timeout => 3,
165 1 port => 5900
166 1 });
167 1  
168   $vnc->backend($self);
169   try {
170   local $SIG{__DIE__} = undef;
171   $self->select_console({testapi_console => 'sut'});
172   }
173   return {};
174 1 }
175    
176   # need to terminate both VNC and console first, otherwise AMT will refuse
177   # to shutdown
178   $self->deactivate_console({testapi_console => 'sol'});
179 1 $self->deactivate_console({testapi_console => 'sut'});
180 1 $self->set_power_state(8);
181 1 return {};
182 1 }
183    
184   my $ret = $self->get_power_state();
185   return $ret == 8;
186   }
187 1  
  1  
  1  
188   1;