Tech_Curiosity - My Wanderings in the Tech World
  • Home
  • About me
Home
About me
Tech_Curiosity - My Wanderings in the Tech World

_> Reads

  • Home
  • About me
Browsing Category
Linux
Debian Debian Docker Linux

Debian Net SNMP 5.8 rolling your own .deb file

February 21, 2020 No Comments

Introduction

Recently I ran into a stone-cold problem. I had to get an advanced version of SNMPv3 with upgraded SHA and AES working on some units in the field. Well, it turns out that as of today’s writing, the default SNMP package for Debian Stretch (9) and Buster (10) is 5.7 which doesn’t have the upgraded SNMP. But they do have a package for 5.8 that is being tested and is also in the unstable channel. Bad news is it won’t build due to some missing Debian tools. The good news is I have a lot of time with Gentoo, and this isn’t my first compiling rodeo. So between the work already done to show which packages I need for my dependencies, I just needed to put the correct commands to work. The problem was, I didn’t know what commands I would need.

So after a long and drawn-out fight with multiple false starts, including an overlooked but important option for AES-256 enablement in the configure file, I have gotten the process down for this package, and I’d like to share some Debian and Docker friendly ways to jump on this. I’ll even give you a way to make this portable for offline systems. The amount of commands will look daunting perhaps and dense, but it’s not that bad really. Mostly a lot of words, but you like reading right? I’m joking. Just don’t get daunted by it.

Disclaimer

I’m a strong proponent of testing before implementing. Therefore, I do not take any responsibility for your use of this script on your systems and the consequences that will ensue (good or bad). Please do not just run this on a Gentoo system without first backing up your files. Remember the golden rules of IT:

1) Have a backup plan
2) Have a data backup

Follow these rules, and you will successfully recover most of the time.

Tools Needed

  1. An operating system. I will ultimately test this on a physical box, but to start with I work in Windows so I can take advantage of some of the other tools listed below.
  2. WinSCP (If you’re using Windows, and for this, it’s almost, almost worth using Windows just to use this awesome, free tool)
  3. Putty, or if you’re on Linux, SSH
  4. Docker for Desktop (Windows if you want to follow along, but you can do this using Docker installed on Linux). Keep in mind you’ll need a login to download Docker for Desktop. It’s worth it for the personal free repository alone. If you do have to or want to install it ensure you have Hyper-V turned on in advance. It will save you some time and grief as it will require a reboot if it’s not already on. Read this post by Microsoft to get yours set up.
  5. Internet connection with both systems on the same network if you’re testing. Otherwise, you’ll just need the internet for the online portion.
  6. My two posts on offline packages. This will give you an idea for capturing the dependency packages you’ll need. Updating Debian Offline 1 of 2. Updating Debian Offline 2 of 2.

Docker Container Code for Inside the Container

#!/bin/bash

##Make it easy to read
apt-get update;

apt-get install -y build-essential fakeroot devscripts checkinstall;

echo "deb-src http://httpredir.debian.org/debian unstable main" >> /etc/apt/sources.list;

apt-get update;

cd /;

mkdir -p src/debian;

cd /src/debian;

apt-get source net-snmp; 

apt-get install -y libwrap0-dev libssl-dev perl libperl-dev autoconf automake debianutils bash findutils procps pkg-config libbsd-dev default-libmysqlclient-dev libpci-dev; 

cd /src/debian/net-snmp-5.8+dfsg;

mkdir build;

##Include either option 1 or option 2 in script

#Option 1 Configure to ouput the compiled sources to the build folder I point it to.
./configure --prefix=/src/debian/net-snmp-5.8+dfsg/build/ --with-transports="DTLSUDP" --with-security-modules="tsm" --enable-blumenthal-aes --with-default-snmp-version="3" --with-sys-contact="@@no.where" --with-sys-location="Unknown" --with-logfile="/var/log/snmpd.log" --with-persistent-directory="/var/net-snmp" && make && checkinstall

#Option 2 Configure no ouput and accept the defaults This one is what
#you want. It will out put a .deb file for you in the same directory.

./configure --with-transports="DTLSUDP" --with-security-modules="tsm" --enable-blumenthal-aes --with-default-snmp-version="3" --with-sys-contact="@@no.where" --with-sys-location="Unknown" --with-logfile="/var/log/snmpd.log" --with-persistent-directory="/var/net-snmp" && make && checkinstall

Container Code as a One-Liner with Direction to Build Folder

apt-get update;apt-get install -y build-essential fakeroot devscripts checkinstall;echo "deb-src http://httpredir.debian.org/debian unstable main" >> /etc/apt/sources.list;apt-get update;cd /;mkdir -p src/debian;cd /src/debian;apt-get source net-snmp; apt-get install -y libwrap0-dev libssl-dev perl libperl-dev autoconf automake debianutils bash findutils procps pkg-config libbsd-dev default-libmysqlclient-dev libpci-dev; cd /src/debian/net-snmp-5.8+dfsg;mkdir build;./configure --prefix=/src/debian/net-snmp-5.8+dfsg/build/ --with-transports="DTLSUDP" --with-security-modules="tsm" --enable-blumenthal-aes --with-default-snmp-version="3" --with-sys-contact="@@no.where" --with-sys-location="Unknown" --with-logfile="/var/log/snmpd.log" --with-persistent-directory="/var/net-snmp" && make && checkinstall

Docker Code

##Well this is crappy. Why do I call with it an interactive switch?
##Why do I restart that container? Did I exit?
##Why am I copying things and then getting back in the container?

docker run -it --network bridge -h deb --name deb debian:stretch /bin/bash;docker start deb;docker cp .\depends\ deb:/tmp;docker exec -it deb /bin/bash


#If you are in the /src/debian/net-snmp_5.8+dfsg/ folder
#./configure --with-default-snmp-version="3" --with-sys-contact="@@no.where" --with-sys-location="Unknown" --with-logfile="/var/log/snmpd.log" --with-persistent-directory="/var/net-snmp" && make && checkinstall

##checkinstall depends for copy and paste
libwrap0-dev,libssl-dev,perl,libperl-dev,autoconf,automake,debianutils,bash,findutils,procps,pkg-config,libbsd-dev,default-libmysqlclient-dev,libpci-dev

The Breakdown

To kick this off, you have one of two ways of going about this. I’m going to keep this on the Debian side of things and call in their test package, but I actually ended up going to source directly and building from there. In that case, you still want to install all of the recommended installs like build-essential, fakeroot, devscripts, and checkinstall. Then you can just run the configuration that I have in the source folder.

But if you want to just work through the Debian commands, which admittedly is a little easier, that is what the script above will do.

You will need to get the dependencies for this package. I have them listed out here:

automake_1%3A1.15-6_all.deb
autotools-dev_20161112.1_all.deb
bzip2_1.0.6-8.1_amd64.deb
default-libmysqlclient-dev_1.0.2_amd64.deb
libbsd-dev_0.8.3-1_amd64.deb
libbsd0_0.8.3-1_amd64.deb
libc-dev-bin_2.24-11+deb9u4_amd64.deb
libc6-dev_2.24-11+deb9u4_amd64.deb
libc6_2.24-11+deb9u4_amd64.deb
libdpkg-perl_1.18.25_all.deb
libffi6_3.2.1-6_amd64.deb
libfile-fcntllock-perl_0.22-3+b2_amd64.deb
libgdbm3_1.8.3-14_amd64.deb
libglib2.0-0_2.50.3-2+deb9u2_amd64.deb
libglib2.0-bin_2.50.3-2+deb9u2_amd64.deb
libglib2.0-data_2.50.3-2+deb9u2_all.deb
libgpm2_1.20.4-6.2+b1_amd64.deb
libicu57_57.1-6+deb9u3_amd64.deb
liblocale-gettext-perl_1.07-3+b1_amd64.deb
libmariadbclient-dev-compat_10.1.44-0+deb9u1_amd64.deb
libmariadbclient-dev_10.1.44-0+deb9u1_amd64.deb
libmariadbclient18_10.1.44-0+deb9u1_amd64.deb
libncurses5_6.0+20161126-1+deb9u2_amd64.deb
libpci-dev_1%3A3.5.2-1_amd64.deb
libpci3_1%3A3.5.2-1_amd64.deb
libperl-dev_5.24.1-3+deb9u6_amd64.deb
libperl5.24_5.24.1-3+deb9u6_amd64.deb
libprocps6_2%3A3.3.12-3+deb9u1_amd64.deb
libsigsegv2_2.10-5_amd64.deb
libssl-dev_1.1.0l-1~deb9u1_amd64.deb
libssl-doc_1.1.0l-1~deb9u1_all.deb
libssl1.1_1.1.0l-1~deb9u1_amd64.deb
libudev-dev_232-25+deb9u12_amd64.deb
libudev1_232-25+deb9u12_amd64.deb
libwrap0-dev_7.6.q-26_amd64.deb
libwrap0_7.6.q-26_amd64.deb
libxml2_2.9.4+dfsg1-2.2+deb9u2_amd64.deb
linux-libc-dev_4.9.210-1_amd64.deb
m4_1.4.18-1_amd64.deb
manpages-dev_4.10-2_all.deb
manpages_4.10-2_all.deb
mysql-common_5.8+1.0.2_all.deb
net-snmp_5.8_amd64.deb
netbase_5.4_all.deb
perl-base_5.24.1-3+deb9u6_amd64.deb
perl-modules-5.24_5.24.1-3+deb9u6_all.deb
perl_5.24.1-3+deb9u6_amd64.deb
pkg-config_0.29-4+b1_amd64.deb
procps_2%3A3.3.12-3+deb9u1_amd64.deb
psmisc_22.21-2.1+b2_amd64.deb
rename_0.20-4_all.deb
sgml-base_1.29_all.deb
shared-mime-info_1.8-1+deb9u1_amd64.deb
tcpd_7.6.q-26_amd64.deb
udev_232-25+deb9u12_amd64.deb
xdg-user-dirs_0.15-2+b1_amd64.deb
xml-core_0.17_all.deb
autoconf_2.69-10_all.deb
xz-utils_5.2.2-1.2+b1_amd64.deb
zlib1g-dev_1%3A1.2.8.dfsg-5_amd64.deb

To obtain them from where they downloaded you can read from this post. Pay attention to the “lists” acquisition and acquiring the packages from a cleaned archives folder. Now the bad news. Unfortunately, if you’re using the docker container option, you need to be aware of something very important. The archives clean up as soon as the install of a package starts. You need to circumvent this by having a second terminal open and copying the packages upon download to somewhere like the /tmp/ folder (which I would have cleaned first). Then you can retrieve them like so:

docker cp deb:/tmp/ .

What I did here was copy the files in the /tmp/ directory to the local folder (.) where I’m at. I’m assuming the container’s name is “deb” although yours might be named differently.

The biggest thing to remember is that this will be installed favoring the following command over the apt-get command I used in the post I referred to earlier.

apt-get update --no-download; dpkg -i *.deb;

The AES-256 Net-SNMP 5.8 Struggle Bus

So perhaps you want to know a little more about some of the switches in that configure call. Three of them were required, from my experience anyway, to get things to install without having to answer questions. But the real money is these flags:

–with-transports=”DTLSUDP”
–with-security-modules=”tsm”
–enable-blumenthal-aes

If you don’t have those three flags set, you can forget about AES-256, and that, my friends, makes the whole exercise pointless, right? Incidentally, this is why it’s important to have OpenSSL installed as this is where it will be pulling the crypto-library.

Checkinstall? What’s that do?

##checkinstall dependencies for copy in
libwrap0-dev,libssl-dev,perl,libperl-dev,autoconf,automake,debianutils,bash,findutils,procps,pkg-config,libbsd-dev,default-libmysqlclient-dev,libpci-dev

As I was fighting my way through trying to actually make a .deb package, I found an easy way. A dead-easy way. The checkinstall package will make the .deb file for you and even install it. It makes sure that anything that gets installed in the package can be removed using the standard package tools included with Debian.

How do I get this all installed?

####To install the full monty:

#Copy the full depends folder to your target computer
#Inside of the depends folder go ahead and put the newly built snmp pkg
#I'd rename the deb file for easier reference
#inside of the depends folder run "dpkg -i *.deb"

What if I want to uninstall it?

/src/debian/net-snmp-5.8+dfsg/net-snmp_5.8+dfsg-1_amd64.deb

 You can remove it from your system anytime using:

      dpkg -r net-snmp

This prints out on the screen. I will give you the uninstall script as well.

Package Builder:

pkg installer notes:

#You might need to install xz-utils package if on container debian:stretch

#You can find out if you have xz-utils installed by running:
apt-cache pkgnames | grep -w ^xz

#create pkg zip xz, note the output deb file I already renamed
tar -cJvf net-snmp_5.8.tar.xz net-snmp_5.8;rm -rf net-snmp_5.8;

#unpackage and install (scripts perform cleanup)
#Does not take into account paths, assumes local directory execution
tar -xJvf net-snmp_5.8.tar.xz;cd net-snmp_5.8;chmod a+x snmp_*;./snmp_install

Install Script

#!/bin/bash

##Assumes root is running
##We know we are now in /root/mhcorbin/cam1/

## Variable to path
exists=/root/.snmp
flderpth=/root/mhcorbin/cam1/net-snmp_5.8
tarcleaner=/root/mhcorbin/cam1/net-snmp_5.8.tar.xz
pkgcheck=$(apt-cache pkgnames | grep -w ^snmp)

## Fix where am I running issue
cd $flderpth;
## Fix apt update lists so pkgs install properly
rm -rf /var/lib/apt/lists/*;
sleep 5;
cp -RTv $flderpth/lists /var/lib/apt/lists;
apt-get update --no-download;
#  Allow time for dpkg lock to release before deleting lock file
sleep 10;

#  Clear DPKG lock to resolve lock error
rm /var/lib/dpkg/lock;

##Determine if a prior SNMP package is installed and if so remove it
if [ -z "$pgkcheck"  ];then
	apt-get -y -f --purge remove snmp;
fi

##Determine what kind of install to perform
if [ -d $exists ]; then
##Install only
	dpkg -i $flderpth/*.deb;
	rm -rf $flderpth/mibs $flderpth/*.deb $flderpth/lists $flderpth/snmp_install
	echo "install only";
else
##Fix Missing Mibs with RSU-MIB included
	dpkg -i $flderpth/*.deb;
	echo "mibs and install";
	mkdir -p /root/.snmp/mibs;
	cp -RTv $flderpth/mibs /root/.snmp/mibs;
	sleep 5;
	rm -rf $flderpth/mibs $flderpth/*.deb $flderpth/lists $flderpth/snmp_install
fi

if [ -f $tarcleaner ]; then
	rm -rf $tarcleaner;
fi

Uninstall Script

#!/bin/bash

dpkg -r net-snmp libwrap0-dev libssl-dev libperl-dev autoconf automake pkg-config libbsd-dev default-libmysqlclient-dev libpci-dev

Conclusion

This was quite a slog, but if you’re still with me, hopefully this has given you an idea of how to put this together. As always, I’m open to comments and alternative ideas. Thanks for reading!

Continue reading
Reading time: 10 min
Written by: cephas0
Gentoo Linux

Gentoo PkgConfCleaner Script

January 14, 2020 No Comments

Introduction

I’m a messy guy when it comes to my /etc/portage/package.accept_keywords or my /etc/portage/package.use conf files. To that end, I created a short script using sed to get things cleaned up. I will admit that I could have avoided using a script at all if I asserted more control over what is put in those files. But if you’re lazy like me and were checking out the deployment script I cobbled together, you might find this useful. Hopefully, my laziness is of benefit to you.

Disclaimer

I’m a strong proponent of testing before implementing. Therefore, I do not take any responsibility for your use of this script on your systems and the consequences that will ensue (good or bad). Please do not just run this on a Gentoo system without first backing up your files. Remember the golden rules of IT:

1) Have a backup plan
2) Have a data backup

Follow these rules, and you will successfully recover most of the time.

Code Me

#!/bin/bash
##Name: pkgconfcleaner
##Author: Cephas0
##License? No Brah!

sed -i 's+#.*++g' /etc/portage/package.use
sed -i '/^\s*$/d' /etc/portage/package.use

sed -i 's+#.*++g' /etc/portage/package.accept_keywords
sed -i '/^\s*$/d' /etc/portage/package.accept_keywords

What does it do?

This is a rather simple thing. The first string finds all of the commented lines in your conf file of choice (hard coded here) and removes them. Then the second line removes all of the leftover space. It looks gnarly but it’s pretty simple in its objective.

I don’t know anything about scripts. How do I get started?

Using a text editor like “nano”, create a file named “pkgconfcleaner” in the /usr/local/bin folder so that the script will be in the path. Next copy and paste the code into the editor. Ok, so here’s a testing hint. If you remove the “-i” from the sed commands, it will not implement the code, but it will print out what the file would look like if it did. Neat, huh? The last thing you need to do to make this work is to run the “chmod” command to make the file executable.

chmod a+x /usr/local/bin/pkgconfcleaner

Something like the code above should be sufficient. (It might not work for you if you are not root or using “sudo”. If you got an error use “sudo” and try again. If it just failed, don’t type it out again, use “sudo !!”)

Wrap up

That’s a wrap on this post. While scripting this short script to fix my laziness may not have been the best allocation of my time, it does have other applicable uses you may find helpful.

Continue reading
Reading time: 2 min
Written by: cephas0
Debian Linux

Debian Package and Dependency Downloader

No Comments
#!/bin/bash

read -p "What pkg are you building?: " pkg

##Code attribution for the code below
##https://www.ostechnix.com/download-packages-dependencies-locally-ubuntu/

for i in $(apt-cache depends $pkg | grep -E 'Depends|Recommends|Suggests' | cut -d ':' -f 2,3 | sed -e s/'<'/''/ -e s/'>'/''/); do sudo apt-get download $i 2>>errors.txt; done

This post is about something I tried when I was working on an offline Debian upgrade project. While it didn’t ultimately provide the solution to that project, it did open up a wonderful possibility. To kick this post off, we must have a talk about dependencies, and since that can become mind numbing quickly, I’m only going to gloss over that topic. We’ll talk about what this script does, how to use it, and then turn you loose.

Dependencies _> The Underworld

Dependencies are what the majority of packages or projects rely on to work. Think of it like a base foundation that many people contribute to. This is usually in the form of “lib” or library packages. Other developers will use this pre-written code in their projects, and that’s the end of it right? Not really. Actually, a single project can use dozens to hundreds of dependencies all stacked upon one another like a pyramid of code. This can quickly become a large security issue as the more a system has installed the more dependencies it relies upon. It is at that point that the system’s security becomes more and more dependent (no pun intended) upon every dependency. In other words, the weakest link in any program is the amount of dependencies it uses as much as a chain is only as strong as its weakest link. 

So there’s some of the ugly; let’s talk about the bad for a second. Let’s say you’ve gotten entangled in a project that needs some offline packages installed. Where do you start?

The Journey

For me I started at the online Debian package repository. I needed to download Java for another project. Needless to say you quickly find that you need at least four packages right off the bat.

openjdk-8-jre.deb openjdk-8-jre-headless.deb openjdk-8-jdk-headless.deb openjdk-8-jdk.deb

Yikes! Each package has even more dependencies. And those have even more dependencies. Wouldn’t it be nice if you could just get all the packages and the dependencies without the downloads?

The Solution

I was getting desperate for a solution. Downloading package after package after package is the worst. I have a life and better things to do. Enter salvation in the form of ingenius scripting from OSTechNix. Simply make a folder of the package you wish to download and get cracking.

Here’s the code again below for reference. We’ll step through it.

#!/bin/bash

read -p "What pkg are you building?: " pkg

##Code attribution for the code below
##https://www.ostechnix.com/download-packages-dependencies-locally-ubuntu/

for i in $(apt-cache depends $pkg | grep -E 'Depends|Recommends|Suggests' | cut -d ':' -f 2,3 | sed -e s/'<'/''/ -e s/'>'/''/); do sudo apt-get download $i 2>>errors.txt; done

The Code

I’m going to assume you have made your directory and you are ready to proceed to the next step. If you want you can copy the script above and put it in your /usr/local/bin which will make your script available in your system paths. Make sure it’s executable. I usually run my scripts as root on test systems, so for your system you may wish to use “sudo” in front of whatever you named this script.

read -p "What pkg are you building?: " pkg

This is the first line I added, and it offers some bonuses. You can put as many different packages as you want, spaced out of course. It’s a simple input line for bash with the variable at the end. As you can see, we use that later.

for i in $(apt-cache depends $pkg | grep -E 'Depends|Recommends|Suggests' | cut -d ':' -f 2,3 | sed -e s/'<'/''/ -e s/'>'/''/) 
     do 
        sudo apt-get download $i 2>>errors.txt
     done

I’m going to skip over the code attribution because I think that’s rather self-documenting. The rest of this code starts with a standard for loop. What follows next is a calling of the apt-cache command and the depends command for the package ($pkg, told you we’d use it later) you want to download. Then we pipe to grep, doing a little cutting, run sed (which does some awesome clean up), and then we finally get to downloading the packages.

Wrapping it up

Before you start running this script, make sure you’re in the actual folder you created. Otherwise you could end up with a lot of deb packages everywhere. Not to worry if you did though. Here’s some shortcode to get things cleaned up. We’ll assume you’re in the /tmp/ folder, and you ran, for example, the java packages I listed out earlier. What a mess!

cd /tmp/
##gotta get in the tmp directory first right?
##remember the java folder (package folder) I made?
mv *.deb /tmp/java

And boom. You’re all good. Hope it helps.

Continue reading
Reading time: 4 min
Written by: cephas0
Gentoo Linux

Gentoo Package Deployment Script

No Comments

Introduction

So you wanna make your life easier when emerging a gentoo package? Good news, so did I. I’m going to start this off with, as with many things I do, it’s not always the best way. I would say the backtracking option is very likely something you can and should take out. Read up on that and see if it makes sense for you. For me, this is something I cobbled together. It has some weak points and places it can be improved. It gets the job done though, and that’s enough for me. That said, I’ve felt like if I continue to just keep this knowledge until it’s perfect, no one can benefit from any of it. Therefore, it is incumbent on you to take responsibility for testing, improving, and revising anything I release. Furthermore, if you want to make recommendations with code examples in the comments, I’m all for it. Help each other out, and together we can make things better. Alright, with that, let’s delve into the code and start making our lives a little easier.

Gentoo? Dear Lord Man. For serial.

If you detected a Southpark vibe there, good on you. Gentoo is not for the faint of heart. It will, however, force you to be better than what you are. You will learn a lot about compiling, systems, kernels, and multiple other things. I started with Calculate Linux (a gentoo based Russian distro). If you’re completely new to linux, don’t let the steep climb throw you. Start with Calculate and learn some of the basics as well as the pitfalls. For my master project, I built out my first Gentoo system. I won’t cover that here, but in an upcoming post, I will go over what and how I did my first build. It took a month because I started with a Dell laptop and had issues with the wifi broadcom drivers. Fun times. Let’s get back to the deployment script though.

Nailed it. Code me.

#!/bin/bash
##Author: Cephas0
##Distro: Gentoo
##Knowledge level needed: Copy and Paste?
##License Brah? No...?

array=($(ls | sed 's/\(Manifest\|metadata.*\|.ebuild\|files\)//g'));

for index in ${!array[@]};do echo "$index ${array[index]}";done

read -p "Enter the pkg to be deployed: " num
pkg=${array[$num]}
current=($(pwd | sed 's+/usr/portage/++g'| sed 's|\(.*\)/.*|\1|'))
emerge -av --autounmask-continue --backtrack=200 =$pkg; dispatch-conf; 
exists=($(find /var/db/pkg | grep $pkg))
if [ -d "$exists" ]; then
   echo "Package has been deployed."
   exit
else 
   emerge -v =$pkg
   echo "Package has been deployed."
fi

Put the alcoholic beverage down and step away from the mouse

What’s all of that Greek?!?! No worries – we’ll go line-by-line through it. For now, if you want to kick it off, put it in your /usr/local/bin which will put it in the system path. Small disclosure: on my personal systems, I run everything as root. It just makes it easier for me. If you’re a sudo person, no problems, just run things as sudo. Make sure you make the script executable.

Code Breakdown

The first line of code is below.

array=($(ls | sed 's/\(Manifest\|metadata.*\|.ebuild\|files\)//g'));

I’ve set up a variable called array. The key to this script is that it assumes you have already found the package you want to install and you are in the correct portage directory.

🔥 Spark Note From the Forge 🔥

But wait. How can I get there? Well let’s use an example. Let’s say I want to install “xclock”. How would I find it?

Well there are two ways I do it; although, full admission, there are more, shall we say, proper ways to get the job done. Regrettably, you poor soul, I’m not very proper.

You could change directory into /usr/portage and run:

find | grep -i xclock

Or you could run something like this:

find /usr/portage | grep -i xclock

And your output should look something like this:



Just make sure you change into the xclock directory before running the deployment script.

Ok, back to it. The first line runs the “ls” command and pipes it through “sed”. This proceeds to filter out unneeded extra things you typically find in the directory that won’t be needed for this process. To that end, we extract the manifest file, any metadata file, and cut off the .ebuild and files from the input that will be shuttled to the array variable.

for index in ${!array[@]};do echo "$index ${array[index]}";done

Ok, so the next line of code is basically a one-liner which is why it has the semicolons. You can put this in a more readable format, but I chose not to because for me it was fairly readable. Just something to keep in mind. We start with a for statement and begin to sort through the array. The nitty-gritty of the “!array[@]” here means that instead of just looping through the array itself and using only the elements in the array (which this code would do shown below)…

array[@]

…we want to go through the slices of the array and use the indices like (0,1,2,3,4).

🔥 Spark Note From the Forge 🔥

Indices? I’m not a programmer!

Don’t sweat it. There’s only one thing to remember: indices start at 0 always. That’s how the system begins its counts. It’s true for all programming, and it’s true here. Here’s one for you LOTR fans: if you think of the “0” as the One Ring, you can think of the rest of the numbers as rings bound to the One Ring which starts at 0.

Geez, what a nerd. Hey, get a room, nerd, with your weird numbers and…stuff!

This is going great. We’re over one of the biggest humps believe it or not. The rest of this line goes through each index number. Then we use “echo” to print out the index number and the array element for each package or element in the array. Simple.

read -p "Enter the pkg to be deployed: " num

If you’ve been reading my other blogs, this will be a familiar one. Skip over it if you have or you know what this is. Otherwise, stay tuned. All this one line does is pauses the script (-p) and takes user input (yours) and then puts that input into a variable (num). Why did I use the variable “num” though? Because the script expects you to put in the index number that was printed.

The script in action

So if we were picking a new virtualbox to install and I wanted the latest package, I would enter the number “4” into the response prompt and press enter.

pkg=${array[$num]}

If you’ve done programming with arrays before, you’ll recognize this move. If not, no worries; I’ll cover it now. All we’re doing is using the array index to select the correct package from the array and putting only that package name into a new variable called “pkg”.

So if we were speaking about the example above and writing pseudo code, it would look somewhat like this:

pkg=${virtualbox-6.1.4[index number 4]}

Ok, so I feel pretty good about the progress we’ve made, and hopefully, if you didn’t know much about bash arrays or indices, you’re picking up some useful ideas for your next script.

current=($(pwd | sed 's+/usr/portage/++g'| sed 's|\(.*\)/.*|\1|'))

The next line is looking for what directory we’re in by basically using the pwd command, which is great, but dumps a lot of extra junk with it. Thankfully we have sed which allows us to clean things up. So if we’re using the virtualbox example above, we’re going to have a string looking like this from pwd:

/usr/portage/app-emulation/virtualbox

But what we really need is only the:

app-emulation

Enter the sed sphere. We pipe the output of pwd to sed and strip the front two tags. Great. That just leaves:

app-emulation/virtualbox

So how to get that last pesky section off? And that, my friends, is why we pipe in the next sed statement of glop. I’ll be completely honest here: I don’t fully remember what it does other than it will pick off the slash and what is after the slash. The how’s and why’s are on the internet and were in my head when I was working on this diligently.

emerge -av --autounmask-continue --backtrack=200 =$pkg; dispatch-conf;

This should look familiar, right? If not, what’s going on is a very questionable use of the emerge command in a script. Basically I’m running emerge, telling it to be verbose, ask, automatically unmask any package requirements (a.k.a. /etc/portage/package.accept_keywords), and backtrack. Why backtrack? The emerge man page puts it best:

–backtrack=COUNT
Specifies an integer number of times to backtrack if dependency calculation fails due to a conflict or an unsatisfied dependency
(default: ´10´).

I’ll leave it there for that. Next we run the “dispatch-conf” command so that we can automatically accept all changes. Side bar here: this will dump an enormous amount of junk into your package files like /etc/portage/package.accept_keywords. If you are strenuous about keeping the amount of comments down and your files clean then, by all means, you can add some code to the script and keep your package.accept_keywords cleaner than mine. I have another script that cleans up that mess for me, but that’s for another post.

exists=($(find /var/db/pkg | grep $pkg))

This line sets up a scenario for the remainder of the script. Namely, we check to see if the package was installed and we set the variable “exists”.

if [ -d "$exists" ]; then
   echo "Package has been deployed."
   exit
else 
   emerge -v =$pkg
   echo "Package has been deployed."
fi

We are in the home stretch now. We start out with an “if else” statement. We check to see if the directory exists (meaning a successful install), and if it does, we end the script and print a success message. If not, we strip all of the options out and automatically try to emerge the package. This is there because of the dispatch-conf option I called earlier.

Wrap up

That’s it for this post. Feels like a lot of ground got covered in a short amount of time. It’s not the most perfect script, but it does get the job done. I won’t promise you it will work all the time. You will have to contend with certain upgrades in a different way such as python and perl. Additionally, dependency conflicts are generally not going to be solved by this. I’ll cover some of these in other posts down the line. For now, enjoy the deployment script and have fun.

Continue reading
Reading time: 8 min
Written by: cephas0
Page 2 of 3«123»

Recent Posts

Setting up Jenkins with a Freestyle Project for Java and Apache Ant

February 28, 2021

Making a Deployment Script Part II

February 21, 2021

Making a Deployment Script Part I

February 14, 2021

Winapps Project on Alpine Linux Allows you to Run Windows Applications like they were Locally Installed

February 7, 2021

Getting an SSL cert into an NGINX Container

February 28, 2020

Archives

  • February 2021
  • February 2020
  • January 2020

Categories

  • Alpine
  • Alpine
  • Debian
  • Debian
  • Docker
  • Gentoo
  • Interesting Tools
  • Jenkins
  • Linux
  • Nginx
  • Shell Scripting
  • Ubuntu 18.04 Server

About me

I am Cephas0, also known as Jack Stone. I write about things that interest me. This could be tech, projects I’m working on, or things that are important to me. Join me in my journey.

Recent Comments

    © 2020 | An Echo Enterprise