Collection Workflows¶
Pulp organizes role content into repositories, and you associate the ansible-galaxy
client with
one or more repositories. From a high level you can:
- Create a repo
- Create a distribution expose that repository at a URL
- Sync content from galaxy.ansible.com
- Install content from the repo with ansible-galaxy
API Client Setup¶
To use the bash examples on this page. Run these basic bash utilities below:
#!/usr/bin/env bash
echo "Setting environment variables for default hostname/port for the API and the Content app"
export BASE_ADDR=${BASE_ADDR:-http://localhost:24817}
export CONTENT_ADDR=${CONTENT_ADDR:-http://localhost:24816}
# Necessary for `django-admin`
export DJANGO_SETTINGS_MODULE=pulpcore.app.settings
# Poll a Pulp task until it is finished.
wait_until_task_finished() {
echo "Polling the task until it has reached a final state."
local task_url=$1
while true
do
local response=$(http $task_url)
local state=$(jq -r .state <<< ${response})
jq . <<< "${response}"
case ${state} in
failed|canceled)
echo "Task in final state: ${state}"
exit 1
;;
completed)
echo "$task_url complete."
break
;;
*)
echo "Still waiting..."
sleep 2
;;
esac
done
}
Create a Repository¶
Create a repository and name it the foo
repository.
echo "Start by creating a new repository named foo"
http POST $BASE_ADDR/pulp/api/v3/repositories/ansible/ansible/ name=foo
# If you want to copy/paste your way through the guide,
# create an environment variable for the repository URI.
export REPO_HREF=$(http $BASE_ADDR/pulp/api/v3/repositories/ansible/ansible/ | \
jq -r '.results[] | select(.name == "foo") | .pulp_href')
echo "Inspecting repository."
http $BASE_ADDR$REPO_HREF
Repository GET Response:
{
"pulp_created": "2019-04-29T15:57:59.763712Z",
"pulp_href": "/pulp/api/v3/repositories/ansible/ansible/1b2b0af1-5588-4b4b-b2f6-cdd3a3e1cd36/",
"latest_version_href": null,
"versions_href": "/pulp/api/v3/repositories/ansible/ansible/1b2b0af1-5588-4b4b-b2f6-cdd3a3e1cd36/versions/",
"description": "",
"name": "foo"
}
Reference (pulpcore): Repository API Usage
Create a Distribution for Repository ‘foo’¶
This will make the latest Repository Version content available for ansible-galaxy` clients. Each
distribution names the url it can be accessed from on an attribute called ``client_url
. The
client_url
can be used with the ansible-galaxy
client with the -s
option. See the
Install a Role, hosted by Pulp, using ansible-galaxy docs for more details.
For example a distribution with base_path
set to my_content
could have a URL like:
http://pulp.example.com/pulp_ansible/galaxy/my_content/
# Distributions are created asynchronously. Create one, and specify the publication that will
# be served at the base path specified.
export TASK_HREF=$(http POST $BASE_ADDR/pulp/api/v3/distributions/ansible/ansible/ \
name='baz' \
base_path='my_content' \
repository=${REPO_HREF} | jq -r '.task')
# Poll the task (here we use a function defined in docs/_scripts/base.sh)
# When the task is complete, it gives us the href for our new Distribution
wait_until_task_finished $BASE_ADDR$TASK_HREF
export DIST_PATH=${CREATED_RESOURCE[0]}
# Lets inspect the Distribution
http $BASE_ADDR$DIST_PATH
{
"pulp_created": "2019-07-26T16:46:23.666410Z",
"pulp_href": "/pulp/api/v3/distributions/ansible/ansible/4262ed83-e86c-4a13-baff-fc543c46a391/",
"base_path": "my_content",
"base_url": "/pulp/content/foo",
"content_guard": null,
"name": "baz",
"repository": "/pulp/api/v3/repositories/ansible/ansible/301bec4f-c5e7-4a20-a124-f8a1ec1f9229/",
"repository_version": null
}
Create a Distribution for a RepositoryVersion (optional)¶
Instead of always distributing the latest RepositoryVersion, you can also specify a specific RepositoryVersion for a Distribution. This should be used in place of the distribution above, not in addition to it.
# Distributions are created asynchronously. Create one, and specify the publication that will
# be served at the base path specified.
export TASK_HREF=$(http POST $BASE_ADDR/pulp/api/v3/distributions/ansible/ansible/ \
name='baz' \
base_path='my_content' \
repository_version=${REPO_HREF}versions/1/ | jq -r '.task')
# Poll the task (here we use a function defined in docs/_scripts/base.sh)
# When the task is complete, it gives us the href for our new Distribution
wait_until_task_finished $BASE_ADDR$TASK_HREF
export DIST_PATH=${CREATED_RESOURCE[0]}
# Lets inspect the Distribution
http $BASE_ADDR$DIST_PATH
{
"pulp_created": "2019-07-26T16:51:04.803014Z",
"pulp_href": "/pulp/api/v3/distributions/ansible/ansible/c9879338-8656-46aa-a2b2-46fa5d7b0329/",
"base_path": "my_content",
"base_url": "/pulp/content/foo",
"content_guard": null,
"name": "baz",
"repository": null,
"repository_version": "/pulp/api/v3/repositories/ansible/ansible/301bec4f-c5e7-4a20-a124-f8a1ec1f9229/versions/1/"
}
Create a CollectionRemote¶
Creating a CollectionRemote object allows Pulp to sync Collections from an external
content source. This is most commonly is https://galaxy.ansible.com/
or another pulp_ansible
instance.
In this example we will be syncing the Collection with namespace=testing
and name=ansible_testing_content
from https://galaxy-dev.ansible.com/
.
# Create a remote that syncs some versions of django into your repository.
http POST $BASE_ADDR/pulp/api/v3/remotes/ansible/collection/ \
name='bar' \
url='https://galaxy-dev.ansible.com/' \
requirements_file:='"collections:\n - testing.ansible_testing_content"'
# Export an environment variable for the new remote URI.
export REMOTE_HREF=$(http $BASE_ADDR/pulp/api/v3/remotes/ansible/collection/ | jq -r '.results[] | select(.name == "bar") | .pulp_href')
# Lets inspect our newly created Remote
http $BASE_ADDR$REMOTE_HREF
Remote GET Response:
{
"pulp_created": "2019-04-29T13:51:10.860792Z",
"pulp_href": "/pulp/api/v3/remotes/ansible/collection/e1c65074-3a4f-4f06-837e-75a9a90f2c31/",
"pulp_last_updated": "2019-04-29T13:51:10.860805Z",
"requirements_file": "collections:\n - testing.ansible_testing_content",
"download_concurrency": 20,
"name": "bar",
"policy": "immediate",
"proxy_url": null,
"ssl_ca_certificate": null,
"ssl_client_certificate": null,
"ssl_client_key": null,
"ssl_validation": true,
"url": "https://galaxy-dev.ansible.com/",
}
For remote sources that require authentication, tokens can be used. You can provide the token
and/or auth_url
.
In this example we will be syncing the Collection with namespace=testing
and name=ansible_testing_content
from https://cloud.redhat.com/api/automation-hub/v3/collections/testing/ansible_testing_content
.
# Create a remote that syncs some versions of django into your repository.
http POST $BASE_ADDR/pulp/api/v3/remotes/ansible/collection/ \
name='bar' \
auth_url='https://sso.qa.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token' \
token=$ANSIBLE_TOKEN_AUTH \
tls_validation=false \
url='https://cloud.redhat.com/api/automation-hub' \
requirements_file:='"collections:\n - testing.ansible_testing_content"'
# Export an environment variable for the new remote URI.
export REMOTE_HREF=$(http $BASE_ADDR/pulp/api/v3/remotes/ansible/collection/ | jq -r '.results[] | select(.name == "bar") | .pulp_href')
# Lets inspect our newly created Remote
http $BASE_ADDR$REMOTE_HREF
Remote GET Response:
{
"pulp_created": "2019-04-29T13:51:10.860792Z",
"pulp_href": "/pulp/api/v3/remotes/ansible/collection/e1c65074-3a4f-4f06-837e-75a9a90f2c31/",
"pulp_last_updated": "2019-04-29T13:51:10.860805Z",
"requirements_file": "collections:\n - testing.ansible_testing_content",
"download_concurrency": 20,
"name": "bar",
"policy": "immediate",
"proxy_url": null,
"ssl_ca_certificate": null,
"ssl_client_certificate": null,
"ssl_client_key": null,
"ssl_validation": true,
"url": "https://galaxy-dev.ansible.com/",
}
Sync Repository foo with CollectionRemote¶
Use the CollectionRemote object to kick off a synchronize task by specifying the Repository to sync with. You are telling Pulp to fetch Collection content from the external source.
#!/usr/bin/env bash
# Sync repository foo using remote bar
echo "Create a task to sync the repository using the remote."
export TASK_HREF=$(http POST $BASE_ADDR$REPO_HREF'sync/' \
remote=$REMOTE_HREF \
| jq -r '.task')
# Poll the task (here we use a function defined in docs/_scripts/base.sh)
wait_until_task_finished $BASE_ADDR$TASK_HREF
# After the task is complete, it gives us a new repository version
echo "Set REPOVERSION_HREF from finished task."
export REPOVERSION_HREF=$(http $BASE_ADDR$TASK_HREF| jq -r '.created_resources | first')
echo "Inspecting RepositoryVersion."
http $BASE_ADDR$REPOVERSION_HREF
Repository Version GET Response (when complete):
{
"pulp_href": "/pulp/api/v3/repositories/ansible/ansible/05813fa6-cf0b-435b-b54b-5a30fc370848/versions/1/",
"pulp_created": "2019-05-28T21:51:08.172095Z",
"number": 1,
"base_version": null,
"content_summary": {
"added": {
"ansible.collection": {
"count": 1,
"href": "/pulp/api/v3/content/ansible/collections/?repository_version_added=/pulp/api/v3/repositories/ansible/ansible/05813fa6-cf0b-435b-b54b-5a30fc370848/versions/1/"
}
},
"removed": {},
"present": {
"ansible.collection": {
"count": 1,
"href": "/pulp/api/v3/content/ansible/collections/?repository_version=/pulp/api/v3/repositories/ansible/ansible/05813fa6-cf0b-435b-b54b-5a30fc370848/versions/1/"
}
}
}
}
Install a Collection, hosted by Pulp, using ansible-galaxy
¶
You can use ansible-galaxy to install a collection by its namespace and name from pulp_ansible using the install command. For example to install the hello collection from above into a directory ~/collections you can specify:
ansible-galaxy collection install testing.ansible_testing_content -c -s http://localhost/pulp_ansible/galaxy/my_content/
This assumes that the hello Collection is being served by the Distribution ansible-galaxy is configured to use.
Using a specific version¶
Install your role by name by specifying the distribution serving your Repository’s content using the
-s
option.
ansible-galaxy collection install testing.ansible_testing_content:4.0.6 -c -s http://localhost/pulp_ansible/galaxy/my_content/
Configuring ansible-galaxy¶
Use the ansible-galaxy config files to specify the distribution
ansible-galaxy
should interact with. To use this, set up your distribution in your ansible
config (e.g. ~/.ansible.cfg
or /etc/ansible/ansible.cfg
):
[galaxy]
server: http://localhost/pulp_ansible/galaxy/my_content/
Then you can install without the -s
url
ansible-galaxy collection install testing.ansible_testing_content:4.0.6
- downloading role 'elasticsearch', owned by elastic
- downloading role from http://localhost/pulp/content/dev/elastic/elasticsearch/6.2.4.tar.gz
- extracting elastic.elasticsearch to /home/vagrant/.ansible/roles/elastic.elasticsearch
- elastic.elasticsearch (6.2.4) was installed successfully
Publish (Upload) a Collection¶
You can use ansible-galaxy to publish any built artifact to pulp_ansible by running:
ansible-galaxy collection build # from inside the root directory of the collection
ansible-galaxy collection publish path/to/artifact.tar.gz
For example if you have ansible-galaxy installed and configured the script below will upload a Collection to pulp_ansible and display it:
ansible-galaxy collection init namespace_name.collection_name
ansible-galaxy collection build namespace_name/collection_name/
ansible-galaxy collection publish namespace_name-collection_name-1.0.0.tar.gz -c -s http://localhost:24817/pulp_ansible/galaxy/my_content/
The client upload the Collection to the Repository associated with the Distribution. Each upload creates a new Repository Version for the Repository.