Using the expect tool for autonomous interaction with SysBack.

We have recently taken over development of SysBack, which had previously been developed by IBM.

Since I had just been working on a round-trip test (for the bare metal restore products developed in-house) it made some sense to extend this test to handle SysBack (since it can perform much the same function as the in-house programs) prior to changing the SysBack code.

One problem I immediately foresaw was that our BMR products have the facility to run ssh which allows remote manipulation of the process. SysBack typically does not enable ssh.

Since the Sysback boot image runs on a hypervisor (IBM’s HMC) all was not lost: we can talk to the hypervisor which in turn can talk to the boot image via its console.

Expect is a venerable program that automates interactions with programs that expose a text terminal interface. While there were a number of technical issues to overcome, it was thought that the modification of our existing test program was feasible; a feeling which was validated once the interaction was eventually coded.

The test program is written in python, so I used Paramiko Expect.

The first thing that I did with Expect was to interact with the SysBack recovery CD which presented some challenges. I started with the exemplar paramiko_expect-demo.py, which defines:

    with SSHClientInteraction(
        client,
        timeout=10,
        display=True) as interact:

The SysBack CD uses [n]curses initially to set up the requisite terminal and requires the user to press y after defining the terminal type to confirm that it appears correctly. Note this is a bare y character, not y followed by a carriage return or a newline character.

Implicit in the use of SSHClientInteraction are some defaults – one of which is newline='\r' (this knowledge gained through study of the source code, paramiko_expect.py ), so my we use:

    with SSHClientInteraction(
        client,
        timeout=100,
        newline='',
        display=True) as interact:

I handle the newlines by sending appropriate characters after the body of my response.

As an aside, I developed first on the Integrated Virtualization Manager (IVM) since, at the time, we did not have a HMC, and there I passed \n, ASCII character 10(decimal) as newline. When I moved the test program to run on a HMC I found out that sending a CR/LF (\r\n ASCII 13 then 10 characters) worked as newline. It took me some time to realise that I needed to make this change.

Once I could talk to the CD effectively, it was soon quite easy to move around the CD. I defined

    esc_char = '\0;33'
    down_arrow = esc_char + '[B'

to facilitate navigation – I guess I only ever left the menu (escape) and went down. Had I needed more control I would have had to find other curses sequences to move up, or right or left or whatever.

I enjoyed the bit of code which filled in a form most :-)

    interact.expect(enter_the_ip, strip_ansi=False)
    interact.send(self.tsm_data['client_ip'] + '\t')
    interact.send(self.tsm_data['node_name'] + '\t')
    interact.send(self.tsm_data['admin_id'] + '\t')
    interact.send(self.tsm_data['server_ip'] + '\t')
    interact.send(self.network_data['gateway'] + '\t')
    interact.send(self.network_data['netmask'] + '\t\t')
    interact.send(self.tsm_data['tsm_password'] + '\t')
    interact.send(esc_char + esc_char + esc_char)

where:

    enter_the_ip = '.*Enter the IP address by which the server.*'

which allows me to set configuration data at the start of the run and then access it within the expect code.

Once SysBack has restored a machine it goes through a reboot cycle then we can use expect (with a very high timeout) to wait for a login prompt:

    login_prompt = r'\s*Console login:\s*'

I login via expect and enable the network and ssh then perform post-recovery analysis via ssh.

I did find it very useful to have the machine running and available and to write small test scripts which supplied the minimum data to the python module which contained the expect code, rather than having to re-run my round-trip test program each time, since it takes quite a long time to backup and restore a machine.