Skip to content

Commit

Permalink
qemu: Automatically create swtpm device
Browse files Browse the repository at this point in the history
- Create device if QEMUTPM is set
- Recommend swtpm packages
- Add swtpm test deps

See: https://progress.opensuse.org/issues/101015
  • Loading branch information
kalikiana committed Nov 15, 2021
1 parent 195774f commit 15851c2
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 17 deletions.
44 changes: 28 additions & 16 deletions backend/qemu.pm
Expand Up @@ -512,6 +512,33 @@ sub qemu_params_ofw ($self) {
return 1;
}

sub setup_tpm ($self, $arch) {
my $vars = \%bmwqemu::vars;
return unless ($vars->{QEMUTPM});
my $tpmn = $vars->{QEMUTPM} eq 'instance' ? $vars->{WORKER_INSTANCE} : $vars->{QEMUTPM};
my $vmpath = "/tmp/mytpm$tpmn";
mkdir $vmpath unless -d $vmpath;
my $vmsock = "$vmpath/swtpm-sock";
unless (-e $vmsock) {
my @args = ('swtpm', 'socket', '--tpmstate', "dir=$vmpath", '--ctrl', "type=unixio,path=$vmsock", '--log', 'level=20', '-d');
push @args, '--tpm2' if (($vars->{QEMUTPM_VER} // '2.0') == '2.0');
runcmd(@args);
}
sp('chardev', "socket,id=chrtpm,path=$vmsock");
sp('tpmdev', 'emulator,id=tpm0,chardev=chrtpm');
if ($arch eq 'aarch64') {
sp('device', 'tpm-tis-device,tpmdev=tpm0');
}
elsif ($arch eq 'ppc64le') {
sp('device', 'tpm-spapr,tpmdev=tpm0');
sp('device', 'spapr-vscsi,id=scsi9,reg=0x00002000');
}
else {
# x86_64
sp('device', 'tpm-tis,tpmdev=tpm0');
}
}

sub start_qemu ($self) {
my $vars = \%bmwqemu::vars;

Expand Down Expand Up @@ -803,22 +830,7 @@ sub start_qemu ($self) {
sp('append', "dhcp && sanhook iscsi:$vars->{WORKER_HOSTNAME}::3260:1:$vars->{NBF}", no_quotes => 1);
}

if ($vars->{QEMUTPM}) {
my $tpmn = $vars->{QEMUTPM} eq 'instance' ? $vars->{WORKER_INSTANCE} : $vars->{QEMUTPM};
sp('chardev', "socket,id=chrtpm,path=/tmp/mytpm$tpmn/swtpm-sock");
sp('tpmdev', 'emulator,id=tpm0,chardev=chrtpm');
if ($arch eq 'aarch64') {
sp('device', 'tpm-tis-device,tpmdev=tpm0');
}
elsif ($arch eq 'ppc64le') {
sp('device', 'tpm-spapr,tpmdev=tpm0');
sp('device', 'spapr-vscsi,id=scsi9,reg=0x00002000');
}
else {
# x86_64
sp('device', 'tpm-tis,tpmdev=tpm0');
}
}
$self->setup_tpm($arch);

my @boot_args;
# Enable boot menu for aarch64 workaround, see bsc#1022064 for details
Expand Down
10 changes: 10 additions & 0 deletions dist/rpm/os-autoinst.spec
Expand Up @@ -28,6 +28,7 @@ Source0: %{name}-%{version}.tar.xz
%if 0%{?suse_version} > 1500
# openSUSE Tumbleweed
%define opencv_require pkgconfig(opencv4)
BuildRequires: swtpm
%else
%define opencv_require pkgconfig(opencv)
%endif
Expand Down Expand Up @@ -143,6 +144,15 @@ Requires: qemu-tools
Convenience package providing os-autoinst and qemu-x86 dependencies.
%endif

%package swtpm
Summary: Convenience package providing os-autoinst+swtpm
Group: Development/Tools/Other
Requires: os-autoinst
Requires: swtpm

%description swtpm
Convenience package providing os-autoinst and swtpm dependencies.

%package s390-deps
Summary: Convenience package providing os-autoinst + s390 worker jumphost deps
Group: Development/Tools/Other
Expand Down
3 changes: 2 additions & 1 deletion doc/backend_vars.asciidoc
Expand Up @@ -122,7 +122,8 @@ QEMUMACHINE;see qemu -machine ?;undef;Machine and chipset to emulate
QEMUPORT;integer;20002 + worker instance * 10;Port on which QEMU monitor should listen
QEMURAM;integer;1024;Size of RAM of VM in MiB
QEMUTHREADS;integer;0;Number of cpu threads used by VM
QEMUTPM;'instance' or appropriate value for local swtpm config;undef;Configure VM to use a TPM emulator device, with appropriate args for the arch. sysadmin is responsible for running swtpm with a socket at /tmp/mytpmX, where X is the value of QEMUTPM or the worker instance number if QEMUTPM is set to 'instance'
QEMUTPM;'instance' or appropriate value for local swtpm config;undef;Configure VM to use a TPM emulator device, with appropriate args for the arch. If a TPM device is available at /tmp/mytpmX, where X is the value of QEMUTPM or the worker instance number if QEMUTPM is set to 'instance', it will be used. Otherwise it will be created at test startup. See QEMUTPM_VER in the latter case.
QEMUTPM_VER;'1.2' or '2.0' depending on which TPM chip should be emulated;'2.0';If no TPM device has been setup otherwise, swtpm will be used internally to create one with a socket at /tmp/mytpmX
QEMUVGA;see qemu -device ?;cirrus;VGA device to use with VM
QEMU_COMPRESS_QCOW2;boolean;1;compress qcow2 images intended for upload
QEMU_IMG_CREATE_TRIES;integer;3;Define number of tries for qemu-img commands
Expand Down
16 changes: 16 additions & 0 deletions t/18-qemu-options.t
Expand Up @@ -112,12 +112,16 @@ subtest qemu_huge_pages_option => sub {
# of QEMU here.
subtest qemu_tpm_option => sub {
# call isotovideo with QEMUTPM=instance
mkdir('/tmp/mytpm3');
path('/tmp/mytpm3/swtpm-sock')->touch;
run_isotovideo(QEMU_ONLY_EXEC => 1, QEMUTPM => 'instance');
like($log, qr|-chardev socket,id=chrtpm,path=/tmp/mytpm3/swtpm-sock|, '-chardev socket option added (instance)');
like($log, qr|-tpmdev emulator,id=tpm0,chardev=chrtpm|, '-tpmdev emulator option added');
like($log, qr|-device tpm-tis,tpmdev=tpm0|, '-device tpm-tis option added');

# call isotovideo with QEMUTPM=2
mkdir('/tmp/mytpm2');
path('/tmp/mytpm2/swtpm-sock')->touch;
run_isotovideo(QEMU_ONLY_EXEC => 1, QEMUTPM => '2');
like($log, qr|-chardev socket,id=chrtpm,path=/tmp/mytpm2/swtpm-sock|, '-chardev socket option added (2)');

Expand All @@ -133,6 +137,18 @@ subtest qemu_tpm_option => sub {
like($log, qr|-chardev socket,id=chrtpm,path=/tmp/mytpm3/swtpm-sock|, '-chardev socket option added (instance)');
like($log, qr/-tpmdev emulator,id=tpm0,chardev=chrtpm/, '-tpmdev emulator option added');
like($log, qr/-device tpm-tis-device,tpmdev=tpm0/, '-device tpm-tis option added');

# call isotovideo with QEMUTPM=4 w/o creating a device beforehand
run_isotovideo(QEMU_ONLY_EXEC => 1, QEMUTPM => '4');
like($log, qr|swtpm socket --tpmstate dir=/tmp/mytpm4 --ctrl type=unixio,path=/tmp/mytpm4/swtpm-sock --log level=20 -d --tpm2|, 'swtpm default device created');

# call isotovideo with QEMUTPM=5, QEMUTPM_VER=2.0 w/o creating a device beforehand
run_isotovideo(QEMU_ONLY_EXEC => 1, QEMUTPM => '5', QEMUTPM_VER => '2.0');
like($log, qr|swtpm socket --tpmstate dir=/tmp/mytpm5 --ctrl type=unixio,path=/tmp/mytpm5/swtpm-sock --log level=20 -d --tpm2|, 'swtpm 2.0 device created');

# call isotovideo with QEMUTPM=6, QEMU_TPM_VER=1.2 w/o creating a device beforehand
run_isotovideo(QEMU_ONLY_EXEC => 1, QEMUTPM => '6', QEMUTPM_VER => '1.2');
like($log, qr|swtpm socket --tpmstate dir=/tmp/mytpm6 --ctrl type=unixio,path=/tmp/mytpm6/swtpm-sock --log level=20 -d|, 'swtpm 1.2 device created');
};

done_testing();

0 comments on commit 15851c2

Please sign in to comment.