summaryrefslogtreecommitdiff
path: root/runservices
blob: f4002ff232b8643c6892e174953976d2621a234c (plain)
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
#!/usr/bin/perl -w

################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# 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 (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################

BEGIN {
  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}

use POSIX;
use File::Temp ();
use File::Copy ();

use strict;

use Build::SimpleXML;

my $servicedir = '/usr/lib/obs/service';
my $buildroot = '';

sub ls {
  local *D;
  opendir(D, $_[0]) || return ();
  my @r = grep {$_ ne '.' && $_ ne '..'} readdir(D);
  closedir D;
  return @r;
}

sub run_services {
  my ($xml) = @_;

  my $servicexml = Build::SimpleXML::parse($xml);
  die("not a valid _service file\n") unless $servicexml && $servicexml->{'services'};
  $servicexml = $servicexml->{'services'}->[0];

  my $tempdir;
  if ($buildroot ne '') {
    $tempdir = File::Temp::tempdir('CLEANUP' => 1, 'DIR' => "$buildroot/tmp");
    die("bad tempdir\n") unless $tempdir =~ s/^\Q$buildroot\E//;
  } else {
    $tempdir = File::Temp::tempdir('CLEANUP' => 1);
  }

  # take default version setting
  for my $s (@{$servicexml->{'service'} || []}) {
    # buildtime only is default
    next unless $s->{'mode'} && $s->{'mode'} eq 'buildtime';
    die("missing name in service\n") unless $s->{'name'};

    if (! -x "$buildroot$servicedir/$s->{'name'}") {
      die("service '$s->{'name'}' configured to run, but is not available\n");
    }

    my @run;
    push @run, "$servicedir/$s->{'name'}";
    for my $param (@{$s->{'param'}}) {
      next if $param->{'name'} eq 'outdir';
      next unless $param->{'_content'};
      push @run, "--$param->{'name'}";
      push @run, $param->{'_content'};
    }
    push @run, "--outdir";
    push @run, $tempdir;
    my $pid = fork();
    die("fork: $!\n") unless defined $pid;
    if ($pid == 0) {
      if ($buildroot ne '') {
        chroot($buildroot) || die("chroot $buildroot: $!\n");
      }
      exec(@run);
      die("$run[0]: $!\n");
    }
    1 while waitpid($pid, 0) != $pid;
    die("service run failed for service '$s->{'name'}'\n") if $?;
    # copy back
    for my $file (grep {!/^[:\.]/} ls("$buildroot$tempdir")) {
      File::Copy::move("$buildroot$tempdir/$file", $file) if -f "$buildroot$tempdir/$file";
    }
  }
}

if (@ARGV > 1 && $ARGV[0] eq '--buildroot') {
  shift @ARGV;
  $buildroot = shift @ARGV;
  $buildroot = '' if $buildroot && $buildroot eq '/';
  $buildroot =~ s@//+@/@;      # or we may fail with 'bad tempdir' later. 
  die("bad buildroot\n") unless $buildroot eq '' || $buildroot =~ /^\//;
}

local *F;
open(F, '<', '_service') || die("_service: $!\n");
my $xml = '';
1 while sysread(F, $xml, 4096, length($xml)) > 0;
close F;

run_services($xml);