Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First implementation of bs_setup #16881

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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@
Expand Down
3 changes: 3 additions & 0 deletions dist/obs-server.spec
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -885,12 +886,14 @@ 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
%{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
Expand Down
2 changes: 2 additions & 0 deletions dist/obs-setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
exec /usr/lib/obs/server/bs_setup "$@"
169 changes: 169 additions & 0 deletions src/backend/BSSetup/Base.pm
Original file line number Diff line number Diff line change
@@ -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 <<EOF;
our \$api_url='http://api-opensuse.suse.de:80';
our \$containers_root="\$bsdir/service/containers";
our \$container_image='$image';
our \$service_wrapper = {
'*' => '$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;
26 changes: 26 additions & 0 deletions src/backend/BSSetup/SUSE.pm
Original file line number Diff line number Diff line change
@@ -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;
99 changes: 99 additions & 0 deletions src/backend/bs_setup
Original file line number Diff line number Diff line change
@@ -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__