aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Whitaker <mageia@martin-whitaker.me.uk>2018-03-24 23:37:16 +0000
committerNeal Gompa <ngompa13@gmail.com>2018-03-30 14:06:37 -0400
commit87af55faa7a169572abd62c52df4b4aa5a43b3c3 (patch)
treeaf46dafece98599d4c004eacf03c11a07af556dc
downloadqarepo-87af55faa7a169572abd62c52df4b4aa5a43b3c3.tar
qarepo-87af55faa7a169572abd62c52df4b4aa5a43b3c3.tar.gz
qarepo-87af55faa7a169572abd62c52df4b4aa5a43b3c3.tar.bz2
qarepo-87af55faa7a169572abd62c52df4b4aa5a43b3c3.tar.xz
qarepo-87af55faa7a169572abd62c52df4b4aa5a43b3c3.zip
Initial code
-rw-r--r--qarepo.pl361
1 files changed, 361 insertions, 0 deletions
diff --git a/qarepo.pl b/qarepo.pl
new file mode 100644
index 0000000..877602c
--- /dev/null
+++ b/qarepo.pl
@@ -0,0 +1,361 @@
+#!/usr/bin/perl
+
+use strict;
+use Gtk3 '-init';
+use Glib qw(TRUE FALSE);
+use MDK::Common;
+
+my $home = $ENV{HOME} or die "ERROR: the HOME environment variable is not set.\n";
+
+my $sudo = $> ? 'sudo' : '';
+
+my %config;
+
+my $config_file = $home . '/.qareporc';
+if (open(my $f, '<', $config_file)) {
+ while (my $line = <$f>) {
+ chomp($line);
+ my ($key, $value) = split(/=/, $line);
+ $config{$key} = $value if $key;
+ }
+ close($f);
+}
+
+my $mirror = $config{MIRROR} || 'rsync://mirrors.kernel.org/mirrors/mageia';
+my $version = $config{VERSION} || '6';
+my $arch = $config{ARCH} || 'x86_64';
+my $qa_repo = $config{QA_REPO} || $home . '/qa-testing';
+
+my $qa_repo_name = 'QA Testing';
+
+my $list_url = `urpmq --list-url | grep '$qa_repo_name'`;
+chomp($list_url);
+
+my $active_qa_repo = $list_url =~ s/$qa_repo_name +//r;
+if ($list_url && $active_qa_repo ne $qa_repo) {
+ disable_repo();
+}
+my $last_version = $version;
+my $last_arch = $arch;
+
+my $window = Gtk3::Window->new('toplevel');
+
+my $grid = Gtk3::Grid->new();
+
+my $label1 = Gtk3::Label->new('Mirror:');
+my $entry1 = Gtk3::Entry->new();
+
+my $label2 = Gtk3::Label->new('Version:');
+my $entry2 = Gtk3::Entry->new();
+
+my $label3 = Gtk3::Label->new('Arch:');
+my $entry3 = Gtk3::ComboBoxText->new();
+
+my $label4 = Gtk3::Label->new('QA Repo:');
+my $entry4 = Gtk3::Entry->new();
+
+my $label5 = Gtk3::Label->new('RPMs:');
+my $entry5 = Gtk3::TextView->new();
+
+my $scroll = Gtk3::ScrolledWindow->new();
+
+my $button1 = Gtk3::Button->new('Quit');
+my $button2 = Gtk3::Button->new($active_qa_repo ? 'Disable' : 'Enable');
+my $button3 = Gtk3::Button->new('Update');
+my $button4 = Gtk3::Button->new('Clear');
+
+$window->set_title('QA Repo');
+$window->set_default_size(500, 300);
+$window->set_border_width(10);
+$window->signal_connect(delete_event => \&quit);
+
+$grid->set_row_spacing(10);
+$grid->set_column_spacing(10);
+
+$label1->set_halign('GTK_ALIGN_END');
+
+$entry1->set_text($mirror);
+$entry1->set_hexpand(TRUE);
+$entry1->signal_connect(changed => \&changed);
+
+$label2->set_halign('GTK_ALIGN_END');
+
+$entry2->set_text($version);
+$entry2->set_hexpand(FALSE);
+$entry2->signal_connect(changed => \&changed);
+
+$label3->set_halign('GTK_ALIGN_END');
+
+$entry3->append_text('i586');
+$entry3->append_text('x86_64');
+if ($arch eq 'x86_64') {
+ $entry3->set_active(1);
+} else {
+ $entry3->set_active(0);
+}
+$entry3->signal_connect(changed => \&changed);
+
+$label4->set_halign('GTK_ALIGN_END');
+
+$entry4->set_text($qa_repo);
+$entry4->set_hexpand(TRUE);
+$entry4->signal_connect(changed => \&changed);
+
+$label5->set_valign('GTK_ALIGN_START');
+$label5->set_halign('GTK_ALIGN_END');
+
+$entry5->get_buffer->set_text(join("\n", get_existing_rpms()));
+$entry5->get_buffer->signal_connect(changed => \&changed);
+
+$scroll->set_hexpand(TRUE);
+$scroll->set_vexpand(TRUE);
+
+$scroll->add($entry5);
+
+$button1->signal_connect(clicked => \&quit);
+
+$button2->signal_connect(clicked => \&enable_disable);
+
+$button3->signal_connect(clicked => \&update);
+$button3->set_valign('GTK_ALIGN_START');
+$button3->set_sensitive(FALSE);
+
+$button4->signal_connect(clicked => \&clear);
+$button4->set_valign('GTK_ALIGN_END');
+
+$grid->attach($label1, 0, 0, 1, 1);
+$grid->attach($entry1, 1, 0, 4, 1);
+$grid->attach($label2, 1, 1, 1, 1);
+$grid->attach($entry2, 2, 1, 1, 1);
+$grid->attach($label3, 3, 1, 1, 1);
+$grid->attach($entry3, 4, 1, 1, 1);
+$grid->attach($label4, 0, 2, 1, 1);
+$grid->attach($entry4, 1, 2, 4, 1);
+$grid->attach($label5, 0, 3, 1, 1);
+$grid->attach($scroll, 1, 3, 4, 2);
+
+$grid->attach($button1, 5, 0, 1, 1);
+$grid->attach($button2, 5, 2, 1, 1);
+$grid->attach($button3, 5, 3, 1, 1);
+$grid->attach($button4, 5, 4, 1, 1);
+
+$window->add($grid);
+$window->show_all;
+
+Gtk3->main;
+
+my $ignore_change;
+
+sub changed() {
+ if ($ignore_change) {
+ $ignore_change = 0;
+ } else {
+ $button3->set_sensitive(TRUE);
+ }
+}
+
+sub quit() {
+ get_settings();
+ if (open(my $f, '>', $config_file)) {
+ print $f "MIRROR=$mirror\n";
+ print $f "VERSION=$version\n";
+ print $f "ARCH=$arch\n";
+ print $f "QA_REPO=$qa_repo\n";
+ close($f);
+ }
+ Gtk3->main_quit;
+}
+
+sub enable_disable() {
+ disable_buttons();
+ if ($active_qa_repo) {
+ disable_repo();
+ } else {
+ get_settings();
+ if (sync_repo()) {
+ enable_repo();
+ }
+ }
+ enable_buttons();
+}
+
+sub update() {
+ disable_buttons();
+ get_settings();
+ if (sync_repo()) {
+ if ($active_qa_repo) {
+ update_repo();
+ } else {
+ enable_repo();
+ }
+ } else {
+ if ($active_qa_repo) {
+ disable_repo();
+ }
+ }
+ enable_buttons();
+}
+
+my $clear_pending;
+
+sub clear() {
+ disable_buttons();
+ get_settings();
+ clear_repo();
+ if ($active_qa_repo) {
+ disable_repo();
+ }
+ my $buffer = $entry5->get_buffer();
+ $ignore_change = $buffer->get_char_count() > 0;
+ $buffer->set_text("");
+ enable_buttons();
+}
+
+sub disable_buttons() {
+ $button1->set_sensitive(FALSE);
+ $button2->set_sensitive(FALSE);
+ $button3->set_sensitive(FALSE);
+ $button4->set_sensitive(FALSE);
+}
+
+sub enable_buttons() {
+ $button1->set_sensitive(TRUE);
+ $button2->set_sensitive(TRUE);
+ $button4->set_sensitive(TRUE);
+}
+
+sub get_settings() {
+ $mirror = $entry1->get_text();
+ $version = $entry2->get_text();
+ $arch = $entry3->get_active_text();
+ $qa_repo = $entry4->get_text();
+ if ($active_qa_repo && $active_qa_repo ne $qa_repo) {
+ disable_repo();
+ }
+}
+
+sub get_required_rpms() {
+ my $buffer = $entry5->get_buffer();
+ my $start = $buffer->get_start_iter();
+ my $end = $buffer->get_end_iter();
+
+ grep { $_ ne '' } split("\n", $buffer->get_text($start, $end, FALSE));
+}
+
+sub get_existing_rpms() {
+ map { basename($_) } glob("$qa_repo/*.rpm");
+}
+
+sub disable_repo() {
+ system("$sudo urpmi.removemedia '$qa_repo_name'") == 0
+ or die "ERROR: couldn't disable the $qa_repo_name media.\n";
+ $button2->set_label('Enable');
+ $active_qa_repo = '';
+}
+
+sub enable_repo() {
+ if (system("$sudo urpmi.addmedia --update '$qa_repo_name' $qa_repo") == 0) {
+ $button2->set_label('Disable');
+ $active_qa_repo = $qa_repo;
+ } else {
+ $active_qa_repo = '';
+ }
+}
+
+sub update_repo() {
+ if (system("$sudo urpmi.update '$qa_repo_name'") != 0) {
+ print "ERROR: couldn't update the $qa_repo_name media.\n";
+ disable_repo();
+ }
+}
+
+sub clear_repo() {
+ my @existing_rpms = get_existing_rpms();
+ if (@existing_rpms) {
+ unlink(map { "$qa_repo/$_" } @existing_rpms)
+ or die "ERROR: couldn't delete/unlink existing RPMs in the QA repo.\n";
+ }
+}
+
+my $sync_ok;
+
+sub sync_repo() {
+ my $sync_file;
+ if ($mirror =~ /^rsync:/) {
+ $sync_file = \&sync_file_rsync;
+ } elsif ($mirror =~ /^ftp:/ || $mirror =~ /^http:/) {
+ $sync_file = \&sync_file_aria2;
+ } elsif ($mirror !~ /^\w+:/) {
+ $sync_file = \&sync_file_link;
+ } else {
+ sync_error("unsupported mirror URL type");
+ return 0;
+ }
+
+ if ($version ne $last_version || $arch ne $last_arch) {
+ clear_repo();
+ }
+
+ my @required_rpms = get_required_rpms();
+ my @existing_rpms = get_existing_rpms();
+ my @unwanted_rpms = difference2(\@existing_rpms, \@required_rpms);
+ if (@unwanted_rpms) {
+ unlink(map { "$qa_repo/$_" } @unwanted_rpms)
+ or die "ERROR: couldn't delete/unlink unwanted RPMs in the QA repo.\n";
+ }
+ my $old_pubkey = "$qa_repo/media_info/pubkey";
+ if (-e $old_pubkey) {
+ unlink($old_pubkey)
+ or die "ERROR: couldn't delete/unlink old pubkey in the QA repo.\n";
+ }
+
+ mkdir_p("$qa_repo/media_info/");
+
+ $sync_ok = 1;
+ my $remote_repo = $mirror . '/distrib/' . $version . '/' . $arch . '/media';
+ foreach my $rpm (difference2(\@required_rpms, \@existing_rpms)) {
+ my $remote_url = $remote_repo;
+ if ($rpm =~ /tainted/) {
+ $remote_url .= '/tainted/updates_testing/' . $rpm;
+ } elsif ($rpm =~ /nonfree/) {
+ $remote_url .= '/nonfree/updates_testing/' . $rpm;
+ } else {
+ $remote_url .= '/core/updates_testing/' . $rpm;
+ }
+ &$sync_file($remote_url, $qa_repo);
+ }
+ &$sync_file($remote_repo . '/core/updates_testing/media_info/pubkey', $qa_repo . '/media_info');
+
+ if ($sync_ok) {
+ system("genhdlist2 $qa_repo") == 0
+ or sync_error("failed to update hdlist");
+ }
+
+ $sync_ok;
+}
+
+sub sync_file_rsync {
+ my ($src_url, $dst_dir) = @_;
+ print "fetching $src_url\n";
+ system("rsync -q $src_url $dst_dir") == 0
+ or sync_error("failed to download $src_url");
+}
+
+sub sync_file_aria2 {
+ my ($src_url, $dst_dir) = @_;
+ print "fetching $src_url\n";
+ system("aria2c -q -d $dst_dir $src_url") == 0
+ or sync_error("failed to download $src_url");
+}
+
+sub sync_file_link {
+ my ($src_file, $dst_dir) = @_;
+ -e $src_file && symlink($src_file, $dst_dir . '/' . basename($src_file))
+ or sync_error("failed to link $src_file");
+}
+
+sub sync_error {
+ my ($message) = @_;
+ print "ERROR: $message.\n";
+ $sync_ok = 0;
+}