Monday 7 November 2016

Ansible in a Virtualenv

Tested on Arch Linux. First install support for the Virtualenv

$ pip2 install virtualenv

Create the virtualenv to host ansible :

$ virtualenv --system-site-packages ansible_env

Activate the environment

$ source ansible_env/bin/activate

Install a specific version

$ pip2 install ansible==2.1.3.0

When complete deactivate

$ deactivate

Sunday 29 May 2016

Midnight Commander Configuration

By default when exiting Midnight Commander bash returns to the directory Midnight Commander was started from, instead of the last open directory. Midnight Commander has a wrapper script which can be used by adding
source /usr/lib/mc/mc.sh
to your
~/.bashrc
Useful Commands are
Copy (to second pane) : F5
Move (to second pane) : F6
Exit Midnight Commander : F10
Tab : Move to second pane
User menu (compress, uncompress) : F8

Midnight Commander Key Bindings

To change the default key bindings for Midnight commander on Arch Linux. From the man pages :
  Redefine hotkey bindings

Hotkey bindings may be read from external file (keymap-file).  Initially, Mignight    Commander creates key bindings using keymap defined in the source code. Then,  two  files  /usr/share/mc/mc.keymap  and  /etc/mc/mc.keymap are loaded always, sequentially reassigned key bindings defined earlier.  User-defined keymap-file is searched on the following algorithm (to the first one found):

              1) command line option -K <keymap> or --keymap=<keymap>
              2) Environment variable MC_KEYMAP
              3) Parameter keymap in section [Midnight-Commander] of config file.
              4) File ~/.config/mc/mc.keymap
Thus we can just
$ cp /etc/mc/mc.default.keymap ~/.config/mc/mc.keymap 
Then edit the keymap file as required. Its useful to save the file within a repository such as git when complete.

Monday 2 May 2016

Ansible Roles variables that differ between OS

Using Ansible roles you may wish to set the package and service name per OS. Within roles we can import them within tasks from the appropriate vars.

tasks/main.yml

- name: Obtain OS Specific Variables
  include_vars: "{{ item }}"
  with_first_found:
    - "../vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml"
    - "../vars/{{ ansible_distribution }}.yml"
    - "../vars/{{ ansible_os_family }}.yml"
    - "../vars/defaults.yml"
Then you can set values within /vars as appropriate e.g. Apache

vars/default.yml

apache_package_name: apache2
apache_service_name: apache2

/vars/RedHat.yml

apache_package_name: httpd
apache_service_name: httpd

/vars/Debian.yml

apache_package_name: apache2
apache_service_name: apache2

Monday 25 April 2016

Using /proc on Linux

/proc on Linux is a pseudo file system that provides an interface to the kernel data structures. It is very useful for troubleshooting and the following highlights some that I have found helpful. The man page can be accessed with full details on Arch Linux with :
# man 5 proc

/proc/cpu

  • A collection of CPU and system architecture dependent items
  • Useful to find the CPU type, number of cores and flags
  • lscpu uses this file to obtain its information
    $ cat /proc/cpu
    

/proc/cmdline

  • Arguments passed to the Linux kernel at boot time
  • Useful to see what options were used by e.g. grub on boot
    $ cat /proc/cmdline
    

/proc/loadavg

  • The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or waiting for disk I/O (state D) averaged over 1, 5, and 15 minutes.
  • Same numbers used by uptime
    $ uptime && cat /proc/loadavg
     20:37:08 up  1:36,  8 users,  load average: 0.51, 2.17, 2.56
     0.51 2.17 2.56 6/681 11570
    
  • The fourth field consists of two numbers separated by a slash (/)
  • The first of these is the number of currently runnable kernel scheduling entities (processes, threads)
  • The value after the slash is the number of kernel scheduling entities that currently exist on the system.
  • The fifth field is the PID of the process that was most recently created on the system.

/proc/meminfo

  • Reports statistics about memory usage on the system
  • Used by free to report the amount of free and used memory (both physical and swap) on the system as well as the shared memory and buffers used by the kernel
     $ cat /proc/meminfo
    

/proc/[pid]/cmdline

  • Everything in Linux is a file and each process has a directory under /proc for its /pid/
  • As pid 1 is the init script we can
    $ cat /proc/1/cmdline
    /sbin/init
    
  • This read-only file holds the complete command line for the process

/proc/[pid]/fd/

  • A subdirectory containing one entry for each file which the process has open, named by its file descriptor
  • Its a symbolic link to the actual file

Sunday 24 April 2016

Best Practices for Docker Container deployments

Container technology like Docker leads to faster testing and deployments of software applications. The following is a list of some best practices to consider when using containers. The key objectives are :
Repeatability
Reliability
Resiliency

To achieve this :

1. Have a single code base, tracked in git with many deploys

  • Docker containers should be immutable
  • Use the environment variables to change anything inside the container
  • Do not build separate images for staging and production

2. Explicitly declare and isolate any dependencies

  • Do not use latest in images. Instead define the exact version e.g. ubuntu:latest vs ubuntu:16.04
  • Its useful to build run times (e.g. Java run time) based on specific images
  • Process -> Base OS -> Run Time (e.g. Java run time) -> Add app

3. Store configuration in the environment

  • Do not have a config.yml or properties.xml
  • Always use environmental variables

4. Treat backing services as attached resources

  • Never use local disk
  • Data will always disappear
  • Connect to network services using connection info from the environment e.g. DB_URL

5. Strictly separate build and run stages

  • Build immutable images and then run them
  • Never install anything on deployments
  • Respect the life cycle : build, run, destroy

6. Execute the application as 1 or more stateless processes

  • Schedule long running processes by distributing them across a cluster of physical hardware

7. Export services via port binding

  • Define ports from environment variables
  • A PID cannot guarantee the port in the container

8. Scale out via process model

  • Horizontally scale by adding instances

9. Maximize robustness with fast start-up and graceful shutdown

  • Quickly scale up when there is a load spike
  • For a data intensive app its tempting to load data into memory as a hot cache. Issue is that this stops having a fast start-up (as need to load data into memory). Could use Redis or memcache as an alternative

10. Keep development, staging and production as simple as possible

  • Run containers in development e.g. DB, caching

11. Treat logs as event streams

  • Log to standard output (stdout) and standard error (stderr)
  • Use something like the ELK stack to collect all the logs
  • Should never need to ssh to check logs
  • There should not be random log files in the container

12. Run admin/management tasks as one off processes

  • Do not use customer containers as one off tasks
  • Reuse app images with specific entry points for tasks

Sunday 17 April 2016

systemd-analyze - Analyze system boot-up performance

The systemd project has an excellent tool systemd-analyze which allows an analysis of system boot performance.

Running without any parameters displays the startup time in total with figures for the kernel + userspace
$ systemd-analyze
Startup finished in 1.190s (kernel) + 8.312s (userspace) = 9.503s
The option blame prints a list of all running units, ordered by the time they took to initialize. This may be used to optimize boot-up times. The output may be misleading as the initialization of one service might be slow simply because it waits for the initialization of another service to complete.
For example the 3 applications that took longest to initialise :
$ systemd-analyze blame | head -n 3
          7.621s man-db.service
          3.174s docker.service
          1.134s mysqld.service
The option critical-chain prints a tree of the time-critical chain of units (for each of the specified UNITs or for the default target otherwise).

The time after the unit is active or started is printed after the “@” character. The time the unit takes to start is printed after the “+” character. Note that the output might be misleading as the initialization of one service might depend on socket activation and because of the parallel execution of units
For example reviewing the docker.service unit

$ systemd-analyze critical-chain docker.service
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.

docker.service +3.174s
`-network.target @1.287s
  `-NetworkManager.service @830ms +172ms
    `-dbus.service @691ms
      `-basic.target @682ms
        `-sockets.target @682ms
          `-docker.socket @681ms +481us
            `-sysinit.target @681ms
              `-systemd-backlight@backlight:acpi_video0.service @1.321s +41ms
                `-system-systemd\x2dbacklight.slice @1.320s
                  `-system.slice @123ms
                    `--.slice @102ms

The plot option prints an SVG graphic detailing which system services have been started at what time, highlighting the time they spent on initialization
$ systemd-analyze plot > plot.svg

How to paste source code in Vim without losing formatting

When pasting code into Vim automatic indenting can occur and your code formatting will be incorrect. To stop this issue there are two options :

Paste option


Within vim
    : set paste

Vimrc function key mapping


It can be useful to have a mapping in your ~/.vimrc file to quickly allow enable/disable of the paste feature :
" Quickly enable/disable 'paste' option
set pastetoggle=<F10>

Saturday 16 April 2016

Upgrading to GNOME 3.20 from 3.18

Every 6 months the GNOME team releases a new version of the Desktop. Running Arch Linux its great to be able to have quick access to the new features quickly. Running near to the bleeding edge always has a few quirks and here are a few I encountered.

Extensions claiming they are not supported

This is a common issue for me on every GNOME upgrade. I discovered this check can quickly be disabled as follows :
$ gsettings set org.gnome.shell disable-extension-version-validation "true"

No Topleft Hot Corner Extension stopped working

One of my ‘must have’ extensions is no topleft hot corner which stopped working. I found that removing the extension from the extensions site and then installing it from the AUR works as its a newer version :
$ packer -S gnome-shell-extension-nohotcorner-git
This installs the extension as follows :
$ ls /usr/share/gnome-shell/extensions/nohotcorner@azuri.free.fr/
extension.js  metadata.json

Excessive Padding in Applications

The css selectors changed in GNOME 3.20 which means that the padding on titlebars e.g. Firefox and terminal is large. GNOME provides a config file for users to tweak their own environment ~/.config/gtk-3.0/gtk.css. I updated mine to :
/* shrink headebars */
headerbar {
    min-height: 0;
    padding-left: 2px; /* same as childrens vertical margins for nicer proportions */
    padding-right: 2px;
    padding-top: 1px;
    padding-bottom: 1px;
}

headerbar entry,
headerbar spinbutton,
headerbar button,
headerbar separator {
    margin-top: 1px; /* same as headerbar side padding for nicer proportions */
    margin-bottom: 1px;
}

 /* shrink ssd titlebars */
.default-decoration {
    min-height: 0; /* let the entry and button drive the titlebar size */ 
    padding-left: 2px; /* same as childrens vertical margins for nicer proportions */
    padding-right: 2px;
    padding-top: 1px;
    padding-bottom: 1px;
}

.default-decoration .titlebutton {
    min-height: 5px; /* tweak these two props to reduce button size */
    min-width: 5px;
}

/* reduce the padding size of buttons */
button, entry {
  min-height: 0;
  min-width: 0;
  padding: 2px;
}

/* reduce the padding of tabs */
notebook tab {
  min-height: 0;
  padding-top: 3px;
  padding-bottom: 3px;
}

/* reduce the padding of buttons */
notebook tab button {
  min-height: 0;
  min-width: 0;
  padding: 2px;
  margin-top: 2px;
  margin-bottom: 2px;
}

notebook button {
  min-height: 0;
  min-width: 0;
  padding: 2px;
}

/* add padding for Vte-terminal */
widget {
    padding: 4px;
}
Restart GNOME shell with Alt + F2 then type ‘r’ which will restart the desktop to ally the changes.

Monday 28 March 2016

chromium - FATAL:setuid_sandbox_client.cc(126)] Check failed: IsFileSystemAccessDenied()

Testing running chromium in Docker I had the following stack trace :
[0329/035746:FATAL:setuid_sandbox_client.cc(126)] Check failed:
 IsFileSystemAccessDenied().
#0 0x55e51a82299e <unknown>
#1 0x55e51a8007ee <unknown>
#2 0x55e51a8934fe <unknown>
#3 0x55e51a7f3f3b <unknown>
#4 0x55e51a7f21a6 <unknown>
#5 0x7fe5e8984710 <unknown>
#6 0x55e51a7f34f9 <unknown>

[1:1:0329/035746:ERROR:nacl_fork_delegate_linux.cc(315)] Bad NaCl helper
 startup ack (0 bytes)
[1:1:0329/035746:FATAL:setuid_sandbox_client.cc(126)] Check failed: 
IsFileSystemAccessDenied().
This is because chromium should not be run as root. From the development list this is by design.

Sunday 27 March 2016

Arch Linux pacstrap options

When creating a base Arch Linux image from scratch for Docker I found the documentation for pacstrap to be limited.
Pacstrap is installed as part of the arch-install-scripts and I eventually found the following options running as the root user
# pacstrap -h
usage: pacstrap [options] root [packages...]

  Options:
    -C config      Use an alternate config file for pacman
    -c             Use the package cache on the host, rather than the target
    -d             Allow installation to a non-mountpoint directory
    -G             Avoid copying the host's pacman keyring to the target
    -i             Avoid auto-confirmation of package selections
    -M             Avoid copying the host's mirrorlist to the target

    -h             Print this help message

pacstrap installs packages to the specified new root directory. If no packages
are given, pacstrap defaults to the "base" group.
The docker script I used was :
spawn pacstrap -C $PACMAN_CONF -c -d -G -i $ROOTFS base haveged 
$PACMAN_EXTRA_PKGS --ignore $PKGIGNORE

Build Arch Linux base image for Docker

As there is no official Docker Hub build for Arch Linux I thought this would be a good oppertunity to find out how images are created from scratch for OS’s. IMHO its good practice to create your own images to ensure you know exactly the providence of what is installed in your container.
As a starting point I used the mkimage-arch.sh script on the Docker github contrib area.
Script must be run as root
if [ “$(id -u)” != “0” ]; then
printf "This script must be run as root\n" 
exit 1
fi
There are two required packages : expect + pacstrap which can be installed with :
$ pacman -S arch-install-scripts expect
The script checks for this as follows :
hash pacstrap &>/dev/null || {
    printf "Could not find pacstrap. Run pacman -S arch-install-scripts"
    exit 1
}

hash expect &>/dev/null || {
    printf "Could not find expect. Run pacman -S expect"
    exit 1
}
The || is similar to && except it tells the shell only to evaluate the expression after it when the first expression fails.

The hash command affects the way the current shell environment remembers the locations of utilities found. If run without any parameters it shows the path of all commands run since the hash was last reset (hash -r) e.g.
$ hash
hits    command
   1    /usr/bin/git
   1    /usr/bin/vim
   3    /usr/bin/cat
   1    /usr/bin/touch
   1    /usr/bin/mv
   1    /usr/bin/mkdir
   3    /usr/bin/man
  13    /usr/bin/ls
The hash table is a feature of bash that prevents it from having to search $PATH every time you type a command by caching the results in memory. For this use case we use it as a way to test if the command is available.
Next we set the language as UTF-8 :
export LANG="C.UTF-8"
Create a temporary root file system with mktemp :
ROOTFS=$(mktemp -d /tmp/rootfs-archlinux-XXXXXXXXXX)
mktemp creates a temporary directory (or file) based on the template provided to randomize the name. Each X value is replaced with a random string.

Set permissions
chmod 755 "$ROOTFS"
Define the packages to not install for minimal image
PKGIGNORE=(
    cryptsetup
    device-mapper
    dhcpcd
    iproute2
    jfsutils
    linux
    lvm2
    man-db
    man-pages
    mdadm
    nano
    netctl
    openresolv
    pciutils
    pcmciautils
    reiserfsprogs
    s-nail
    systemd-sysvcompat
    usbutils
    vi
    xfsprogs
)
Expanding an array without an index only gives the first element. The $IFS is a special shell variable which stands for Internal Field Separator.
IFS=','
PKGIGNORE="${PKGIGNORE[*]}"
unset IFS
printf "%s""\nPackages not to be installed : $PKGIGNORE\n"
Set pacman.conf to provided conf file
PACMAN_CONF='./arch-docker-pacman.conf'
Define the mirror for pacman :
PACMAN_MIRRORLIST='Server = https://mirrors.kernel.org/archlinux/\$repo/os/\$arch'
Set basic variables to create image
PACMAN_EXTRA_PKGS=''
EXPECT_TIMEOUT=60
ARCH_KEYRING=archlinux
DOCKER_IMAGE_NAME=archlinux
Export pacman mirror
export PACMAN_MIRRORLIST
Use expect to auto reply to pacstrap
expect <<EOF
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- \$arg
    }
    set timeout $EXPECT_TIMEOUT

     spawn pacstrap -C $PACMAN_CONF -c -d -G -i $ROOTFS base haveged $PACMAN_EXTRA_PKGS --ignore $PKGIGNORE
    expect {
        -exact "anyway? \[Y/n\] " { send -- "n\r"; exp_continue }
        -exact "(default=all): " { send -- "\r"; exp_continue }
        -exact "installation? \[Y/n\]" { send -- "y\r"; exp_continue }
    }
EOF
Remove manual files to save space
arch-chroot "$ROOTFS" /bin/sh -c 'rm -r /usr/share/man/*'
Use haveged to generate random numbers and feed linux random device. You must run pacman-key –init before first using pacman; the local keyring can then be populated with the keys of all official Arch Linux packagers with pacman-key –populate archlinux.
arch-chroot "$ROOTFS" /bin/sh -c "haveged -w 1024; pacman-key --init; pkill haveged; pacman -Rs --noconfirm haveged; pacman-key --populate $ARCH_KEYRING; pkill gpg-agent"
Set local timezone to UTC
arch-chroot "$ROOTFS" /bin/sh -c "ln -s /usr/share/zoneinfo/UTC /etc/localtime"
Set locale to ‘en_US.UTF-8 UTF-8’
echo 'en_US.UTF-8 UTF-8' > "$ROOTFS"/etc/locale.gen
arch-chroot "$ROOTFS" locale-gen
Set pacman mirrorlist
arch-chroot "$ROOTFS" /bin/sh -c "echo $PACMAN_MIRRORLIST > /etc/pacman.d/mirrorlist"
udev is a device manager for the Linux kernel. Udev primarily manages device nodes in the /dev directory and also handles all user space events raised while hardware devices are added into the system or removed from it, including firmware loading as required by certain devices.
udev doesn’t work in containers, rebuild /dev
DEV=$ROOTFS/dev
rm -rf "$DEV"
mkdir -p "$DEV"
mknod -m 666 "$DEV"/null c 1 3
mknod -m 666 "$DEV"/zero c 1 5
mknod -m 666 "$DEV"/random c 1 8
mknod -m 666 "$DEV"/urandom c 1 9
mkdir -m 755 "$DEV"/pts
mkdir -m 1777 "$DEV"/shm
mknod -m 666 "$DEV"/tty c 5 0
mknod -m 600 "$DEV"/console c 5 1
mknod -m 666 "$DEV"/tty0 c 4 0
mknod -m 666 "$DEV"/full c 1 7
mknod -m 600 "$DEV"/initctl p
mknod -m 666 "$DEV"/ptmx c 5 2
ln -sf /proc/self/fd "$DEV"/fd
tar root file system and import image to Docker.
tar --numeric-owner --xattrs --acls -C "$ROOTFS" -c . | docker import - "$DOCKER_IMAGE_NAME"
Options for tar used :
--numeric-owner  Always use numbers for user/group names.
--xattrs         Enable extended attributes support
--acls           Enable the POSIX ACLs support
-C               Change to directory
-c               Create new archive 
Test new image
docker run --rm -t $DOCKER_IMAGE_NAME echo Success
Delete temp root file system
rm -rf "$ROOTFS"
Running the script should finish with
tar: ./etc/pacman.d/gnupg/S.gpg-agent: socket ignored
sha256:82b0356924efb95e5483417dd4f0cef85fce7afbacb75c18632de7bc45edd796
Success
Script available on my docker repository on github.

Sunday 13 March 2016

Python Monary Unable to find cmonary shared library libcmonary.so

Monary provides a Python interface for fast column queries from MongoDB. I set-up on Arch Linux as follows :
 $ pacman -S libmongoc python-numpy
 $ pip install pkgconfig
 $ pip install monary
Running the Monary package produces the following error :
RuntimeError: ('Unable to find cmonary shared library: ', 'libcmonary.so')
With some research I found this is an open issue with Monary.
To work around the issue open :
$ sudo vim /usr/lib/python3.5/site-packages/monary/monary.py
And update around line 68 to :
else:
    cmonary_fname = "libcmonary.cpython-35m-x86_64-linux-gnu.so"
I also found errors with the WriteConcern import which as a workaround in the monary.py file I updated to :
sys.path.append('/usr/lib/python3.5/site-packages/monary')
from write_concern import WriteConcern

Monday 29 February 2016

Vagrant Change default ssh forwarded port

Vagrant is a great tool for quickly setting up and destroying a development test environment. By default it will define a local port on your workstation to port forward ssh traffic to the Vagrant box. For a multi server set-up environment I prefer to be able to specify the exact port to use for ssh port forwarding.
For example to set the ssh port forwarding as 4001 in the Vagrantfile you can define :
db.vm.network "forwarded_port", guest: 22, host: 4001, id: 'ssh'
It does require the id: section to be set for ssh. I find this really useful for Ansible so I can define the exact ssh port and IP address within my Ansible File.

Sunday 28 February 2016

Ansible Facts Caching With Redis

Ansible is an amazing tool for automation of tasks. Facts are details about the host that Ansible gathers when it connect to the machine. It will gather a significant amount of useful information that can be used in Playbooks e.g. OS version, IPv4/IPv6 addresses. To make Ansible go faster we can store the facts in a cache the first time in connects to the hosts. On subsequent Playbook executions Ansible will only look up the facts in the cache instead of gathering them again. There is a cache option fact_caching_timeout that can be modified to define how long the cache should be valid for in seconds.

Setup Redis for Ansible Caching

On Arch Linux install redis and enable it
  $ pacman -S redis
  $ systemctl enable redis
  $ systemctl start redis
Install the Python Redis packages
$ pacman -S python2-redis python-redis
Check redis is responding
$ redis-cli ping
PONG
Update /etc/ansible/ansible.cfg in a text editor
gathering = smart
fact_caching = redis
fact_caching_timeout = 86400
fact_caching_connection = localhost:6379:0
After running a Playbook redis-cli can be used to view the keystore e.g.
$ redis-cli 
127.0.0.1:6379> keys *
1) "ansible_cache_keys"
2) "ansible_factsDB1"

Sunday 21 February 2016

ssh agent and forwarding on Arch Linux for Ansible

I have been using Ansible a lot for automation of deployments recently. One of my deployments had the need to clone a git hosted project from a server in the cloud. I did not want to have to place my private key on the cloud server for security reasons. The answer for me was setting up an ssh agent on my Arch Linux workstation to simplify working for ssh keys. With the ssh agent in place I could use ssh agent forwarding to authenticate using the private key on my workstation. The same process would work for any version of Linux.

SSH Agent set-up

On the Arch Linux Wiki there is a number of suggestions but the one I found was the easiest was from this StackOverflow article by adding the following to my ~/.bash_profile
SSH_ENV="$HOME/.ssh/environment"

function start_agent {
echo "Initialising new SSH agent..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
    start_agent;
}
else
start_agent;
fi
This will check if you already have an ssh-agent running and if not will start a new agent. You can always check its running:
$ pgrep -a ssh-agent
23409 /usr/bin/ssh-agent
The ssh-agent daemon will automatically import the private key ~/.ssh/id_rsa which can be listed with:
$ ssh-add -L
Other private keys can be included for use by the ssh-agent with :
$ ssh-add <path to private key>

Agent Forwarding

Within my /etc/ansible/ansible.cfg file I set the following ssh settings
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes
When Ansible is on the remote machine and clones from the git project the authentication will automatically be forwarded to my Arch workstation to be authenticated by the ssh-agent.

Obtain Random Words from a Dictionary in Linux

It can be very useful to be able to quickly generate random words from a dictionary in Linux. One common use case I have is generating random responses for the Security Questions on web sites. This is to avoid anyone easily guessing what the answers are. Typically the questions tend to be the same and not very difficult to guess. I save the actual responses in the Notes section of the Password Manager than I use.

Obtain A Dictionary Text File

There is a great dictionary list that is available with GNU Aspell (ftp://ftp.gnu.org/gnu/aspell/dict/0index.html) which provides a collection of International ‘words’ files for /usr/share/dict.
To install on Arch Linux :
$ pacman -S words
$ wc -l /usr/share/dict/usa
119095 /usr/share/dict/usa
There are a number of dictionaries installed under /usr/share/dict/ that you can choose from
$ ls /usr/share/dict/
american-english british british-english catala catalan finnish french german italian ngerman ogerman spanish usa

shuf - generate random permutations

We can use the shuf command to generate random words using a dictionary. Install shuf if its not installed :
$ pacman -S shuf
Then use the n argument to define the number of words you would like e.g.
$ shuf -n5 /usr/share/dict/usa
macroeconomic
visualizes
shabbiest
sen
chortler
To easily access this I have an alias :
alias GenerateRandomWord=’shuf -n5 /usr/share/dict/usa’