line |
stmt |
code |
1
|
|
# Copyright 2016-2021 SUSE LLC |
2
|
|
# SPDX-License-Identifier: GPL-2.0-or-later |
3
|
|
|
4
|
|
use Mojo::Base 'backend::baseclass', -signatures; |
5
|
1
|
use autodie ':all'; |
|
1
|
|
|
1
|
|
6
|
1
|
use bmwqemu qw(diag fctwarn); |
|
1
|
|
|
1
|
|
7
|
1
|
use File::Path 'mkpath'; |
|
1
|
|
|
1
|
|
8
|
1
|
require IPC::System::Simple; |
|
1
|
|
|
1
|
|
9
|
|
use File::Basename; |
10
|
1
|
use Digest::MD5 'md5_hex'; |
|
1
|
|
|
1
|
|
11
|
1
|
use osutils qw(dd_gen_params gen_params runcmd); |
|
1
|
|
|
1
|
|
12
|
1
|
|
|
1
|
|
|
1
|
|
13
|
|
# this backend relies on NovaLink tools being around on the worker |
14
|
|
# host. It supports HDD_1 and publishing assets |
15
|
|
|
16
|
|
# the spvm backend will only support the basics, but generally through |
17
|
|
# ssh to a novalink installation (so you only need ssh and terminal on worker) |
18
|
|
|
19
|
|
# uncoverable statement |
20
|
|
|
21
|
0
|
my $self = $class->SUPER::new; |
|
0
|
|
|
0
|
|
22
|
|
$self->{pid} = undef; |
23
|
1
|
$self->{children} = []; |
|
1
|
|
|
1
|
|
24
|
1
|
$self->{pidfilename} = 'pvm.pid'; |
25
|
1
|
$self->{pvmctl} = $ENV{PVMCTL} // '/usr/bin/pvmctl'; |
26
|
1
|
$self->{masterlpar} = substr(_masterlpar, 0, -1); |
27
|
1
|
die "pvmctl not found" unless -x $self->{pvmctl}; |
28
|
1
|
backend::baseclass::handle_deprecate_backend('PVM'); |
29
|
1
|
return $self; |
30
|
1
|
} |
31
|
1
|
|
32
|
1
|
$self->start_lpar(); |
33
|
|
return {}; |
34
|
|
} |
35
|
0
|
|
|
0
|
|
|
0
|
|
36
|
0
|
my $vars = \%bmwqemu::vars; |
37
|
0
|
my $hdd_num = $args->{hdd_num}; |
38
|
|
my $name = $args->{name}; |
39
|
|
my $img_dir = $args->{dir}; |
40
|
0
|
my $format = $args->{format}; |
|
0
|
|
|
0
|
|
|
0
|
|
41
|
0
|
my $disk = $vars->{"HDD_$hdd_num"}; |
42
|
0
|
my $lpar = $self->{masterlpar}; |
43
|
0
|
my $cmd = "pvmctl scsi list -w"; |
44
|
0
|
$cmd .= " VirtualDisk.name=$disk -d VirtualDisk.udid --hide-label"; |
45
|
0
|
#attach disk |
46
|
0
|
diag "Attaching $disk to $lpar"; |
47
|
0
|
$self->pvmctl("scsi", "create", "lv", $disk, $lpar); |
48
|
0
|
|
49
|
0
|
my $prefix = "/dev/disk/by-id/scsi-SAIX_VDASD_"; |
50
|
|
my $id = qx{$cmd}; |
51
|
0
|
chomp($id); |
52
|
0
|
my $device = $prefix . substr($id, 2); |
53
|
|
|
54
|
0
|
if (!$format || $format !~ /^raw$/) { |
55
|
0
|
diag "do_extract_assets: Image will be saved as raw eitherway"; |
56
|
0
|
} |
57
|
0
|
|
58
|
|
#rescan scsi for newly attached disk |
59
|
0
|
qx{sudo rescan-scsi-bus.sh -a}; |
60
|
0
|
#wait until udev creates a link |
61
|
|
until (-l $device) { |
62
|
|
sleep 1; |
63
|
|
} |
64
|
0
|
mkpath($img_dir); |
65
|
|
runcmd("sudo", "dd", "if=$device", "of=$img_dir/$name.$format", "bs=8096", "conv=sparse"); |
66
|
0
|
|
67
|
0
|
#detach disk |
68
|
|
$self->pvmctl("scsi", "delete", "lv", $disk, $lpar); |
69
|
0
|
qx/sudo rescan-scsi-bus.sh -r/; |
70
|
0
|
} |
71
|
|
|
72
|
|
my $vars = \%bmwqemu::vars; |
73
|
0
|
|
74
|
0
|
die "pvmctl: Not enough arguments (at least you should supply a type and an action)" unless ($type && $action); |
75
|
|
|
76
|
|
push(my @cmd, $self->{pvmctl}, $type, $action); |
77
|
0
|
my $lpar = $vars->{LPAR}; |
|
0
|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
0
|
|
78
|
0
|
|
79
|
|
if ($type =~ /lpar/) { |
80
|
0
|
gen_params \@cmd, "i", "name=$lpar" if ($lpar && $action =~ /power|restart|delete/); |
81
|
|
if ($action =~ /create/) { |
82
|
0
|
my ($cpu, $memory) = @args; |
83
|
0
|
dd_gen_params \@cmd, "proc-type", "shared"; |
84
|
|
dd_gen_params \@cmd, "sharing-mode", "uncapped"; |
85
|
0
|
dd_gen_params \@cmd, "type", "AIX/Linux"; |
86
|
0
|
dd_gen_params \@cmd, "proc", $cpu if $cpu; |
87
|
0
|
dd_gen_params \@cmd, "mem", $memory if $memory; |
88
|
0
|
dd_gen_params \@cmd, "name", $lpar if $lpar; |
89
|
0
|
dd_gen_params \@cmd, "proc-unit", $cpu * 0.05 if $cpu; |
90
|
0
|
} |
91
|
0
|
} |
92
|
0
|
elsif ($type =~ /scsi/) { |
93
|
0
|
my ($kind, $file, $target) = @args; |
94
|
0
|
die "pvmctl: scsi type needs at least both kind and file" unless ($kind && $file); |
95
|
0
|
|
96
|
|
#so far only disks are reatachable to the master LPAR |
97
|
|
#set it back to default if argument is omitted |
98
|
|
$lpar = $target if $target; |
99
|
0
|
dd_gen_params \@cmd, "type", $kind; |
100
|
0
|
dd_gen_params \@cmd, "stor-id", $file; |
101
|
|
dd_gen_params \@cmd, "lpar", "name=$lpar" if $lpar; |
102
|
|
dd_gen_params \@cmd, "vg", "name=rootvg" if ($type =~ /lv/); |
103
|
|
} |
104
|
0
|
elsif ($type =~ /lv/) { |
105
|
0
|
my ($name, $size) = @args; |
106
|
0
|
dd_gen_params \@cmd, "name", $name if $name; |
107
|
0
|
dd_gen_params \@cmd, "size", $size if $size; |
108
|
0
|
} |
109
|
|
elsif ($type =~ /eth/) { |
110
|
|
my ($vlan, $vswitch) = @args; |
111
|
0
|
dd_gen_params \@cmd, "pvid", $vlan if $vlan; |
112
|
0
|
dd_gen_params \@cmd, "vswitch", $vswitch if $vswitch; |
113
|
0
|
gen_params \@cmd, "p", "name=$lpar" if $lpar; |
114
|
|
} |
115
|
|
else { |
116
|
0
|
die "Unrecognized command $type"; |
117
|
0
|
} |
118
|
0
|
runcmd(@cmd); |
119
|
0
|
} |
120
|
|
my $vncport = qx{sudo /usr/sbin/mkvtermutil --id $vars->{LPARID} --vnc --local --log serial0 2>/dev/null}; |
121
|
|
$vncport =~ /([0-9]+)/; |
122
|
0
|
chomp($vncport); |
123
|
|
$vars->{VNC} = $vncport; |
124
|
0
|
diag "VNC is $vars->{VNC}"; |
125
|
|
} |
126
|
0
|
|
|
0
|
|
|
0
|
|
127
|
0
|
#lv already exists? |
128
|
0
|
my @cmd; |
129
|
0
|
my $pvmctlcmd = "pvmctl lv list -w LogicalVolume.name=$img -d LogicalVolume.name LogicalVolume.capacity -f , --hide-label"; |
130
|
0
|
my ($name, $capacity) = split(",", qx/$pvmctlcmd/); |
131
|
0
|
return if !($name =~ /$img/); |
132
|
|
if (($img =~ /$name/) && ($size =~ /$capacity/)) { |
133
|
|
push(@cmd, "sudo viosvrcmd --id 1 -r -c \"dd if=/dev/zero bs=1024 count=1 of=/dev/r$name\""); |
134
|
0
|
} |
|
0
|
|
|
0
|
|
|
0
|
|
135
|
|
else { |
136
|
0
|
push(@cmd, "sudo viosvrcmd --id 1 -c\"rmbdsp -sp rootvg -bd $name\""); |
137
|
0
|
} |
138
|
0
|
runcmd(@cmd); |
139
|
0
|
} |
140
|
0
|
my $vars = \%bmwqemu::vars; |
141
|
0
|
#general settiings |
142
|
|
$vars->{LPAR} = "osauto" . $vars->{WORKER_ID}; |
143
|
|
$vars->{CPUS} ||= 1; |
144
|
0
|
$vars->{MEM} ||= "2048"; |
145
|
|
#disk settings |
146
|
0
|
$vars->{NUMDISKS} //= 1; |
147
|
|
$vars->{HDDSIZEGB} ||= 15; |
148
|
0
|
#network settings |
|
0
|
|
|
0
|
|
149
|
0
|
$vars->{NIC} ||= "sea"; |
150
|
|
$vars->{NICVLAN} ||= 1; |
151
|
0
|
$vars->{VSWITCH} ||= "ETHERNET0"; |
152
|
0
|
#unfortunately NovaLink can't take files longer than 38 chars. So we need to shorten ISO name here |
153
|
0
|
$vars->{VIOISO} = md5_hex(basename($vars->{ISO})) . ".iso"; |
154
|
|
my $iso = $vars->{VIOISO}; |
155
|
0
|
die "$iso exceeds 37 characters\n" if (length($iso) > 37); |
156
|
0
|
|
157
|
|
if (!($vars->{ARCH} =~ /ppc64/)) { |
158
|
0
|
die "arch $vars->{ARCH} is not allowed on pvm backend"; |
159
|
0
|
} |
160
|
0
|
#create lpar |
161
|
|
$self->pvmctl("lpar", "create", $vars->{CPUS}, $vars->{MEM}); |
162
|
0
|
|
163
|
0
|
my $id = substr(qx/pvmctl lpar list -d LogicalPartition.id --where LogicalPartition.name=$vars->{LPAR}/, 3); |
164
|
0
|
chomp($id); |
165
|
|
$vars->{LPARID} = $id; |
166
|
0
|
bmwqemu::save_vars(); |
167
|
0
|
|
168
|
|
#we copy isos from nfs mount on VIO side to VMLibrary |
169
|
|
my $source_iso = '/iso/' . basename($vars->{ISO}); |
170
|
0
|
diag "source_iso: $source_iso, vio iso: $iso"; |
171
|
|
my $iso_present = qx/pvmctl media list -d VirtualOpticalMedia.media_name --where VirtualOpticalMedia.name=$iso/; |
172
|
0
|
if ($iso_present !~ /$iso/) { |
173
|
0
|
#copy over from nfs to VMLibrary |
174
|
0
|
my @viocmd = ("sudo viosvrcmd --id 1 -r -c\"cp $source_iso /var/vio/VMLibrary/$iso\""); |
175
|
0
|
push(@viocmd, "sudo viosvrcmd --id 1 -r -c\"chown padmin:staff /var/vio/VMLibrary/$iso\""); |
176
|
|
push(@viocmd, "sudo viosvrcmd --id 1 -c\"chvopt -name $iso -access ro\""); |
177
|
|
foreach my $viocmd (@viocmd) { |
178
|
0
|
runcmd($viocmd); |
179
|
0
|
} |
180
|
0
|
} |
181
|
0
|
$self->pvmctl('scsi', 'create', 'vopt', $iso); |
182
|
|
|
183
|
0
|
for my $i (1 .. $vars->{NUMDISKS}) { |
184
|
0
|
my $name = $vars->{LPAR} . "_" . $i; |
185
|
0
|
$vars->{"HDD_$i"} = $name; |
186
|
0
|
my $size = $vars->{HDDSIZEGB}; |
187
|
0
|
$self->pvmctl("lv", "create", $name, $size) if !image_exists($name, $size); |
188
|
|
$self->pvmctl("scsi", "create", "lv", $name); |
189
|
|
} |
190
|
0
|
|
191
|
|
$self->pvmctl("eth", "create", $vars->{NICVLAN}, $vars->{VSWITCH}); |
192
|
0
|
$self->pvmctl("lpar", "power-on"); |
193
|
0
|
bmwqemu::save_vars(); |
194
|
0
|
|
195
|
0
|
attach_console; |
196
|
0
|
bmwqemu::save_vars(); |
197
|
0
|
|
198
|
|
my $vnc = $testapi::distri->add_console( |
199
|
|
'sut', |
200
|
0
|
'vnc-base', |
201
|
0
|
{ |
202
|
0
|
hostname => 'localhost', |
203
|
|
port => $vars->{VNC}, |
204
|
0
|
description => 'mkvtermutil VNC'}); |
205
|
0
|
$vnc->backend($self); |
206
|
|
$self->select_console({testapi_console => 'sut'}); |
207
|
|
} |
208
|
|
|
209
|
|
my $id = $bmwqemu::vars{LPARID}; |
210
|
|
return qx{pvmctl lpar list -i id=$id -d LogicalPartition.state --hide-label}; |
211
|
|
} |
212
|
|
|
213
|
0
|
|
214
|
0
|
my $vars = \%bmwqemu::vars; |
215
|
0
|
$self->pvmctl("lpar", "power-off") if (!$self->is_shutdown); |
216
|
|
runcmd("rmvterm", "--id", $vars->{LPARID}); |
217
|
|
for my $i (1 .. $vars->{NUMDISKS}) { |
218
|
0
|
my $disk = $vars->{LPAR} . "_" . $i; |
|
0
|
|
|
0
|
|
219
|
0
|
$self->pvmctl("scsi", "delete", "lv", $disk); |
220
|
0
|
} |
221
|
|
$self->pvmctl("scsi", "delete", "vopt", $vars->{VIOISO}); |
222
|
|
$self->pvmctl("lpar", "delete"); |
223
|
0
|
} |
|
0
|
|
|
0
|
|
|
0
|
|