1 package Fedora
::Rebuild
::Repository
;
4 use version
0.77; our $VERSION = version
->declare("v0.10.0");
13 use HTTP
::Status
qw(:constants :is status_message);
14 use Fedora
::Rebuild
::Execute
;
17 # Directory where the repository exists
18 has
'path' => ( is
=> 'ro', isa
=> 'Str', required
=> 1);
21 has
'pid' => ( is
=> 'rw', isa
=> 'Int', lazy
=> 1, init_arg
=> undef,
23 has
'url' => ( is
=> 'rw', isa
=> 'Maybe[Str]', lazy
=> 1, init_arg
=> undef,
26 around BUILDARGS
=> sub {
31 if (! defined $attrs{'path'} || $attrs{'path'} eq '') {
32 croak
"Path must be a non-empty string";
35 $attrs{'path'} = File
::Spec
->rel2abs($attrs{'path'});
36 if (! -d
$attrs{'path'}) {
37 File
::Path
::make_path
($attrs{'path'}) or
38 croak
("Could not create repository directory `". $attrs{'path'} .
42 return $class->$orig(%attrs);
45 # Make object shared between threads to prevent killing daemon by DEMOLISH
46 # from scheduler threads.
47 # XXX: No attributes are shared automatically.
51 return shared_clone
($class->$orig(@_));
54 # Kill the server process on object desctruction
59 # Insert binary RPM files built from the package, the argument, into
60 # repository. It will not update the YUM metatada. You need to update the
61 # reporitoty explicitly.
64 my ($self, $package) = @_;
65 for my $file ($package->listbinaryrpmfiles) {
66 my ($volume, $prefix, $file_name) = File
::Spec
->splitpath($file);
67 my $link = File
::Spec
->catfile($self->path, $file_name);
68 my $target = File
::Spec
->abs2rel($file, $self->path);
69 if (-l
$link or -e
$link) {
70 unlink $link or croak
("Could not remove old `" . $link .
73 if (!symlink($target, $link)) {
74 croak
("Could not insert RPM file `" . $file . "' of package `" .
75 $package->name . "' into `" . $self->path . "': $!\n");
81 # Update the repository.
82 # This updates YUM metadata.
85 print "Updating YUM repository of already rebuilt packages...\n";
86 if (!Fedora
::Rebuild
::Execute
->new->do(
87 $self->path, 'createrepo', '--update', '.')) {
88 croak
("Could not update repository.\n");
90 print "Repository updated successufully.\n";
95 # Start to serve the repository over HTTP.
96 # Return URL. undef in case of error.
100 if ($self->pid && kill(0, $self->pid)) {
101 # Server is already running
108 my $server = HTTP
::Daemon
->new( 'LocalAddr' => 'localhost' );
109 if (!defined($server)) {
113 if (!defined $daemon) {
117 } elsif ($daemon == 0) {
119 $self->run_daemon($server);
124 $self->url($server->url);
130 # Stop serving the repository
135 waitpid($self->pid, 0);
143 my ($self, $server) = @_;
144 if (! defined $server) { return -1; }
148 if (defined $connection) {
153 $connection = $server->accept;
154 my $request = $connection->get_request;
155 $connection->force_last_request;
157 if (! defined $request) {
158 print STDERR
"repository server: Bad request\n";
161 if ($request->method eq 'GET') {
162 my $rpath = $request->uri;
163 if ($rpath =~ m
|\
.\
./|) {
164 $connection->send_error(HTTP_FORBIDDEN
,
165 "Parent directories are fobidden");
169 $connection->send_file_response(
170 File
::Spec
->catfile($self->path, $rpath));
172 $connection->send_error(HTTP_NOT_IMPLEMENTED
,
173 "Only GET method is supported");