Search This Blog

Friday, August 28, 2020

Molecule and extra variables for Ansible

Imagine that you want to use Molecule to test an Ansible role with a not default value. That's just one off test, so adjusting molecule configuration in the converge.yml (or similar) file is not required. It's not very prominent in documentation, but you can pass Ansible variables after "--" (minus, minus) in the molecule commend. For example:

molecule converge -- -e "role_new_var=true"

Wednesday, August 26, 2020

How to find a word in files spread over many subdirectories

Imagine that you need to try to find a word in hundreds files located in a plenty of subfolders. grep -Rc might be a good candidate, but it's going to print the list of all files and the word is in just a handful of them. To make the output better grep can be joined with awk (and in the example below with zsh). 

I needed to find an example of sqlcmd command usage in my Ansible roles collection. I used the power of ZSH globbing (a few other examples can be found here and in other places) to limit search to yml file only. ZSH "**" pattern is also a nice replacement to the grep "--recursive"option. In awk the "-F" flag replaces the standard delimiter with the ":" character and prints only lines with second field not equal to zero.

grep -c sqlcmd **/*.yml | awk -F":" ' ($2 != 0 ){print $0}'

Wednesday, April 29, 2020

Get Public IP address of Azure VM from shell on VM - part II

Last year I wrote a quick note with a method of getting Azure VM public address from the shell on VM. Recently I spent a bit more time to look at https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service and found more precise call to get IP address from the metadata url: 

curl -H Metadata:true \
 "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text"

BTW. The same method allows to get a private IP address.

curl -H Metadata:true \
 "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text"

Tuesday, April 07, 2020

Painful encounter with oversized Postgres (9.6)

I had not so nice encounter with an oversize PostgresDB. Somehow rather small DB ballooned to 256 GB (what was a partition size). I'm not PostgresDB expert. I can barely use it, but I've spent some time doing internet search and that might be useful for other (or for me in the future).

In the end I regained nearly 200 GB of space with simple command:

vacuum full

As it is suggested by this Stack Overflow question.

The key to find above suggestion was to understand that the problem was related to pg_toast table. I found that fact out using oid2name tool, which BTW in Ubuntu is in /usr/lib/postgresql/10/bin/.


/usr/lib/postgresql/10/bin/oid2name -H localhost -U postgres -d postgres -f 24806

From database "postgres":
  Filenode      Table Name
--------------------------
     24806  pg_toast_24729


I learnt about the tool from this document and learnt how to use from the man page.

It's also worth to remember that following query didn't help me. I think it's nice, so posting it here, anyway:

SELECT table_schema, 
    table_name, 
    pg_relation_filepath('"'||table_schema||'"."'||table_name||'"') 
FROM information_schema.tables 
WHERE 
    pg_relation_filepath('"'||table_schema||'"."'||table_name||'"') 
LIKE 'base/12404/248%';

The above query was built based on another good suggestion from Stack Overflow. This one shows all big tables.

SELECT
    table_schema,
    table_name,
    pg_relation_size('"'||table_schema||'"."'||table_name||'"')
FROM  information_schema.tables
ORDER BY 3
LIMIT 10

Monday, March 16, 2020

prt-get/pkgmk adjustments

If I'm ever going to lose my current Crux config. I need to remember, to adjust following files for Crux:
  • /etc/prt-get.conf to ensure that scripts as executed:

    runscripts yes            # (no|yes)


  • /etc/pkgmk.conf to ensure that md5sums are ignored:

    PKGMK_IGNORE_MD5SUM="yes"

Thursday, March 12, 2020

Bash and Arrays

Short reminder for my 'extended memory' on how to deal with lists in bash.

To define:
  • a list (an array): declare -a list
  • a dictionary (an associative array): declare -A dict
To use an array in loop: for item in ${list[@]}

Now the best, at least for scripts testing:
To print a whole array: declare -p list (please note, no "$" before list name).


Found at https://www.tutorialkart.com/bash-shell-scripting/bash-array/


Saturday, November 30, 2019

AMDGPU firmware and homebuild kernel

Not sure how it happens in less DIY type distributions, but in Crux I struggled to add firmware of AMDGPU drivers to a initrmfs. Maybe I haven't tried long enough, but without firmware in the initial ramfs, I could not properly start my desktop.

I learnt that drivers are on a disk, in what looked like the right directory (/lib/firmware/amdgpu/). They just were not loaded. After passing a few times the directory name via a CLI option I figured out that the path could be added to the dracut config.

Now, I have following config file on which make rebuilding kernel much easier.

cat /etc/dracut.conf.d/wawrzek.conf
install_items+=/lib/firmware/amdgpu/*

Thanks to that I can simple run command like that to add ramfs to:

mkinitrd /boot/initramfs-5.4.0-1.img 5.4.0

Friday, September 06, 2019

Copy files around in CentOS with SELinux (e.g. Nginx)

Imagine that you want to enable https traffic on a site served by Nginx. Sounds simple. A series of command like these should work:

scp example.com.* your_remote_server:
ssh your_remote_server
sudo mkdir /etc/nginx/ssl
sudo cp example.com.* /etc/nginx/ssl

Edit appropriate configuration file(s). Finally, run:

sudo systemctl restart nginx

and nothing, or rather an error message with information that nginx cannot access ssl certificate files. You check and files exists, so what's the problem?

The problem is a SELinux security context, diffrent for /etc/ngnix and /home/X

To change it you need to run chcon. For example:

chcon --reference /etc/nginx/nginx.conf /etc/nginx/ssl/example.com.*

More info at: https://www.cyberciti.biz/faq/rhel-centos-feora-linux-change-copy-selinux-context/

Wednesday, July 03, 2019

OpenSSL and certs

I was battling with SSL certificates recently and have two useful command I would like to store in my extended memory (this blog).


a) To ensure that all certificates in a bundle are OK. There should be a clear 'line of trust' in output.

FILENAME=your.domain.crt
openssl crl2pkcs7 -nocrl -certfile $FILENAME | openssl pkcs7 -print_certs -noout

b) To ensure that the EC (Eliptic Curve) key in the csr and the certifciate is equal to the actual signing key run these 3 commands. The public key for each command should be the same.

NAME=your.domain
openssl ec -pubout -in $NAME.key
openssl req -noout -pubkey -in $NAME.csr
openssl x509 -noout -pubkey -in $NAME.crt

Sunday, May 19, 2019

Ansi control characters in Vim


The ANSI/VT100 terminals and their emulators allows to use escape sequences to  display colours and formatted text. (Check this link for more information on how to do this.) That's look cool in a terminal window. Problems starts when terminal output is redirected to a file (e.g. logs). Editors like Vim are virtual useless with such files, because files are full of "rubbish". At least by default, because for Vim there is a good plug-in called "Asci Highlighting". It takes escapes sequences and colour text appropriately.


Links:
  • https://misc.flogisoft.com/bash/tip_colors_and_formatting 
  • http://www.drchip.org/astronaut/vim/index.html#ANSIESC


Tuesday, April 30, 2019

Get Public IP address of Azure VM from shell on VM

Sometimes you need to get an IP address of the VM from inside of it. You can do this relatively simple from Azure VM with curl and jq thanks to Metadata endpoint as described in this document https://azure.microsoft.com/en-us/blog/announcing-general-availability-of-azure-instance-metadata-service/

And if you need the public IP address of interface eth0 this is the command:

curl -H Metadata:true http://169.254.169.254/metadata/instance?api-version=2017-04-02| jq '.network.interface[0].ipv4.ipAddress[0].publicIpAddress'


Thursday, December 20, 2018

One liner to list interactive Unix users


If you need simple command to list all interactive users this awk one-liner might be helpful. It prints all usernames without few keywords in shell. May trigger false positives, so be careful.

awk -F: '$NF !~ /(false|nologin|halt|shutdown|sync)/ {print $1}'  /etc/passwd

Friday, October 27, 2017

Terraform debugging (Azure Storage long names)

I had strange problem with Terraform on Azure. Everything looked good, but ever time I got. I tried to changed few things. Didn't help. All the time:

* module.storage.azurerm_storage_container.vhds: 1 error(s) occurred:

* module.storage.azurerm_storage_container.vhds: Resource \
'azurerm_storage_account.vhds' not found for variable \
'azurerm_storage_account.vhds.name'

I couldn't find any explanation to me problems, so I started to look to increase amount of information from Terraform. I found that TF_LOG controls log level. I ran

TF_LOG=TRACE terraform plan| grep ERROR

And found following line:

2017/10/27 20:31:37 [ERROR] root.storage: eval: *terraform.EvalValidateResource, \
err: Warnings: []. Errors: [name can only consist of lowercase letters and numbers, \
and must be between 3 and 24 characters long]


Yes, the create name was a bit long, but aaaa... The original error message is not the most obvious one.

Tuesday, March 07, 2017

OpenSSL and Azure VPN

I had to set up an Azure Point-to-Site VPN, but didn't want to do it from Windows machine (I'm Linux/MacOSX kind of the guy) but luckily I found this Aris Plakias' article which describe in a plain language with good example how to prepare all necessary certificates using OpenSSL.

Actually I've created this small script so I can easily repeat client creation step.

#/bin/sh
name=$1
openssl genrsa -out ${name}1Cert.key 2048
openssl req -new -out ${name}1Cert.req -key ${name}1Cert.key -subj /CN="MyAzureVPN"
openssl x509 -req -sha256 -in ${name}1Cert.req -out ${name}1Cert.cer -CAkey MyAzureVPN.key -CA MyAzureVPN.cer -days 180 -CAcreateserial -CAserial serial
openssl pkcs12 -export -out ${name}1Cert.pfx -inkey ${name}1Cert.key -in ${name}1Cert.cer -certfile MyAzureVPN.cer

Tuesday, February 21, 2017

Firefox update in Crux

Updating Firefox, without rebuilding all other ports in Crux, is not the easiest task. Quite often you need to update one of packages Firefox depends one, but not all of them.

In my case, limited space on root partition is an additional problem. In the same time I have another, much bigger partition attached.

To address both issues I prepared this small script. It updates require dependencies (autoconf, sqlite, libpng, nspr, nss) and then updates Firefox, but with working directory in no default location (PKGMK_WORK_DIR).


prt-get update autoconf
prt-get update sqlite3
prt-get update libpng
prt-get update nspr
prt-get update nss
PKGMK_WORK_DIR=/media/pictures prt-get update firefox

Sunday, January 01, 2017

Bringing my Crux Enligthement+ repo back to live [Part I]

I wasn't doing anything with my home Linux machines for some time and recently decided to change it a bit. There are quite a few projects I hope to push a  forward. For example put all my pictures from CDROMs/DVDs into Dropbox, enable internal streaming from my RPi, install Linux on my Dell laptop.To achieve the last one I tried Kubuntu, but it's not so easy properly configure KDE nowadays (KDE5). I tried Enlightenment from Ubuntu PPA, but it connman seemed to be broken. So it seemed that I had to use Crux. Another option could be Arch, but I had already spent quite a lot of time configuring Enlightenment for Crux.

The package repository is located at wawrzek.name/crux/wawrzek/, and I keep my work in github wawrzek/crux-ports repository.

The first problem I encountered was issues with access to some .httpup related info:

Connecting to http://wawrzek.name/crux/wawrzek/
Updating collection wawrzek
 Edit: wawrzek/.httpup-repo.current
Failed to download http://wawrzek.name/crux/wawrzek/.httpup-repo.current: The requested URL returned error: 403 Forbidden
 Edit: wawrzek/.httpup-urlinfo
Failed to download http://wawrzek.name/crux/wawrzek/.httpup-urlinfo: The requested URL returned error: 403 Forbidden
Finished successfully


I host my repo on Linux virtual machine and I could easily confirm that all files has right access privileges, so I eliminated OS level problem. All other files in the same directory were properly accessible, so I started to suspect Apache configuration and that was a case. Apache Debian/Ubuntu configuration has block preventing web clients accessing .htaccess and .htpasswd, but definition is rather generous (^\.ht or everything what starts with string ".ht"). I decided that the simplist resolution is going to replace it with more specific rule (^\.ht(access|passwd)) what matches only ".htaccess" or ".htpasswd". Updated block of configuration is below:


#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht(access|passwd)">
        Require all denied
</FilesMatch>



Saturday, December 31, 2016

Control terminal name and comment block in VIM

Somewhere (I think it was Stackoverflow) I found simple command to control the name of terminal from commandline which works very nice with iterm2 tabs on MacOSX and decided to add to my zsh environment this function:

termname() {
 echo -en "\e]1; $1 \a"
}
 

And if we are saying about Stackoverflow one of the most useful Vim suggestion I've ever found is this instruction to comment/uncomment a multiple lines in VIM.

Tuesday, November 10, 2015

Many AWS accounts and Zsh

That might not be a common problem, but I have to deal with many AWS accounts in the same time. For example I might to have to run an Ansible playbook for one account and a CLI commend for other one in parallel. To make my life easier i wrote this ZSH function. (It's probably going to work in other advance shell).

There are two ways to use it.
  • awsenv list - returns the list of all available accounts/environments.
  • awsenv - sets, based on values provided in ~/.aws/credentaials and ~/.aws/config, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION.
The list is create with simple AWK script (assuming that any lines with "[]" is OK.

The actual command to set environment uses two AWK scripts. First one looks for requested account name and set variable "a" to 1. When "a" equals 1 it prints shell export command for access_key_id and for secret_access_key to  standard output, which is redirected to $TMP_FILE. Then it sources, prints and deletes that file.

Please note that in current form script requires access_key_id being define before secret_access_key.  Printing the value of all variables, especially secret_aceess_key could be consider as security weakness, so you might want to modify/remove "cat $TMP_FILE line.

# vim: set filetype=sh
awsenv () {
    if [[  $1 == list ]]
        then
        print $1
        awk  '/\[.*\]/ {print $1}'  ~/.aws/credentials
    else
        TMP_FILE=/tmp/current_aws
        awk \
           'BEGIN{a=0};\
           /\['$1'\]/ {a=1};\
           /access_key_id/ {if (a==1){printf "export %s=%s\n", toupper($1), $3}};\
           /secret_access_key/ {if (a==1) {printf "export %s=%s\n", toupper($1), $3;a=0}}'\
            ~/.aws/credentials > $TMP_FILE
        awk \
            'BEGIN{a=0};\
            /\[profile '$1'\]/ {a=1};\
            /region/ {if (a==1){printf "export AWS_DEFAULT_%s=%s\n", toupper($1), $3; a=0}}'\
            ~/.aws/config >> $TMP_FILE
        source $TMP_FILE
        cat $TMP_FILE
        rm $TMP_FILE
    fi
}



Finally, initial version of this script and some discusion on profiles in older boto versions is in this post http://larryn.blogspot.co.uk/2015/03/how-to-deal-with-aws-profiles.html

Wednesday, September 02, 2015

Real "Get All Launch Configuration" In Boto

During my recent Ansible tests I created 'some' number of launch configuration, enough to reach account limit and I wanted/had to clean it. Boto sounded like a good candidate to do this. This few lines should address my problem.

import boto
import boto.ec2
import boto.ec2.autoscale

asg = boto.ec2.autoscale.connect_to_region('us-east-1')
results = asg.get_all_launch_configurations()

But it didn't. I could even found my launch configurations in the results sets. I figured out quickly that my results set is rather big and by default get_all_lunch_configurations method paging results (AFAIR default value is 20). Using example from this post on SDB I create following function doing what above method name promises - get all lunch configuration.


def get_all_launch_configuration(connection)
    """get_all_launch_configuration(connection) -
       returns results set of all launch configuration,
       regardless it size. Function require established
       boto.ec2.autoscaling connection."""

    results = connection.get_all_launch_configurations()
    token = results.next_token
    while True:
        if token:
            r =  asg.get_all_launch_configurations(next_token=token)
            token = r.next_token
            results.extend(r)
        else:
            break

    return results
       

Monday, June 08, 2015

A small example of advance aptitude usage

Few years ago I 'preserved' few example of advance aptitude usage I found on a Debian mailing list. Recently I had a chance to use them again. I was looking for a version of packages with distinguish string in a name (let say it was 'apache').

aptitude versions \$(aptitude search ~iapache| awk '{print \$2}')

  • So first I ran aptitude search for 'apache' term, but only among installed packages - aptitude search ~iapache
  • From the results I cut package name (second column) - awk '{print \$2}'. Please note I escaped dollar character, because I run this command using Ansible (see this blog entry for more details).
  • The outcome of those two command allows me to query package versions - aptitude versions

Links