Rex-Repositorio

 view release on metacpan or  search on metacpan

lib/Rex/Repositorio/Repository/Apt.pm  view on Meta::CPAN

#
# (c) Jan Gehring <jan.gehring@gmail.com>
#
# vim: set ts=2 sw=2 tw=0:
# vim: set expandtab:

package Rex::Repositorio::Repository::Apt;

use Moose;
use Try::Tiny;
use File::Basename qw'basename dirname';
use Data::Dumper;
use Digest::SHA;
use Carp;
use Params::Validate qw(:all);
use File::Spec;
use IO::All;

our $VERSION = '1.2.1'; # VERSION

extends "Rex::Repositorio::Repository::Base";

sub mirror {
  my ( $self, %option ) = @_;

  $self->repo->{url} =~ s/\/$//;
  $self->repo->{local} =~ s/\/$//;
  my $name = $self->repo->{name};

  my $dist = $self->repo->{dist};

  my @archs = split /, ?/, $self->repo->{arch};

  ##############################################################################
  # get meta data
  ##############################################################################
  my $url      = $self->repo->{url} . "/dists/${dist}";
  my $contents = $self->download("$url/Release");
  my $ref      = $self->_parse_debian_release_file($contents);
  my $arch     = $self->repo->{arch};

  $self->app->logger->notice('Downloading metadata...');

  my $destbase     = $self->app->get_repo_dir(repo => $self->repo->{name});

  # try download Release and Release.gpg
  try {
    $self->download_metadata(
      url   => $url . '/Release',
      dest  => File::Spec->catfile('dists',$dist,'Release'),
      force => $option{update_metadata},
    );

    $self->app->logger->info("1/2 ${url}");

    $self->download_metadata(
      url   => $url . '/Release.gpg',
      dest  => File::Spec->catfile('dists', $dist, 'Release.gpg'),
      force => $option{update_metadata},
    );

    $self->app->logger->info("2/2 ${url}");

  }
  catch {
    $self->app->logger->info("2/2 ${url}");
    $self->app->logger->error($_);
  };


  $self->app->logger->notice('Downloading file listing...');
  my $f_count = 0;
  my $f_total = scalar( @{ $ref->{SHA1} || $ref->{SHA1Sum} } );

  for my $file_data ( @{ $ref->{SHA1} || $ref->{SHA1Sum} } ) {

    my $file_url = $url . "/" . $file_data->{file};
    my $file     = $file_data->{file};

    $f_count++;
    $self->app->logger->info("${f_count}/${f_total} ${file_url}");

    my $arch_str = join( "|", @archs );
    my $regexp   = qr{i18n|((Contents|binary|installer)\-(udeb-)?($arch_str))};
    next
      if ( $file_data->{file} !~ $regexp );

    try {
      $self->download_metadata(
        url   => $file_url,
        dest  => File::Spec->catfile('dists',$dist,$file),
        force => $option{update_metadata},
      );
    }
    catch {
      $self->app->logger->info(
        "Can't find the url: $file_url. " . "This should be no problem." );
      $self->app->logger->info($_);
    };
  }

  ##############################################################################
  # download packages
  ##############################################################################
  if ( $option{update_files} || $option{force} ) {

    my @components;
    if ( exists $self->repo->{components} ) {
      @components = split /, ?/, $self->repo->{components};
    }
    else {
      @components = ( $self->repo->{component} );
    }
    for my $component (@components) {

      my $local_components_path = File::Spec->catdir(
        $self->app->get_repo_dir( repo => $self->repo->{name} ),
        'dists',$dist,$component);

lib/Rex/Repositorio/Repository/Apt.pm  view on Meta::CPAN

  );

  my $dist      = $self->repo->{dist};
  my $component = $self->repo->{component};

  my $dest = File::Spec->catdir(
      $self->app->get_repo_dir( repo => $self->repo->{name} ),
     'pool',$dist,$component,basename( $option{file} ));

  $self->add_file_to_repo( source => $option{file}, dest => $dest );

  $self->_run_ftp_archive();
}

sub remove_file {
  my $self = shift;

  my %option = validate(
    @_,
    {
      file => {
        type => SCALAR
      },
    }
  );

  my $dist      = $self->repo->{dist};
  my $component = $self->repo->{component};

  my $file = File::Spec->catdir(
      $self->app->get_repo_dir( repo => $self->repo->{name} ),
     'pool',$dist,$component,basename( $option{file} ));

  $self->remove_file_from_repo( file => $file );

  $self->_run_ftp_archive();
}

sub _run_ftp_archive {
  my $self = shift;

  my $dist = $self->repo->{dist};
  my $repo_dir = $self->app->get_repo_dir( repo => $self->repo->{name} );

  # TODO: should probably check that apt-ftparchive exists and is executable

  system
    "cd $repo_dir ; apt-ftparchive generate -c=aptftp.conf aptgenerate.conf";

  if ( $? != 0 ) {
    confess "Error running apt-ftparchive generate";
  }

  system
    "cd $repo_dir ; apt-ftparchive release -c=aptftp.conf dists/$dist >dists/$dist/Release";

  if ( $? != 0 ) {
    confess "Error running apt-ftparchive release";
  }

  if ( exists $self->repo->{gpg} && $self->repo->{gpg}->{key} ) {
    my $key  = $self->repo->{gpg}->{key};
    my $pass = $self->repo->{gpg}->{password};
    if ( !$pass ) {
      $pass = $self->read_password("GPG key passphrase: ");
    }

    unlink "$repo_dir/dists/$dist/Release.gpg";

    my $cmd =
        "cd $repo_dir ; gpg -u $key "
      . "--batch --passphrase '"
      . $pass
      . "' -bao dists/$dist/Release.gpg dists/$dist/Release";

    system $cmd;

    if ( $? != 0 ) {
      $cmd =~ s/\Q$pass\E/\*\*\*\*\*\*\*/;
      confess "Error running gpg sign: $cmd";
    }

    # export pub key as asc file
    my $pub_file = $self->repo->{name} . ".asc";
    $cmd = "cd $repo_dir ; gpg -a --output $pub_file --export $key";
    system $cmd;

    if ( $? != 0 ) {
      confess "Error running gpg export: $cmd";
    }
  }
}

# test if all necessary parameters are available
override verify_options => sub {
  my $self = shift;
  super();

  if ( !exists $self->repo->{local} ) {
    confess "No local path (local) given for: " . $self->repo->{name};
  }

  if ( !exists $self->repo->{arch} ) {
    confess "No architecture (arch) given for: " . $self->repo->{name};
  }

  if ( !exists $self->repo->{dist} ) {
    confess "No distribution (dist) given for: " . $self->repo->{name};
  }

  if ( !exists $self->repo->{component} ) {
    confess "No component (component) given for: " . $self->repo->{name};
  }
};

1;



( run in 0.956 second using v1.01-cache-2.11-cpan-df04353d9ac )