Getting started with Pulp and Pulp-smash

This summer, I have joined the PulpQE team in Red Hat as a summer internship. My main job is to contribute automated CLI/API-based tests through Pulp-Smash, a test suite for Pulp. Through the summer, I’d like to record what I have learned from a perspective of “newbie”, thus providing a fresh idea to young developers like me for learning Pulp and Pulp-Smash. This post will cover how I install pulp and pulp-smash in a step-by-step process.

Install the development environment

The very first step is to install Pulp on my host. I’m using Fedora 23, and I want to setup a virtual machine for Pulp to avoid messing up my local environment. It’s great that the Pulp team has already provided a Vagrantfile that can “automatically deploy a virtual machine on your host with a Pulp development environment configured”. The reference of the Developer Setup Documentation is here on the official documentation:

http://docs.pulpproject.org/dev-guide/contributing/dev_setup.html

Here I just extracted out the commands from that doc as my notes for installation:

  1. Install vagrant, ansible, and nfs-utils. NFS will be used to share your code directory with the deployed virtual machine:
    </p> > $ sudo dnf install –best –allowerasing ansible nfs-utils vagrant-libvirt

  2. Grant the nfsnobody user rx access to the folder to check out code with, especially in Fedora; since $HOME typically does not allow such access to other users. So in the future, the working directory will become $HOME/devel or similar in the vm, which is sharable to my local filesystem. For example, the path to my folder of Pulp is /home//Documents/pulp, so in vm it is actually /home/vagrant/devel/pulp. This is really nice and convenient for development.
    </span></p> > $ setfacl -m user:nfsnobody:r-x $HOME

  3. Start and enable the nfs-server service:
    </p> > $ sudo systemctl enable nfs-server && sudo systemctl start nfs-server

  4. Allow NFS services through your firewall:
    </p> > $ sudo firewall-cmd –permanent –add-service=nfs
    $ sudo firewall-cmd –permanent –add-service=rpc-bind
    $ sudo firewall-cmd –permanent –add-service=mountd
    $ sudo firewall-cmd –reload

  1. Check out the Pulp code
    </p>

    $ cd $HOME/devel
    $ git clone git@github.com:pulp/pulp.git

  2. Change the Vagrantfile in the pulp directory
    The Pulp project provides an example Vagrantfile that you can use as a starting point by copying it. Change this line to something like this:
    </p>

    config.vm.provision “shell”, inline: “sudo dnf upgrade -y || sudo dnf upgrade -y”

  3. Begin provisioning your Vagrant environment. We will finish by running vagrant reload. This allows the machine to reboot after provisioning
    </p>

    $ cd pulp
    $ cp Vagrantfile.example Vagrantfile
    $ vagrant up
    $ vagrant reload
    # Reboot the machine at the end to apply kernel updates

  1. ssh into your Vagrant environment:

    $ vagrant ssh

  2. Verify the installation through the status of Pulp admin and Pulp API:
    </p>

    $ pulp-admin status
    +———————————————————————-+
    Status of the server
    +———————————————————————-+

    Api Version:           2
    Database Connection:
    Connected: True
    ……
    Messaging Connection:
    Connected: True
    Versions:
    Platform Version: 2.9.0b1  # Note the Pulp’s version here.

    $ phttp https://dev/pulp/api/v2/status/

  3. You can migrate the database after a fresh install:
    </p>

    $ sudo -u apache pulp-manage-db

  4. The Pulp development environment also provides a `pclean` to restore database. But it will destroy all user data. You can refer to the man page of it through phelp. It will also provide several other useful commands such as phttp, pjournal, prestart, etc.

And now you have a running deployed Pulp development machine! Pretty easy and convenient to deploy Pulp in such an automatic way. Please take note that every time you halt the vm you need to `vagrant up` again. So I just played around in the Pulp with the help of official docs. And some of the excerpts will be listed in the next section.


Several services can be accessed through systemctl manually, according to the developer’s setup doc:

Start the broker:          sudo systemctl start qpidd

Start the agent:           sudo systemctl start goferd

Start the database:        sudo systemctl start mongod

Synchronize db:            sudo -u apache pulp-manage-db

Start the server:          sudo systemctl start httpd

Start pulp workers:        sudo systemctl start pulp_workers;

Start pulp celerybeat:     sudo systemctl start pulp_celerybeat;

Start pulp resource manager: sudo systemctl start pulp_resource_manager

Well, are these pulp services’ names the major components for Pulp? Yes, and here’s a detailed introduction to some the components listed: https://docs.pulpproject.org/user-guide/server.html

How to Install a plugin

Pulp has a feature called Pulp Platform, which can manage content/software packages extensible to nearly any type of digital content. Here’s the excerpt from here:

Pulp manages content, and its original focus was software packages such as RPMs and Puppet modules. The core features of Pulp, such as syncing and publishing repositories, have been implemented in a generic way that can be extended by plugins to support specific content types. We refer to the core implementation as the Pulp Platform. With this flexible design, Pulp can be extended to manage nearly any type of digital content.

And here’s an example of installing pulp-rpm. At least one plugin must be installed for every pulp instance.

$ git clone https://github.com/pulp/pulp_rpm.git
$ cd pulp_rpm
$ sudo yum install pulp-rpm-plugins
$ sudo ./manage_setup_pys.sh develop
$ sudo python ./pulp-dev.py -I
$ sudo -u apache pulp-manage-db

Issues after installing pulp-rpm plugin

I encountered an error “The importer type yum_importer does not exist” after the fresh install of pulp.

To solve this, I tried to execute a pclean to restore the database. However, another error came up as “ImportError: No module named createrepo”…

Finally I got a clue from https://www.redhat.com/archives/pulp-list/2015-June/msg00013.html. It looks like there’s a missing yum package on the Vagrant’s system. After installing the package through `sudo yum install pulp-rpm-plugins`, everything is ok now. I have also added this command into the above code snippet. Please change to pulp-puppet-plugins in order to install pulp-puppet plugin.

You can test the repo’s functionality manually through this snippet FYI:

$ pulp-admin -u admin -p admin rpm repo create –repo-id repo1 –relative-url zoo –feed \
http://repos.fedorapeople.org/repos/pulp/pulp/demo_repos/repo1
$ pulp-admin -u admin -p admin rpm repo sync run –repo-id repo1
$ pulp-admin -u admin -p admin rpm repo delete –repo-id repo1

Note that a newer version of pclean automatically creates a repository called zoo with the same feed. Please check that with `pulp-admin repo list`. Now that I have successfully deployed a Pulp on my vm, it is time to further install pulp-smash. The next section of this blog covers how to configure the pulp-smash after a fresh installation of Pulp under the Vagrant environment.


 

Introduction to Pulp Smash

Before installation, I will briefly give an introduction to Pulp Smash. All tests in Pulp Smash are automated and suited for use in a continuous integration environment, providing both CLI- and API-based test cases for the Pulp platform. It can thus talk to multiple systems via their API and CLI, and it can stop and start system services, drop databases, delete files from their filesystems, and so on.

According to the comments here, users can tell Pulp Smash what system(s) are available via (by default) a `~/.config/pulp_smash/settings.json` file, and Pulp Smash can choose which tests to run based on what’s available via `python -m unittest2 pulp_smash.tests`. Pulp Smash can be executed on any types of target systems, such as VMs backed by libvirt, virtualbox, vmware, xen, etc, or docker containers, or bare-metal systems, or the local system, or even a mixture of these. This imparts a great deal of flexibility.

Install the Pulp-Smash on the VM

Step 1. Check out pulp-smash from github and install required packages.

$ sudo pip install -r requirements.txt -r requirements-dev.txt
$ # After fresh install of pulp-smash, run the following command to see guidance:
$ python -m pulp_smash

Step 2. Create a configuration file in the vm environment.

The configuration file at /home/vagrant/.config/pulp_smash/settings.json will be automatically created after the execution of `python -m pulp_smash`. The configuration file should have this structure:

{

    “pulp”: {

        “base_url”: “https://pulp.example.com“,

        “auth”: [“username”, “password”],

        “verify”: true,

        “version”: “2.7.5”,

        “cli_transport”: “local”

    },

    “pulp agent”: {

        “base_url”: “https://pulp-agent.example.com

    }
}

My only responsibility as a user is to put the right information (including version) in ~/.config/pulp_smash/settings.json. And here’s my working example of that file:

[vagrant@dev ~]$ cat .config/pulp_smash/settings.json
{

    “pulp”: {

            “base_url”: “https://dev“,

            “auth”: [“admin”, “admin”],

            “verify”: true,

            “version”: “2.9.0b1”,

            “cli_transport”: “local”

    }

}

Step 3. Call python -m unittest2 discover pulp_smash.tests.

This step may take a while to execute. Have a cup of coffee :  )


Get handy with automated scripts

In this section, I’ll also list some useful excerpts from the official documentation. The author was very nice to provide a starting point to learn pulp-smash:

http://pulp-smash.readthedocs.io/en/latest/about.html#learning-pulp-smash

For example, to verify the sanity of your development environment, cd into the Pulp Smash source code directory and execute `make all`. The author has also suggested to me that, before sending out a Pull Request on github, it is useful to execute this command again to pass Travis CI tests. Also, please copy & paste the output from the test run as a comment in the GitHub pull request: `python -m unittest2 pulp_smash.tests`

In case that you are not familiar with Python’s unittest module, its official documentation would be another good material to learn:

https://docs.python.org/3/library/unittest.html#command-line-interface

This is also suggested by the author that I may run a single test case such as `python -m unittest2 pulp_smash.tests.platform.api_v2.test_login`; and I can consult the source code to see which other test modules are available.

Package Structure

From the doc, I also found it helpful to read through all commented code on this module:

http://pulp-smash.readthedocs.io/en/latest/introductory-module.html

Errors encountered for Beginners of Pulp-Smash

There’s no doubt that I’ll meet several errors by the first time I install pulp-smash. But it really matters how you view/treat those barriers. Do you just feel frustrated by being blocked for couple of hours? Sure it is…but when you finally solved it, it is also a good chance to improve, right? And more importantly, don’t miss the chance to consult the authors on IRC’s freenode!

MissingSchema

requests.exceptions.MissingSchema: Invalid URL ‘/pulp/api/v2/plugins/types/’: No schema supplied. Perhaps you meant http://pulp/api/v2/plugins/types/

How it is solved: without that https://, Pulp Smash doesn’t know whether to contact Pulp on port 80, 443, or what.

ConnectionError

requests.exceptions.ConnectionError: HTTPSConnectionPool(host=’127.0.0.1′, port=443): Max retries exceeded with url: /pulp/api/v2/plugins/types/ (Caused by NewConnectionError(‘<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f22e8f0c510>: Failed to establish a new connection: [Errno 111] Connection refused’,))

How it is solved: First I’ll check if pulp is running:

$ systemctl status ‘*pulp*’

It turns out that I need to start httpd service manually after the vm is halted: sudo systemctl start httpd

SSLError

requests.exceptions.SSLError: hostname ‘localhost’ doesn’t match either of ‘dev’, ‘dev.example.com

How it is solved:
1. My solution 1 is to execute `sudo hostnamectl set-hostname “localhost”` in order to change the hostname. However, changing hostname only doesn’t help since it still needs default hostname of dev.

2. My solution 2 is to set “https://dev” as base_url for the configuration. I found out what’s happening here is that we’re telling our client to make an SSL-secured connection to the “localhost” domain (as configured). The client starts doing that, but when it discovers that the server’s SSL certificate isn’t valid for the “localhost” domain, but is instead valid for “dev” and “dev.example.com” (by default), the client freaks out.