This is a report for the Configuration Management Systems course taught by Tero Karvinen
Date: 28-11-2020
To start this off the goal was to create a simple hello world
script so i added the shebang
line in a file (called hello) and a simple echo command to go with it.
#!/bin/bash
echo 'Hello World'
Running the file with bash
prints Hello World
on the screen as expected. Next i added the executable bit to the file with chmod +x hello
so it can be ran by running hello
. Finally to run it from anywhere i added it to a folder in my path (/usr/local/bin
). One last thing i did to it was changing the permissions with sudo chmod 755 /usr/local/bin/hello
.
sudo mv hello /usr/local/bin/
.
-rwxr-xr-x 1 niko niko 31 marras 27 16:53 /usr/local/bin/hello
Now to automate this i used this state i created earlier.
/usr/local/bin/:
file.recurse:
- source: salt://hello/scripts/
- file_mode: 755
This will take all files in /srv/salt/hello/scripts/
then copy them over to /usr/local/bin
on the minions and set the permissions to 755. Applying the state was successful and so was running hello
on the minion. Permissions for the file on the minion were correct as well.
-rwxr-xr-x 1 root root 31 Nov 27 15:10 hello
To create some script that gives relevant information all i could come up with at the moment was getting the time, cpu model and ip address. I created a simple a simple script as follows.
#!/bin/bash
echo "Time: $(date +'%H:%M')"
cpu=$(lscpu|grep 'Model '|awk -F':' '{print $2}')
# This way random whitespace is removed
echo $cpu|xargs echo 'CPU:'
echo "IP: $(hostname -I)"
Applying the state succeeded as expected so logged in to the target minion and tried running the command. This ran as expected as well.
Time: 08:42
CPU: AMD Ryzen 5 1600X Six-Core Processor
IP: 10.0.2.15 172.28.128.122
For a python script i wanted to use some script i wrote when i was studying some cryptography. I made my own CBC mode for AES encryption and packed it all up in a script that can encrypt files with a password. To make it work as a command i just added the python shebang line #!/usr/bin/python3
at the top of the file but running the file gave me the following error.
-bash: ./encrypt.py: /usr/bin/python3^M: bad interpreter: No such file or directory
Oddly enough running the script with python3
worked just fine but i believe ive seen this issue before. It might be a formatting issue because i copied over the whole python file from windows and i think windows uses some diffrent line terminators or something. After scratching my head for a minute i remembered that the easy way to fix this issue was to run the following command.
dos2unix encrypt.py
This command converts windows files to the linux format. Now running the file with ./encrypt.py -h
gives the desired output.
usage: encrypt.py [-h] [-d] [-f IN_FILE] [-o OUT_FILE] -k KEY
Encrypt a file with AES-CBC
optional arguments:
-h, --help show this help message and exit
-d, --decrypt Decrypt the file
-f IN_FILE, --file IN_FILE
Choose an input file (Default: stdin)
-o OUT_FILE, --output OUT_FILE
Choose an outfile (Default: stdout)
Required arguments:
-k KEY, --key KEY The key for encryption and decryption
Now i just renamed the srcipt to encrypt
and applied the state. At this point i wasnt expecting this to work yet because the minions dont have python3 installed as far as i know. Apparently i was wrong and my ubuntu 20.04 slaves have python3 installed so the script works as it should.
vagrant@slave-1:~$ encrypt -f /etc/passwd -o encrypted -k 'SaltIsCool'
vagrant@slave-1:~$ encrypt -f encrypted -k 'SaltIsCool' -d
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
Here the goal was to look at some previously created modules for this course and describe them. I browsed terokarvinen.com and looked at a few reports.
Source: https://github.com/rootElmo/Harjoitus-7/blob/master/text/harj7_report.md
First one i wanted to look into a bit was one created by Elmo Rouhula
and his module setup a minecraft server for him. The module uses pillars to get users and their passwords setup on the target server and setup minecraft server as well.
Source: https://jorilinux.wordpress.com/palvelinten-hallinta-viikkotehtava-7/
This one was a relatively simple state that starts with installing a few things like git and curl then sets up apache with php. Most of the work is done through file.managed
and file.symlink
to add the required configuration files and symolic links. Finally the module checks if apache2 is running when the php configuretion file is changed.
Source: https://elisalinux.wordpress.com/2018/12/10/palvelinten-hallinta-loppuprojekti/
This module mainly installs the software refered to as LAMP. This includes Apache, MySQL and PHP. The module installs everything automatically and sets everything up which includes enabling a mod, running apache, adding a default website and creating a database. There was also a short module to create a bunch of new users in a loop.
Finally to try one of these modules i decided to go with the one that installs LAMP because all of the files were conveniently in a repository. I cloned the repository with git clone https://github.com/elisapa/smallnetwork.git
then moved the state i wanted to the right place with sudo cp -R lamp/ /srv/salt/
. My understanding is that this was tested on Ubuntu-16.04 while my slaves are running Ubuntu-20.04 so there could be some issues. As i suspected when i tried applying the state i got lots of errors most noteably these.
slave-3:
----------
ID: installation
Function: pkg.installed
Result: False
Comment: Problem encountered installing package(s). Additional info follows:
errors:
- Running scope as unit: run-r8b09459f40c94f5193628ca88f33dd01.scope
E: Unable to locate package libapache2-mod-php7.0
E: Couldn't find any package by glob 'libapache2-mod-php7.0'
E: Couldn't find any package by regex 'libapache2-mod-php7.0'
E: Unable to locate package php7.0-mysql
E: Couldn't find any package by glob 'php7.0-mysql'
E: Couldn't find any package by regex 'php7.0-mysql'
Started: 13:05:37.801265
Duration: 3389.913 ms
Seems like the issue was php7.0
. I changed all instances of php7.0
to just php
. With those changes everything installed without any issues but i still got an error.
ID: cat /tmp/commands.sql|sudo mysql -u root
Function: cmd.run
Result: False
Comment: Command "cat /tmp/commands.sql|sudo mysql -u root" run
Started: 13:11:17.212130
Duration: 447.681 ms
Changes:
----------
pid:
25945
retcode:
1
stderr:
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY '34iwacsn'' at line 1
stdout:
Summary for slave-3
------------
Succeeded: 7 (changed=7)
Failed: 1
Seems like the SQL comands have failed but luckily i have encountered this problem before and know that i just need to update the syntax in the commands. I looked at some of my other homework and it seems like the problem is with this line (again).
GRANT ALL ON lamp_database.* TO 'minion_lamp' IDENTIFIED BY '34iwacsn';
I changed it to these lines.
GRANT ALL ON lamp_database.* TO 'minion_lamp'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
For some reason i was still getting errors so the seem to be some issues with the first line as well.
ID: cat /tmp/commands.sql|sudo mysql -u root
Function: cmd.run
Result: False
Comment: Command "cat /tmp/commands.sql|sudo mysql -u root" run
Started: 13:19:04.719012
Duration: 302.688 ms
Changes:
----------
pid:
26014
retcode:
1
stderr:
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'minion_lamp'@'localhost'
stdout:
Summary for slave-3
I logged in to the slave and tried something. I ran the same command salt was trying to run and that failed as expected but creating a user with a diffrent name succeeded.
mysql> CREATE USER 'minion_lamp'@'localhost' IDENTIFIED BY '34iwacsn';
ERROR 1396 (HY000): Operation CREATE USER failed for 'minion_lamp'@'localhost'
mysql> CREATE USER 'something_else'@'localhost' IDENTIFIED BY '34iwacsn';
Query OK, 0 rows affected (0.01 sec)
To solve this issue i changed the command to something more idempotent. Source: https://dev.mysql.com/doc/refman/8.0/en/create-user.html
CREATE USER IF NOT EXISTS 'minion_lamp'@'localhost' IDENTIFIED BY '34iwacsn';
Applying the state now gives me this error.
ERROR 1007 (HY000) at line 2: Can't create database 'lamp_database'; database exists
Seems like creating the database has the same issue so i tried the same solution.
CREATE DATABASE IF NOT EXISTS lamp_database;
Now everything runs just fine and is idempotent. To finally verify that the site is up i used curl because i dont have a graphical interface on my minions.
curl localhost|less
Running this command shows the default page for apache so everything seems to have worked just fine. I did also check that the database was created and MySQL was listening on port 3306 as it should.
...
This is the default welcome page used to test the correct
operation of the Apache2 server after installation on Ubuntu systems.
It is based on the equivalent page on Debian, from which the Ubuntu Apache
packaging is derived.
If you can read this page, it means that the Apache HTTP server installed at
this site is working properly. You should <b>replace this file</b> (located at
<tt>/var/www/html/index.html</tt>) before continuing to operate your HTTP server.
...
I also tried applying this state to a fresh minion as a sanity check and that seems to work just fine as well (event after applying it multiple times).