From 9a351c23f15a46de4817acca3bddadd78165f6a9 Mon Sep 17 00:00:00 2001 From: Frank Schreiner Date: Fri, 20 Sep 2024 13:36:52 +0200 Subject: [PATCH 1/2] [backend] initial version of bs_setup --- dist/obs-server.spec | 2 + src/backend/BSSetup/Base.pm | 169 ++++++++++++++++++++++++++++++++++++ src/backend/BSSetup/SUSE.pm | 26 ++++++ src/backend/bs_setup | 99 +++++++++++++++++++++ 4 files changed, 296 insertions(+) create mode 100755 src/backend/BSSetup/Base.pm create mode 100644 src/backend/BSSetup/SUSE.pm create mode 100755 src/backend/bs_setup diff --git a/dist/obs-server.spec b/dist/obs-server.spec index 1f4f674f05a..a31d53ffd96 100644 --- a/dist/obs-server.spec +++ b/dist/obs-server.spec @@ -861,6 +861,7 @@ fi %{_unitdir}/obsnotifyforward.service %{_unitdir}/obsredis.service /usr/sbin/obs_admin +/usr/sbin/obs-setup /usr/sbin/obs_serverstatus /usr/sbin/obsscheduler %if 0%{?suse_version} @@ -891,6 +892,7 @@ fi %{obs_backend_dir}/License %{obs_backend_dir}/README %{obs_backend_dir}/bs_admin +%{obs_backend_dir}/bs_setup %{obs_backend_dir}/bs_cleanup %{obs_backend_dir}/bs_archivereq %{obs_backend_dir}/bs_check_consistency diff --git a/src/backend/BSSetup/Base.pm b/src/backend/BSSetup/Base.pm new file mode 100755 index 00000000000..cafb50d0953 --- /dev/null +++ b/src/backend/BSSetup/Base.pm @@ -0,0 +1,169 @@ +package BSSetup::Base; + +use strict; +use warnings; + +our ($FATAL, $ERROR, $WARN, $INFO, $DEBUG, $TRACE) = (qw/1 2 3 4 5 6/); + +sub new { + my ($class, @opts) = @_; + bless {@opts}, $class; +} + +sub hostname { $_[0]->{hostname} || '' } + +sub print_log { + my ($self, $loglevel, @msgs) = @_; + return if (($loglevel||1) < $main::LOGLEVEL); + print "$_\n" for @msgs; +} + +sub execute_cmd { + my ($self, $cmd, $fatal) = @_; + my @out = `$cmd`; + if ($?) { + my $rc = $? >> 8; + if ($fatal) { + die "Command '$cmd' failed($rc): @out\n"; + } else { + warn "Command '$cmd' failed($rc): @out\n"; + } + } + + return @out; +} + +sub prepare_mounts_conf { + my ($self, @opts) = @_; + my @remove_from_mounts; + my $mounts_conf = '/etc/containers/mounts.conf'; + $self->print_log($DEBUG, "Starting prepare_mounts_conf\n"); + if (-f $mounts_conf) { + $self->print_log($DEBUG, "Found file $mounts_conf\n"); + for my $path (qw{/etc/SUSEConnect /etc/zypp/credentials.d/SCCcredentials}) { + push @remove_from_mounts, $path unless -f $path; + } + + my $tmp = join '|', @remove_from_mounts; + my $re = qr{^($tmp)$}; + my $content; + + # Comment out non existant files in /etc/containers/mounts.conf + if (open my $fh, '+<', $mounts_conf) { + while (my $line = <$fh>) { + $line =~ s/$re/# $1 ## --- disabled by `obs_admin --service-container setup`/; + $content .= $line; + } + seek $fh, 0, 0; + truncate $fh, 0; + print $fh $content || die "Could not write to $mounts_conf: $!\n"; + close $fh || die "Could not close to $mounts_conf: $!\n"; + } else { + warn "Could not open $mounts_conf: $!\n"; + } + } else { + $self->print_log($DEBUG, "No such file $mounts_conf\n"); + } + + return 1; +} + +sub prepare_storage_conf { + my ($self, @opts) = @_; + $self->print_log($DEBUG, "Starting prepare_storage_conf\n"); + my $storage_conf = '/etc/containers/storage.conf'; + if (open my $fh, '+<', $storage_conf) { + $self->print_log($DEBUG, "Reconfigure $storage_conf\n"); + local $/ = undef; + my $content = <$fh>; + my $re = qr#additionalimagestores\s*=\s*\[([^\]]*)\]#; + if ($content =~ $re) { + my $cdir = "$BSConfig::bsdir/service/containers"; + my $val = $1; + if ($val !~ /$cdir/) { + my $repl = "additionalimagestores = [\n '$cdir'".( $val ? ",\n $val" : q{})."]"; + $content =~ s/$re/$repl/smx; + seek $fh, 0, 0; + truncate $fh, 0; + print $fh $content || die "Could not write to $storage_conf: $!\n"; + } + } + close $fh || die "Could not close to $storage_conf: $!\n"; + } else { + warn "Could not open $storage_conf: $!\n"; + } + + return 1; +} + +sub configure_bsserviceuser { + my ($self, $user, @opts) = @_; + my $cmd; + my @out; + + $cmd = "id -u $user"; + @out = `$cmd`; + if ($?) { + my $rc = $? >> 8; + die "Command '$cmd' failed($rc): @out\n"; + } + $cmd = "loginctl enable-linger $out[0]"; + @out = `$cmd`; + + # Configure system settings for obsservicerun _before_ installing container + # containment rpm to make sure that import to image store works properly + $cmd = "usermod -v 200000-265535 -w 200000-265535 $user"; + @out = `$cmd`; + warn "Command '$cmd' failed:\n@out" if $?; + return 1; +} + +sub libdir { + my ($self, $libdir) = @_; + $self->{_libdir} = $libdir if defined $libdir; + return $self->{_libdir} if exists $self->{_libdir}; + $self->{_libdir} = __FILE__; + $self->{_libdir} =~ s#/[^/]+/[^/]+$##; + return $self->{_libdir}; +} + +sub generate_bsconfig { + my ($self) = @_; + # Settings for package BSConfig + my $hostname = $self->hostname; + my $image = 'localhost/obs-source-service-podman:latest'; + my $bs_config = "/usr/lib/obs/server/bsconfig.$hostname"; + my $libdir = $self->libdir; + if (open my $fh, '>>', $bs_config) { + print $fh < '$libdir/call-service-in-container', +}; + +1; +EOF + close $fh || die "Could not close $bs_config: $!\n"; + } else { + die "Could not open $bs_config: $!\n"; + } + return 1; +} + +sub restart_bs_service { + my ($self) = @_; + $self->print_log($DEBUG, "Restarting bs_service\n"); + my $libdir = $self->libdir; + my @cmd = ("$libdir/bs_service", '--restart'); + system(@cmd); + if ($?) { + $self->print_log($WARN, "Failed system call '@cmd'\n"); + return 0; + } + $self->print_log($DEBUG, "System call '@cmd' succeed\n"); + return 1; +} + +1; diff --git a/src/backend/BSSetup/SUSE.pm b/src/backend/BSSetup/SUSE.pm new file mode 100644 index 00000000000..ed4ba05f427 --- /dev/null +++ b/src/backend/BSSetup/SUSE.pm @@ -0,0 +1,26 @@ +package BSSetup::SUSE; + +use base 'BSSetup::Base'; + +sub install_pkg { + my ($self, @pkgs) = @_; + + for my $pkg (@pkgs) { + $self->print_log($DEBUG, "Checking if package $pkg is installed"); + my $rpm = `rpm -q $pkg`; + if (!$? && $rpm) { + chomp $rpm; + $self->print_log($DEBUG, "Installed package $rpm found"); + } else { + #local $/ = undef; + $self->print_log($DEBUG, "Package $pkg not found. Installing...\n"); + my $cmd = "zypper -n install $pkg"; + my $out = `$cmd`; + die "Command '$cmd' failed:\n$out" if $?; + } + } + + return 1 +} + +1; diff --git a/src/backend/bs_setup b/src/backend/bs_setup new file mode 100755 index 00000000000..5acb7a6eed7 --- /dev/null +++ b/src/backend/bs_setup @@ -0,0 +1,99 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Net::Domain; + +BEGIN { + my ($wd) = $0 =~ m-(.*)/- ; + $wd ||= '.'; + unshift @INC, "$wd/build"; + unshift @INC, "$wd"; +} + + +use BSConfig; +no warnings 'once'; +my $hostname=Net::Domain::hostfqdn || ''; +use warnings 'all'; + +$::LOGLEVEL=0; + +my $distro = get_distro(); +my $distro_obj; +if ($distro =~ /suse/) { + print "Using distro family SUSE" if $::LOGLEVEL; + require BSSetup::SUSE; + BSSetup::SUSE->import; + $distro_obj = BSSetup::SUSE->new(hostname=>$hostname); +} else { + die "Operating system not implemented yet!"; +} + +my @args = @ARGV; + +my %global_options = ( + '--debug' => sub { $::LOGLEVEL = 1; }, +); + +my %commands = ( + 'service-containers' => \&setup_service_containers, + 'sc' => \&setup_service_containers, +); + +for my $opt (@args) { + if (ref($global_options{$opt}) eq 'CODE') { + shift @args; + $global_options{$opt}->(); + } else { + die "Unknown option: $opt\n" unless $commands{$opt}; + print "End of global options\n" if $::LOGLEVEL; + } +} + +my $cmd_count=0; + +for my $cmd (@args) { + my $cmd_ref = $commands{$cmd}; + if (ref($cmd_ref) eq 'CODE') { + $cmd_count++; + shift @args; + die "Command $cmd failed!" unless $cmd_ref->(@args); + } else { + die "Unknown command: $cmd\n"; + } +} + +die "No command executed!\n" unless $cmd_count; + +exit 0; + +############################################################################### +sub get_distro { + return `. /etc/os-release;echo \$ID`; +} + +sub setup_service_containers { + my @opts = @_; + print "Starting setup of service containers\n" if $::LOGLEVEL; + + my @remove_from_mounts; + + # First install podman, which includes /etc/containers/storage.conf + # Before installing any container containment rpm we need to set the + # `additionalimagestores` in /etc/containers/storage.conf + $distro_obj->install_pkg('podman'); + + + # Prepare data required for modifing /etc/containers/mounts.conf if file exists + # e.g. on SLE + $distro_obj->prepare_mounts_conf(); + + $distro_obj->prepare_storage_conf(); + $distro_obj->configure_bsserviceuser($BSConfig::bsserviceuser); + $distro_obj->install_pkg('obs-source-service-podman-image'); + $distro_obj->generate_bsconfig(); + $distro_obj->restart_bs_service(); +} + +__END__ From e350ff79119aef687b406a4e4efb51682b1197ac Mon Sep 17 00:00:00 2001 From: Frank Schreiner Date: Tue, 24 Sep 2024 10:00:05 +0200 Subject: [PATCH 2/2] [dist] add obs-setup script --- dist/Makefile | 2 +- dist/obs-server.spec | 1 + dist/obs-setup | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 dist/obs-setup diff --git a/dist/Makefile b/dist/Makefile index 56efb7b98e9..610a20a54a8 100644 --- a/dist/Makefile +++ b/dist/Makefile @@ -3,7 +3,7 @@ include ../Makefile.include LOGROTATE_CONFIGS := obs-api obs-server obs-source_service OBS_BIN_SCRIPTS := obs_productconvert -OBS_SBIN_SCRIPTS := obs_admin obs_serverstatus obsscheduler obsworker obsstoragesetup +OBS_SBIN_SCRIPTS := obs_admin obs_serverstatus obsscheduler obsworker obsstoragesetup obs-setup SYSTEMD_TARGET_FILES := obs-api-support SYSTEMD_SERVICE_FILES := obs-clockwork obs-delayedjob-queue-project_log_rotate obs-delayedjob-queue-consistency_check obs-delayedjob-queue-default obs-delayedjob-queue-releasetracking obs-delayedjob-queue-issuetracking obs-delayedjob-queue-mailers obs-delayedjob-queue-staging obs-delayedjob-queue-scm obs-sphinx obsdeltastore obsdispatcher obsdodup obswarden obssrcserver obsrepserver obspublisher obssigner obsservice obsservicedispatch obssourcepublish obsgetbinariesproxy obsclouduploadserver obsclouduploadworker obsscheduler obsworker obsstoragesetup obsapisetup obsnotifyforward obsredis SYSTEMD_SERVICE_FILES_WITHOUT_LINK := obs-delayedjob-queue-quick@ diff --git a/dist/obs-server.spec b/dist/obs-server.spec index a31d53ffd96..955b29a556f 100644 --- a/dist/obs-server.spec +++ b/dist/obs-server.spec @@ -886,6 +886,7 @@ fi %{obs_backend_dir}/BSSched %{obs_backend_dir}/BSSrcServer %{obs_backend_dir}/BSPublisher +%{obs_backend_dir}/BSSetup %{obs_backend_dir}/*.pm %{obs_backend_dir}/BSConfig.pm.template %{obs_backend_dir}/DESIGN diff --git a/dist/obs-setup b/dist/obs-setup new file mode 100644 index 00000000000..fa95f6511c3 --- /dev/null +++ b/dist/obs-setup @@ -0,0 +1,2 @@ +#!/bin/bash +exec /usr/lib/obs/server/bs_setup "$@"