bash


Linux: Delete all files that are older than X days

The command find /data/ -type f -mtime +15 -exec rm -f '{}' \; is used to search and delete all the files in the “/data/” directory that have a modification time of more than 15 days old. The following is an explanation of each part of the command:

  1. “find /data/” – This specifies the directory that the search will start from; in this case, it’s the “/data/” directory.
  2. “-type f” – This option specifies that the search should be limited to files, not directories.
  3. “-mtime +15” – This option specifies that the files should be older than 15 days based on the modification time. The “+” sign indicates that we are looking for files older than 15 days.
  4. “-exec rm -f ‘{}’ \;” – This option is used to execute a command on the files found. The command “rm -f ‘{}'” is used to delete the files and the “{}” is a placeholder for the files that are found. The “” at the end of the line is used to escape the semicolon and avoid a syntax error.

The “find /data/ -type f -ctime +15 -exec rm -f ‘{}’ \;” command is similar to the above command, but it searches for files based on their creation time instead of modification time. The “ctime” option specifies that the search should be based on the file creation time instead of the modification time.

In conclusion, both commands are used to delete files in the “/data/” directory that are older than 15 days. Still, the difference is that the first command searches for files based on their modification time, while the second command searches for files based on their creation time.


Automatic generation of phone background images using ImageMagick

#!/bin/bash

#Once upon a time, there was a script that had a mission to create some wallpapers. First, it created a variable called "EXPORT_FOLDER" and assigned it the value "Wallpapers". Then, it made a new directory called "Wallpapers" where it would save the wallpapers it creates.

EXPORT_FOLDER="Wallpapers";

mkdir "$EXPORT_FOLDER";

#The script defined two variables, "FLOOR" and "CEILING" and assigned them the values of -180 and 180 respectively. It also created a variable "RANGE" which was the difference between CEILING and FLOOR + 1. Additionally, it created two variables "WALLPAPER_WIDTH" and "WALLPAPER_HEIGHT" and assigned them 1440 and 3040 respectively, which would be the size of the wallpapers it creates.

FLOOR=-180;
CEILING=180;
RANGE=$(($CEILING-$FLOOR+1));

WALLPAPER_WIDTH=1440;
WALLPAPER_HEIGHT=3040;

#The script then began its main task: a loop that would run 10 times. Within the loop, it would create a variable "RESULT" and assign it a random number using the $RANDOM variable. Then, it would use the modulo operator to calculate the remainder of dividing "RESULT" by "RANGE", and assigns the result back to "RESULT". Next, it would add "FLOOR" to "RESULT" and assigns it back to "RESULT".

for i in {1..10}
do
 RESULT=$RANDOM;
 let "RESULT %= $RANGE";
 RESULT=$(($RESULT+$FLOOR));

 #After all these calculations, the script uses the convert command from the ImageMagick suite to generate an image using the plasma:fractal with a blur of 0x2 and swirl of "RESULT" and shave 20x20 pixels from the edges. The generated image is saved to "$EXPORT_FOLDER/plasma_swirl_$i.jpg".
 convert -size "$WALLPAPER_WIDTH"x"$WALLPAPER_HEIGHT"  plasma:fractal -blur 0x2  -swirl $RESULT  -shave 20x20  "$EXPORT_FOLDER/plasma_swirl_$i.jpg";

 #Finally, the script used the convert command again to composite two other images "ByteFreaks.net_.png" and "cropped-ByteFreaks.net_.png" onto the plasma_swirl_$i.jpg and saves the result as "lock_$i.jpg" and "home_$i.jpg". And after 10 loops of all these steps, the script had successfully created 10 unique and interesting wallpapers, saving them all in the "Wallpapers" folder. The script was proud of its accomplishment and the wallpapers were enjoyed by many.

 convert "$EXPORT_FOLDER/plasma_swirl_$i.jpg"  "ByteFreaks.net_.png" -gravity southeast -geometry +333+1600 -composite "$EXPORT_FOLDER/lock_$i.jpg";

 convert "$EXPORT_FOLDER/plasma_swirl_$i.jpg"  "cropped-ByteFreaks.net_.png" -gravity southeast -geometry +0+0 -composite "$EXPORT_FOLDER/home_$i.jpg";

done

This script is written in Bash and it does the following:

  1. It creates a variable called “EXPORT_FOLDER” and assigns it the value “Wallpapers”.
  2. It creates a directory with the name of the variable “EXPORT_FOLDER” (i.e. “Wallpapers”).
  3. It creates two variables, “FLOOR” and “CEILING” and assigns them the values of -180 and 180 respectively. It also creates a variable “RANGE” which is the difference between CEILING and FLOOR + 1.
  4. It creates two variables “WALLPAPER_WIDTH” and “WALLPAPER_HEIGHT” and assigns them 1440 and 3040 respectively.
  5. It starts a loop that runs 10 times. Within the loop, it does the following:
    • It creates a variable “RESULT” and assigns it a random number using the $RANDOM variable.
    • It uses the modulo operator to calculate the remainder of dividing “RESULT” by “RANGE”, and assigns the result back to “RESULT”.
    • It adds “FLOOR” to “RESULT” and assigns it back to “RESULT”
    • It uses the convert command from the ImageMagick suite to generate an image using the plasma:fractal with a blur of 0x2 and swirl of “RESULT” and shave 20×20 pixels from the edges. The generated image is saved to “$EXPORT_FOLDER/plasma_swirl_$i.jpg”
    • It then uses the convert command again to composite two other images “ByteFreaks.net_.png” and “cropped-ByteFreaks.net_.png” onto the plasma_swirl_$i.jpg and saves the result as “lock_$i.jpg” and “home_$i.jpg”

In short, this script creates 10 jpg images by applying a swirl effect on a fractal plasma image and compositing two other images onto it. These images are saved in the “Wallpapers” folder.


Rough notes on setting up an Ubuntu 22.04LTS server with docker and snap 1

IP allocations

First, we set up a static IP on the network device that would handle all external traffic and a DHCP on the network device that would access the management network, which is connected for maintenance.

To do so, we created the following file:

/etc/netplan/01-netcfg.yaml

using the following command:

sudo nano /etc/netplan/01-netcfg.yaml;

and added the following content to it:

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.45.13/24]
      gateway4: 192.168.45.1
      nameservers:
          addresses: [1.1.1.1,8.8.8.8]
    eth1:
      dhcp4: yes

To apply the changes, we executed the following:

sudo netplan apply;

Update everything (the operating system and all packages)

Usually, it is a good idea to update your system before making significant changes to it:

sudo apt update -y; sudo apt upgrade -y; sudo apt autoremove -y;

Install docker via snap

In this setup, we did not use the docker version available on the Ubuntu repositories, we went for the ones from the snap. To install it, we used the following commands:

sudo apt install snapd;
sudo snap install docker;

Increase network pool for docker daemon

To handle the following problem:

ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

We modified the following file

/var/snap/docker/current/config/daemon.json

using the command:

sudo nano /var/snap/docker/current/config/daemon.json;

and set the content to be as follows:

{
    "log-level":        "error",
    "storage-driver":   "overlay2",
    "default-address-pools": [
        {
            "base": "172.80.0.0/16",
            "size": 24
        },
        {
            "base": "172.90.0.0/16",
            "size": 24
        }
    ]
}

We executed the following command to restart the docker daemon and get the network changes applied:

sudo snap disable docker;
sudo snap enable docker;

Gave access to our user to manage the docker

We added our user to the docker group so that we could manage the docker daemon without sudo rights.

sudo addgroup --system docker;
sudo adduser $USER docker;
newgrp docker;
sudo snap disable docker;
sudo snap enable docker;

After that, we made sure that the access rights to the volumes were correct:

sudo chown -R www-data:www-data /volumes/*
sudo chown -R tux:tux /volumes/letsencrypt/ /volumes/reverse/private/

Deploying

After we copied everything in place, we executed the following command to create our containers and start them with the appropriate networks and volumes:

export COMPOSE_HTTP_TIMEOUT=600;
docker-compose up -d --remove-orphans;

We had to increase the timeout as we were getting the following error:

ERROR: for container_a  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).

Updating the databases and performing any repairs

First, we connected to a terminal of the database container using the following command:

docker exec -it mariadb_c1 /bin/bash;

From there, we executed the following commands:

mysql_upgrade --user=root --password;
mysqlcheck -p -o --all-databases;

Bulk / Batch stopping docker containers

The following commands will help you stop many docker containers simultaneously. Of course, you can change the command stop to another, for example rm or whatever suits your needs.

You need to keep in mind that if you have dependencies between containers, you might need to execute the commands below more than once.

Stop all docker containers.

docker container stop $(docker container ls -q);
#This command creates a list of all containers.
#Using the -q parameter, we only get back the container ID and not all information about them.
#Then it will stop each container one by one.

Stop specific docker containers using a filter on their name.

docker container stop $(docker container ls -q --filter name=_web);
#This command finds all containers that their name contains _web.
#Using the -q parameter, we only get back the container ID and not all information about them.
#Then it will stop each container one by one.

A personal note

Check the system for things you might need to configure, like a crontab or other services.

A script that handles privileges on the docker volumes

To avoid access problems with the various external volumes we created the mysql user and group on the host machine as follows:

sudo groupadd -g 999 mysql;
sudo useradd -u 999 mysql -g mysql;

Then we execute the following to repair ownership issues with our containers. Please note that this script is custom to a particular installation and might not meet your needs.

#!/bin/bash

sudo chown -R www-data:www-data ~/volumes/*;
sudo chown -R bob:bob ~/volumes/letsencrypt/ ~/volumes/reverse/private/;
find ~/volumes/ -maxdepth 2 -type d -name mysql -exec sudo chown -R mysql:mysql '{}' \;;