{"id":6061,"date":"2024-07-09T02:13:00","date_gmt":"2024-07-09T06:13:00","guid":{"rendered":"https:\/\/www.both.org\/?p=6061"},"modified":"2024-07-09T06:16:03","modified_gmt":"2024-07-09T10:16:03","slug":"how-to-do-fast-repeatable-linux-installations-2-bash-scripts-rpm","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=6061","title":{"rendered":"How to do fast, repeatable Linux installations #2 &#8212; Bash scripts + RPM"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"6061\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p class=\"wp-block-paragraph\">In Episode 1, <a href=\"https:\/\/www.both.org\/?p=6009\" data-type=\"link\" data-id=\"https:\/\/www.both.org\/?p=6009\" target=\"_blank\" rel=\"noreferrer noopener\">How to do fast, repeatable Linux installations #1 &#8212; Bash scripts<\/a>, I discussed how I used a Bash script after performing a basic Fedora installation to perform a series of post-installation tasks that can&#8217;t be performed by the standard installer. This saved me a great deal of time and effort dealing with multiple installations each day.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That was a great solution for a number of years, but I began to add tasks to the script that caused it to become more complicated. I also decided for a number of reasons that it might be a good idea to use an RPM to perform many of those tasks for me. I also wanted to learn how to create RPMs as an exercise. So I decided to create an RPM to install several tools including the postinstall.sh script, perform some configuration tasks, and prompt the user to run the postinstall.sh script. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Most of the tools I installed were available from the Fedora repository and were intended to make the rest of the tasks required for my post-install work easier to perform. This included tools like screen and Midnight Commander (mc) so I could perform some manual tasks while postinstall.sh was still running, while using my familiar and favorite tools. I used the RPM I created for several years, making a large number of modifications to it in order to keep up with changes to Fedora and changes to the tasks I wanted it to perform.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Build RPMs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In a previous article, <a href=\"https:\/\/www.both.org\/?p=5251\">How to build rpm packages<\/a>, I explained how to &#8212; you guessed it &#8212; build RPM packages. Once built, the simple package created in that article could be installed like any other RPM package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since that previous article covers all the details of how to &#8212; well &#8212; build RPM packages, I won&#8217;t cover that here. So read that article and build the RPM it describes so that you can return here and use the information in the rest of this article to build your own postinstall RPM.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Warning!!! &#8212; Don&#8217;t use the RPM created in this article on a production host. This article and the code that goes with it are intended as a tool to demonstrate what can be done with an RPM and a Bash program to perform post-installation tasks. Use a non-production VM if you want to experiment with this project.<\/em><\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The spec file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The spec file in Figure 1 is a modified version of the one I used. I&#8217;ve removed the installs for some applications, desktop themes, and wallpapers, that are not necessary for a demonstration such as this. I&#8217;ve also removed some tasks from the %post section that are no longer necessary on current Fedora releases. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>################################################################################\n# Spec file for Davids post-installation utilities\n# David Both\n################################################################################\n# Configured to be built by non-root user\n################################################################################\n################################################################################\n################################################################################\n# WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!        #\n#                                                                              #\n# DO NOT USE THE RPM CREATED BY THIS SPEC FILE IN A PRODUCTION ENVIRONMENT!!!  #\n# This spec file and the RPM it creates is intended only for educational       #\n# purposes and should never be used in a production environment.               #\n#                                                                              #\n# WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!        #\n################################################################################\n################################################################################\n################################################################################\n#\nSummary: A collection of Fedora tools, configuration files, and administrative utility programs mostly written in BASH.\nName: postinstall\nVersion: 2.6\nRelease: 5   \nLicense: GPL2\nURL: https:\/\/www.both.org\nGroup: System\nPackager: David Both LinuxGeek@both.org\nVendor: David Both\nRequires: bash \nRequires: wget \nRequires: deltarpm \nRequires: mc \nRequires: dmidecode\nRequires: screen\n\n# Build with the following syntax:\n# rpmbuild --target noarch -bb postinstall.spec\n\n%description\nThis package is a collection of BASH scripts, wallpapers, fonts, and tools that I have\ndeveloped over the years to perform various useful administrative tasks. \n\nThis RPM and the tools it installs is for testing and edulcationanl purposes only!\nDo not use it in a production environment.\n\nBackups - A backup program called rsbu. Configuration is in \/usr\/local\/etc\/rsbu.conf\nsysdata - A program that can collect a very large amount of data about your Linux computer.\ncreateMOTDLinux - Creates an MOTD with current data about \n          your computer.\ncreate_motd - with a link in cron.daily, runs createMOTDLinux \n          each day with the correct options.\npostinstall.sh - A script to perform all of the usual configuration\n          tasks that I perform on newly installed systems. This script\n          takes up to 2 hours to complete if everything is installed but\n          it saves me much time and typing. It includes installing all\n          available updates. It copies some favorite default\n          configurations for Midnight Commander, NTP, and makes some\n          changes to GRUB configuration. It installs a large number\n          of compatibility and other useful fonts. It can\n          also install many of the servers I use on a server host.\nLogBanner - A banner that is used as a security warning prior to remote\n          logins.\nUpgradeFedora - A BASH script to upgrade Fedora from one version to the next using\n          dnf system-upgrade.\n ...and more.\n\nThis RPM also does the following:\n-  Adds a symlink to \/etc\/cron.daily to point to \/usr\/local\/bin\/create_motd.\n-  Appends a new alias (lsn) to \/etc\/bashrc to specifically use the color=no\n   option with ls.\n-  Installs a script, \/root\/postinstall.sh, which can be run by root and\n   automatically installs some other useful packages if they are not already installed.\n\n%prep\n################################################################################\n# Create the build tree and copy the files from the development directories    #\n# into the build tree.                                                         #\n################################################################################\necho \"BUILDROOT = $RPM_BUILD_ROOT\"\nmkdir -p $RPM_BUILD_ROOT\/etc\/profile.d\nmkdir -p $RPM_BUILD_ROOT\/etc\/glances\nmkdir -p $RPM_BUILD_ROOT\/root\/mcconfigfiles\/\nmkdir -p $RPM_BUILD_ROOT\/tmp\nmkdir -p $RPM_BUILD_ROOT\/usr\/local\/bin\/\nmkdir -p $RPM_BUILD_ROOT\/usr\/local\/etc\/\nmkdir -p $RPM_BUILD_ROOT\/usr\/share\/doc\/postinstall\/\nmkdir -p $RPM_BUILD_ROOT\/var\/spool\/cron\n\n\ncp \/home\/dboth\/development\/utils\/trunk\/bash_logout $RPM_BUILD_ROOT\/root\ncp \/home\/dboth\/development\/utils\/trunk\/create_motd $RPM_BUILD_ROOT\/usr\/local\/bin\ncp \/home\/dboth\/development\/utils\/trunk\/doUpdates $RPM_BUILD_ROOT\/usr\/local\/bin\ncp \/home\/dboth\/development\/utils\/trunk\/GPL_LICENSE.txt $RPM_BUILD_ROOT\/usr\/share\/doc\/postinstall\ncp \/home\/dboth\/development\/utils\/trunk\/ifcfg-ifnamehere* $RPM_BUILD_ROOT\/root\ncp \/home\/dboth\/development\/utils\/trunk\/iptables $RPM_BUILD_ROOT\/root\ncp \/home\/dboth\/development\/utils\/trunk\/LogBanner $RPM_BUILD_ROOT\/etc\/\ncp \/home\/dboth\/development\/utils\/trunk\/glances.conf $RPM_BUILD_ROOT\/etc\/glances\ncp -r \/home\/dboth\/development\/utils\/trunk\/mc\/* $RPM_BUILD_ROOT\/root\/mcconfigfiles\ncp \/home\/dboth\/development\/utils\/trunk\/misc-files\/.toprc $RPM_BUILD_ROOT\/root\ncp \/home\/dboth\/development\/utils\/trunk\/myBashConfig.sh $RPM_BUILD_ROOT\/etc\/profile.d\ncp \/home\/dboth\/development\/utils\/trunk\/mymotd $RPM_BUILD_ROOT\/usr\/local\/bin\ncp \/home\/dboth\/development\/utils\/trunk\/postinstall.sh $RPM_BUILD_ROOT\/root\ncp \/home\/dboth\/development\/utils\/trunk\/root.crontab $RPM_BUILD_ROOT\/var\/spool\/cron\/root\ncp \/home\/dboth\/development\/utils\/trunk\/rsbu $RPM_BUILD_ROOT\/usr\/local\/bin\ncp \/home\/dboth\/development\/utils\/trunk\/rsbu.conf $RPM_BUILD_ROOT\/usr\/local\/etc\ncp \/home\/dboth\/development\/utils\/trunk\/sysdata $RPM_BUILD_ROOT\/usr\/local\/bin\ncp \/home\/dboth\/development\/utils\/trunk\/tmpwatch $RPM_BUILD_ROOT\/root\ncp \/home\/dboth\/development\/utils\/trunk\/UpgradeFedora.sh $RPM_BUILD_ROOT\/root\n\n%files\n%attr(0600, root, root) \/root\/iptables\n%attr(0644, root, root) %config \/var\/spool\/cron\/root\n%attr(0644, root, root) %config \/etc\/LogBanner\n%attr(0644, root, root) %config \/etc\/profile.d\/myBashConfig.sh\n%attr(0754, root, root) \/usr\/local\/bin\/rsbu\n%attr(0644, root, root) %config \/usr\/local\/etc\/rsbu.conf\n%attr(0755, root, root) \/usr\/local\/bin\/doUpdates\n%attr(0755, root, root) \/usr\/local\/bin\/sysdata\n%attr(0754, root, root) \/usr\/local\/bin\/create_motd\n%attr(0755, root, root) \/usr\/local\/bin\/mymotd\n%attr(0744, root, root) \/root\/postinstall.sh\n%attr(0744, root, root) \/root\/UpgradeFedora.sh\n%attr(0644, root, root) \/root\/.toprc\n%attr(0644, root, root) \/root\/bash_logout\n%attr(0754, root, root) \/root\/tmpwatch\n%attr(0644, root, root) \/root\/mcconfigfiles\/ini\n%attr(0644, root, root) \/root\/mcconfigfiles\/panels.ini\n%attr(0744, root, root) \/usr\/share\/doc\/postinstall\/GPL_LICENSE.txt\n%attr(0644, root, root) \/etc\/glances\/glances.conf\n\n%pre\n\n%post\n################################################################################\n# First get the distro info out of the file in a way that produces consistent  # \n# results for Fedora.                                                          #\n################################################################################\nDistro=`cat \/etc\/*elease* 2&gt;\/dev\/null | grep release | uniq | sed -e \"s\/&#91;lL]inux \/\/g\"`\nif echo $Distro | grep Fedora &gt; \/dev\/null\nthen\n   # This is Fedora\n   NAME=\"Fedora\"\nelse\n  # This is not Fedora so is not supported\n  echo \"Error: Unsupported distribution. This is not Fedora\"\nfi\n\necho \"############ Name = $NAME ##############\"\n\n################################################################################\n# Turn off PackageKit updates if it is installed.                              #\n################################################################################\nif &#91; -e \/etc\/yum\/pluginconf.d\/refresh-packagekit.conf ]\nthen\n   cd \/etc\/yum\/pluginconf.d\/\n   # Edit the refresh-packagekit.conf and set disabled\n   sed -i -e \"s\/enabled=1\/enabled=0\/\" refresh-packagekit.conf\nfi\n# do the same in the dnf directory\nif &#91; -e \/etc\/dnf\/pluginconf.d\/refresh-packagekit.conf ]\nthen\n   cd \/etc\/dnf\/pluginconf.d\/\n   # Edit the refresh-packagekit.conf and set disabled\n   sed -i -e \"s\/enabled=1\/enabled=0\/\" refresh-packagekit.conf\nfi\n\n################################################################################\n# Perform these tasks only if this is Fedora                                   #\n################################################################################\nif &#91; $NAME = \"Fedora\" ]\nthen\n   # If the tmpwatch file does not aleady exist\n   if &#91; ! -f \/etc\/cron.daily\/tmpwatch ]\n   then\n      # Copy tmpwatch script to correct location\n      cd \/root\n      cp tmpwatch \/etc\/cron.daily\n   fi\nfi\n\n# Now create the motd file\necho \"Creating the MOTD for $HOSTNAME\"\n\/usr\/local\/bin\/create_motd\n\n# Print instructions about the postinstall.sh file.\n\necho \"################################################################################\"\necho \"# The next step is to run doUpdates -vr to install all current updates. Then   #\"\necho \"# run the \/root\/postinstall.sh script as described in the next section.        #\"\necho \"#                                                                              #\"\necho \"#------------------------------------------------------------------------------#\"\necho \"#                                                                              #\"\necho \"# Now run the script \/root\/postinstall.sh to install some additional desirable #\"\necho \"# administrative packages. These inlcude screen, powertop, iftop,              #\"\necho \"# iptraf-ng, iotop and sysstat among others. It also installs                  #\"\necho \"# a number of useful fonts that provide close analogues to various common      #\"\necho \"# fonts used in other operating systems.                                       #\"\necho \"#                                                                              #\"\necho \"# Run .\/postinstall.sh -h to display all of the options and help.              #\"\necho \"################################################################################\"\n\n%postun\n\n%clean\ncd ~\/rpmbuild\/\nrm -rf BUILD*\n\n%changelog\n* Tue Jul 02 2024 David Both &lt;david@both.org&gt;\n  - Modify for use in a Both.org article.\n   ################################################################################\n   ################################################################################\n   ################################################################################\n   # WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!        #\n   #                                                                              #\n   # DO NOT USE THE RPM CREATED BY THIS SPEC FILE IN A PRODUCTION ENVIRONMENT!!!  #\n   # This spec file and the RPM it creates is intended only for educational       #\n   # purposes and should never be used in a production environment.               #\n   #                                                                              #\n   # WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!   WARNING!!        #\n   ################################################################################\n   ################################################################################\n   ################################################################################<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center has-medium-font-size wp-block-paragraph\">Figure 1: The sample SPEC file for the post-install RPM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparing to build the RPM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Follow the example in the article, <a href=\"https:\/\/www.both.org\/?p=5251\">How to build rpm packages<\/a>, for how to prepare for building an RPM. To be a little more specific for this project, you&#8217;ll need to perform the following steps.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a subdirectory of your home directory and name it development. You could use another name but that&#8217;s the one I like to use for my development projects.<\/li>\n\n\n\n<li>Copy the spec file from this article and paste it into a file named postinstall.spec in the development directory. Many spec files define the &#8220;buildroot&#8221; but we don&#8217;t need to do that since the default buildroot is the builder&#8217;s home directory.<\/li>\n\n\n\n<li>Create the build directory structure as described in <a href=\"https:\/\/www.both.org\/?p=5251\">How to build rpm packages<\/a>.<\/li>\n\n\n\n<li>The %prep section of the spec file lists the files that the RPM will install and the locations from which those files are copied during the build. Be sure to change the name of my home directory to that of yours when you create those locations.<\/li>\n\n\n\n<li>Download the files listed in the %description section of the spec file and copy them to the locations from which they&#8217;ll be copied during the build. The <a href=\"https:\/\/www.both.org\/?page_id=4666\" data-type=\"link\" data-id=\"https:\/\/www.both.org\/?page_id=4666\" target=\"_blank\" rel=\"noreferrer noopener\">downloads<\/a> page of this site lists those files.<\/li>\n\n\n\n<li>Modify the %prep section where it copies the various files into the directory tree created at the top of this section. These modifications will include deleting &#8212; or at least commenting out &#8212; copying the files you don&#8217;t have or don&#8217;t want. <\/li>\n\n\n\n<li>In the %files section, delete the lines for any files that you&#8217;ve decided not to install. <\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Building the RPM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Build the RPM using this same section of <a href=\"https:\/\/www.both.org\/?p=5251\">How to build rpm packages<\/a> as a guide, changing names as appropriate. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the build process encounters errors, fix them and try the build again. I frequently get errors due to misspellings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing the RPM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Remember, this entire project should only be performed in a non-production VM, espcially installing the RPM and running the scripts. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After building the RPM, install it on your VM. As part of this project, you should verify that at least some of the dependencies were installed and that the files were installed. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running the postinstall.sh script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Try running the postinstall.sh script. It may throw some errors but this article is not about making that script or any others work correctly. This is simply about using the RPM to install this script along with some others, as well as some other tools and configuration files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final thoughts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This approach to configuring my Fedora installations like I want them worked for a few years. However, it was even more cumbersome than using just the script. It required intervention on my part because I first needed to install the RPM, and then run the postinstall.sh script. This two-part process took time, despite the fact that using the RPM package to deliver and install a lot of files made sense.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I also ran into problems if I needed to run the script again to fix a problem or to install updated versions of the scripts and configuration files. That sometimes caused more problems than it was intended to fix because it didn&#8217;t always check to see if a particular task had been performed previously. It could mangle some existing files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So this was a less than ideal solution.  I needed a better, more integrated approach. I&#8217;ll cover that in the next &#8212; and probably last &#8212; installment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Episode 1, How to do fast, repeatable Linux installations #1 &mdash; Bash scripts, I discussed how I<\/p>\n","protected":false},"author":2,"featured_media":5090,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[149,98,461,5,89],"tags":[151,104,460,152,396],"class_list":["post-6061","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bash","category-code","category-installation","category-linux","category-system-administration","tag-bash","tag-command-line","tag-installation","tag-programming","tag-rpm-packaging"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/6061","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6061"}],"version-history":[{"count":27,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/6061\/revisions"}],"predecessor-version":[{"id":6371,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/6061\/revisions\/6371"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/5090"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6061"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6061"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6061"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}