Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
systemsmanagement:Uyuni:Master
spacewalk-setup
spacewalk-setup-git-0.7bafd50.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File spacewalk-setup-git-0.7bafd50.obscpio of Package spacewalk-setup
07070100000000000041FD0000000000000000000000076615495400000000000000000000000000000000000000000000001000000000spacewalk-setup07070100000001000081B40000000000000000000000016615495400000073000000000000000000000000000000000000001800000000spacewalk-setup/ChangesRevision history for Spacewalk-Setup 0.01 Date/time First version, released on an unsuspecting world. 07070100000002000081B400000000000000000000000166154954000046AC000000000000000000000000000000000000001800000000spacewalk-setup/LICENSE GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. 07070100000003000081B4000000000000000000000001661549540000009A000000000000000000000000000000000000001900000000spacewalk-setup/MANIFESTChanges MANIFEST META.yml # Will be created by "make dist" Makefile.PL README lib/Spacewalk/Setup.pm t/00-load.t t/boilerplate.t t/pod-coverage.t t/pod.t 07070100000004000081B400000000000000000000000166154954000003E9000000000000000000000000000000000000001C00000000spacewalk-setup/Makefile.PLuse strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Spacewalk::Setup', AUTHOR => 'Devan Goodwin <dgoodwin@redhat.com>', VERSION_FROM => 'lib/Spacewalk/Setup.pm', ABSTRACT_FROM => 'lib/Spacewalk/Setup.pm', PL_FILES => {}, EXE_FILES => ['bin/spacewalk-setup', 'bin/spacewalk-make-mount-points', 'bin/spacewalk-setup-cobbler', 'bin/spacewalk-setup-httpd'], PREREQ_PM => { 'Test::More' => 0, }, MAN1PODS => { 'lib/Spacewalk/Setup.pm' => '$(INST_MAN1DIR)/spacewalk-setup.$(MAN1EXT)', }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Spacewalk-Setup-*' }, ); package MY; sub tools_other { my $self = shift; my $ret = $self->SUPER::tools_other(@_); $ret =~ s/^(FIXIN\b.+)$/## $1\nFIXIN = \$(PERLRUN) -e 1/m; return $ret; } 07070100000005000081B40000000000000000000000016615495400000338000000000000000000000000000000000000002000000000spacewalk-setup/Makefile.pythonTHIS_MAKEFILE := $(realpath $(lastword $(MAKEFILE_LIST))) CURRENT_DIR := $(dir $(THIS_MAKEFILE)) include $(CURRENT_DIR)../../rel-eng/Makefile.python # Docker tests variables DOCKER_CONTAINER_BASE = uyuni-master DOCKER_REGISTRY = registry.mgr.suse.de DOCKER_RUN_EXPORT = "PYTHONPATH=$PYTHONPATH" DOCKER_VOLUMES = -v "$(CURDIR)/../../:/manager" __pylint :: $(call update_pip_env) pylint --rcfile=pylintrc $(shell find -name '*.py') > reports/pylint.log || true docker_pylint :: docker run --rm -e $(DOCKER_RUN_EXPORT) $(DOCKER_VOLUMES) $(DOCKER_REGISTRY)/$(DOCKER_CONTAINER_BASE)-pgsql /bin/sh -c "cd /manager/spacewalk/setup; make -f Makefile.python __pylint" docker_shell :: docker run -t -i --rm -e $(DOCKER_RUN_EXPORT) $(DOCKER_VOLUMES) $(DOCKER_REGISTRY)/$(DOCKER_CONTAINER_BASE)-pgsql /bin/bash 07070100000006000081B40000000000000000000000016615495400000553000000000000000000000000000000000000001700000000spacewalk-setup/READMESpacewalk-Setup The README is used to introduce the module and provide instructions on how to install the module, any machine dependencies it may have (for example C compilers and installed libraries) and any other information that should be provided before the module is installed. A README file is required for CPAN modules since CPAN extracts the README file from a module distribution so that people browsing the archive can use it get an idea of the modules uses. It is usually a good idea to provide version information here so that people can decide whether fixes for the module are worth downloading. INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. perldoc Spacewalk::Setup You can also look for information at: Search CPAN http://search.cpan.org/dist/Spacewalk-Setup CPAN Request Tracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Spacewalk-Setup AnnoCPAN, annotated CPAN documentation: http://annocpan.org/dist/Spacewalk-Setup CPAN Ratings: http://cpanratings.perl.org/d/Spacewalk-Setup COPYRIGHT AND LICENCE Copyright (C) 2008 Devan Goodwin This program is free software licensed under GPLv2. 07070100000007000081B4000000000000000000000001661549540000015D000000000000000000000000000000000000001C00000000spacewalk-setup/answers.txtadmin-email = root@localhost ssl-set-org = Example Org ssl-set-org-unit = Some Dept. ssl-set-city = Brno ssl-set-state = CZ ssl-set-country = CZ ssl-password = x ssl-set-email = root@localhost ssl-config-sslvhost = Y db-backend=postgresql db-user=foo db-password=bar db-name=service_name.world db-host=hostname.of.your.db db-port=5432 enable-tftp=N 07070100000008000041FD0000000000000000000000026615495400000000000000000000000000000000000000000000001400000000spacewalk-setup/bin07070100000009000081FD0000000000000000000000016615495400000B6C000000000000000000000000000000000000003000000000spacewalk-setup/bin/spacewalk-make-mount-points#!/usr/bin/perl # Given a list of directories (for example, /var/satellite) # check if they exist and if they do not exist, create them # with apache as owner. Also run restorecon on them, and # if they are nfs_t mounted, set spacewalk_nfs_mountpoint boolean. use strict; use warnings FATAL => 'all'; use Spacewalk::Setup (); my %dirs; @dirs{@ARGV} = (); # Add both potential Apache group IDs (SUSE/RHEL) my $apache_uid = (getpwnam('wwwrun') // "") . (getpwnam('apache') // ""); if ($apache_uid eq "" ) { die "Failed to retrieve uid of user apache, the user does not seem to exist.\n"; } my $seen_nfs = 0; for my $dir (sort { length $a <=> length $b } keys %dirs) { if (not -e $dir) { my @parts = grep { $_ ne '' } split /\//, $dir; my $path = ''; for my $p (@parts) { $path .= "/$p"; if (not -e $path) { mkdir $path, 0755 or die "Error creating directory [$path]: $!\n"; } } } chown $apache_uid, -1, $dir or die "Error chowning dir [$dir] to [wwwrun]: $!\n"; my @paths = $dir; if (-l $paths[0]) { # if the path is a symlink, we will try to restorecon # the target as well push @paths, "$paths[0]/."; } if (Spacewalk::Setup::have_selinux()) { for my $path (@paths) { my $type = `ls -d -Z -- $path`; if (defined $type and $type =~ /^.+?:.+?:(.+?)(:|\s)/ and $1 eq 'nfs_t') { $seen_nfs = 1; } else { if (Spacewalk::Setup::have_selinux()) { system('/sbin/restorecon', '-r', $path); } } } } } if ($seen_nfs and Spacewalk::Setup::have_selinux()) { system('/usr/sbin/setsebool', '-P', 'spacewalk_nfs_mountpoint', 1); system('/usr/sbin/setsebool', '-P', 'cobbler_use_nfs', 1); } exit 0; =pod =head1 NAME spacewalk-make-mount-points - prepare directories for Spacewalk =head1 SYNOPSIS spacewalk-make-mount-points [DIR1 [DIR2 ...]] =head1 DESCRIPTION Given a list of directories (for example, /var/satellite) this script will check if directories exist and if they do not exist, create them with apache as owner. Also run restorecon on them, and if they are nfs_t mounted, set spacewalk_nfs_mountpoint boolean. This script is not intended to be run directly by human. spacewalk-setup use this script internally. =head1 SEE ALSO spacewalk-setup(8) =head1 COPYRIGHT AND LICENSE Copyright (c) 2011--2015 Red Hat, Inc. Released under GNU General Public License, version 2 (GPLv2). =cut 0707010000000A000081FD00000000000000000000000166154954000087E3000000000000000000000000000000000000002400000000spacewalk-setup/bin/spacewalk-setup#!/usr/bin/perl # # Copyright (c) 2010--2022 SUSE LLC # Copyright (c) 2008--2017 Red Hat, Inc. # # This software is licensed to you under the GNU General Public License, # version 2 (GPLv2). There is NO WARRANTY for this software, express or # implied, including the implied warranties of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 # along with this software; if not, see # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. # # Red Hat trademarks are not licensed under GPLv2. No permission is # granted to use or replicate Red Hat trademarks that are incorporated # in this software or its documentation. use strict; use warnings; use English; use Params::Validate qw(validate); Params::Validate::validation_options(strip_leading => "-"); use Mail::RFC822::Address (); use File::Spec (); use File::Copy; use DBI (); use Digest::SHA qw/sha256_hex/; use Time::Piece; use Sys::Hostname (); use Spacewalk::Setup (); use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC); use IO::Socket (); use RHN::DB (); use MIME::Base64; my $DEBUG; $DEBUG = 0; # force autoflush on stdout write $|++; use constant DEFAULT_CA_CERT_NAME => 'RHN-ORG-TRUSTED-SSL-CERT'; use constant COBBLER_COMMAND => 'spacewalk-setup-cobbler'; my %opts = Spacewalk::Setup::parse_options(); my %answers = (); $answers{'db-backend'} = 'postgresql'; # the only supported currently my @skip = (); push @skip, Spacewalk::Setup::EMBEDDED_DB_ANSWERS if not Spacewalk::Setup::is_embedded_db(\%opts); Spacewalk::Setup::load_answer_file(\%opts, \%answers, \@skip); my $product_name = $answers{'product_name'} || 'Spacewalk'; my $hn = `/bin/hostname -f`; chomp($hn); $hn = Sys::Hostname::hostname if(!defined $hn || $hn eq ""); $answers{hostname} ||= "$hn"; if (not $opts{"skip-fqdn-test"} and not (lc($answers{hostname}) eq $answers{hostname})) { print Spacewalk::Setup::loc( "ERROR: Hostname '$answers{hostname}' of this server contains uppercase letters. It can cause Proxy communications to fail.\n"); exit 4; } if (not defined $opts{"clear-db"} and defined $answers{"clear-db"} and $answers{"clear-db"} =~ /Y/i){ $opts{'clear-db'} = 1; } $opts{"skip-db-install"} = 1 if $opts{"clear-db"}; # Skip the logfile init, normally just used when called from install.pl, # which already did this. if (not $opts{"skip-logfile-init"}) { Spacewalk::Setup::init_log_files($product_name, @ARGV); } if (Spacewalk::Setup::have_selinux()) { print Spacewalk::Setup::loc("* Setting up SELinux..\n"); Spacewalk::Setup::system_or_exit(['/usr/sbin/spacewalk-selinux-enable', ''], 42, 'Could not enable selinux policy.'); } if ($opts{"run-cobbler"}) { print Spacewalk::Setup::loc("* Setting up Cobbler..\n"); setup_cobbler(\%opts, \%answers); exit 0; } my %rhnOptions = (); if (-e Spacewalk::Setup::DEFAULT_RHN_CONF_LOCATION) { Spacewalk::Setup::read_config(Spacewalk::Setup::DEFAULT_RHN_CONF_LOCATION, \%rhnOptions); } setup_cc(\%opts, \%answers); setup_default_proxy(\%answers); Spacewalk::Setup::postgresql_setup_db(\%opts, \%answers); if ($opts{'db-only'}) { exit; } remove_old_jvm(\%opts, \%answers); remove_tomcat_cache(\%opts); setup_services(); setup_admin_email(\%opts, \%answers, \%rhnOptions); if(not $opts{"skip-initial-configuration"}) { print Spacewalk::Setup::loc("* Performing initial configuration.\n"); my $config_opts = populate_initial_configs(\%opts, \%answers); mkdir_mount_points($config_opts->{'mount_point'}, $config_opts->{'mount_point'} . '/packages', $config_opts->{'mount_point'} . '/systems', $config_opts->{'kickstart_mount_point'}); chmod 0775, $config_opts->{'mount_point'} . '/systems'; # Check for both potential Apache groups (SUSE/RHEL) my $www_gid = getgrnam(`grep -hsoP "(?<=Group ).*" /etc/httpd/conf/*.conf /etc/apache2/*.conf | tr -d '\n'`); chown -1, $www_gid, $config_opts->{'mount_point'} . '/systems'; } print Spacewalk::Setup::loc("* Configuring apache SSL virtual host.\n"); setup_mod_ssl(\%opts, \%answers); print Spacewalk::Setup::loc("* Creating SSL certificates.\n"); setup_ssl_certs(\%opts, \%answers); if(not $opts{"skip-reportdb-setup"}) { Spacewalk::Setup::postgresql_reportdb_setup(\%opts, \%answers); print Spacewalk::Setup::loc("* Report DB Configured. \n"); } if(not $opts{"skip-db-population"}) { print Spacewalk::Setup::loc("* Update configuration in database.\n"); final_db_config(\%opts, \%answers); } print Spacewalk::Setup::loc("* Setting up Cobbler..\n"); setup_cobbler(\%opts, \%answers); print Spacewalk::Setup::loc("* Deploying configuration files.\n"); populate_final_configs(\%opts, \%answers); if ($opts{'upgrade'}) { Spacewalk::Setup::postgresql_start() if (Spacewalk::Setup::is_embedded_db(\%opts)); print Spacewalk::Setup::loc("This portion of the $product_name upgrade process has successfully completed.\n"); if ($product_name =~ /Satellite/) { print Spacewalk::Setup::loc("Please refer to appropriate upgrade document in /etc/sysconfig/rhn/satellite-upgrade\n"); print Spacewalk::Setup::loc("for any remaining steps in the process.\n"); } } else { if (!$opts{'skip-services-restart'}){ print Spacewalk::Setup::loc("* Restarting services.\n"); Spacewalk::Setup::system_or_exit(['/usr/sbin/spacewalk-service', 'restart'], 40, 'Could not restart spacewalk services.'); wait_for_tomcat() or exit 56; } print Spacewalk::Setup::loc("Installation complete.\n"); print Spacewalk::Setup::loc("Visit https://%s to create the $product_name administrator account.\n", $answers{hostname}); } exit 0; sub remove_old_jvm { my $opts = shift; my $answers = shift; return unless (($opts{"upgrade"}) and ($product_name =~ /Satellite/)); my $jvm_list = Spacewalk::Setup::SHARED_DIR . "/old-jvm-list"; local *F; open F, $jvm_list or die "Error opening [$jvm_list]: $!\n"; my @jvms = <F>; close F; chomp @jvms; my $remove; foreach my $jvm (@jvms) { system("rpm -q $jvm >& /dev/null"); $remove .= " $jvm" unless $? >> 8; } if ($remove) { print Spacewalk::Setup::loc("Setup found following old java packages:\n"); foreach my $p (split (" ", $remove)) { print Spacewalk::Setup::loc("\t$p\n"); } } else { return; } Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Should setup remove these packages", -test => sub { my $text = shift; return $text =~ /^[YyNn]/ }, -answer => \$answers->{"remove-old-jvm"}, -default => 'Y', ); unless ( $answers->{"remove-old-jvm"} =~ /^[Yy]/ ) { print Spacewalk::Setup::loc("** Skipping removal of old java packages.\n"); return; } my $result = `rpm -e $remove 2>&1`; if ($? >> 8) { print Spacewalk::Setup::loc("** Error occurred while removing the packages:\n"); print Spacewalk::Setup::loc($result); } } sub remove_tomcat_cache { my $opts = shift; return unless ($opts->{'upgrade'}); my @dirs = glob "/var/cache/tomcat?/work"; if (scalar @dirs > 0) { system("rm -rf /var/cache/tomcat?/work/* > /dev/null 2>&1"); } } sub setup_cobbler { my $opts = shift; my $answers = shift; my %options = (); Spacewalk::Setup::read_config('/usr/share/rhn/config-defaults/rhn.conf',\%options); system(COBBLER_COMMAND . " --apache2-config-directory " . $options{'httpd_config_dir'} . " -f " . $answers->{'hostname'}); my $skip_rhnconf = 0; open(FILE, "<" . Spacewalk::Setup::DEFAULT_RHN_CONF_LOCATION); while (<FILE>) { if ($_ =~ /^cobbler\.host/) { $skip_rhnconf = 1; last; } } close(FILE); if (!$skip_rhnconf) { open(FILE, ">>" . Spacewalk::Setup::DEFAULT_RHN_CONF_LOCATION); print FILE "#cobbler host name\n"; print FILE "cobbler.host = localhost \n"; close(FILE); } if ( system("ps -A | grep cobblerd") == 0 ) { system("cobbler mkloaders"); system("cobbler sync"); } Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Cobbler requires tftp and xinetd services be turned on for PXE provisioning functionality. Enable these services", -test => sub { my $text = shift; return $text =~ /^[YyNn]/ }, -answer => \$answers->{"enable-tftp"}, -default => 'Y', ); if ($opts{'enable-tftp'}) { $answers{'enable-tftp'} = $opts{'enable-tftp'}; } if (($answers{'enable-tftp'} and $answers{'enable-tftp'} =~ /^[Yy]/) || $opts{"non-interactive"}) { if (-e '/usr/lib/systemd/system/tftp.socket') { system("systemctl --quiet enable tftp.socket 2>&1"); system("systemctl start tftp.socket 2>&1"); } else { if (-e '/usr/lib/systemd/system/atftpd.socket') { system("systemctl --quiet enable atftpd.socket 2>&1"); system("systemctl start atftpd.socket 2>&1"); } else { system("systemctl --quiet enable atftpd.service 2>&1"); system("systemctl start atftpd.service 2>&1"); } } } } sub setup_admin_email { my $opts = shift; my $answers = shift; my $rhnoptions = shift; if ($rhnoptions->{'traceback_mail'}) { $answers->{'admin-email'} = $rhnoptions->{'traceback_mail'}; } else { Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Admin Email Address", -test => sub { my $text = shift; valid_multiple_email($text) && length($text) <= 128 }, -answer => \$answers{'admin-email'}); } } sub setup_default_proxy { my $answers = shift; my %proxyOptions = (); if(! -e Spacewalk::Setup::DEFAULT_PROXY_CONF_LOCATION) { return; } Spacewalk::Setup::read_config(Spacewalk::Setup::DEFAULT_PROXY_CONF_LOCATION, \%proxyOptions); $proxyOptions{'PROXY_ENABLED'} =~ s/^[\s"]*//; $proxyOptions{'PROXY_ENABLED'} =~ s/[\s"]*$//; if (lc($proxyOptions{PROXY_ENABLED}) ne "yes") { return; } if ($proxyOptions{'HTTP_PROXY'} =~ /https?:\/\/([^\/"]+)\/?/) { $answers{'rhn-http-proxy'} = $1 if not defined $answers{'rhn-http-proxy'}; } if (! -e Spacewalk::Setup::DEFAULT_PROXYAUTH_CONF_LOCATION) { return; } open(RC, "< ".Spacewalk::Setup::DEFAULT_PROXYAUTH_CONF_LOCATION) and do { while(<RC>) { if($_ =~ /^[\s-]+proxy-user\s*=?\s*"([^:]+:.+)"\s*$/&& defined $1 && $1 ne "") { my $creds = $1; $creds =~ s/\\"/"/g; my ($user, $pass) = split(/:/, $creds, 2); $answers{'rhn-http-proxy-username'} = $user if not defined $answers{'rhn-http-proxy-username'}; $answers{'rhn-http-proxy-password'} = $pass if not defined $answers{'rhn-http-proxy-password'}; last; } } }; } sub setup_cc { my $opts = shift; my $answers = shift; if (! $opts{"scc"}) { # no customer center connection wanted $answers{'setup-scc'} = 'N'; return; } $opts{disconnected} = 1; $answers{'setup-scc'} = 'Y'; Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "SCC Organization Credential Username", -test => sub { my $text = shift; return $text =~ /\S+/ && length($text) <= 128 }, -answer => \$answers{'scc-user'}); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "SCC Organization Credential Password", -test => sub { my $text = shift; return $text =~ /\S+/ && length($text) <= 128 }, -answer => \$answers{'scc-pass'}, -password => 1); } sub passwords_match { my $password_1 = shift; my $password_2 = shift; if ($password_1 eq $password_2) { return 1; } print Spacewalk::Setup::loc("Passwords did not match, please try again.\n"); return 0; } sub valid_ssl_cert_password { my $password = shift; my $ret; if (not $password) { print Spacewalk::Setup::loc("You must enter a password.\n"); return 0; } if ($password =~ /([\t\r\n\f\013&+%\'\`\\\"=\#)])/) { $ret = $1; } if ($ret) { print Spacewalk::Setup::loc("Invalid character: '%s'.\n", $ret); return 0; } return 1; } sub valid_cert_countries { my $answers = shift; my $dbh = Spacewalk::Setup::get_dbh($answers); my $sth = $dbh->prepare(<<EOQ); SELECT VC.code AS CODE, VC.short_name AS NAME FROM valid_countries VC ORDER BY VC.short_name EOQ $sth->execute; my ($by_code, $by_name); while (my ($code, $name) = $sth->fetchrow) { $by_code->{$code} = $name; $by_name->{$name} = $code; } $sth->finish(); $dbh->disconnect(); return ($by_code, $by_name); } sub default_cert_expiration { my $dt = Time::Piece->localtime; my $dt2 = Time::Piece->strptime("2038-01-18", "%Y-%m-%d"); my $diff = $dt2 - $dt; return int($diff->years) - 1; } sub setup_mod_ssl { my $opts = shift; my $answers = shift; if ($opts{"skip-ssl-vhost-setup"}) { print Spacewalk::Setup::loc("** Skipping SSL virtual host configuration.\n"); return; } Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Should setup configure apache's default ssl server for you (saves original ssl.conf)", -test => sub { my $text = shift; return $text =~ /^[YyNn]/ }, -answer => \$answers->{"ssl-config-sslvhost"}, -default => 'Y', ); unless ( $answers->{"ssl-config-sslvhost"} =~ /^[Yy]/ ) { print Spacewalk::Setup::loc("** Skipping SSL virtual host configuration.\n"); return; } my $no_ssl_arg = ($answers->{"no-ssl"} && $answers->{"no-ssl"} =~ /^[Yy]/) ? ' --no-ssl' : ''; system(split / /, "/usr/bin/spacewalk-setup-httpd$no_ssl_arg"); } sub setup_ssl_certs { my $opts = shift; my $answers = shift; if ($opts{"skip-ssl-cert-generation"} || $opts{"upgrade"}) { print Spacewalk::Setup::loc("** Skipping SSL certificate generation.\n"); return; } Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Do you want to import exising certificates?", -test => sub { my $text = shift; return $text =~ /^[YyNn]/ }, -answer => \$answers->{"ssl-use-existing-certs"}, -default => 'N', ); my $use_own_certs = $answers->{'ssl-use-existing-certs'} && $answers->{'ssl-use-existing-certs'} =~ /^[Yy]/; if (!$use_own_certs) { my ($password_1, $password_2); unless ($answers->{"ssl-password"}) { unless ($opts{"skip-ssl-ca-generation"}) { do { ($password_1, $password_2) = (undef, undef); # clear previous passwords Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "CA certificate password", -test => \&valid_ssl_cert_password, -answer => \$password_1, -password => 1, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Re-enter CA certificate password", -test => \&valid_ssl_cert_password, -answer => \$password_2, -password => 1, ); } until (passwords_match($password_1, $password_2)); } else { do { $password_1 = undef; Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "CA certificate password", -test => \&valid_ssl_cert_password, -answer => \$password_1, -password => 1, ); } until (check_ca_key($password_1)==0); } $answers->{"ssl-password"} ||= $password_1; }; Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Cname alias of the machine (comma separated)", -test => sub { my $text = shift; return length($text) <= 128 }, -answer => \$answers->{"ssl-set-cnames"}, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Organization", -test => sub { my $text = shift; return $text =~ /\S/ && length($text) <= 128 }, -answer => \$answers->{"ssl-set-org"}, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Organization Unit", -test => sub { my $text = shift; return $text =~ /\S/ && length($text) <= 128 }, -default => $answers->{'hostname'}, -answer => \$answers->{"ssl-set-org-unit"}, ); $answers->{"ssl-set-common-name"} ||= $answers->{hostname}; Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => 'Email Address', -test => sub { my $text = shift; valid_multiple_email($text) && length($text) <= 128 }, -default => $answers->{'admin-email'}, -answer => \$answers->{'ssl-set-email'}, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => 'City', -test => sub { my $text = shift; $text =~ /\S+/ && length($text) < 128 }, -answer => \$answers->{'ssl-set-city'}, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => 'State', -test => sub { my $text = shift; length($text) > 0 && length($text) < 128 }, -answer => \$answers->{'ssl-set-state'}, ); my ($by_code, $by_name) = valid_cert_countries($answers); while (not $answers->{'ssl-set-country'} or not (exists $by_code->{$answers->{'ssl-set-country'}} or exists $by_name->{$answers->{'ssl-set-country'}})) { Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => 'Country code (Examples: "US", "JP", "IN", or type "?" to see a list)', -test => sub { my $text = shift; exists $by_code->{$text} or exists $by_name->{$text} or $text eq '?' }, -answer => \$answers->{'ssl-set-country'}, ); if ($answers->{'ssl-set-country'} eq '?') { print_country_list($by_name); $answers->{'ssl-set-country'} = ""; } } if (my $code = $by_name->{$answers->{'ssl-set-country'}}) { $answers->{'ssl-set-country'} = $code; } $answers->{'ssl-ca-cert-expiration'} ||= default_cert_expiration(); $answers->{'ssl-server-cert-expiration'} ||= default_cert_expiration(); } else { Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Path to CA Certificate", -test => sub { my $text = shift; length($text) > 0 && -r $text && -s $text }, -answer => \$answers->{"ssl-ca-cert"}, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Path to Server Certificate", -test => sub { my $text = shift; length($text) > 0 && -r $text && -s $text }, -answer => \$answers->{"ssl-server-cert"}, ); Spacewalk::Setup::ask( -noninteractive => $opts{"non-interactive"}, -question => "Path to Server Key", -test => sub { my $text = shift; length($text) > 0 && -r $text && -s $text }, -answer => \$answers->{"ssl-server-key"}, ); } my @hostname_parts = split(/\./, $answers->{hostname}); my $system_name; if (scalar @hostname_parts > 2) { $system_name = join('.', splice(@hostname_parts, 0, -2)); } else { $system_name = join('.', @hostname_parts); } $answers->{'ssl-dir'} ||= '/root/ssl-build'; unless ($opts->{"skip-ssl-ca-generation"} || $use_own_certs) { print Spacewalk::Setup::loc("** SSL: Generating CA certificate.\n"); generate_ca_cert(-dir => $answers->{'ssl-dir'}, -password => $answers->{'ssl-password'}, '-set-country' => $answers->{'ssl-set-country'}, '-set-state' => $answers->{'ssl-set-state'}, '-set-city' => $answers->{'ssl-set-city'}, '-set-org' => $answers->{'ssl-set-org'}, '-set-org-unit' => $answers->{'ssl-set-org-unit'}, '-set-common-name' => $answers->{'ssl-set-common-name'}, '-cert-expiration' => $answers->{'ssl-ca-cert-expiration'}, ); $answers->{'ssl-ca-cert'} = File::Spec->catfile($answers->{'ssl-dir'}, "RHN-ORG-TRUSTED-SSL-CERT"); } else { if (! $use_own_certs) { $answers->{'ssl-ca-cert'} = File::Spec->catfile($answers->{'ssl-dir'}, "RHN-ORG-TRUSTED-SSL-CERT"); } my @osImageOpts = ("--ca-cert-full-path=$answers->{'ssl-ca-cert'}"); Spacewalk::Setup::system_or_exit(['/usr/sbin/mgr-package-rpm-certificate-osimage', @osImageOpts], 35, 'Could not import CA certificate.'); Spacewalk::Setup::system_or_exit(['/usr/sbin/mgr-package-rpm-certificate-osimage', '--target-os', 'SLE11', @osImageOpts], 35, 'Could not import CA certificate.'); } if (!$use_own_certs) { print Spacewalk::Setup::loc("** SSL: Generating server certificate.\n"); generate_server_cert(-dir => $answers->{'ssl-dir'}, -password => $answers->{'ssl-password'}, '-set-country' => $answers->{'ssl-set-country'}, '-set-state' => $answers->{'ssl-set-state'}, '-set-city' => $answers->{'ssl-set-city'}, '-set-org' => $answers->{'ssl-set-org'}, '-set-org-unit' => $answers->{'ssl-set-org-unit'}, '-cert-expiration' => $answers->{'ssl-server-cert-expiration'}, '-set-email' => $answers->{'ssl-set-email'}, '-set-hostname' => $answers->{'hostname'}, '-set-cnames' => $answers->{'ssl-set-cnames'}, ); $answers->{"ssl-server-cert"} = File::Spec->catfile($answers->{'ssl-dir'}, $system_name, "server.crt"); $answers->{"ssl-server-key"} = File::Spec->catfile($answers->{'ssl-dir'}, $system_name, "server.key"); } my @opts = ("--root-ca-file=$answers->{'ssl-ca-cert'}", "--server-cert-file=$answers->{'ssl-server-cert'}", "--server-key-file=$answers->{'ssl-server-key'}"); Spacewalk::Setup::system_or_exit(['/usr/bin/mgr-ssl-cert-setup', @opts], 37, "Could not deploy the certificates."); } sub print_country_list { my $by_name = shift; foreach my $name (sort keys %{$by_name}) { printf("%s\t%s\n", $by_name->{$name}, $name); } return } sub generate_ca_cert { my %params = validate(@_, { dir => 1, password => 1, 'set-country' => 1, 'set-state' => 1, 'set-city' => 1, 'set-org' => 1, 'set-org-unit' => 1, 'set-common-name' => 0, 'cert-expiration' => 1, # In years }); $params{'cert-expiration'} *= 365; my @opts = ( "--gen-ca", "--force", "--no-rpm" ); foreach my $name (keys %params) { next unless ($params{$name}); push @opts, qq(--$name=$params{$name}); } my @osImageOpts = ( "--ca-cert-full-path=$params{dir}/" . DEFAULT_CA_CERT_NAME); Spacewalk::Setup::system_or_exit(['/usr/bin/rhn-ssl-tool', @opts], 35, 'Could not generate CA certificate.'); Spacewalk::Setup::system_or_exit(['/usr/sbin/mgr-package-rpm-certificate-osimage', @osImageOpts], 35, 'Could not generate CA certificate.'); Spacewalk::Setup::system_or_exit(['/usr/sbin/mgr-package-rpm-certificate-osimage', '--target-os', 'SLE11', @osImageOpts], 35, 'Could not import CA certificate.'); return; } sub generate_server_cert { my %params = validate(@_, { dir => 1, password => 1, 'set-country' => 1, 'set-state' => 1, 'set-city' => 1, 'set-org' => 1, 'set-org-unit' => 1, 'cert-expiration' => 1, 'set-email' => 1, 'set-hostname' => 1, 'set-cnames' => 0, }); $params{'cert-expiration'} *= 365; my @opts = ("--gen-server", "--no-rpm"); foreach my $name (keys %params) { next unless ($params{$name}); if ($name eq "set-cnames") { foreach my $alias (split(/\s*,\s*/, $params{$name})) { chomp($alias); next if length($alias) <= 0; push @opts, qq(--set-cname=$alias); } } else { push @opts, qq(--$name=$params{$name}); } } Spacewalk::Setup::system_or_exit(['/usr/bin/rhn-ssl-tool', @opts], 36, 'Could not generate server certificate.'); return; } sub populate_initial_configs { my $opts = shift; my $answers = shift; # TODO: This may need to be addressed. Can query this for postgresql with # "show client_encoding;": my $charset = 'UTF8'; # Define some db specific settings: Spacewalk::Setup::set_hibernate_conf($answers); # Set the document root depending on OS. my $DOC_ROOT = $Spacewalk::Setup::DEFAULT_DOC_ROOT; $DOC_ROOT = $Spacewalk::Setup::SUSE_DOC_ROOT if(is_suse_like()); my %config_opts = ( mount_point => $answers->{'mount-point'} || '/var/spacewalk', kickstart_mount_point => $answers->{'kickstart-mount-point'} || $answers->{'mount-point'} || '/var/spacewalk', serverDOTsatelliteDOThttp_proxy => ($opts->{'rhn-http-proxy'} ? $opts->{'rhn-http-proxy'} : $answers->{'rhn-http-proxy'}) || '', serverDOTsatelliteDOThttp_proxy_username => ($opts->{'rhn-http-proxy'} ? $opts->{'rhn-http-proxy-username'} : $answers->{'rhn-http-proxy-username'}) || '', serverDOTsatelliteDOThttp_proxy_password => ($opts->{'rhn-http-proxy'} ? $opts->{'rhn-http-proxy-password'} :$answers->{'rhn-http-proxy-password'}) || '', javaDOThostname => $answers->{hostname}, encrypted_passwords => 1, db_backend => $answers->{'db-backend'}, db_user => $answers->{'db-user'}, db_password => $answers->{'db-password'}, db_name => $answers->{'db-name'}, db_host => $answers->{'db-host'}, db_port => $answers->{'db-port'}, db_ssl_enabled => $answers->{'db-ssl-enabled'}, externaldb => $answers->{'externaldb'}, externaldb_admin_user => $answers->{'externaldb-admin-user'}, externaldb_admin_password => $answers->{'externaldb-admin-password'}, db_sslrootcert => $answers->{'db-ca-cert'}, hibernate_dialect => $answers->{'hibernate.dialect'}, hibernate_driver => $answers->{'hibernate.connection.driver_class'}, hibernate_driver_proto => $answers->{'hibernate.connection.driver_proto'}, traceback_mail => $answers->{'admin-email'}, serverDOTnls_lang => 'english.' . $charset, server_secret_key => generate_secret(), cobblerDOThost => 'localhost', report_db_backend => $answers->{'db-backend'}, report_db_user => $answers->{'report-db-user'}, report_db_password => $answers->{'report-db-password'}, report_db_name => $answers->{'report-db-name'}, report_db_host => $answers->{'report-db-host'}, report_db_port => $answers->{'report-db-port'}, report_db_ssl_enabled => $answers->{'report-db-ssl-enabled'}, report_db_sslrootcert => $answers->{'report-db-ca-cert'}, ); for ($config_opts{'db_password'}) { s/\\/\\\\/g if defined $_; } my %rhnopt = (); if ($answers->{disconnected} || $opts->{disconnected}) { $rhnopt{'disconnected'} = "1"; } for my $key (qw/product_name web.version enable_nvrea web.subscribe_proxy_channel force_package_upload web.l10n_resourcebundles web.default_mail_from/) { if (defined($answers->{$key})) { $rhnopt{$key} = $answers->{$key}; } } if ($answers->{'setup-scc'} && $answers->{'setup-scc'} =~ /^[Yy]/) { my %mgrDefaults = (); if (-e Spacewalk::Setup::DEFAULT_SUSEMANAGER_CONF) { Spacewalk::Setup::read_config(Spacewalk::Setup::DEFAULT_SUSEMANAGER_CONF, \%mgrDefaults); } $mgrDefaults{'scc_url'} = Spacewalk::Setup::DEFAULT_SCC_URL if (not $mgrDefaults{'scc_url'}); my $sccpasswdenc = encode_base64($answers->{'scc-pass'}); chomp($sccpasswdenc); # encode_base64 add \n at the end # SCC - write to DB my $st = sprintf("insert into suseCredentials (id, user_id, type, username, password, url) values (sequence_nextval('suse_credentials_id_seq'), NULL, 'scc', '%s', '%s', '%s');", $answers->{'scc-user'}, $sccpasswdenc, $mgrDefaults{'scc_url'}); Spacewalk::Setup::system_or_exit(["/bin/bash", "-c", "echo \"$st\" | spacewalk-sql --select-mode - 2>&1"], 1, "*** Setup Organization Credentials failed."); my $apache_gid = getgrnam(`grep -hsoP "(?<=Group ).*" /etc/httpd/conf/*.conf /etc/apache2/*.conf | tr -d '\n'`); if ($apache_gid && -e Spacewalk::Setup::SCC_CREDENTIAL_FILE) { chown -1, $apache_gid, Spacewalk::Setup::SCC_CREDENTIAL_FILE; chmod 0640, Spacewalk::Setup::SCC_CREDENTIAL_FILE; } } if(keys %rhnopt) { Spacewalk::Setup::write_config( \%rhnopt, '/var/lib/rhn/rhn-satellite-prep/etc/rhn/rhn.conf' ); } foreach my $opt_name (qw/session_swap_secret session_secret/) { foreach my $i (1 .. 4) { $config_opts{"${opt_name}_${i}"} = generate_secret(); } } Spacewalk::Setup::generate_satcon_dict(); Spacewalk::Setup::write_config(\%config_opts, Spacewalk::Setup::DEFAULT_SATCON_DICT); Spacewalk::Setup::satcon_deploy(); return \%config_opts; } # given a list of directories (by default, /var/satellite) # check if they exist and if they do not exist, create them # with apache as owner sub mkdir_mount_points { system('/usr/bin/spacewalk-make-mount-points', @_); } sub populate_final_configs { my $options = shift; my $answers = shift; Spacewalk::Setup::satcon_deploy(-tree => '/var/lib/rhn/rhn-satellite-prep/etc/rhn', -dest => '/etc/rhn'); if($answers->{"no-ssl"} && $answers->{"no-ssl"} =~ /^[Yy]/) { open(my $FILE, '>>', '/etc/rhn/rhn.conf'); print $FILE "server.no_ssl = 1"; close $FILE; } return; } sub final_db_config { my $options = shift; my $answers = shift; my $dbh = Spacewalk::Setup::get_dbh($answers); my $sth = $dbh->prepare(<<EOQ); SELECT TS.value FROM rhnTemplateString TS WHERE TS.label = 'hostname' EOQ $sth->execute(); my ($current_hostname) = $sth->fetchrow(); unless ($current_hostname) { $sth = $dbh->prepare(<<EOQ); INSERT INTO rhnTemplateString (id, category_id, label, value, description) VALUES (sequence_nextval('rhn_template_str_id_seq'), (SELECT TC.id FROM rhnTemplateCategory TC WHERE TC.label = 'org_strings'), 'hostname', ?, 'Host name for the Red Hat Satellite') EOQ $sth->execute($answers->{hostname}); if ($DEBUG) { $dbh->rollback(); } else { $dbh->commit(); } } $sth->finish; $dbh->disconnect(); return; } sub generate_secret { return sha256_hex(random_bits(4096)); } sub random_bits { my $n = shift; open(RANDOM, '/dev/urandom') or die "could not open /dev/urandom for reading!\n"; binmode(RANDOM); my $rand_data; my $result = read(RANDOM, $rand_data, $n >> 3); close(RANDOM); unless (defined $result) { die "could not read from /dev/urandom!\n"; } return $rand_data; } # Satellite services are handled by chkconfig now. sub setup_services { Spacewalk::Setup::system_or_exit(["/usr/sbin/spacewalk-service", "--level", "35", "enable"], 11, 'Could not turn spacewalk services on.'); return 1; } sub is_suse_like { my $filename = '/etc/os-release'; if(! -e $filename) { return; } open my $fh, "<", $filename or die "Could not open '$filename': $!\n"; while( my $line = <$fh> ) { if ($line =~ m/ID_LIKE=".*suse.*"/) { close $fh; return 1; } } close $fh; return; } sub check_ca_key{ my $password = shift; return Spacewalk::Setup::system_debug('/usr/bin/rhn-ssl-tool',"--check-key", "--password=$password"); } sub valid_multiple_email { my $text = shift || ''; my @addys = grep { $_ } split(/[\s,]+/, $text); my $valid = 1; foreach my $addy (@addys) { if (not Mail::RFC822::Address::valid($text)) { print Spacewalk::Setup::loc("'%s' does not appear to be a valid email address.\n", $text); $valid = 0; } } unless (@addys) { print Spacewalk::Setup::loc("You must enter an email address.\n"); $valid = 0; } return $valid; } sub wait_for_tomcat { for (my $i = 0; $i < 20; $i++) { IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => '8009', Proto => 'tcp' ) and last; sleep 5; } for (my $i = 0; $i < 20; $i++) { my $retval = system("/usr/bin/curl -fkIL http://localhost/ > /dev/null 2>&1"); if ($retval) { sleep 5; } else { return 1; } } print "Tomcat failed to start properly or the installer ran out of tries. Please check /var/log/tomcat/catalina.out or /var/log/tomcat/catalina.\$(date +%Y-%m-%d).log for errors.\n"; return 0; } 0707010000000B000081FD000000000000000000000001661549540000162A000000000000000000000000000000000000002C00000000spacewalk-setup/bin/spacewalk-setup-cobbler#!/usr/bin/python3 # Copyright (c) 2021 SUSE LLC # # This software is licensed to you under the GNU General Public License, # version 2 (GPLv2). There is NO WARRANTY for this software, express or # implied, including the implied warranties of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 # along with this software; if not, see # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. # Initial creator of the script: Enno Gotthold <egotthold@suse.de> import os import socket import yaml import argparse from configparser import ConfigParser from shutil import copyfile parser = argparse.ArgumentParser(description='Setup Cobbler for Uyuni.') parser.add_argument('--cobbler-config-directory', '-c', dest='cobbler_config_directory', default="/etc/cobbler/", help='The directory where "settings" and "modules.conf" are in.') parser.add_argument('--apache2-config-directory', '-a', dest='httpd_config_directory', default="/etc/apache2/conf.d", help='The directory where the Apache config file "cobbler.conf" is in.') parser.add_argument('--fqdn', '-f', dest='fqdn', default=None) COBBLER_CONFIG_DIRECTORY = "/etc/cobbler/" COBBLER_CONFIG_FILES = ["modules.conf", "settings.yaml"] HTTPD_CONFIG_DIRECTORY = "/etc/apache2/conf.d/" COBBLER_HTTP_CONFIG = "cobbler.conf" def backup_file(file_path: str): """ Copies the file and adds a suffix ".backup" to it. :param file_path: The full path to the file which should be backed up. :raises FileNotFoundError: In case the path specified was not existing. """ copyfile(file_path, "%s.backup" % file_path) def manipulate_cobbler_settings(config_dir: str, settings_yaml: str, fqdn: str): """ Manipulate the main Cobbler configuration file which is in YAML format. This function backs the original configuration up and writes a new one with the required changes to the disk. :param config_dir: The directory of Cobbler where the config files are. :param settings_yaml: The name of the main YAML file of Cobbler. :param fqdn: The FQDN of the server. If None (default), the FQDN is resolved from the system """ full_path = os.path.join(config_dir, settings_yaml) backup_file(full_path) with open(full_path) as settings_file: filecontent = yaml.safe_load(settings_file.read()) filecontent["server"] = fqdn or socket.getfqdn() # In case of failing DNS resolution, we get a OSError (socket.gaierror) try: filecontent["next_server_v4"] = socket.getaddrinfo(filecontent["server"], None, socket.AF_INET)[1][4][0] except OSError: filecontent["next_server_v4"] = "" try: filecontent["next_server_v6"] = socket.getaddrinfo(filecontent["server"], None, socket.AF_INET6)[1][4][0] except OSError: filecontent["next_server_v6"] = "" if not filecontent["next_server_v4"] and not filecontent["next_server_v6"]: print("ERROR: Neither IPv4 nor IPv6 addresses can be resolved for configured FQDN: {}. Please check your DNS and hostname configuration.".format(filecontent["server"])) exit(1) filecontent["pxe_just_once"] = True filecontent["redhat_management_server"] = fqdn or socket.getfqdn() filecontent["client_use_localhost"] = True filecontent["uyuni_authentication_endpoint"] = "http://localhost" yaml_dump = yaml.safe_dump(filecontent) with open(full_path, "w") as settings_file: settings_file.write(yaml_dump) def manipulate_cobbler_modules(config_dir: str, modules_ini: str): """ Manipulates the authentication of Cobbler to use the SUMA/Uyuni Server directly. :param config_dir: The directory of Cobbler where the config files are. :param modules_ini: The name of the configuration in INI style for the modules Cobbler uses at runtime. """ full_path = os.path.join(config_dir, modules_ini) backup_file(full_path) # Read Ini File cp = ConfigParser() cp.read(full_path) # Modify Authentication to Spacewalk module cp["authentication"]["module"] = "authentication.spacewalk" # Write Ini File with open(full_path, "w") as modules_conf: cp.write(modules_conf) def remove_virtual_host(conf_directory: str, conf_file: str): """ Replaces all occurrences of lines with "VirtualHost" with an empty one. :param conf_directory: The directory where the Apache2 configuration files are. :param conf_file: The file to edit. """ full_path = os.path.join(conf_directory, conf_file) backup_file(full_path) with open(full_path, "r") as http_config: http_lines = http_config.readlines() for i in range(0, len(http_lines)): if "VirtualHost" in http_lines[i]: http_lines[i] = "" with open (full_path, 'w') as http_config_update: http_config_update.writelines(http_lines) def sanitize_args(args): global COBBLER_CONFIG_DIRECTORY COBBLER_CONFIG_DIRECTORY = os.path.join(args.cobbler_config_directory, '') global HTTPD_CONFIG_DIRECTORY HTTPD_CONFIG_DIRECTORY = os.path.join(args.httpd_config_directory, '') def main(): """ Main entrypoint for the script to get Cobbler in the correct state for SUMA. """ args = parser.parse_args() sanitize_args(args) manipulate_cobbler_settings(COBBLER_CONFIG_DIRECTORY, COBBLER_CONFIG_FILES[1], args.fqdn) manipulate_cobbler_modules(COBBLER_CONFIG_DIRECTORY, COBBLER_CONFIG_FILES[0]) remove_virtual_host(HTTPD_CONFIG_DIRECTORY, COBBLER_HTTP_CONFIG) if __name__ == "__main__": # execute only if run as a script main() 0707010000000C000081FD0000000000000000000000016615495400001BC7000000000000000000000000000000000000002A00000000spacewalk-setup/bin/spacewalk-setup-httpd#!/usr/bin/perl eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' if 0; # not running under some shell # # Copyright (c) 2014--2015 Red Hat, Inc. # # This software is licensed to you under the GNU General Public License, # version 2 (GPLv2). There is NO WARRANTY for this software, express or # implied, including the implied warranties of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 # along with this software; if not, see # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. # # Red Hat trademarks are not licensed under GPLv2. No permission is # granted to use or replicate Red Hat trademarks that are incorporated # in this software or its documentation. # use strict 'refs'; use warnings; use Getopt::Long; use Spacewalk::Setup; sub id_like_match { $what = shift; my $filename = '/etc/os-release'; if(! -e $filename) { return 0; } open my $fh, "<", $filename or die "Could not open '$filename': $!\n"; while( my $line = <$fh> ) { if ($line =~ m/ID_LIKE="$what"/) { close $fh; return 1; } } close $fh; return 0; } sub is_suse_like { return id_like_match(".*suse.*"); } sub is_opensuse { return id_like_match(".*opensuse.*"); } sub os_fips_mode_on { # For kernels without CONFIG_CRYPTO_FIPS enabled return 0 if (!-e '/proc/sys/crypto/fips_enabled'); my $sysctl = (-x '/usr/sbin/sysctl') ? '/usr/sbin/sysctl' : '/sbin/sysctl'; my $ret = `$sysctl -n crypto.fips_enabled`; chomp($ret); return $ret; } sub mod_ssl_fipsmode_option { # Remove this IF as soon as we have FIPS support enabled at openSUSE Leap 15.2. if (is_opensuse()) { return 0; } if(is_suse_like()) { # Remove this return as soon as we have FIPS support enabled at SLE15SP2. return 0; $mod_ssl_version = `rpm -q --qf='%{VERSION}' apache2-prefork`; } else { $mod_ssl_version = `rpm -q --qf='%{VERSION}' mod_ssl`; } # mod_ssl > 2.4 supports SSLFIPS directive (Fedora 19, 20, ...) # apache2-prefork > 2.4 supports SSLFIPS directive (SLE15, openSUSE Leap 15.0, ...) if ($mod_ssl_version gt '2.4.0') { return 1; } return 0; } sub modify_conf_content { my $conf_content = ${(shift)}; my $conf_files = shift; local *FILE; for my $file (glob Spacewalk::Setup::SHARED_DIR . "/$conf_files.*") { open FILE, $file or die "Error reading [$file]: $!\n"; my $regexp = <FILE>; chomp $regexp; my $content; { local $/ = undef; $content = <FILE>; } close FILE; $conf_content =~ s!$regexp!$content!gm or $conf_content .= $content; } return $conf_content; } sub setup_mod_nossl { my $sslconf_dir = is_suse_like() ? '/etc/apache2/vhosts.d' : '/etc/httpd/conf.d'; my $sslconf = is_suse_like() ? 'vhost-nossl.conf' : 'nossl.conf'; my $sslconf_path = "$sslconf_dir/$sslconf"; if(is_suse_like() && ! -f $sslconf_path) { my $config_path = Spacewalk::Setup::SHARED_DIR . "/vhost-nossl.conf"; `cp "$config_path" "$sslconf_path"`; } return; } sub setup_mod_ssl { my $fips_mode_on = shift; my ($sslconf_content, $original_sslconf_content, $pre, $vhost, $post); my $sslconf_dir = '/etc/httpd/conf.d'; $sslconf_dir = '/etc/apache2/vhosts.d' if(is_suse_like()); my $sslconf = 'ssl.conf'; $sslconf = 'vhost-ssl.conf' if(is_suse_like()); my $sslconf_path = "$sslconf_dir/$sslconf"; local *FILE; if(is_suse_like() && ! -f $sslconf_path) { `cp "$sslconf_dir/vhost-ssl.template" "$sslconf_path"`; } die "$sslconf_path does not exist.\n" unless (-f $sslconf_path); { open FILE, $sslconf_path or die "Error opening [$sslconf_path]: $!\n"; local $/ = undef; $sslconf_content = <FILE>; $original_sslconf_content = $sslconf_content; close FILE; } if ($sslconf_content =~ /(.*<VirtualHost _default_:443>)(.*)(<\/VirtualHost>.*)/s) { $pre = $1; $vhost = $2; $post = $3; } else { print Spacewalk::Setup::loc("Setup was unable to locate VirtualHost section " . "in existing mod_ssl configuration.\n"); exit; } $vhost = modify_conf_content(\$vhost, 'mod_ssl.conf.vhost'); # (If requested explicitly or the OS is already switched into FIPS mode) and # the particular mod_ssl being used supports SSLFIPS option if (($fips_mode_on or os_fips_mode_on()) and mod_ssl_fipsmode_option()) { $post = modify_conf_content(\$post, 'mod_ssl.conf.sslfips'); } $sslconf_content = $pre . $vhost . $post; if ($sslconf_content ne $original_sslconf_content) { Spacewalk::Setup::backup_file($sslconf_dir, $sslconf); open FILE, ">$sslconf_path" or die "Error opening [$sslconf_path]: $!\n"; chmod 0644, $sslconf_path; print FILE $pre . $vhost . $post; close FILE; } return; } # main my $help; my $fips_mode_on; my $no_ssl; my $usage = <<EOHELP; Usage: $0 --help | --fips-mode-on | --no-ssl Options: --help Print this help message --fips-mode-on Turn SSL FIPS mode on (when applicable) --no-ssl Configure without SSL EOHELP GetOptions( "help" => \$help, "fips-mode-on" => \$fips_mode_on, "no-ssl" => \$no_ssl ) or die $usage; if ($help) { print $usage; exit 0; } if ($no_ssl) { setup_mod_nossl(); } else { setup_mod_ssl($fips_mode_on); } =head1 NAME spacewalk-setup-httpd - utility for configuring httpd service to work with Uyuni / SUSE Manager =head1 SYNOPSIS B<spacewalk-setup-httpd> [B<--help>] [B<--fips-mode-on>] [B<--no-ssl>] =head1 OPTIONS =over 5 =item B<--fips-mode-on> Configure httpd to work correctly in FIPS mode. For mod_ssl, this means turning the SSLFIPS directive on in ssl.conf where applicable. =item B<--no-ssl> Configure httpd without SSL. =item B<--help> Print help message. =back =head1 DESCRIPTION B<spacewalk-setup-httpd> is a utility for configuring httpd service to work with Uyuni / SUSE Manager. The script uses configuration templates to modify existing httpd configuration files. Ordinarily, spacewalk-setup-httpd is called by spacewalk-setup(1) during initial Uyuni / SUSE Manager configuration or upgrade. =head1 FILES mod_ssl configuration F</etc/httpd/conf.d/ssl.conf> Configuration templates F</usr/share/spacewalk/setup/mod_ssl*> =head1 SEE ALSO B<spacewalk-setup>(1) - Spacewalk setup program =head1 AUTHORS Milan Zazrivec <mzazrivec@redhat.com> =cut 0707010000000D000041FD0000000000000000000000026615495400000000000000000000000000000000000000000000001400000000spacewalk-setup/doc0707010000000E000081B400000000000000000000000166154954000001A9000000000000000000000000000000000000001C00000000spacewalk-setup/doc/conf.py# pylint: disable=missing-module-docstring # -- Project information ----------------------------------------------------- project = "spacewalk-cobbler-setup" # pylint: disable-next=redefined-builtin copyright = "2021, The Uyuni Project" author = "Uyuni Project" # -- General configuration --------------------------------------------------- source_suffix = ".rst" master_doc = "spacewalk-cobbler-setup" language = "en" 0707010000000F000081B4000000000000000000000001661549540000035C000000000000000000000000000000000000003000000000spacewalk-setup/doc/spacewalk-cobbler-setup.rstspacewalk-cobbler-setup ======================= Synopsis ######## spacewalk-cobbler-setup [-h] [-c cobbler-config-dir] [-a apache2-config-dir] Description ########### A script to do Cobbler related configuration in the context of the Uyuni Project. This is only thought for inital use and not for maintenance. It's intended use is the main ``spacewalk-setup`` script not an end user. Options ####### --help --cobbler-config-directory cobbler-config-dir --apache2-config-directory apache2-config-dir Examples ######## Uses the defaults to configure the Cobbler Server: .. code:: spacewalk-cobbler-setup Uses a different Cobbler configuration directory: .. code:: spacewalk-cobbler-setup -c /etc/different/cobbler/directory/ Uses a different Apache2 configuration directory: .. code:: spacewalk-cobbler-setup -a /etc/httpd/conf.d/ 07070100000010000041FD0000000000000000000000036615495400000000000000000000000000000000000000000000001400000000spacewalk-setup/lib07070100000011000041FD0000000000000000000000026615495400000000000000000000000000000000000000000000001E00000000spacewalk-setup/lib/Spacewalk07070100000012000081B4000000000000000000000001661549540000AC1A000000000000000000000000000000000000002700000000spacewalk-setup/lib/Spacewalk/Setup.pmpackage Spacewalk::Setup; require Exporter; use warnings; use strict; use English; use Exporter 'import'; use vars '@EXPORT_OK'; @EXPORT_OK = qw(loc system_debug system_or_exit postgresql_clear_db); use Getopt::Long qw(GetOptions); use Symbol qw(gensym); use IPC::Open3 qw(open3); use Pod::Usage qw(pod2usage); use POSIX ":sys_wait_h"; use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC); use Socket; eval { require Net::LibIDN2; Net::LibIDN2->import(); sub idn_to_ascii($;$$) { return Net::LibIDN2::idn2_lookup_u8( shift ) } 1; } or do { my $error = $@; require Net::LibIDN; Net::LibIDN->import( qw(idn_to_ascii) ); }; use Params::Validate qw(validate); Params::Validate::validation_options(strip_leading => "-"); =head1 NAME Spacewalk::Setup, spacewalk-setup =head1 VERSION Version 1.1 =cut our $VERSION = '1.1'; use constant SHARED_DIR => "/usr/share/spacewalk/setup"; use constant POSTGRESQL_SCHEMA_FILE => File::Spec->catfile("/usr", "share", 'susemanager', 'db', 'postgres', 'main.sql'); use constant POSTGRESQL_DEPLOY_FILE => File::Spec->catfile("/usr", "share", 'susemanager', 'db', 'postgres', 'deploy.sql'); use constant DEFAULT_ANSWER_FILE_GLOB => SHARED_DIR . '/defaults.d/*.conf'; use constant DEFAULT_RHN_CONF_LOCATION => '/etc/rhn/rhn.conf'; use constant DEFAULT_PROXY_CONF_LOCATION => '/etc/sysconfig/proxy'; use constant DEFAULT_PROXYAUTH_CONF_LOCATION => '/root/.curlrc'; use constant DEFAULT_UP2DATE_LOCATION => '/etc/sysconfig/rhn/up2date'; use constant DEFAULT_RHN_ETC_DIR => '/etc/sysconfig/rhn'; use constant DEFAULT_SATCON_DICT => '/var/lib/rhn/rhn-satellite-prep/satellite-local-rules.conf'; use constant DEFAULT_RHN_SATCON_TREE => '/var/lib/rhn/rhn-satellite-prep/etc'; use constant DEFAULT_BACKUP_DIR => '/etc/sysconfig/rhn/backup-' . `date +%F-%R`; use constant INSTALL_LOG_FILE => '/var/log/rhn/rhn_installation.log'; use constant DB_INSTALL_LOG_FILE => '/var/log/rhn/install_db.log'; use constant DB_POP_LOG_FILE => '/var/log/rhn/populate_db.log'; use constant PG_POP_LOG_SIZE => 156503; use constant ORA_POP_LOG_SIZE => 132243; use constant RHN_LOG_DIR => '/var/log/rhn'; use constant DB_UPGRADE_LOG_FILE => '/var/log/rhn/upgrade_db.log'; use constant DB_UPGRADE_LOG_SIZE => 22000000; use constant DB_INSTALL_LOG_SIZE => 11416; use constant DB_MIGRATION_LOG_FILE => '/var/log/rhn/rhn_db_migration.log'; use constant EMBEDDED_DB_ANSWERS => '/usr/share/spacewalk/setup/defaults.d/embedded-postgresql.conf'; our $DEFAULT_DOC_ROOT = "/var/www/html"; our $SUSE_DOC_ROOT = "/usr/share/susemanager/www/htdocs"; our $CA_TRUST_DIR = '/etc/pki/ca-trust/source/anchors'; our $SUSE_CA_TRUST_DIR = '/etc/pki/trust/anchors'; use constant DEFAULT_SUSEMANAGER_CONF => '/usr/share/rhn/config-defaults/rhn_server_susemanager.conf'; use constant DEFAULT_SCC_URL => 'https://scc.suse.com'; use constant SCC_CREDENTIAL_FILE => '/etc/zypp/credentials.d/SCCcredentials'; my $DEBUG; $DEBUG = 0; my $DRY_RUN; $DRY_RUN = 0; sub parse_options { my @valid_opts = ( "help", "skip-initial-configuration", "skip-system-version-test", "skip-selinux-test", "skip-fqdn-test", "skip-python-test", "skip-updates-install", "skip-db-install", "skip-db-diskspace-check", "skip-db-population", "skip-reportdb-setup", "skip-ssl-cert-generation", "skip-ssl-ca-generation", "skip-ssl-vhost-setup", "skip-services-check", "skip-services-restart", "skip-logfile-init", "clear-db", "re-register", "answer-file=s", "non-interactive", "upgrade", "run-updater:s", "run-cobbler", "enable-tftp:s", "external-postgresql", "external-postgresql-over-ssl", "db-only", "rhn-http-proxy:s", "rhn-http-proxy-username:s", "rhn-http-proxy-password:s", "managed-db", "scc", "disconnected" ); my $usage = loc("usage: %s %s\n", $0, "[ --help ] [ --answer-file=<filename> ] [ --non-interactive ] [ --skip-initial-configuration ] [ --skip-system-version-test ] [ --skip-selinux-test ] [ --skip-fqdn-test ] [ --skip-db-install ] [ --skip-db-diskspace-check ] [ --skip-db-population ] [--skip-reportdb-setup ] [ --skip-ssl-cert-generation ] [--skip-ssl-ca-generation] [--skip-ssl-vhost-setup] [ --skip-services-check ] [ --skip-services-restart ] [ --clear-db ] [ --re-register ] [ --upgrade ] [ --run-updater=<yes|no>] [--run-cobbler] [ --enable-tftp=<yes|no>] [ --external-postgresql [ --external-postgresql-over-ssl ] ] [--scc] [--disconnected]" ); # Terminate if any errors were encountered parsing the command line args: my %opts; if (not GetOptions(\%opts, @valid_opts)) { die("\n"); } if ($opts{help}) { ( my $module = __PACKAGE__ ) =~ s!::!/!g; pod2usage(-exitstatus => 0, -verbose => 1, -message => $usage, -input => $INC{$module . '.pm'}); } return %opts; } # This function is a simple wrapper around sprintf, which I'm using as # a placeholder until or unless real I18N support is required. Doing # it this way should make it easier to identify which strings need # localization, and help me avoid lazily catting strings together. sub loc { my $string = shift; return sprintf($string, @_); } sub read_config { my $config_file = shift; my $options = shift; local * CONFIG; open(CONFIG, '<', $config_file) or die "Could not open $config_file: $!"; while (my $line = <CONFIG>) { if ($line =~ /^#/ or $line =~ /\[comment\]/ or $line =~ /^\s*$/) { next; } else { chomp($line); (my $key, my $value) = split (/=/, $line); $key =~ s/^\s*//msg; $key =~ s/\s*$//msg; $value =~ s/^\s*//msg; $value =~ s/\s*$//msg; $options->{$key} = $value; if ($DEBUG) { print("read $key = $value from $config_file\n"); } } } return; } sub write_config { my $options = shift; my $target = shift; my @opt_strings = map { "--option=${_}=" . $options->{$_} } grep { defined $options->{$_} } keys %{$options}; Spacewalk::Setup::system_or_exit([ "/usr/bin/rhn-config-satellite.pl", "--target=$target", @opt_strings, ], 29, 'There was a problem setting initial configuration.'); return 1; } sub load_answer_file { my $options = shift; my $answers = shift; my (@skip) = @{(shift)}; my @files = (); foreach my $afile (glob(DEFAULT_ANSWER_FILE_GLOB)) { push @files, $afile if not grep $_ eq $afile, @skip; } push @files, $options->{'answer-file'} if $options->{'answer-file'}; for my $file (@files) { next unless (-r $file or $file eq $options->{'answer-file'}); if ($options->{'answer-file'} and $file eq $options->{'answer-file'}) { print loc("* Loading answer file: %s.\n", $file); } local * FH; open FH, '<', $file or die loc("Could not open answer file: %s\n", $!); while (my $line = <FH>) { next if substr($line, 0, 1) eq '#'; $line =~ /([\w\.-]*)\s*=\s*(.*)/; my ($key, $value) = ($1, $2); next unless $key; $answers->{$key} = $value; } close FH; } if ($answers->{'db-host'}) { $answers->{'db-host'} = idn_to_ascii($answers->{'db-host'}, "utf8"); } return; } # Check if we're installing with an embedded database. sub is_embedded_db { my $opts = shift; return not (defined($opts->{'external-postgresql'}) or defined($opts->{'managed-db'})); } sub system_debug { my @args = @_; my $logfile = INSTALL_LOG_FILE; if ($DEBUG) { print "Command: '" . join(' ', @args) . "'\n"; } if ($DRY_RUN) { return 0; } else { local $SIG{'ALRM'}; if (@args == 1) { die "Single parameter system_debug [@args] not supported.\n"; } else { local *LOGFILE; open(LOGFILE, ">>", $logfile) or do { print "Error writing log file '$logfile': $!\n"; print STDERR "Error writing log file '$logfile': $!\n"; return 1; }; my $orig_stdout = select LOGFILE; $| = 1; select $orig_stdout; local *PROCESS_OUT; set_spinning_callback(); my $pid = open3(gensym, \*PROCESS_OUT, \*PROCESS_OUT, @args); my ($vecin, $vecout) = ('', ''); vec($vecin, fileno(PROCESS_OUT), 1) = 1; my $ret; # Some programs that daemonize themselves do not close their stdout, # so doing just while (<PROCESS_OUT>) would block forever. That's why # we try to select'n'sysread, to have a chance to see if the child # is ready to be reaped, even if we did not get eof. while (1) { if (select($vecout=$vecin, undef, undef, 10) > 0) { my $buffer; if (sysread(PROCESS_OUT, $buffer, 4096) > 0) { print LOGFILE $buffer; redo; } } my $pidout = waitpid($pid, WNOHANG); if ($pidout < 0) { print LOGFILE "We've lost the child [@args] pid [$pid]\n"; $ret = -1; last; } if ($pidout) { $ret = $?; last; } } close PROCESS_OUT; close LOGFILE; alarm 0; return $ret; } } } sub system_or_exit { my $command = shift; my $exit_code = shift; my $error = shift; my @args = @_; my $ret = system_debug(@{$command}); if ($ret) { my $exit_value = $? >> 8; print loc($error . " Exit value: %d.\n", (@args, $exit_value)); print "Please examine @{[ INSTALL_LOG_FILE ]} for more information.\n"; exit $exit_code; } return 1; } sub upgrade_stop_services { my $opts = shift; if ($opts->{'upgrade'} && not $opts->{'skip-services-check'}) { print "* Upgrade flag passed. Stopping necessary services.\n"; if (-e "/usr/sbin/spacewalk-service") { system_or_exit(['/usr/sbin/spacewalk-service', 'stop'], 16, 'Could not stop the rhn-satellite service.'); } else { # shutdown pre 3.6 services proerly system_or_exit(['/sbin/service', 'apache2', 'stop'], 25, 'Could not stop the http service.'); system_or_exit(['/sbin/service', 'taskomatic', 'stop'], 27, 'Could not stop the taskomatic service.'); if (is_embedded_db($opts)) { system_or_exit(['/sbin/service', 'rhn-database', 'stop'], 31, 'Could not stop the rhn-database service.'); } } } return 1; } my $spinning_callback_count; my @spinning_pattern = split /\n/, <<EOF; (°- · · · · · (°< · · · · · (°- · · · · (°< · · · · (°- · · · (°< · · · (°- · · (°< · · (°- · (°< · (°- EOF my $spinning_pattern_maxlength = 0; for (@spinning_pattern) { if (length > $spinning_pattern_maxlength) { $spinning_pattern_maxlength = length; } } sub spinning_callback { my $old = select STDOUT; $| = 1; my $index = ($spinning_callback_count++ % scalar(@spinning_pattern)); print STDOUT $spinning_pattern[$index], (' ' x ($spinning_pattern_maxlength - length($spinning_pattern[$index]))), "\r"; select $old; alarm 1; } sub set_spinning_callback { if (not -t STDOUT) { return; } $spinning_callback_count = 0; $SIG{'ALRM'} = \&spinning_callback; alarm 1; } sub init_log_files { my $product_name = shift; my @args = @_; if (not -e RHN_LOG_DIR) { mkdir RHN_LOG_DIR; } log_rotate(INSTALL_LOG_FILE); if (have_selinux()) { local *X; open X, '>', INSTALL_LOG_FILE and close X; system('/sbin/restorecon', INSTALL_LOG_FILE); } log_rotate(DB_INSTALL_LOG_FILE); log_rotate(DB_POP_LOG_FILE); local * FH; open(FH, ">", INSTALL_LOG_FILE) or die "Could not open '" . INSTALL_LOG_FILE . "': $!"; my $log_header = "Installation log of $product_name\nCommand: " . $0 . " " . join(" ", @args) . "\n\n"; print FH $log_header; close(FH); return; } sub log_rotate { my $file = shift; my $counter = 1; if (-e $file) { while (-e $file . '.' . $counter) { $counter++; } rename $file, $file . '.' . $counter; } return; } sub check_users_exist { my @required_users = @_; my $missing_a_user; foreach my $user (@required_users) { if (not getpwnam($user)) { print loc("The user '%s' should exist.\n", $user); $missing_a_user = 1; } } if ($missing_a_user) { exit 7; } } sub check_groups_exist { my @required_groups = @_; my $missing_a_group; foreach my $group (@required_groups) { if (not getgrnam($group)) { print loc("The group '%s' should exist.\n", $group); $missing_a_group = 1; } } if ($missing_a_group) { exit 8; } } sub clear_db { my $answers = shift; my $dbh = get_dbh($answers); print loc("** Database: Shutting down spacewalk services that may be using DB.\n"); system_debug('/usr/sbin/spacewalk-service', 'stop'); print loc("** Database: Services stopped. Clearing DB.\n"); my $select_sth = $dbh->prepare(<<EOQ); SELECT 'drop ' || UO.object_type ||' '|| UO.object_name AS DROP_STMT FROM user_objects UO WHERE UO.object_type NOT IN ('TABLE', 'INDEX', 'TRIGGER', 'LOB') UNION SELECT 'drop ' || UO.object_type ||' '|| UO.object_name || ' cascade constraints' AS DROP_STMT FROM user_objects UO WHERE UO.object_type = 'TABLE' AND UO.object_name NOT LIKE '%$%' EOQ $select_sth->execute(); while (my ($drop_stmt) = $select_sth->fetchrow()) { my $drop_sth = $dbh->prepare($drop_stmt); $drop_sth->execute(); } if ($DRY_RUN) { $dbh->rollback(); } else { $dbh->commit(); } $dbh->disconnect(); return; } # TODO: Still duplicated in install.pl, didn't move out to module as nicely # as other routines on account of usage of $opts: sub ask { my %params = validate(@_, { noninteractive => 1, question => 1, test => 0, answer => 1, password => 0, default => 0, completion => 0, }); if (${$params{answer}} and not $params{default}) { $params{default} = ${$params{answer}}; } while (not defined ${$params{answer}} or not answered($params{test}, ${$params{answer}})) { if ($params{noninteractive}) { if (defined ${$params{answer}}) { die "The answer '" . ${$params{answer}} . "' provided for '" . $params{question} . "' is invalid.\n"; } else { die "No answer provided for '" . $params{question} . "'\n"; } } my $default_string = ""; if ($params{default}) { if ($params{password}) { $default_string = " [******]"; } else { $default_string = " [" . $params{default} . "]"; } } print loc("%s%s? ", $params{question}, $default_string); if ($params{password}) { my $stty_orig_val = `stty -g`; system('stty', '-echo'); ${$params{answer}} = <STDIN>; system("stty $stty_orig_val"); print "\n"; } else { if ($params{completion}) { require Term::Completion::Path; my $tc = Term::Completion::Path->new(); ${$params{answer}} = $tc->complete(); } else { ${$params{answer}} = <STDIN>; } } chomp ${$params{answer}}; ${$params{answer}} =~ s/^\s+|\s+$//g; ${$params{answer}} ||= $params{default} || ''; } ${$params{answer}} ||= $params{default} || ''; return; } sub answered { my $test = shift; my $answer = shift; my $testsub; if (ref $test eq 'CODE') { $testsub = $test; } else { $testsub = sub { my $param = shift; if ($param =~ $test) { return 1 } else { print loc("'%s' is not a valid response\n", $param); return 0 } }; } return $testsub->($answer); } sub get_nls_database_parameters { my $answers = shift; my $dbh = get_dbh($answers); my $sth = $dbh->prepare(<<EOQ); SELECT NDP.parameter, NDP.value FROM nls_database_parameters NDP EOQ $sth->execute(); my %nls_database_parameters; while (my ($param, $value) = $sth->fetchrow()) { $nls_database_parameters{$param} = $value; } $sth->finish(); $dbh->disconnect(); return %nls_database_parameters; } sub print_progress { my %params = validate(@_, { init_message => 1, log_file_name => 1, log_file_size => 1, err_message => 1, err_code => 1, system_opts => 1, }); print "Running " . join(" ", @{$params{system_opts}}) . "\n"; local *LOGFILE; open(LOGFILE, ">>", $params{log_file_name}) or do { print "Error writing log file '$params{log_file_name}': $!\n"; print STDERR "Error writing log file '$params{log_file_name}': $!\n"; exit $params{err_code}; }; $| = 1; my $orig_stdout = select LOGFILE; $| = 1; select $orig_stdout; print loc($params{init_message}); local *PROCESS_OUT; my $progress_hashes_done = 0; my $progress_callback_length = 0; my $pid = open3(gensym, \*PROCESS_OUT, \*PROCESS_OUT, @{$params{system_opts}}); while (<PROCESS_OUT>) { print LOGFILE $_; $progress_callback_length += length; if (-t STDOUT and $params{log_file_size}) { my $target_hashes = int(60 * $progress_callback_length / $params{log_file_size}); if ($target_hashes > $progress_hashes_done) { print "#" x ($target_hashes - $progress_hashes_done); $progress_hashes_done = $target_hashes; } } } close PROCESS_OUT; waitpid($pid, 0); my $ret = $?; close LOGFILE; print "\n"; if ($ret) { print loc($params{err_message}); exit $params{err_code}; } } sub postgresql_get_database_answers { my $opts = shift; my $answers = shift; my %config = (); read_config(DEFAULT_RHN_CONF_LOCATION, \%config); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Hostname (leave empty for local)", -test => sub { 1 }, -answer => \$answers->{'db-host'}); if ($answers->{'db-host'} ne '') { $answers->{'db-host'} = idn_to_ascii($answers->{'db-host'}, "utf8"); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Port", -test => qr/\d+/, -default => 5432, -answer => \$answers->{'db-port'}); } else { $answers->{'db-port'} = ''; } ask( -noninteractive => $opts->{"non-interactive"}, -question => "Database", -test => qr/\S+/, -default => $config{'db_name'}, -answer => \$answers->{'db-name'}); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Username", -test => qr/\S+/, -default => $config{'db_user'}, -answer => \$answers->{'db-user'}); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Password", -test => qr/\S+/, -default => $config{'db_password'}, -answer => \$answers->{'db-password'}, -password => 1); if ($opts->{'external-postgresql-over-ssl'}) { $answers->{'db-ssl-enabled'} = '1'; ask( -noninteractive => $opts->{"non-interactive"}, -question => "Path to CA certificate for connection to database", -test => sub { return (-f shift) }, -default => $ENV{HOME} . "/.postgresql/root.crt", -answer => \$answers->{'db-ca-cert'}); } return; } sub postgresql_get_reportdb_answers { my $opts = shift; my $answers = shift; my %config = (); read_config(DEFAULT_RHN_CONF_LOCATION, \%config); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Hostname (leave empty for local)", -test => sub { 1 }, -answer => \$answers->{'report-db-host'}); if ($answers->{'report-db-host'} ne '') { $answers->{'report-db-host'} = idn_to_ascii($answers->{'report-db-host'}, "utf8"); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Port", -test => qr/\d+/, -default => 5432, -answer => \$answers->{'report-db-port'}); } else { $answers->{'report-db-port'} = ''; } ask( -noninteractive => $opts->{"non-interactive"}, -question => "Database", -test => qr/\S+/, -default => $config{'report_db_name'}, -answer => \$answers->{'report-db-name'}); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Username", -test => qr/\S+/, -default => $config{'report_db_user'}, -answer => \$answers->{'report-db-user'}); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Password (leave empty for autogenerated password)", -test => sub { 1 }, -answer => \$answers->{'report-db-password'}, -password => 1); ask( -noninteractive => $opts->{"non-interactive"}, -question => "Path to CA certificate to connect to the reporting database", -test => sub { return (-f shift) }, -default => "/etc/pki/trust/anchors/LOCAL-RHN-ORG-TRUSTED-SSL-CERT", -answer => \$answers->{'report-db-ca-cert'}); $answers->{'report-db-ssl-enabled'} = '1'; return; } ############################ # PostgreSQL Specific Code # ############################ # Parent PostgreSQL setup function: sub postgresql_setup_db { my $opts = shift; my $answers = shift; print Spacewalk::Setup::loc("** Database: Setting up database connection for PostgreSQL backend.\n"); my $connected; if (is_embedded_db($opts)) { postgresql_start(); } postgresql_setup_embedded_db($opts, $answers); while (not $connected) { postgresql_get_database_answers($opts, $answers); if ($opts->{'external-postgresql-over-ssl'}) { $ENV{PGSSLROOTCERT} = $answers->{'db-ca-cert'}; $ENV{PGSSLMODE} = "verify-full"; } my $dbh; eval { $dbh = get_dbh($answers); $dbh->disconnect(); }; if ($@) { print Spacewalk::Setup::loc("Could not connect to the database. Your connection information may be incorrect. Error: %s\n", $@); delete @{$answers}{qw/db-host db-port db-name db-user db-password/}; } else { $connected = 1; } } my $populate_db = 0; set_hibernate_conf($answers); write_rhn_conf($answers, 'db-backend', 'db-host', 'db-port', 'db-name', 'db-user', 'db-password', 'db-ssl-enabled'); postgresql_populate_db($opts, $answers, $populate_db); return 1; } sub postgresql_reportdb_setup { my $opts = shift; my $answers = shift; print Spacewalk::Setup::loc("** Database: Setting up report database.\n"); # check for answers, but use defaults in case the values are not specified postgresql_get_reportdb_answers($opts, $answers); if ($opts->{"clear-db"}) { print Spacewalk::Setup::loc("** Database: --clear-db option used. Clearing report database.\n"); postgresql_drop_reportdb($answers); } $ENV{PGSSLROOTCERT} = $answers->{'report-db-ca-cert'}; if ($answers->{'report-db-host'} ne 'localhost') { $ENV{PGSSLMODE} = "verify-full"; } write_rhn_conf($answers, 'externaldb-admin-user','externaldb-admin-password', 'report-db-backend', 'report-db-host', 'report-db-port', 'report-db-name', 'report-db-user', 'report-db-password', 'report-db-ssl-enabled'); my @cmd = ('/usr/bin/uyuni-setup-reportdb', 'create', '--db', $answers->{'report-db-name'}, '--user', $answers->{'report-db-user'}, '--host', $answers->{'report-db-host'}); if ($answers->{'externaldb'}) { push @cmd, "--externaldb-admin-user", $answers->{'externaldb-admin-user'}, "--externaldb-admin-password", $answers->{'externaldb-admin-password'}, "--externaldb-root-cert", $answers->{'report-db-ca-cert'}; if ($answers->{'externaldb-provider'} ne '') { push @cmd, "--externaldb-provider", $answers->{'externaldb-provider'}; } } else { push @cmd, "--address", '*', "--remote", '0.0.0.0/0,::/0'; } if ($answers->{'report-db-password'} ne '') { push @cmd, "--password", $answers->{'report-db-password'}; } else { push @cmd, "--autogenpw"; } print_progress(-init_message => "*** Progress: #", -log_file_name => DB_INSTALL_LOG_FILE, -log_file_size => DB_INSTALL_LOG_SIZE, -err_message => "Could not install report database.\n", -err_code => 15, -system_opts => \@cmd); if (-e Spacewalk::Setup::DEFAULT_RHN_CONF_LOCATION) { my %dbOptions = (); ### uyuni-setup-reportdb writes param in rhn.conf. We need to read them and persists them in satellite-local-rules.conf read_config(Spacewalk::Setup::DEFAULT_RHN_CONF_LOCATION, \%dbOptions); ### here we need _ instead of - cause we read them from rhn.conf write_rhn_conf(\%dbOptions, 'report_db_backend', 'report_db_host', 'report_db_port', 'report_db_name', 'report_db_user', 'report_db_password', 'report_db_ssl_enabled','report_db_sslrootcert'); } print loc("** Database: Installation complete.\n"); return 1; } sub postgresql_start { my $pgservice=`systemctl list-unit-files | grep postgresql | cut -f1 -d. | tr -d '\n'`; system("service $pgservice status >&/dev/null"); system("service $pgservice start >&/dev/null") if ($? >> 8); return ($? >> 8); } sub postgresql_setup_embedded_db { my $opts = shift; my $answers = shift; if (not is_embedded_db($opts)) { return 0; } if ($opts->{"skip-db-install"} or $opts->{"upgrade"}) { print loc("** Database: Embedded database installation SKIPPED.\n"); return 0; } if (not -x '/usr/bin/spacewalk-setup-postgresql') { print loc(<<EOQ); The spacewalk-setup-postgresql does not seem to be available. You might want to use --external-postgresql command line option. EOQ exit 24; } my $pgdata=`runuser -l postgres -c env | grep PGDATA | cut -f2- -d=`; if (-d "$pgdata/base" and ! system(qq{/usr/bin/spacewalk-setup-postgresql check --db $answers->{'db-name'}})) { my $shared_dir = SHARED_DIR; print loc(<<EOQ); The embedded database appears to be already installed. Either rerun this script with the --skip-db-install option, or use the '/usr/bin/spacewalk-setup-postgresql remove --db $answers->{'db-name'} --user $answers->{'db-user'}' script to remove the embedded database and try again. EOQ exit 13; } if (not $opts->{"skip-db-diskspace-check"}) { system_or_exit(['python3', SHARED_DIR . '/embedded_diskspace_check.py', '$pgdata', '12288'], 14, 'There is not enough space available for the embedded database.'); } else { print loc("** Database: Embedded database diskspace check SKIPPED!\n"); } printf loc(<<EOQ, DB_INSTALL_LOG_FILE); ** Database: Installing the database: ** Database: This is a long process that is logged in: ** Database: %s EOQ if (have_selinux()) { local *X; open X, '>', DB_INSTALL_LOG_FILE and close X; system('/sbin/restorecon', DB_INSTALL_LOG_FILE); } print_progress(-init_message => "*** Progress: #", -log_file_name => DB_INSTALL_LOG_FILE, -log_file_size => DB_INSTALL_LOG_SIZE, -err_message => "Could not install database.\n", -err_code => 15, -system_opts => [ "/usr/bin/spacewalk-setup-postgresql", "create", "--db", $answers->{'db-name'}, "--user", $answers->{'db-user'}, "--password", $answers->{'db-password'}]); print loc("** Database: Installation complete.\n"); return 1; } sub postgresql_populate_db { my $opts = shift; my $answers = shift; my $populate_db = shift; print Spacewalk::Setup::loc("** Database: Populating database.\n"); if ($opts->{"skip-db-population"} or ($opts->{'upgrade'} and not $populate_db)) { print Spacewalk::Setup::loc("** Database: Skipping database population.\n"); return 1; } if ($opts->{"clear-db"}) { print Spacewalk::Setup::loc("** Database: --clear-db option used. Clearing database.\n"); my $dbh = get_dbh($answers); postgresql_clear_db($dbh, $answers); } if (postgresql_test_db_schema($answers)) { ask( -noninteractive => $opts->{"non-interactive"}, -question => "The Database has schema. Would you like to clear the database", -test => qr/(Y|N)/i, -answer => \$answers->{'clear-db'}, -default => 'Y', ); if ($answers->{"clear-db"} =~ /Y/i) { print Spacewalk::Setup::loc("** Database: Clearing database.\n"); my $dbh = get_dbh($answers); postgresql_clear_db($dbh, $answers); print Spacewalk::Setup::loc("** Database: Re-populating database.\n"); } else { print Spacewalk::Setup::loc("** Database: The database already has schema. Skipping database population.\n"); return 1; } } my $sat_schema = POSTGRESQL_SCHEMA_FILE; my $sat_schema_deploy = POSTGRESQL_DEPLOY_FILE; system_or_exit([ "/usr/bin/rhn-config-schema.pl", "--source=" . $sat_schema, "--target=" . $sat_schema_deploy, "--tablespace-name=None" ], 22, 'There was a problem populating the deploy.sql file.', ); my $logfile = DB_POP_LOG_FILE; my @opts = ('spacewalk-sql', '--select-mode-direct', $sat_schema_deploy); print_progress(-init_message => "*** Progress: #", -log_file_name => Spacewalk::Setup::DB_POP_LOG_FILE, -log_file_size => Spacewalk::Setup::PG_POP_LOG_SIZE, -err_message => "Could not populate database.\n", -err_code => 23, -system_opts => [@opts]); return 1; } # Check if the database appears to already have schema loaded: sub postgresql_test_db_schema { my $answers = shift; my $dbh = get_dbh($answers); # Assumption, if web_customer table exists then schema exists: my $sth = $dbh->prepare("SELECT tablename from pg_tables where schemaname='public' and tablename='web_customer'"); $sth->execute; my ($row) = $sth->fetchrow; $sth->finish; $dbh->disconnect(); return $row ? 1 : 0; } # Clear the PostgreSQL schema by deleting the 'public' schema with cascade, # then re-creating it. Also delete all the other known schemas that # Spacewalk might have created. my @POSTGRESQL_CLEAR_SCHEMA = ( 'drop schema if exists rpm cascade ;', 'drop schema if exists rhn_exception cascade ;', 'drop schema if exists rhn_config cascade ;', 'drop schema if exists rhn_server cascade ;', 'drop schema if exists rhn_entitlements cascade ;', 'drop schema if exists rhn_bel cascade ;', 'drop schema if exists rhn_cache cascade ;', 'drop schema if exists rhn_channel cascade ;', 'drop schema if exists rhn_config_channel cascade ;', 'drop schema if exists rhn_org cascade ;', 'drop schema if exists rhn_user cascade ;', 'drop schema if exists logging cascade ;', ); sub postgresql_clear_db { my $dbh = shift; my $answers = shift; my $do_shutdown = (defined($_[0]) ? shift : 1); if ($do_shutdown) { print loc("** Database: Shutting down spacewalk services that may be using DB.\n"); # The --exclude=postgresql is needed for embedded database Satellites. system_debug('/usr/sbin/spacewalk-service', '--exclude=postgresql', 'stop'); print loc("** Database: Services stopped. Clearing DB.\n"); } local $dbh->{RaiseError} = 0; local $dbh->{PrintError} = 1; local $dbh->{PrintWarn} = 0; local $dbh->{AutoCommit} = 1; if (lc $answers->{'externaldb-provider'} ne 'aws') { push @POSTGRESQL_CLEAR_SCHEMA, "drop schema if exists public cascade ;", "create schema public authorization postgres ;"; } foreach my $c (@POSTGRESQL_CLEAR_SCHEMA) { $dbh->do($c); } $dbh->disconnect; return 1; } sub postgresql_drop_reportdb { my $answers = shift; my @cmd = ('/usr/bin/uyuni-setup-reportdb', 'remove', '--db', $answers->{'report-db-name'}, '--user', $answers->{'report-db-user'}, '--host', $answers->{'report-db-host'}); if ($answers->{'externaldb'}) { push @cmd, "--externaldb-admin-user", $answers->{'externaldb-admin-user'}, "--externaldb-admin-password", $answers->{'externaldb-admin-password'}; } system_debug(@cmd); return 1; } sub get_dbh { my $answers = shift; my $reportdb = shift || 0; my $dbh_attributes = { RaiseError => 1, PrintError => 0, Taint => 0, AutoCommit => 0, }; my $backend = $reportdb ? $answers->{'report-db-backend'} : $answers->{'db-backend'}; if ($backend eq 'postgresql') { my $dsn = "dbi:Pg:dbname="; $dsn .= $reportdb ? $answers->{'report-db-name'} : $answers->{'db-name'}; my $dbhost = $reportdb ? $answers->{'report-db-host'} : $answers->{'db-host'}; my $dbport = $reportdb ? $answers->{'report-db-port'} : $answers->{'db-port'}; if ($dbhost ne '' && $dbhost ne 'localhost') { $dsn .= ";host=$dbhost"; if ($dbport ne '') { $dsn .= ";port=$dbport"; } } my $dbh = DBI->connect($dsn, $reportdb ? $answers->{'report-db-user'} : $answers->{'db-user'}, $reportdb ? $answers->{'report-db-password'} : $answers->{'db-password'}, $dbh_attributes); return $dbh; } die "Unknown db-backend [$backend]\n"; } # Function to check that we have SELinux, in the sense that we are on # system with modular SELinux (> RHEL 4), and the module spacewalk is loaded. my $have_selinux; sub have_selinux { return $have_selinux if defined $have_selinux; if( not -x "/usr/sbin/selinuxenabled") { $have_selinux = 0; } elsif (system(q!/usr/sbin/selinuxenabled && /usr/sbin/semodule -l 2> /dev/null | grep '^spacewalk\b' 2>&1 > /dev/null!)) { $have_selinux = 0; } else { $have_selinux = 1; } return $have_selinux; } sub generate_satcon_dict { my %params = validate(@_, { conf_file => { default => DEFAULT_SATCON_DICT }, tree => { default => DEFAULT_RHN_SATCON_TREE },}); system_or_exit([ "/usr/bin/satcon-build-dictionary.pl", "--tree=" . $params{tree}, "--target=" . $params{conf_file} ], 28, 'There was a problem building the satcon dictionary.'); return 1; } sub satcon_deploy { my %params = validate(@_, { conf_file => { default => DEFAULT_SATCON_DICT }, tree => { default => DEFAULT_RHN_SATCON_TREE }, dest => { default => '/etc' }, backup => { default => DEFAULT_BACKUP_DIR }, }); $params{backup} =~ s/\s+$//; my @opts = ("--source=" . $params{tree}, "--dest=" . $params{dest}, "--conf=" . $params{conf_file}, "--backupdir=" . $params{backup}); system_or_exit([ "/usr/bin/satcon-deploy-tree.pl", @opts ], 30, 'There was a problem deploying the satellite configuration.'); return 1; } sub backup_file { my $dir = shift; my $file = shift; my $backup_suffix = shift || '-swsave'; system("cp", "--backup=numbered", "$dir/$file", "$dir/$file$backup_suffix"); if ( $? >> 8 ) { die loc("An error ocurred while attempting to back up your original $file\n"); } else { print loc("** $dir/$file has been backed up to $file$backup_suffix\n"); } } # Write subset of $answers to /etc/rhn/rhn.conf. # Config written here is used only for database population # and config will be later on replaced by one generated from templates. sub write_rhn_conf { my $answers = shift; my %config = (); for my $n (@_) { if (defined $answers->{$n}) { my $name = $n; $name =~ s!-!_!g; $config{$name} = $answers->{$n}; } } write_config(\%config, DEFAULT_RHN_CONF_LOCATION); write_config(\%config, Spacewalk::Setup::DEFAULT_SATCON_DICT); } # Set hibernate strings into answers according to DB backend. sub set_hibernate_conf { my $answers = shift; if ($answers->{'db-backend'} eq 'postgresql') { $answers->{'hibernate.dialect'} = "org.hibernate.dialect.PostgreSQLDialect"; $answers->{'hibernate.connection.driver_class'} = "org.postgresql.Driver"; $answers->{'hibernate.connection.driver_proto'} = "jdbc:postgresql"; } write_rhn_conf($answers, 'hibernate.dialect', 'hibernate.connection.driver_class', 'hibernate.connection.driver_proto'); } =head1 DESCRIPTION Spacewalk::Setup is a module which provides the guts of the spacewalk-setup program. In will run the necessary steps to configure the Spacewalk server. =head1 OPTIONS =over 8 =item B<--help> Print this help message. =item B<--answer-file=<filename>> Indicates the location of an answer file to be use for answering questions asked during the installation process. See answers.txt for an example. =item B<--non-interactive> For use only with --answer-file. If the --answer-file doesn't provide a required response, exit instead of prompting the user. # todo @ =item B<--re-register> Register the system with RHN, even if it is already registered. =item B<--clear-db> Clear any pre-existing database schema before installing. This will destroy any data in the Satellite database and re-create empty Satellite schema. This option implies B<--skip-db-install>. =item B<--skip-system-version-test> Do not test the Red Hat Enterprise Linux version before installing. =item B<--skip-selinux-test> For the installation and setup to proceed properly, SELinux should be in Permissive or Enforcing mode. If you are certain that you are not in Disabled mode or you want to install in Disabled anyway, re-run the installer with the flag --skip-selinux-test. =item B<--skip-fqdn-test> Do not verify that the system has a valid hostname. Red Hat Satellite requires that the hostname be properly set during installation. Using this option may result in a Satellite server that is not fully functional. =item B<--skip-db-install> Do not install the embedded database. This option may be useful if you are re-installing the satellite, and do not want to clear the database. =item B<--skip-db-diskspace-check> Do not check to make sure there is enough free disk space to install the embedded database. =item B<--skip-db-population> Do not populate the database schema. =item B<--skip-ssl-cert-generation> Do not generate the SSL certificates for the Satellite. =item B<--skip-ssl-ca-generation> Do not generate the SSL CA, use existing CA to sign certificate for the Satellite. =item B<--skip-ssl-vhost-setup> Do not configure the default SSL virtual host for Spacewalk. Note that if you choose to have Spacewalk setup skip this step, it's up to you to ensure that the following are included in the virtual host definition: RewriteEngine on RewriteOptions inherit SSLProxyEngine on =item B<--upgrade> Only runs necessary steps for a Satellite upgrade. =item B<--skip-services-check> Proceed with upgrade if services are already stopped. =item B<--skip-services-restart> Do not restart services at the end of installation. =item B<--run-updater=<yes|no>> Set to 'yes' to automatically install needed packages from RHSM, provided the system is registered. Set to 'no' to terminate the installer if any needed packages are missing. =item B<--run-cobbler> Only runs the necessary steps to setup cobbler =item B<--enable-tftp=<yes|no>> Set to 'yes' to automatically enable tftp and xinetd services needed for Cobbler PXE provisioning functionality. Set to 'no' if you do not want the installer to enable these services. =item B<--external-postgresql> Assume the Red Hat Satellite installation uses an external PostgreSQL database (Red Hat Satellite only). =item B<--external-postgresql-over-ssl> When used, installation will assume that external PostgreSQL server allows only connections over SSL. This option is supposed to be used only in conjuction with B<--external-postgresql>. =item B<--managed-db> Setup PostgreSQL database for multi-server installation (database and Spacewalk / Red Hat Satellite on different machines). =back =head1 SEE ALSO See documentation at L<https://github.com/spacewalkproject/spacewalk/> for more details and the Spacewalk server, its configuration and use.. =head1 AUTHOR Devan Goodwin, C<< <dgoodwin at redhat.com> >> =head1 BUGS Please report any bugs using or feature requests using L<https://bugzilla.redhat.com/enter_bug.cgi?product=Spacewalk>. =head1 COPYRIGHT & LICENSE Copyright (c) 2008--2017 Red Hat, Inc. This software is licensed to you under the GNU General Public License, version 2 (GPLv2). There is NO WARRANTY for this software, express or implied, including the implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 along with this software; if not, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. Red Hat trademarks are not licensed under GPLv2. No permission is granted to use or replicate Red Hat trademarks that are incorporated in this software or its documentation. =cut 1; # End of Spacewalk::Setup 07070100000013000041FD0000000000000000000000026615495400000000000000000000000000000000000000000000001500000000spacewalk-setup/salt07070100000014000081B4000000000000000000000001661549540000005A000000000000000000000000000000000000002B00000000spacewalk-setup/salt/salt-ssh-logging.confssh_minion_opts: log_file: ../../../../../var/log/salt-ssh.log log_level: warning 07070100000015000081B40000000000000000000000016615495400000AC4000000000000000000000000000000000000002600000000spacewalk-setup/salt/susemanager.conf# Setup cherrypy rest_cherrypy: port: 9080 host: 127.0.0.1 collect_stats: false expire_responses: false ssl_crt: /etc/salt/pki/api/salt-api.crt ssl_key: /etc/salt/pki/api/salt-api.key # Setup API authentication external_auth: file: ^filename: /etc/salt/master.d/susemanager-users.txt ^hashtype: sha512 admin: - .* - '@wheel' - '@runner' - '@jobs' # Enable netapi clients netapi_enable_clients: - local - local_async - local_batch - runner - runner_async - ssh - wheel - wheel_async # Configure different file roots. Custom salt states should only be placed in /srv/salt. # Users should not touch other directories listed here. file_roots: base: - /usr/share/susemanager/salt - /usr/share/salt-formulas/states - /usr/share/susemanager/formulas/states - /srv/susemanager/salt - /srv/salt # Configure different pillar roots. Custom pillar data should only be placed in /srv/pillar. # Users should not touch other directories listed here. pillar_roots: base: - /srv/pillar # Configure Salt Reactor rules for SUSE Manager. reactor: - 'salt/minion/*/start': - /usr/share/susemanager/reactor/resume_action_chain.sls # Extension modules path extension_modules: /usr/share/susemanager/modules # Runner modules runner_dirs: - /usr/share/susemanager/modules/runners # Engine modules engines_dirs: - /usr/share/susemanager/modules/engines # Master top configuration master_tops: mgr_master_tops: True # Configure external pillar ext_pillar: - suma_minion: True # Scalability configuration parameters # This sets the number of salt-master worker processes. # Raising this number allows the Salt master to cope with a higher number of # slow-responding minions at the same time, but will also consume more main # memory (typically 80 MB per worker). # # In general the default value should be sufficient, unless the following error # appears in minion logs: # # Salt request timed out. The master is not responding. If this error persists after # verifying the master is up, worker_threads may need to be increased worker_threads: 8 # Use several sockets to handle multiple concurrent API calls from Java components sock_pool_size: 30 # Wait for slow minions, or long running operations, longer. Default is 15s in total. # Raise the timeout after 4 minutes. timeout: 120 gather_job_timeout: 120 # Ensure that certifi is part of the thin thin_extra_mods: certifi # Location for storing temporary roster files rosters: - /srv/susemanager/tmp # Allow minions to upload files to master file_recv: True file_recv_max_size: 300 # Maximum size of a message allowed onto the master event bus. The value is expressed in bytes. max_event_size: 4194304 07070100000016000041FD0000000000000000000000046615495400000000000000000000000000000000000000000000001600000000spacewalk-setup/share07070100000017000081B40000000000000000000000016615495400000263000000000000000000000000000000000000002A00000000spacewalk-setup/share/add_appbase.xml.xsl<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Copy all nodes and attributes as they are --> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="/Server/Service/Engine/Host"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:attribute name="appBase">/usr/share/susemanager/www/tomcat/webapps</xsl:attribute> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> 07070100000018000041FD0000000000000000000000026615495400000000000000000000000000000000000000000000002100000000spacewalk-setup/share/defaults.d07070100000019000081B40000000000000000000000016615495400000BAC000000000000000000000000000000000000002F00000000spacewalk-setup/share/defaults.d/defaults.conf# Administrator's email address. Required. # Multiple email addresses can be used, seperated with commas. # # Example: # admin-email = user@example.com, otheruser@example.com admin-email = ## RHN connection information. # # Passed to rhn-register to register the system if it is not already # registered. # # Only required if the system is not already registered, or if the # '--re-register' commandline option is used. Not used at all if the # '--disconnected' commandline option is used. #rhn-username = #rhn-password = # HTTP proxy. Not Required. # # Example: # rhn-http-proxy = proxy.example.com:8080 #rhn-http-proxy = #rhn-http-proxy-username = #rhn-http-proxy-password = # RHN Profile name. Not required. Defaults to the system's hostname # or whatever 'hostname' is set to. # rhn-profile-name = ## SSL certificate information. # The name of your organization. Required. # # Example: # ssl-set-org = Riboflavin, Inc. ssl-set-org = # The unit within the organization that the satellite is assigned to. # Not required. # # Example: # ssl-set-org-unit = Information Systems Department ssl-set-org-unit = # Location information for the SSL certificates. Required. # # Example: # ssl-set-city = New York # ssl-set-state = NY # ssl-set-country = US ssl-set-city = ssl-set-state = ssl-set-country = # Password for CA certificate. Required. Do not lose or forget this # password! # # Example: # ssl-password = c5esWL7s ssl-password = ## Database connection information. # # Required if the database is an external (not embedded) database. # db-user = # db-password = # db-host = # db-name = # db-port = 1521 ## Apache conf.d/ssl.conf virtual host definition reconfiguration # # A value of "Y" or "y" here will cause the installer to make a numbered # backup of the system's existing httpd/conf.d/ssl.conf file and replace # the original with one that's set up properly to work with Spacewalk. # The recommended answer is Y # # ssl-config-sslvhost = # *** Options below this line usually don't need to be set. *** # The Satellite server's hostname. This must be the working FQDN of # the satellite server. # # hostname = # The mount point for the RHN package repository. Defaults to # /var/rhn/satellite # # mount-point = # Mail configuration. # # mail-mx = # mdom = # 'Common name' for the SSL certificates. Defaults to the system's # hostname, or whatever 'hostname' is set to. # # ssl-set-common-name = # The email address for the SSL certificates. Defaults to 'admin-email'. # # ssl-set-email = # The expiration (in years) for the satellite certificates. Defaults # to the number of years until 2037. # # ssl-ca-cert-expiration = # ssl-server-cert-expiration = # *** For troubleshooting/testing only. *** # rhn-parent = satellite.rhn.redhat.com # ssl-dir = # ssl-server-rpm = # If this machine is registered to RHN, install RHEL packages that are # needed for Satellite on top of @base group. # The default is to ask. # # run-updater = 0707010000001A000081B40000000000000000000000016615495400001ADC000000000000000000000000000000000000003200000000spacewalk-setup/share/embedded_diskspace_check.py#!/usr/bin/python """ Checks diskspace sizes for for /rhnsat and /opt. Used only by the install.sh code. Copyright (c) 2002--2012 Red Hat, Inc. All rights reserved. Author: Todd Warner <taw@redhat.com> """ import os import sys import stat import argparse # these numbers are for *after* package installation. DEFAULT_NEEDS = { "/rhnsat": 12 * (2**30), # 12GB "/opt/apps/oracle": 0.5 * (2**30), } # 0.5GB additionally def _listify(seq): if not isinstance(seq, (list, tuple)): seq = [seq] return seq def _unique(seq): """return a list that has unique members""" seq = _listify(seq) useq = {} for elem in seq: useq[elem] = 1 return list(useq.keys()) def _abspath(path): # cleanup absolute path: if os.path.exists(path) and os.path.islink(path): path = os.readlink(path) path = os.path.abspath(os.path.expanduser(os.path.expandvars(path))) return path # pylint: disable-next=invalid-name def _firstDir(path): """takes a path and walks backwards until it finds an existing directory. Follows symlinks. FIXME: need to test against NFS directory. """ path = _abspath(path) while not (os.path.exists(path) and os.path.isdir(path)): path = os.path.dirname(path) return path def _mountpoint(path): """figures out the mountpoint of a directory (or what would be the mountpoint if just about to create the directory). FIXME: need to test against NFS directory. """ path = _firstDir(path) st_dev = os.stat(path)[stat.ST_DEV] # pylint: disable-next=invalid-name _next = os.path.dirname(path) while os.stat(_next)[stat.ST_DEV] == st_dev and path != "/": path = _next # pylint: disable-next=invalid-name _next = os.path.dirname(path) return path def paths2mountpoints(paths): """returns a tuple of two dictionaries - one indexed by path, one indexed by mountpoint: ( {path00: mpoint0?, path01: mpoint0?, ...}, {mpoint00: [path00, path01, ...], mpoint02: [path05, path06, ...], ...}, ) """ paths = _unique(paths) pathsd = {} # 1:1 mpointsd = {} # indexed on mpoints 1:N for path in paths: mpoint = _mountpoint(path) pathsd[path] = mpoint if mpoint not in mpointsd: mpointsd[mpoint] = [] mpointsd[mpoint].append(path) return pathsd, mpointsd def paths2freespace(paths): """returns a dictionary indexed by path: {path00: freespace, path01: freespace, ...} """ paths = _unique(paths) pathsd = {} # 1:1 for path in paths: vfs = os.statvfs(path) pathsd[path] = int(vfs.f_bavail) * vfs.f_bsize return pathsd # pylint: disable-next=invalid-name def getNeeds(needsDict=None): # pylint: disable=redefined-outer-name """returns two dictionaries of fulfilled and unfilled space per mountpoint: unfullfilled = { mountpoint00: (paths, needs, freespace), mountpoint01: (paths, needs, freespace), ..., } fulfilled = { mountpoint00: (paths, needs, freespace), mountpoint01: (paths, needs, freespace), ..., } needsDict is by default DEFAULT_NEEDS (see top of module) """ needsDict = needsDict or DEFAULT_NEEDS # pylint: disable-next=invalid-name mp2pMap = paths2mountpoints(list(needsDict.keys()))[1] # pylint: disable-next=invalid-name mp2fsMap = paths2freespace(list(mp2pMap.keys())) unfulfilled = {} fulfilled = {} for mountpoint, paths in mp2pMap.items(): # pylint: disable-next=invalid-name totalNeeds = 0 for path in paths: # pylint: disable-next=invalid-name totalNeeds = totalNeeds + needsDict[path] freespace = mp2fsMap[mountpoint] if freespace < totalNeeds: unfulfilled[mountpoint] = (paths, totalNeeds, freespace) else: fulfilled[mountpoint] = (paths, totalNeeds, freespace) return unfulfilled, fulfilled # pylint: disable-next=invalid-name def _humanReadable(n): s = repr(n) if n >= 2**10: # pylint: disable-next=consider-using-f-string s = "%.1fK" % (n / (2**10)) if n >= 2**20: # pylint: disable-next=consider-using-f-string s = "%.1fM" % (n / (2**20)) if n >= 2**30: # pylint: disable-next=consider-using-f-string s = "%.1fG" % (n / (2**30)) return s # pylint: disable-next=invalid-name def check(needsDict=None): # pylint: disable=redefined-outer-name """determine failed needs if any given needsDict. needsDict is by default DEFAULT_NEEDS (see top of module) """ needsDict = needsDict or DEFAULT_NEEDS unfulfilled = getNeeds(needsDict)[0] if unfulfilled: sys.stderr.write( "ERROR: diskspace does not meet minimum system " "requirements:\n" ) items = unfulfilled.items() # pylint: disable-next=invalid-name lenItems = len(items) for mountpoint, data in items: # pylint: disable-next=invalid-name paths, totalNeeds, freespace = data # pylint: disable-next=consider-using-f-string msg = """\ Mountpoint: %s Relevant paths serviced by mountpoint: %s Disk space needed: %s bytes (app. %s) Disk space available: %s bytes (app. %s) """ % ( mountpoint, ", ".join(paths), totalNeeds, _humanReadable(totalNeeds), freespace, _humanReadable(freespace), ) sys.stderr.write(msg) # pylint: disable-next=invalid-name lenItems = lenItems - 1 if lenItems: sys.stderr.write("\n") if unfulfilled: return 1 return 0 def main(): """ Main app function. """ prs = argparse.ArgumentParser(description="Check embedded disk space") prs.add_argument( "DEFAULT_NEEDS", nargs="+", help=( "Set default map of failed needs: [directory] [size] ... " "Example: /var/lig/pgsql/data 12288" ), ) args = prs.parse_args() if not len(args.DEFAULT_NEEDS) % 2: needs_dict = {} for directory, size in zip(args.DEFAULT_NEEDS[0::2], args.DEFAULT_NEEDS[1::2]): try: needs_dict[directory] = int(size) * 2**20 except ValueError as err: prs.error(err) sys.exit(check(needs_dict) or 0) else: prs.print_help() if __name__ == "__main__": # pylint: disable-next=pointless-string-statement """ Run main function if this script is called directly. """ # pylint: disable=pointless-string-statement main() 0707010000001B000081B4000000000000000000000001661549540000001E000000000000000000000000000000000000002D00000000spacewalk-setup/share/mod_ssl.conf.sslfips.1^[ \t]*SSLFIPS.*\n SSLFIPS on 0707010000001C000081B4000000000000000000000001661549540000002A000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.1^[ \t]*RewriteEngine.*\n RewriteEngine on 0707010000001D000081B40000000000000000000000016615495400000031000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.2^[ \t]*RewriteOptions.*\n RewriteOptions inherit 0707010000001E000081B4000000000000000000000001661549540000002C000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.3^[ \t]*SSLProxyEngine.*\n SSLProxyEngine on 0707010000001F000081B40000000000000000000000016615495400000052000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.4^[ \t]*SSLCertificateFile.*\n SSLCertificateFile /etc/pki/tls/certs/spacewalk.crt 07070100000020000081B4000000000000000000000001661549540000005A000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.5^[ \t]*SSLCertificateKeyFile.*\n SSLCertificateKeyFile /etc/pki/tls/private/spacewalk.key 07070100000021000081B40000000000000000000000016615495400000077000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.6[ \t]*<IfModule mod_jk.c>\s*\n\s*JkMountCopy.*\n\s*</IfModule>\s*\n <IfModule mod_jk.c> JkMountCopy On </IfModule> 07070100000022000081B40000000000000000000000016615495400000049000000000000000000000000000000000000002B00000000spacewalk-setup/share/mod_ssl.conf.vhost.7^[ \t]*DocumentRoot.*\n DocumentRoot "/usr/share/susemanager/www/htdocs" 07070100000023000081B4000000000000000000000001661549540000009F000000000000000000000000000000000000002300000000spacewalk-setup/share/old-jvm-listjava-1.4.2-ibm java-1.4.2-ibm-devel java-1.5.0-ibm java-1.5.0-ibm-devel java-1.5.0-sun java-1.5.0-sun-devel java-epoch-bridge bouncycastle bouncycastle-jdk1.5 07070100000024000081FD000000000000000000000001661549540000042A000000000000000000000000000000000000002400000000spacewalk-setup/share/run_pytest.sh#!/bin/bash # # This is a temporary solution before all # tests are running on docker. # # Author: bo@suse.de # VENV=".spacewalk-setup-env" # # Setup environment # function setup_venv () { if [ ! -d $VENV ]; then python3.6 -m venv $VENV source $VENV/bin/activate pip install --upgrade pip pip install six pip install pytest fi echo "NOTE: Virtual setup environment as $VENV" } # # Ignore environment # function git_ignore_venv () { GITIGNORE=$(find -maxdepth 1 -name '.gitignore') if [ "$GITIGNORE" == "" ]; then echo $VENV >> .gitignore else ENV_ADDED=$(grep $VENV .gitignore) if [ "$ENV_ADDED" == "" ]; then echo $VENV >> .gitignore fi fi } # # Activate virtual environment # function activate_venv () { which deactivate &>/dev/null if [ "$?" == "1" ]; then source $VENV/bin/activate fi } setup_venv; git_ignore_venv; activate_venv; HERE=$(cd $(dirname "${BASH_SOURCE[0]}") >/dev/null 2>&1 && pwd) export PYTHONPATH="$PYTHONPATH:$HERE:$HERE/tests" pytest --disable-warnings --tb=native --color=yes -svv 07070100000025000081B40000000000000000000000016615495400000F62000000000000000000000000000000000000002500000000spacewalk-setup/share/server.xml.xsl<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="no" omit-xml-declaration="yes" /> <xsl:preserve-space elements="Connector"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/Server/Service[@name='Catalina']/Connector[@port='8009' and (not(@address) or @address='127.0.0.1')]"> <xsl:element name="Connector"> <xsl:copy-of select="@*" /> <xsl:attribute name="URIEncoding">UTF-8</xsl:attribute> <xsl:attribute name="address">127.0.0.1</xsl:attribute> <xsl:attribute name="maxThreads">150</xsl:attribute> <xsl:attribute name="connectionTimeout">900000</xsl:attribute> <xsl:attribute name="keepAliveTimeout">300000</xsl:attribute> <xsl:attribute name="secretRequired">false</xsl:attribute> </xsl:element> <xsl:if test="not(../Connector[@port='8009' and @address='::1'])"> <xsl:copy-of select="preceding-sibling::node()[last()][self::text()]" /> <xsl:element name="Connector"> <xsl:copy-of select="@*" /> <xsl:attribute name="URIEncoding">UTF-8</xsl:attribute> <xsl:attribute name="address">::1</xsl:attribute> <xsl:attribute name="maxThreads">150</xsl:attribute> <xsl:attribute name="connectionTimeout">900000</xsl:attribute> <xsl:attribute name="keepAliveTimeout">300000</xsl:attribute> <xsl:attribute name="secretRequired">false</xsl:attribute> </xsl:element> </xsl:if> </xsl:template> <xsl:template match="/Server/Service[@name='Catalina']/Connector[@port='8009' and @address='::1']"> <xsl:element name="Connector"> <xsl:copy-of select="@*" /> <xsl:attribute name="URIEncoding">UTF-8</xsl:attribute> <xsl:attribute name="address">::1</xsl:attribute> <xsl:attribute name="maxThreads">150</xsl:attribute> <xsl:attribute name="connectionTimeout">900000</xsl:attribute> <xsl:attribute name="keepAliveTimeout">300000</xsl:attribute> <xsl:attribute name="secretRequired">false</xsl:attribute> </xsl:element> </xsl:template> <xsl:template match="/Server/Service[@name='Catalina'][not(Connector[@port='8009'])]"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:text> </xsl:text> <xsl:element name="Connector"> <xsl:attribute name="port">8009</xsl:attribute> <xsl:attribute name="protocol">AJP/1.3</xsl:attribute> <xsl:attribute name="redirectPort">8443</xsl:attribute> <xsl:attribute name="URIEncoding">UTF-8</xsl:attribute> <xsl:attribute name="address">127.0.0.1</xsl:attribute> <xsl:attribute name="maxThreads">150</xsl:attribute> <xsl:attribute name="connectionTimeout">900000</xsl:attribute> <xsl:attribute name="keepAliveTimeout">300000</xsl:attribute> <xsl:attribute name="secretRequired">false</xsl:attribute> </xsl:element> <xsl:text> </xsl:text> <xsl:element name="Connector"> <xsl:attribute name="port">8009</xsl:attribute> <xsl:attribute name="protocol">AJP/1.3</xsl:attribute> <xsl:attribute name="redirectPort">8443</xsl:attribute> <xsl:attribute name="URIEncoding">UTF-8</xsl:attribute> <xsl:attribute name="address">::1</xsl:attribute> <xsl:attribute name="maxThreads">150</xsl:attribute> <xsl:attribute name="connectionTimeout">900000</xsl:attribute> <xsl:attribute name="keepAliveTimeout">300000</xsl:attribute> <xsl:attribute name="secretRequired">false</xsl:attribute> </xsl:element> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <xsl:template match="/Server/Service[@name='Catalina']/Connector[@port='8080']"> <xsl:element name="Connector"> <xsl:copy-of select="@*" /> <xsl:attribute name="URIEncoding">UTF-8</xsl:attribute> <xsl:attribute name="address">127.0.0.1</xsl:attribute> </xsl:element> </xsl:template> </xsl:stylesheet> 07070100000026000081B40000000000000000000000016615495400000278000000000000000000000000000000000000002C00000000spacewalk-setup/share/server_update.xml.xsl<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="no" omit-xml-declaration="yes" /> <xsl:preserve-space elements="Connector"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/Server/Service[@name='Catalina']/Connector[@connectionTimeout='20000']"> <xsl:element name="Connector"> <xsl:copy-of select="@*" /> <xsl:attribute name="connectionTimeout">900000</xsl:attribute> </xsl:element> </xsl:template> </xsl:stylesheet> 07070100000027000041FD0000000000000000000000026615495400000000000000000000000000000000000000000000001C00000000spacewalk-setup/share/tests07070100000028000081B4000000000000000000000001661549540000029A000000000000000000000000000000000000003D00000000spacewalk-setup/share/tests/test_embedded_diskspace_check.py# coding: utf-8 """ Test embeded diskspace check. """ import embedded_diskspace_check from unittest.mock import MagicMock, patch class TestEmbeddedDiskspaceCheck: """ Test embedded diskspace check. """ @patch("sys.exit", MagicMock()) @patch("sys.argv", ["dummy", "/tmp", "100000", "/etc", "2000"]) def test_cli_arguments(self): """ Test command line arguments. """ with patch("embedded_diskspace_check.check", MagicMock()) as edcc: embedded_diskspace_check.main() args = edcc.call_args_list[0][0][0] assert args["/tmp"] == 104857600000 assert args["/etc"] == 2097152000 07070100000029000081B400000000000000000000000166154954000000E8000000000000000000000000000000000000002C00000000spacewalk-setup/share/tomcat_java_opts.confJAVA_OPTS="$JAVA_OPTS -ea -Xms256m -Xmx1G -Djava.awt.headless=true -Dorg.xml.sax.driver=com.redhat.rhn.frontend.xmlrpc.util.RhnSAXParser -Dorg.apache.tomcat.util.http.Parameters.MAX_COUNT=1024 -Dnet.sf.ehcache.skipUpdateCheck=true" 0707010000002A000081B4000000000000000000000001661549540000009D000000000000000000000000000000000000003100000000spacewalk-setup/share/tomcat_java_opts_suse.confJAVA_OPTS="$JAVA_OPTS --add-exports java.annotation/javax.annotation.security=ALL-UNNAMED --add-opens java.annotation/javax.annotation.security=ALL-UNNAMED" 0707010000002B000081B40000000000000000000000016615495400000138000000000000000000000000000000000000002700000000spacewalk-setup/share/vhost-nossl.conf<VirtualHost _default_:80> # General setup for the virtual host DocumentRoot "/usr/share/susemanager/www/htdocs" ErrorLog /var/log/apache2/error_log TransferLog /var/log/apache2/access_log RewriteEngine on RewriteOptions inherit <IfModule mod_jk.c> JkMountCopy On </IfModule> </VirtualHost> 0707010000002C000081B40000000000000000000000016615495400006CC4000000000000000000000000000000000000002800000000spacewalk-setup/spacewalk-setup.changes------------------------------------------------------------------- Thu Apr 04 18:01:55 CEST 2024 - marina.latini@suse.com - version 5.0.4-0 * Replace java 11 with java 17 * set cobbler.host to localhost (bsc#1219887) * set uyuni_authentication_endpoint to http://localhost (bsc#1219887) ------------------------------------------------------------------- Mon Jan 29 12:00:29 CET 2024 - rosuna@suse.com - version 5.0.3-1 * Apply Black and Pylint to enforce Python style ------------------------------------------------------------------- Thu Jan 18 11:03:34 CET 2024 - jgonzalez@suse.com - version 5.0.2-1 * schema dir moved to /usr/share/susemanager/db ------------------------------------------------------------------- Tue Jan 16 08:06:55 CET 2024 - jgonzalez@suse.com - version 5.0.1-1 * Updated query to the new credentials structure * fix setting scc password during setup ------------------------------------------------------------------- Fri Dec 15 17:22:42 CET 2023 - rosuna@suse.com - version 4.4.11-1 * Move all file managed by RPM from /srv to /usr/share/susemanager ------------------------------------------------------------------- Wed Nov 01 20:22:05 CET 2023 - marina.latini@suse.com - version 4.4.10-1 * Use localhost for Cobbler client to avoid hairpins * Replace "filesize" in spec file with "stat" to allow installation on Enterprise Linux. ------------------------------------------------------------------- Mon Sep 18 14:35:43 CEST 2023 - rosuna@suse.com - version 4.4.9-1 * remove storing CA in DB directly as it is now part of mgr-ssl-cert-setup (bsc#1212856) * Do not rely on rpm runtime status, rather check rhn.conf if is configured (bsc#1210935) * Drop usage of salt.ext.six in embedded_diskspace_check * drop spacewalk-setup-sudoers which does only cleanups which should be applied already since several years. The functionality is obsolete * Don't force ssl verification to setup reportdb using localhost * Setup cobbler with provided FQDN rather than from system discovery * Print the command that is running in Setup.pm to ease debugging * Fix to detect correct Apache group instead of assuming it (gh#7092) * Align /var/spacewalk folder permissions with uyuni-base-server package. * Move set tomcat user setup to uyuni-base spec file * Add option to disable SSL setup * Corrected requirement to install Tomcat before spacewalk-setup. * Automatically detect PostgreSQL service and data folder name. ------------------------------------------------------------------- Wed Apr 19 13:00:08 CEST 2023 - marina.latini@suse.com - version 4.4.8-1 * Persist report_db_sslrootcert value (bsc#1210349) * Fix migration test * Escape `%` in spec file. * remove useless tomcat configuration (bsc#1206191) * use template for reportdb configuration (bsc#1206783) * Enable netapi clients in master configuration (required for Salt 3006) ------------------------------------------------------------------- Tue Feb 21 12:29:07 CET 2023 - jgonzalez@suse.com - version 4.4.7-1 * Do not specify a cobbler version, as that is now centralized at the patterns ------------------------------------------------------------------- Wed Dec 14 14:07:13 CET 2022 - jgonzalez@suse.com - version 4.4.6-1 * remove jabberd and osa-dispatcher ------------------------------------------------------------------- Fri Nov 18 15:01:37 CET 2022 - jgonzalez@suse.com - version 4.4.5-1 * Re-added alternative usage of perl-Net-LibIDN2. ------------------------------------------------------------------- Mon Nov 14 15:07:32 CET 2022 - jgonzalez@suse.com - version 4.4.4-1 * Fix possible wrong autoinstall value from Cobbler collections (bsc#1203478) ------------------------------------------------------------------- Fri Nov 04 17:14:50 CET 2022 - jgonzalez@suse.com - version 4.4.3-1 * Execute migration of Cobbler version 2 collections (bsc#1203478) ------------------------------------------------------------------- Thu Oct 20 10:41:06 CEST 2022 - jgonzalez@suse.com - version 4.4.2-1 * Fix detected issues to perform migration of Cobbler settings and collections. ------------------------------------------------------------------- Wed Sep 28 10:25:24 CEST 2022 - jgonzalez@suse.com - version 4.4.1-1 * Trigger migration of Cobbler settings and collections if necessary during package installation (bsc#1203478) * fix prototype missmatch in idn_to_ascii (bsc#1203385) * Execute "cobbler mkloaders" when setting up cobbler * Adjust next_server cobbler settings for cobbler >= 3.3.1 * Add options for connecting to a remote postgres instance ------------------------------------------------------------------- Wed Jul 27 14:02:50 CEST 2022 - jgonzalez@suse.com - version 4.3.10-1 * spacewalk-setup-cobbler assumes /etc/apache2/conf.d now as a default instead of /etc/httpd/conf.d (bsc#1198356) * Allow alternative usage of perl-Net-LibIDN2. ------------------------------------------------------------------- Wed May 04 15:23:20 CEST 2022 - jgonzalez@suse.com - version 4.3.9-1 * remove creation of extra java truststores for database SSL connections ------------------------------------------------------------------- Tue Apr 19 12:07:06 CEST 2022 - jgonzalez@suse.com - version 4.3.8-1 * delopy local CA under different name in the truststore to avoid conflicts with CAs deployed during a registration ------------------------------------------------------------------- Fri Mar 11 14:53:20 CET 2022 - jgonzalez@suse.com - version 4.3.7-1 * drop the reporting DB when clear-db option is set * Remove pylint according to Fedora package guidelines. ------------------------------------------------------------------- Tue Feb 15 10:04:35 CET 2022 - jgonzalez@suse.com - version 4.3.6-1 * setup reporting database * integrate new TLS Certificate setup and deployment tool ------------------------------------------------------------------- Tue Jan 18 13:59:44 CET 2022 - jgonzalez@suse.com - version 4.3.5-1 * Remove cluster providers support * Merge all external pillars into one * During upgrade, set tomcat connector connectionTimeout to 900000 if the previous values is the old default (20000) * Increase "max_event_size" value for the Salt master (bsc#1191340) ------------------------------------------------------------------- Fri Dec 03 13:10:28 CET 2021 - jgonzalez@suse.com - version 4.3.4-1 * Allow configuration of Cobbler > 3.2.0 ------------------------------------------------------------------- Fri Nov 05 13:53:01 CET 2021 - jgonzalez@suse.com - version 4.3.3-1 * Add postgresql external pillar configuration * Simplified perl module dependency. * Fixed com.sun.bind issue on package update. * Enabled pylint for all builds but don't stop on error. * Leave Cobbler bootloader directory at the default (bsc#1187708) * Don't delete cobbler.conf contents. * Fixed FileNotFoundError on cobbler setup. * cobbler20-setup was removed * spacewalk-setup-cobbler was reimplemented in Python * Config files for Cobbler don't get edited in place anymore, thus the original ones are saved with a ".backup" suffix ------------------------------------------------------------------- Fri Sep 17 12:11:36 CEST 2021 - jgonzalez@suse.com - version 4.3.2-1 * Don't delete cobbler.conf contents. * Fixed FileNotFoundError on cobbler setup. * cobbler20-setup was removed * spacewalk-setup-cobbler was reimplemented in Python * Config files for Cobbler don't get edited in place anymore, thus the original ones are saved with a ".backup" suffix ------------------------------------------------------------------- Mon Aug 09 11:05:32 CEST 2021 - jgonzalez@suse.com - version 4.3.1-1 - Enable logging for salt SSH - Increase max size for uploaded files to Salt master ------------------------------------------------------------------- Fri Apr 16 13:23:27 CEST 2021 - jgonzalez@suse.com - version 4.2.6-1 - set AJP parameters differently to prevent AH00992, AH00877 and AH01030: ajp_ilink_receive() can't receive header errors (bsc#1179271) - Use syslinux folder for cobbler loaders. ------------------------------------------------------------------- Fri Feb 12 14:30:21 CET 2021 - jgonzalez@suse.com - version 4.2.5-1 - Added Apache configuration updates for Cobbler. ------------------------------------------------------------------- Wed Jan 27 13:05:48 CET 2021 - jgonzalez@suse.com - version 4.2.4-1 - Use Java module com.sun.bind only for SUSE systems. - Added RHEL Apache gid handling. - Drop the ssl_available option (SSL is always present) - Added dynamic path for trust store and doc root. - Updated SPEC for RHEL and Fedora. ------------------------------------------------------------------- Thu Dec 03 13:51:33 CET 2020 - jgonzalez@suse.com - version 4.2.3-1 - Fixed cobbler version detection. - Generalised cobblerd service detection. ------------------------------------------------------------------- Wed Nov 25 12:24:50 CET 2020 - jgonzalez@suse.com - version 4.2.2-1 - add sock_pool_size setting by default for better performance ------------------------------------------------------------------- Fri Sep 18 12:34:52 CEST 2020 - jgonzalez@suse.com - version 4.2.1-1 - Update package version to 4.2.0 ------------------------------------------------------------------- Wed Sep 16 16:58:25 CEST 2020 - jgonzalez@suse.com - version 4.1.6-1 - Use the Salt API in authenticated and encrypted form (bsc#1175884, CVE-2020-8028) ------------------------------------------------------------------- Wed Jun 10 12:20:44 CEST 2020 - jgonzalez@suse.com - version 4.1.5-1 - Enable CaaSP cluster provider ------------------------------------------------------------------- Wed Mar 11 10:56:46 CET 2020 - jgonzalez@suse.com - version 4.1.4-1 - create AJP connector for tomcat if it does not exist (bsc#1165927, bsc#1166388) ------------------------------------------------------------------- Mon Feb 17 12:51:58 CET 2020 - jgonzalez@suse.com - version 4.1.3-1 - spell correctly "successful" and "successfully" ------------------------------------------------------------------- Wed Jan 22 12:13:54 CET 2020 - jgonzalez@suse.com - version 4.1.2-1 - Fix spacewalk-setup-httpd for future FIPS support at SLE and openSUSE ------------------------------------------------------------------- Wed Nov 27 17:03:14 CET 2019 - jgonzalez@suse.com - version 4.1.1-1 - Bump version to 4.1.0 (bsc#1154940) - fix cobbler authentication module configuration required for new cobbler package - prevent CherryPy timeouts (bsc#1118175, bsc#1149343) - configure 150 Tomcat workers by default, matching httpds MaxClients ------------------------------------------------------------------- Wed Jul 31 17:36:47 CEST 2019 - jgonzalez@suse.com - version 4.0.9-1 - Add support for salt formulas for standalone salt ------------------------------------------------------------------- Wed May 15 15:18:10 CEST 2019 - jgonzalez@suse.com - version 4.0.8-1 - SPEC cleanup - fix check for empty lines in rhn.conf for spacewalk-setup (bsc#1133560) ------------------------------------------------------------------- Mon Apr 22 12:15:57 CEST 2019 - jgonzalez@suse.com - version 4.0.7-1 - Generate SLE11 specific ssl-cert-osimage package - add makefile and configuration for the pylint - Add proper argument parsing to the embedded diskspace check. - Fix Python3 porting issues ------------------------------------------------------------------- Wed Feb 27 13:03:51 CET 2019 - jgonzalez@suse.com - version 4.0.6-1 - enable and start tftp socket (bsc#1124822) ------------------------------------------------------------------- Thu Jan 31 09:42:41 CET 2019 - jgonzalez@suse.com - version 4.0.5-1 - Add Java module options for Tomcat needed when running on Java 11 - Point to the correct log file when tomcat is not able to start - Fix distribution detection to work with openSUSE Leap 15 and SLE 15 ------------------------------------------------------------------- Wed Jan 16 12:24:40 CET 2019 - jgonzalez@suse.com - version 4.0.4-1 - Fix building for Python3 ------------------------------------------------------------------- Mon Dec 17 14:41:40 CET 2018 - jgonzalez@suse.com - version 4.0.3-1 - Add support for Python 3 on spacewalk-setup - use a Salt engine to process return results (bsc#1099988) - increase maximum number of threads and open files for taskomatic (bsc#1111966) ------------------------------------------------------------------- Fri Oct 26 10:42:58 CEST 2018 - jgonzalez@suse.com - version 4.0.2-1 - clean up correct system sudoers file (bsc#1099517) ------------------------------------------------------------------- Fri Aug 10 15:30:39 CEST 2018 - jgonzalez@suse.com - version 4.0.1-1 - Bump version to 4.0.0 (bsc#1104034) - Feat: add OS Image building with Kiwi FATE#322959 FATE#323057 FATE#323056 - Fix copyright for the package specfile (bsc#1103696) - sudoers file is now in /etc/sudoers.d/spacewalk (bsc#1099517) ------------------------------------------------------------------- Tue Jun 05 10:11:13 CEST 2018 - jgonzalez@suse.com - version 2.8.7.2-1 - remove RH defaults (bsc#1091993) ------------------------------------------------------------------- Mon Apr 23 09:16:36 CEST 2018 - jgonzalez@suse.com - version 2.8.7.1-1 - Sync with upstream (bsc#1083294) ------------------------------------------------------------------- Mon Mar 26 09:04:58 CEST 2018 - jgonzalez@suse.com - version 2.8.5.3-1 - Sync with upstream (bsc#1083294) - Configure Salt Reactor for handle Action Chain execution on Minions ------------------------------------------------------------------- Mon Mar 05 08:56:03 CET 2018 - jgonzalez@suse.com - version 2.8.5.2-1 - remove clean section from spec (bsc#1083294) ------------------------------------------------------------------- Wed Feb 28 09:54:25 CET 2018 - jgonzalez@suse.com - version 2.8.5.1-1 - Fix FIPS detection for kernels without CONFIG_CRYPTO_FIPS (as in openSUSE) - Enable and start atftpd.socket instead of atftpd.service when atftp is using systemd natively. ------------------------------------------------------------------- Wed Jan 17 10:40:16 CET 2018 - jgonzalez@suse.com - version 2.8.4.1-1 - Remove temporary workaround (bsc#1064520) - add temporary setting of user to salt - Bumping package versions for 2.8. - point users to proper log on tomcat 7+ ------------------------------------------------------------------- Wed May 03 15:54:47 CEST 2017 - michele.bologna@suse.com - version 2.7.4.2-1 - add new option skip-services-restart - adjust log path on tomcat 7+ ------------------------------------------------------------------- Mon Apr 03 14:50:04 CEST 2017 - mc@suse.de - version 2.7.4.1-1 - enhance check for Oracle 12.2 Database ------------------------------------------------------------------- Fri Mar 31 09:37:30 CEST 2017 - mc@suse.de - version 2.7.3.1-1 - create /var/spacewalk/systems in spacewalk-setup and ensure perms on upgrade - support cnames in mgr-setup and spacewalk-setup (bsc#1029899) ------------------------------------------------------------------- Tue Mar 07 14:40:13 CET 2017 - mc@suse.de - version 2.7.2.1-1 - add xccdf result xslt - Migrating Fedorahosted to GitHub - reset stdin for failed connections - don't leak output of cobbler sync into installer - change RHN on RHSM in installer script ------------------------------------------------------------------- Tue Feb 07 15:23:47 CET 2017 - michele.bologna@suse.com - version 2.7.0.2-1 - Store temporary roster in configured location (bsc#1019672) ------------------------------------------------------------------- Wed Jan 11 16:36:20 CET 2017 - michele.bologna@suse.com - version 2.7.0.1-1 - Version 2.7.0 ------------------------------------------------------------------- Fri Dec 16 12:12:07 CET 2016 - michele.bologna@suse.com - version 2.5.3.11-1 - Preventing stderr output from systemctl calls (bsc#1015055) - Removing non-used '/srv/susemanager/pillar' - Removing '/usr/share/susemanager/pillar' path - Retreiving SUMA static pillar data from ext_pillar (bsc1010674) ------------------------------------------------------------------- Mon Nov 07 11:02:51 CET 2016 - michele.bologna@suse.com - version 2.5.3.10-1 - Enforce putting certifi module in salt thin (bsc#990439) ------------------------------------------------------------------- Thu Oct 06 14:50:45 CEST 2016 - mc@suse.de - version 2.5.3.9-1 - Commented on file_roots/pillar_roots - Added formula directories and formulas.sls to setup script - master_tops module provides static top information - Merging top.sls files in base env (bsc#986770) ------------------------------------------------------------------- Mon Jul 18 14:21:18 CEST 2016 - jrenner@suse.com - version 2.5.3.8-1 - change path to oracle LD Config file ------------------------------------------------------------------- Tue Apr 12 17:20:43 CEST 2016 - mc@suse.de - version 2.5.3.7-1 - use static file to configure salt-master in SUSE Manager - add ext_pillar to master.d/susemanager.conf (bsc#974853) ------------------------------------------------------------------- Wed Apr 06 08:45:13 CEST 2016 - mc@suse.de - version 2.5.3.6-1 - Use localhost instead of hostname during setup, so we do not rely on correct proxy setup (bsc#970690) - Set better defaults according to initial scalability tests - Raise the maximum memory available for Tomcat to accommodate for >100 minions onboarding at once (bsc#971573) - enable and start atftpd (bsc#972168) ------------------------------------------------------------------- Mon Mar 21 16:32:21 CET 2016 - mc@suse.de - version 2.5.3.5-1 - Remove SHA256 explicit master configuration as it is shipped now as default with our salt package - Use SHA256 hash type for the Salt Master instead of default MD5. ------------------------------------------------------------------- Wed Mar 09 11:31:48 CET 2016 - mc@suse.de - version 2.5.3.4-1 - configure pillar for salt-master ------------------------------------------------------------------- Wed Mar 02 11:23:45 CET 2016 - mc@suse.de - version 2.5.3.3-1 - rename Mirror Credentials to Organization Credentials at user visible places ------------------------------------------------------------------- Tue Jan 26 13:55:36 CET 2016 - mc@suse.de - version 2.5.3.2-1 - fix spacewalk-setup post script (bsc#962546) ------------------------------------------------------------------- Wed Dec 16 11:10:39 CET 2015 - mc@suse.de - version 2.5.3.1-1 - setup called with option db_only should not configure tomcat - removing create first org code from installer ------------------------------------------------------------------- Thu Dec 10 17:50:32 CET 2015 - mc@suse.de - version 2.5.2.2-1 - Fix a syntax errors when writing the configuration for the Salt Master ------------------------------------------------------------------- Mon Nov 30 10:51:21 CET 2015 - mc@suse.de - version 2.5.2.1-1 - Configure multiple file roots for the Salt Master - migration from SUMA 2.1 to SUMA 3 - adapt checks for cert trust dirs - use --upgrade option for sw-dump-schema during migrations ------------------------------------------------------------------- Wed Oct 07 13:58:26 CEST 2015 - mc@suse.de - version 2.5.0.1-1 - Remove certificate handling from setup (FATE#311619) - Remove monitoring setup ------------------------------------------------------------------- Mon Jun 22 15:49:07 CEST 2015 - jrenner@suse.de - version 2.1.14.12-1 - configure tomcat with maxThreads=200 and timeout 20 sec (bsc#922923) - CVE-2014-8162 - Use newly introduced SAXParser class (bsc#922525) - introduce variables to import own certificates on setup ------------------------------------------------------------------- Wed Apr 08 09:20:09 CEST 2015 - mc@suse.de - version 2.1.14.11-1 - fix typo: use chmod to change permissions ------------------------------------------------------------------- Tue Mar 31 14:31:24 CEST 2015 - mc@suse.de - version 2.1.14.10-1 - add read permissions for tomcat to the NCCcredentials file ------------------------------------------------------------------- Tue Feb 03 13:19:29 CET 2015 - mc@suse.de - version 2.1.14.9-1 - Getting rid of Tabs and trailing spaces ------------------------------------------------------------------- Fri Nov 07 12:59:45 CET 2014 - mc@suse.de - version 2.1.14.8-1 - no activation if db population should be skipped (bsc#900956) ------------------------------------------------------------------- Tue Oct 14 15:14:21 CEST 2014 - mc@suse.de - version 2.1.14.7-1 - give tomcat read permissions on the NCCcredentials file - setup with scc credentials in DB ------------------------------------------------------------------- Fri Sep 12 14:58:56 CEST 2014 - mc@suse.de - version 2.1.14.6-1 - Do not enable spacewalk-service in runlevel 4 (bnc#879992) ------------------------------------------------------------------- Tue Jun 17 10:12:51 CEST 2014 - jrenner@suse.de - version 2.1.14.5-1 - Use curl instead of libwww-perl - Setup /etc/sudoers in SUSE Manager upgrade scripts (bnc#881711) ------------------------------------------------------------------- Tue May 27 17:09:55 CEST 2014 - mc@suse.de - version 2.1.14.4-1 - fix regex for a more lazy match to remove JAVA_OPTS from tomcat6.conf ------------------------------------------------------------------- Fri May 16 12:46:39 CEST 2014 - mc@suse.de - version 2.1.14.3-1 - editarea has been replaced with ace-editor ------------------------------------------------------------------- Thu Mar 27 10:16:48 CET 2014 - fcastelli@suse.com - version 2.1.14.2-1 - Add mgr-ncc-sync to the sudo commands - jpam.so is in /usr/lib even on x86_64 ------------------------------------------------------------------- Fri Feb 07 13:41:07 CET 2014 - mc@suse.de - version 2.1.14.1-1 - remove setup embedded oracle code - add oracle library path directly to commandline - install tomcat6 filter - disable ehcache check for updates - spacewalk-setup-tomcat packaging - Updating the copyright years info ------------------------------------------------------------------- Mon Jan 13 09:27:50 CET 2014 - mc@suse.de - version 2.1.7.1-1 - external PG: remove postgresql from spacewalk services ------------------------------------------------------------------- Mon Dec 09 16:36:26 CET 2013 - mc@suse.de - version 2.1.6.1-1 - switch to 2.1 ------------------------------------------------------------------- Wed Jun 12 13:36:03 CEST 2013 - mc@suse.de - version 1.7.9.11-1 - suppress uninitialized value messages ------------------------------------------------------------------- Fri Sep 28 16:37:33 CEST 2012 - mc@suse.de - version 1.7.9.10-1 - Read system proxy values during setup and use them as default. ------------------------------------------------------------------- Fri Aug 03 18:28:37 CEST 2012 - mc@suse.de - version 1.7.9.9-1 - update tomcat java opts with Parameters.MAX_COUNT - added tftp server options to cobbler modules.conf file ------------------------------------------------------------------- Thu Aug 02 16:31:17 CEST 2012 - mc@suse.de - version 1.7.9.8-1 - increase allowed parameter count for tomcat ------------------------------------------------------------------- Mon Jul 16 15:28:31 CEST 2012 - ug@suse.de - version 1.7.9.7-1 - Exit if starting tomcat did not pass. ------------------------------------------------------------------- Tue Jul 10 15:02:27 CEST 2012 - ug@suse.de - changed cobbler-setup to use the FQDN as hostname (bnc#768135) ------------------------------------------------------------------- Wed Jul 4 16:49:45 CEST 2012 - ug@suse.de - fix LD_LIBRARY_PATH in tomcat6.conf in case of upgrade (bnc#769909) ------------------------------------------------------------------- Thu Jun 21 11:14:13 CEST 2012 - jrenner@suse.de - version 1.7.9.6-1 - add LICENSE file and change mention Artistic licence to GPLv2 (bnc#764855) - Suppress db notices when clearing the schema ------------------------------------------------------------------- Thu May 31 10:58:02 CEST 2012 - mc@suse.de - version 1.7.9.5-1 - get rid of jabberd xsl templates in spacewalk-setup ------------------------------------------------------------------- Mon May 14 10:59:03 CEST 2012 - mc@suse.de - version 1.7.9.4-1 - remove usage of rhn_quota package - spacewalk-setup-cobbler: extend verbose output ------------------------------------------------------------------- Fri Apr 27 16:15:13 CEST 2012 - mc@suse.de - version 1.7.9.3-1 - call cobbler sync only once - modify Makefile.PL for new cobbler setup layout - spacewalk-setup-cobbler: script to configure cobbler for Spacewalk - Rename cobbler-setup to cobbler20-setup - Create deploy.sql on PostgreSQL as well ------------------------------------------------------------------- Tue Apr 24 11:48:16 CEST 2012 - ug@suse.de - avoid "cobbler not running" warning during setup when cobbler version greater than 2.0 is in use ------------------------------------------------------------------- Fri Apr 13 15:46:24 CEST 2012 - mc@suse.de - version 1.7.9.2-1 - fixed clearing db for postgresql installation - remove RHN_DB_USERNAME from monitoring scout configuration - remove RHN_DB_PASSWD from monitoring scout configuration - remove RHN_DB_NAME from monitoring scout configuration - remove tableowner from monitoring scout configuration ------------------------------------------------------------------- Wed Mar 21 17:05:55 CET 2012 - mc@suse.de - version 1.7.9.1-1 - Bumping package version ------------------------------------------------------------------- Mon Feb 13 15:37:12 CET 2012 - ug@suse.de - avoid cobbler exception during startup (bnc#746718) ------------------------------------------------------------------- Wed Dec 21 14:34:21 CET 2011 - ug@suse.de - switched spacewalk-setup to atftpd ------------------------------------------------------------------- Thu Aug 18 14:30:05 CEST 2011 - iartarisi@suse.cz - fixed AttributeError: 'module' object has no attribute 'rhnConfig' ------------------------------------------------------------------- Tue Jun 14 17:43:50 CEST 2011 - mc@suse.de - add /usr/lib and /usr/lib64 to lib path for tomcat to make jpam work (bnc#691918, FATE#312400) ------------------------------------------------------------------- Wed May 25 11:23:43 CEST 2011 - mc@suse.de - allow only secure SSLCipher and SSLProtocols (bnc#685550) ------------------------------------------------------------------- Thu Feb 17 17:35:30 CET 2011 - mc@suse.de - autoflush stdout (bnc#672565) ------------------------------------------------------------------- Wed Feb 16 14:49:41 CET 2011 - ug@suse.de - suppress a warning when selinux is missing (bnc#671641) ------------------------------------------------------------------- Fri Feb 11 15:10:35 CET 2011 - ug@suse.de - don't start xinted ------------------------------------------------------------------- Fri Feb 11 12:36:20 CET 2011 - mc@suse.de - no selinux, if selinuxenabled binary is not found (bnc#671204) ------------------------------------------------------------------- Tue Feb 8 15:59:45 CET 2011 - mc@suse.de - change mountpoint and prepended_dir (bnc#669558) ------------------------------------------------------------------- Sun Jan 30 15:32:04 CET 2011 - mc@suse.de - backport upstrem fixes ------------------------------------------------------------------- Tue Dec 21 15:59:11 CET 2010 - ug@suse.de - patch added to Requires ------------------------------------------------------------------- Wed Sep 15 10:05:42 CEST 2010 - mantel@suse.de - Initial release of spacewalk-setup ------------------------------------------------------------------- 0707010000002D000081B400000000000000000000000166154954000021B9000000000000000000000000000000000000002500000000spacewalk-setup/spacewalk-setup.spec# # spec file for package spacewalk-setup # # Copyright (c) 2024 SUSE LLC # Copyright (c) 2008-2018 Red Hat, Inc. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via https://bugs.opensuse.org/ # %if 0%{?suse_version} > 1320 || 0%{?rhel} || 0%{?fedora} # SLE15 builds on Python 3 %global build_py3 1 %endif %define pythonX %{?build_py3:python3}%{!?build_py3:python2} %if 0%{?suse_version} %define apache_user wwwrun %define apache_group www %define misc_path /srv/ %else %define apache_user apache %define apache_group apache %define misc_path %{_var} %endif %{!?fedora: %global sbinpath /sbin}%{?fedora: %global sbinpath %{_sbindir}} Name: spacewalk-setup Version: 5.0.4 Release: 0 Summary: Initial setup tools for Spacewalk License: GPL-2.0-only Group: Applications/System URL: https://github.com/uyuni-project/uyuni Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build %if 0%{?fedora} BuildRequires: perl-interpreter %else BuildRequires: perl %endif BuildRequires: perl(ExtUtils::MakeMaker) %if 0%{?suse_version} BuildRequires: python3-Sphinx %else BuildRequires: python3-sphinx %endif BuildRequires: tomcat ## non-core #BuildRequires: perl(Getopt::Long), perl(Pod::Usage) #BuildRequires: perl(Test::Pod::Coverage), perl(Test::Pod) BuildArch: noarch %if 0%{?fedora} Requires: perl-interpreter %else Requires: perl %endif Requires: perl-Params-Validate Requires: spacewalk-schema Requires: perl(Term::Completion::Path) %if 0%{?suse_version} Requires: curl Requires: patch Requires: perl-Frontier-RPC Requires: perl-XML-LibXML Requires: perl-XML-SAX Requires: perl-libwww-perl Requires: policycoreutils # to have /etc/salt/master.d Requires(pre): salt-master # for salt to be generated into the thin %if 0%{?build_py3} Requires: python3-certifi %else Requires: python-certifi %endif BuildRequires: perl-libwww-perl %else Requires: %{sbinpath}/restorecon %endif Requires(post): cobbler Requires: perl-Satcon Requires: spacewalk-admin Requires: spacewalk-backend-tools Requires: spacewalk-certs-tools Requires(post): tomcat %if 0%{?build_py3} Requires: (python3-PyYAML or python3-pyyaml) %else Requires: (python-PyYAML or PyYAML) %endif Requires: curl Requires: perl-Mail-RFC822-Address %if 0%{?rhel} Requires: perl-Net-LibIDN2 %else Requires: perl-Net-LibIDN %endif Requires: spacewalk-base-minimal Requires: spacewalk-base-minimal-config Requires: spacewalk-java-lib >= 2.4.5 Requires: uyuni-setup-reportdb %if 0%{?rhel} Requires(post): libxslt-devel %else Requires(post): libxslt-tools %endif Provides: salt-formulas-configuration Conflicts: otherproviders(salt-formulas-configuration) %description A collection of post-installation scripts for managing Spacewalk's initial setup tasks, re-installation, and upgrades. %prep %setup -q %build %{__perl} Makefile.PL INSTALLDIRS=vendor make %{?_smp_mflags} # Fixing shebang for Python 3 %if 0%{?build_py3} for i in $(find . -type f); do sed -i '1s=^#!/usr/bin/\(python\|env python\)[0-9.]*=#!/usr/bin/python3=' $i; done # timestamp of Makefile must always be newer than Makefile.PL, else build will fail touch Makefile %endif # Fix python executable in Perl code %if 0%{?build_py3} sed -i "s/'python'/'python3'/g" lib/Spacewalk/Setup.pm %endif # Build RST manpages sphinx-build -b man doc/ out/ %install make pure_install PERL_INSTALL_ROOT=%{buildroot} find %{buildroot} -type f -name .packlist -exec rm -f {} ';' find %{buildroot} -type d -depth -exec rmdir {} 2>/dev/null ';' chmod -R u+w %{buildroot}/* install -d -m 755 %{buildroot}/%{_datadir}/spacewalk/setup/ install -d -m 755 %{buildroot}/%{_sysconfdir}/salt/master.d/ install -d -m 755 %{buildroot}/%{_sysconfdir}/tomcat/conf.d/ install -m 0755 share/embedded_diskspace_check.py %{buildroot}/%{_datadir}/spacewalk/setup/ install -m 0644 share/mod_ssl.conf.* %{buildroot}/%{_datadir}/spacewalk/setup/ install -m 0644 share/tomcat_java_opts.conf %{buildroot}/%{_sysconfdir}/tomcat/conf.d/ %if 0%{?suse_version} install -m 0644 share/tomcat_java_opts_suse.conf %{buildroot}/%{_sysconfdir}/tomcat/conf.d/ %endif install -m 0644 share/server.xml.xsl %{buildroot}/%{_datadir}/spacewalk/setup/ install -m 0644 share/server_update.xml.xsl %{buildroot}/%{_datadir}/spacewalk/setup/ install -m 0644 share/add_appbase.xml.xsl %{buildroot}/%{_datadir}/spacewalk/setup/ install -m 0644 share/old-jvm-list %{buildroot}/%{_datadir}/spacewalk/setup/ install -m 0644 share/vhost-nossl.conf %{buildroot}/%{_datadir}/spacewalk/setup/ install -d -m 755 %{buildroot}/%{_datadir}/spacewalk/setup/defaults.d/ install -m 0644 share/defaults.d/defaults.conf %{buildroot}/%{_datadir}/spacewalk/setup/defaults.d/ install -d -m 755 %{buildroot}/%{_datadir}/spacewalk/setup/cobbler install -m 0644 salt/susemanager.conf %{buildroot}/%{_sysconfdir}/salt/master.d/ install -m 0644 salt/salt-ssh-logging.conf %{buildroot}/%{_sysconfdir}/salt/master.d/ # create a directory for misc. Spacewalk things install -d -m 755 %{buildroot}/%{misc_path}/spacewalk mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8 /usr/bin/pod2man --section=8 $RPM_BUILD_ROOT/%{_bindir}/spacewalk-make-mount-points | gzip > $RPM_BUILD_ROOT%{_mandir}/man8/spacewalk-make-mount-points.8.gz /usr/bin/pod2man --section=1 $RPM_BUILD_ROOT/%{_bindir}/spacewalk-setup-httpd | gzip > $RPM_BUILD_ROOT%{_mandir}/man1/spacewalk-setup-httpd.1.gz # Sphinx built manpage %define SPHINX_BASE_DIR %(echo %{SOURCE0}| sed -e 's/\.tar\.gz//' | sed 's@.*/@@') install -m 0644 %{_builddir}/%{SPHINX_BASE_DIR}/out/spacewalk-cobbler-setup.1 $RPM_BUILD_ROOT%{_mandir}/man1/spacewalk-setup-cobbler.1 # Standalone Salt formulas configuration install -Dd -m 0755 %{buildroot}%{_prefix}/share/salt-formulas install -Dd -m 0755 %{buildroot}%{_prefix}/share/salt-formulas/states install -Dd -m 0755 %{buildroot}%{_prefix}/share/salt-formulas/metadata %post if [ ! -f /etc/rhn/rhn.conf -o $(stat -c %%s "/etc/rhn/rhn.conf") -eq 0 ]; then # rhn.conf does not exists or is empty, this is new installation or update of new installation CURRENT_DATE=$(date +"%%Y-%%m-%%dT%%H:%%M:%%S.%%3N") cp /etc/tomcat/server.xml /etc/tomcat/server.xml.$CURRENT_DATE xsltproc %{_datadir}/spacewalk/setup/server.xml.xsl /etc/tomcat/server.xml.$CURRENT_DATE > /etc/tomcat/server.xml fi CURRENT_DATE=$(date +"%%Y-%%m-%%dT%%H:%%M:%%S.%%3N") cp /etc/tomcat/server.xml /etc/tomcat/server.xml.$CURRENT_DATE xsltproc %{_datadir}/spacewalk/setup/add_appbase.xml.xsl /etc/tomcat/server.xml.$CURRENT_DATE > /etc/tomcat/server.xml if [ -e /etc/zypp/credentials.d/SCCcredentials ]; then chgrp www /etc/zypp/credentials.d/SCCcredentials chmod g+r /etc/zypp/credentials.d/SCCcredentials fi if [ -d /var/cache/salt/master/thin ]; then # clean the thin cache rm -rf /var/cache/salt/master/thin fi if [ -f /etc/rhn/rhn.conf ]; then # Ensure all the apache configuration are present, also during upgrade /usr/bin/spacewalk-setup-httpd fi exit 0 %check make test %files %defattr(-,root,root,-) %doc Changes README answers.txt %config %{_sysconfdir}/salt/master.d/susemanager.conf %config %{_sysconfdir}/salt/master.d/salt-ssh-logging.conf %config %{_sysconfdir}/tomcat/conf.d/tomcat_java_opts.conf %if 0%{?suse_version} %config %{_sysconfdir}/tomcat/conf.d/tomcat_java_opts_suse.conf %endif %{perl_vendorlib}/* %{_bindir}/spacewalk-setup %{_bindir}/spacewalk-setup-httpd %{_bindir}/spacewalk-make-mount-points %{_bindir}/spacewalk-setup-cobbler %{_mandir}/man[13]/*.[13]* %dir %attr(0755, root, root) %{_prefix}/share/salt-formulas/ %dir %attr(0755, root, root) %{_prefix}/share/salt-formulas/states/ %dir %attr(0755, root, root) %{_prefix}/share/salt-formulas/metadata/ %dir %{_datadir}/spacewalk %{_datadir}/spacewalk/* %attr(755, %{apache_user}, root) %{misc_path}/spacewalk %{_mandir}/man8/spacewalk-make-mount-points* %license LICENSE %changelog 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor