File: generalhw.pm

package info (click to toggle)
os-autoinst 4.3%2Bgit20160919-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 10,860 kB
  • ctags: 665
  • sloc: perl: 7,624; cpp: 1,584; python: 216; makefile: 188; sh: 63
file content (149 lines) | stat: -rw-r--r-- 3,481 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Copyright © 2016 SUSE LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.

# this backend uses a KVM connector speaking VNC and external tools
# for serial line and power cycling

package backend::generalhw;
use strict;
use base ('backend::baseclass');
use bmwqemu qw(diag);
use testapi qw(get_required_var get_var);
use IPC::Run ();
require IPC::System::Simple;
use autodie qw(:all);
use File::Basename qw(basename);

sub new {
    my $class = shift;
    # required for the tests to access our HTTP port
    get_required_var('WORKER_HOSTNAME');
    return $class->SUPER::new;
}

sub get_cmd {
    my ($self, $cmd) = @_;

    my $dir = get_required_var('GENERAL_HW_CMD_DIR');
    if (!-d $dir) {
        die "GENERAL_HW_CMD_DIR is not pointing to a directory";
    }
    $cmd = get_required_var($cmd);
    $cmd = "$dir/" . basename($cmd);
    if (!-x $cmd) {
        die "CMD $cmd is not an executable";
    }
    return $cmd;
}

sub run_cmd {
    my ($self, $cmd) = @_;

    my ($stdin, $stdout, $stderr, $ret);
    $ret = IPC::Run::run([$self->get_cmd($cmd)], \$stdin, \$stdout, \$stderr);
    chomp $stdout;
    chomp $stderr;

    die $cmd . ": $stderr" unless ($ret);
    bmwqemu::diag("IPMI: $stdout");
    return $stdout;
}

sub poweroff_host {
    my ($self) = @_;
    $self->run_cmd('GENERAL_HW_POWEROFF_CMD');
    return;
}

sub restart_host {
    my ($self) = @_;

    $self->poweroff_host;
    sleep(3);
    $self->run_cmd('GENERAL_HW_POWERON_CMD');
    return;
}

sub relogin_vnc {
    my ($self) = @_;

    if ($self->{vnc}) {
        close($self->{vnc}->socket);
        sleep(1);
    }

    my $vnc = $testapi::distri->add_console(
        'sut',
        'vnc-base',
        {
            hostname        => get_required_var('GENERAL_HW_VNC_IP'),
            port            => 5900,
            depth           => 16,
            connect_timeout => 50
        });
    $vnc->backend($self);
    $self->select_console({testapi_console => 'sut'});

    return 1;
}

sub do_start_vm() {
    my ($self) = @_;

    # remove backend.crashed
    $self->unlink_crash_file;
    $self->restart_host;
    $self->relogin_vnc;
    $self->start_serial_grab;
    return {};
}

sub do_stop_vm {
    my ($self) = @_;

    $self->poweroff_host;
    $self->stop_serial_grab();
    return {};
}

# serial grab

sub start_serial_grab {
    my ($self) = @_;

    $self->{serialpid} = fork();
    if ($self->{serialpid} == 0) {
        setpgrp 0, 0;
        open(my $serial, '>',  $self->{serialfile});
        open(STDOUT,     ">&", $serial);
        open(STDERR,     ">&", $serial);
        exec($self->get_cmd('GENERAL_HW_SOL_CMD'));
        die "exec failed $!";
    }
    return;
}

sub stop_serial_grab {
    my ($self) = @_;
    return unless $self->{serialpid};
    kill("-TERM", $self->{serialpid});
    return waitpid($self->{serialpid}, 0);
}

# serial grab end

1;

# vim: set sw=4 et: