“Besides black art, there is only automation and mechanization.” Federico García Lorca

Where I work, Jenkins is what we use for continuous integration. Skype is what we use to communicate. Now imagine with me that every day, at least 6 times, I’m being asked to run a build, and then another 6 to check the status of the build! And then another 6 times to run a deploy.

And guess what? Another 6 times to check the status of the deploy, which is then followed by 4 questions on why the platform is down!

gyah

All this because some managers are too scared to let non-technical people touch Jenkins, and some of the non-technical people are too lazy to take the initiative to know how to run or check Jenkins’ jobs.

I was getting annoyed and bored with these repetitive tasks, so I decided to build a robot and delegate these jobs to it.

Every request is sent directly to the robot as a command. It performs the action automatically, and listens for any change on the status of the Jenkins job. If it detects any change or transition, it sends us a notification.

Jenkins

The robot is just Python script running on the background as demon, using Skype4Py and Jenkins API module, and some basic logic that can be easily extended.

Skype

Things are not so easy as they look however, and so I will present a step by step guide to how I built a functional Robot.

First, we cannot run two instances of Skype on the same machine, and I could not use another Windows machine. I had access to the server where Jenkins is installed: so why not install Skype there and run the python script?

The Server has no GUI! That was not an issue. I had only to forward X11 socket to my machine. The problem was that there is no installable version of Skype on that server.

Docker is what I thought of to solve the problem  – so it was time for free shopping from Docker Hub!

I used python:2.7.10 as a base image for my new Docker file, and added the instruction to install Skype inspired by jess/skype

FROM python:2.7.10

MAINTAINER Youssef El Jaoujat <eljoujat@gmail.com>

# Tell debconf to run in non-interactive mode
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get -f install --fix-missing
# Setup multiarch because Skype is 32bit only
# Make sure the repository information is up to date
RUN dpkg --add-architecture i386 &&
 apt-get update && apt-get install -y
 curl
 --no-install-recommends
# Install Skype
RUN curl http://download.skype.com/linux/skype-debian_4.3.0.37-1_i386.deb -o /usr/src/skype.deb
RUN dpkg -i /usr/src/skype.deb || true

# Automatically detect and install dependencies
RUN apt-get -fy install --fix-missing
RUN rm -rf /var/lib/apt/lists/* # pureg temp data
# Start Skype
ENTRYPOINT ["skype"]

To build this, Docker just executes from the command line:

docker build -t eljoujat/skype .

At this point, I have a Docker container with Skype and Python installed inside. To test the container, just run the container:

docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix  -e DISPLAY=unix$DISPLAY --device /dev/snd  eljoujat/skype

If you get an error with the x11 protocols , just run the following command to grant access to everyone:

xhost +

Our Python uses two modules that need to be installed. We have just to add the instruction on the Docker file and rebuild the image.

## Install Python modules
RUN apt-get install -y python-pip &&
    pip install Skype4Py &&
    pip install jenkinsapi

Next step is to make the script available inside the image so we can execute.

A best practice when working with Docker is decoupling applications into multiple containers. For the sake of simplicity, I did not completely respect this rule, but it’s simple to apply with the script and make things very easy.

So, to do it I had just to use ‘-v’ option when running the Docker image

docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /media/eljaoujat/Linux/job/labs/docker/skype:/scripts/scripts -e DISPLAY=unix$DISPLAY --device /dev/snd  eljoujat/skype:V1.1

/media/eljaoujat/Linux/job/labs/docker/skype is my locale folder and/scripts/scripts will be created inside the container and will be mapped with my locale folder

When running the image, Skype gets executed…oops !

I have to accept the terms of use…

Skype

And login!

skype log in

I have no problem with the term of use (or I have !?) and login, but doing it each time I run the container is not good at all.

I searched for a solution to automate this on the Docker file but with no help, there is no argument we can pass to Skype so it will connect automatically.

The only solution I found is to use the commit command of Docker.

This command allows you to make the change directly on the running container and create a new image from this changes. It was so easy and simple, I had just to accept the terms and login with the remember me option .

accept the term of Use

and Commit,

docker commit b2ec5c9e295e eljoujat/skype:v.1.1

b2ec5c9e295e is the container ID can be obtained by running:

docker ps

after that I fall in love with Docker instantly.

Let’s check what happens inside the Container, and test our script . To do this we have to access via SSH, which has to be added to the Docker file and the image has to be rebuilt.

A better solution is to use nsenter to install run the following command:

docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter

To use nsenter with a running container we should first get this ID:

terminal

Get the PID:

PID=$(docker inspect --format  1d46c2cb556c)

Then use nsenter:

sudo nsenter  --target $PID --mount  --uts --ipc --net --pid

After lsing the /scrtips directory inside the container we find our Python script.

scrtips

We can also run it and see what works well.

At this point, all that is left to do is to run the script automatically when the container starts.

A good solution I found for this is to use supervisor. Supervisor is a process control system, and when it’s added to the container it will allow us to execute as many processes as we want – we have just to configure them. In our case, we want to execute our Python script once the container starts. A possible configuration file could be :

[supervisord]
nodaemon=false

[include]
files = /etc/supervisor/conf.d/*.conf

[program:skype]
command=python /scripts/buildchatbot.py
autostart=true

autorestart=true
startretries=20
stderr_logfile=/opt/nodehook.err.log
stdout_logfile=/opt/nodehook.out.log

So I added supervisor and rebuilt the image with a higher tag version.

The final dockerfile version is :

FROM python:2.7.10

MAINTAINER Youssef El Jaoujat <eljoujat@gmail.com>

# Tell debconf to run in non-interactive mode
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get -f install --fix-missing
# Setup multiarch because Skype is 32bit only
# Make sure the repository information is up to date
RUN dpkg --add-architecture i386 &&
    apt-get update && apt-get install -y
    curl
    --no-install-recommends

# Install Skype
RUN curl http://download.skype.com/linux/skype-debian_4.3.0.37-1_i386.deb -o /usr/src/skype.deb
RUN dpkg -i /usr/src/skype.deb || true
RUN apt-get -fy install --fix-missing                    # Automatically detect and install dependencies
RUN rm -rf /var/lib/apt/lists/* # pureg temp data

# Install Supervisor
RUN
  sed -i 's/# (.*multiverse$)/1/g' /etc/apt/sources.list &&
  apt-get update &&
  apt-get -y upgrade

# supervisor installation &&
# create directory for child images to store configuration in
RUN apt-get -y install supervisor &&
  mkdir -p /var/log/supervisor &&
  mkdir -p /etc/supervisor/conf.d

# supervisor base configuration

## Install skype4py and jenkinsapi modules

RUN apt-get install -y python-pip &&
    pip install Skype4Py &&
    pip install jenkinsapi

# add the Supervisor config
ADD supervisor.conf /etc/supervisor.conf

CMD [ "sh", "-c", " supervisord -c /etc/supervisor.conf && skype" ]

-To build:

docker build -t eljoujat/skype:V1.2 .

-To run:

docker run -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /media/eljaoujat/Linux/job/labs/docker/skype:/scripts/scripts -e DISPLAY=unix$DISPLAY --device /dev/snd  eljoujat/skype:V1.2

-To test: just send a messgae to the Jenkins robot telling it to run a job.

“I believe that there is always an other way to do it, and i hope that you let me know .”

How to Use Docker to Build a Skype Robot Controlling Jenkins!

About The Author
-

1 Comment

  • Steve
    Reply

    This is great. I was hoping you’d have the python code in there. Looking for examples as I’m struggling with my own robot. Thanks

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>