Dummy java loop/sleep for test of init scripts

A dummy java executable (actually a jar) was required to develop init scripts without access to the client’s application.   The process of creating a Java ‘sleep’ application and wrapping within a ‘jar’ complete with manifest was not obvious to me.  The ‘thread.sleep’ also didn’t work as I expected, requiring an additional exception handler.  Not to mention the requirement for the manifest to require multiple new lines before being syntactically correct (and no report otherwise when incorrectly parsed, except ‘no main manifest attribute’ when attempting to run).  Why Java, WHY?

The following tgz contains both the compiled java executable plus source, manifest and instructions to build / compile the jar should the wait time (default 100 seconds) need to be modified.

WaitLoop.tgz (source and executable tgz)
WaitLoop (Github Project)

The .jar can be executed with:-

java -jar WaitLoop.jar

X forwarding over ssh and sudo

This has bugged me for years – with random success depending on sudo, su – etc.

The proper solution:-

steve@studio:~$ ssh -X
Last login: Fri Feb 10 21:54:11 2017 from
[steve@fleabox ~]$ xauth list
fleabox.track3.org.uk/unix:12  MIT-MAGIC-COOKIE-1  b4339e07fb0e4febdde6128fc56419e4
[steve@fleabox ~]$ sudo su -
[sudo] password for steve: 
[root@fleabox ~]# xauth add fleabox.track3.org.uk/unix:12  MIT-MAGIC-COOKIE-1  b4339e07fb0e4febdde6128fc56419e4
[root@fleabox ~]# virt-manager &
[1] 7168


Docker and Apache QuickStart

mkdir -p dockerfile/C7httpd; cd dockerfile/C7httpd
vi Dockerfile

FROM centos:7
MAINTAINER "Steve Netting" steve@netting.org.uk
ENV container docker
RUN yum -y --setopt=tsflags=nodocs update && \
yum -y --setopt=tsflags=nodocs install httpd && \
yum clean all


ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh

CMD ["/run-httpd.sh"]

vi run-httpd.sh


# Make sure we're not confused by old, incompletely-shutdown httpd
# context after restarting the container. httpd won't start correctly
# if it thinks it is already running.
rm -rf /run/httpd/* /tmp/httpd*

exec /usr/sbin/apachectl -DFOREGROUND

docker build .
docker images
docker run -d -p:8082:80 steve/httpd:latest
docker ps
curl http://localhost:8082

... If you can read this page it means that this site is working properly ...

To start interactive shell from inside running container:
docker exec -i -t romantic_noyce /bin/bash

Retrieving SCSI/LUN IDs from Linux /dev/sd*

Useful to identify disks present before/after a rescan of LUNs:-

for x in `ls -1 /dev/sd*`; do echo -n "$x:"; sudo /sbin/scsi_id -g $x; done > file.txt

The output is then in the format:-


Capture output before/after rescan of SCSI bus then use something like this to reveal the newly added LUNs (SCSI IDs):-

sdiff prescan.txt postscan.txt | grep ">"  | awk '{ print $2 }' | cut -d":" -f2 | sort -n | uniq

VPN-like functionality over ssh tunnel (sshuttle)

Running TCP over TCP (for example, TCP over an SSH tunnel) results in poor performance and reliability.  There’s several ways to do this; for example basic port forwarding in ssh or via pppd over ssh.

However, there’s a much nicer solution:  sshuttle!

From GitHub:

“As far as I know, sshuttle is the only program that solves the following common case:

  • Your client machine (or router) is Linux, FreeBSD, or MacOS.
  • You have access to a remote network via ssh.
  • You don’t necessarily have admin access on the remote network.
  • The remote network has no VPN, or only stupid/complex VPN protocols (IPsec, PPTP, etc). Or maybe you are the admin and you just got frustrated with the awful state of VPN tools.
  • You don’t want to create an ssh port forward for every single host/port on the remote network.
  • You hate openssh’s port forwarding because it’s randomly slow and/or stupid.
  • You can’t use openssh’s PermitTunnel feature because it’s disabled by default on openssh servers; plus it does TCP-over-TCP, which has terrible performance (see below).”

‘sshuttle’ appears to be available in both in the standard debian/ubuntu repos and the RHEL/Centos EPEL repo.

The following creates ane then routes all traffic (including DNS lookuos) over a ‘VPN-like’ ssh tunnel.

sudo sshuttle --dns -r <user>@<target host>:<port> 0/0 -vv

Once this is working you can drop the -vv (verbose level 2).  Also, if you’re not concerned about DNS hijacking you can omit the –dns to speed up DNS lookups (resolve locally).  To stop the tunnel just CTRL-C.

The man page for sshuttle is quite detailed; check there for more information.

Ansible: Simple template example within a role

Here, we create a role which a) deploys a file into /tmp and b) demonstrates the use of a host variable to modify the contents of this file. As the contents is dynamic we use the ‘template’ module, rather than file.

Using Ansible Galaxy we create the role directory structure:-

steve@devbox:~$ cd ~ansible/roles
steve@devbox:~/ansible/roles$ ansible-galaxy init testtmp
- testtmp was created successfully

Let’s go ahead and create our template file:-

steve@devbox:~/ansible/roles$ cd testtmp/templates
steve@devbox:~/ansible/roles/testtmp/templates$ vi tmp.conf

Swap Free = {{ ansible_swapfree_mb }}

The {{ ansible_swapfree_mb }} indicates a variable (in this case, a host fact).

Now create a simple task top deploy the above template:-

steve@devbox:~/ansible/roles/testtmp/templates$ cd ../tasks/
steve@devbox:~/ansible/roles/testtmp/tasks$ vi main.yml 

# tasks file for testtmp
- name: Drop template into /tmp
  template: src=~/ansible/roles/testtmp/templates/tmp.conf dest=/tmp/tmp.txt

We now modify (or create) our site.yml:-

steve@devbox:~/ansible/roles/testtmp/tasks$ cd ~/ansible/
steve@devbox:~/ansible$ ls
roles  site.yml
steve@devbox:~/ansible$ vi site.yml 

- name: Deploy test roles
  hosts: all
  become: true

    - time
    - testtmp

Now let’s run the playbook:-

steve@devbox:~/ansible$ ansible-playbook site.yml

PLAY [test ntp via time role] **************************************************

TASK [setup] *******************************************************************
ok: []

TASK [time : Install NTP] ******************************************************
ok: []

TASK [testtmp : Drop template into /tmp] ***************************************
changed: []

PLAY RECAP *********************************************************************                  : ok=3    changed=1    unreachable=0    failed=0   

Success! Let’s hit the target and check the actual changes:-

steve@devbox:~/ansible$ ssh
Last login: Tue Nov 22 12:55:29 2016 from
steve@testtarget:~$ ls -l /tmp
total 4
-rw-r--r-- 1 root root 17 Nov 22 12:55 tmp.txt
steve@testtarget:~$ cat /tmp/tmp.txt 
Swap Free = 767

Yes! The template is deployed and the variable is set correctly.

Ansible: From install to roles in 5 minutes

Here’s a real quick walkthrough from install of Ansible to a primitive role based playbook.

Install ansible and create/edit our ansible hosts file:-

steve@devbox:~$ sudo aptitude install ansible
steve@devbox:~$ sudo vi /etc/ansible/hosts


In my case I have a single target in the ‘test’ group:-

I copy my private key to the remote system (authorized_keys) ensuring permissions are correct.
We should then be able to do an ansible ping. Be aware you will need python installed on the target.

steve@devbox:~$ ansible -m ping all | SUCCESS => {
    "changed": false, 
    "ping": "pong"

Now I make a basic directory structure to store our yaml files.

steve@devbox:~$ mkdir ansible/roles
steve@devbox:~$ cd ansible/roles

ansible-galaxy can help us with the layout of the role directory structure:-

steve@devbox:~$ ansible-galaxy init time
- time was created successfully

Let’s take a look at what ansible-galaxy has created for us:-

steve@devbox:~$ cd time; ls
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars

Great stuff. Let’s start by creating a task. I’d like to install NTP and ensure it’s running.

steve@devbox:~$ cd tasks
steve@devbox:~$ vi main.yml

# tasks file for time
- name: Install NTP
  apt: pkg=ntp state=installed update_cache=true
  notify: start ntp

The above includes a ‘notify’ for a handler to take action. Let’s create that handler:-

steve@devbox:~$ cd ../handlers
steve@devbox:~$ vi main.yml

# handlers file for time
- name: start ntp
  service: name=ntp state=started

Now move back to the root of our ansible configs and create a simple playbook (site.yml)

steve@devbox:~$ cd ~/ansible
steve@devbox:~$ vi site.yml


- name: test ntp via time role
  hosts: all
  become: true

    - time

The above indicates we want all hosts to include the NTP role. We’ll need to ‘become root’ on the target in order to install software. The role we want to run is called ‘time’ (as per the ansible-galaxy init and our resultant direcctory structure).

Finally, let’s run the site playbook:-

steve@devbox:~$ ansible-playbook site.yaml

PLAY [test ntp via time role] **************************************************

TASK [setup] *******************************************************************
ok: []

TASK [time : Install NTP] ******************************************************
changed: []

RUNNING HANDLER [time : start ntp] *********************************************
ok: []

PLAY RECAP *********************************************************************                  : ok=3    changed=1    unreachable=0    failed=0   


Correlate devices and LUNs with powerpath pseudo-devices

Quick bash snippet to list powerpath pseudo-devices, LUNs and underlying devices.  This takes the raw output of ‘powermt display dev-all’ and massages it into a parseable list:-


Pseudo name=emcpowera
Symmetrix ID=000192600720
Logical device ID=047C
Device WWN=60000970000192600720533030343743
state=alive; policy=SymmOpt; queued-IOs=0
--------------- Host ---------------   - Stor -  -- I/O Path --   -- Stats ---
###  HW Path               I/O Paths    Interf.  Mode     State   Q-IOs Errors
   3 lpfc                   sdadq      FA 10f:00 active   alive      0      0
   1 lpfc                   sdrj       FA 12f:00 active   alive      0      0
   0 lpfc                   sdaw       FA  5f:00 active   alive      0      0


emcpowera 60000970000192600720533030343743 sdadq sdrj sdaw

Note: the sed may need to be adjusted to to match your storage solution / HW Path.

for field in $(sudo powermt display dev=all | egrep "Pseudo|lpfc|WWN" | awk '{ print $2" "$3 }' | cut -d"=" -f2 | sed 's/lpfc //g'); do
    if [[ $field = "emcpower"* ]]; then
      echo -en "\n$field "
      echo -n "$field ";


Just CPC: The 2015 Amstrad CPC Clone

On the 7th January 2015 Piotr Bugaj released the first details regarding his Amstrad CPC clone.  The original specification included 64Kb RAM and MX4 expansion connectors, in addition to the standard edge connector.

The Original ‘Just CPC’ Design

By August 2015 the first boards started arriving.  By this point it had lost one MX4 slot but gained a voltage rectifier, regulator, 128Kb RAM and an onboard floppy controller (DDI-1) including Parados ROM and a PS/2 keyboard interface.

The ‘Just CPC 128K’

The complete board is a 4 layer design and is available as either a complete or unpopulated board.  The ‘Just CPC 128k’ is available from http://www.sellmyretro.com/.

‘Just CPC 128k’, Zaxon (Speccy.pl)