Automate updating docker compose files

Each time when a developer change the core service version they need to update docker compose file in several repositories. For now there are four repositories: openlmis-contract-tests, openlmis-ref-distroopenlmis-reference-ui and openlmis-deployment. In the last repository the developer needs to update the docker files for each OpenLMIS server that use service SNAPSHOT version (currently there are two servers: test and perftest). This document will try to show solutions to the problem.

Single version file

With the  OLMIS-3316 - Getting issue details... STATUS  the openlmis-ref-distro repository has a single file that contain all service versions. Thanks that the developer does not need to find and update single row in docker-compose file (which is huge) but instead they need to update single line in very small file which content should be fully visible on the screen. Implementing this solution to other repositories should decrease time needed to find correct line in docker-compose file and for openlmis-deployment will decrease places that need update because when the developer update version servers will automatically retrieve correct version:

.env
TEST_PREFIX="-SNAPSHOT"
UAT_PREFIX=""
PERFTEST_PREFIX="-SNAPSHOT"

OPENLMIS_REFERENCEDATA_VERSION=10.0.0
OPENLMIS_REQUISITION_VERSION=5.1.1

Example of using the .env file in test and UAT servers:

test_env/docker-compose.yml
...
  requisition:
    restart: always
    image: openlmis/requisition:${OPENLMIS_REFERENCEDATA_VERSION}${TEST_PREFIX}
...
  referencedata:
    restart: always
    image: openlmis/referencedata:${OPENLMIS_REQUISITION_VERSION}${TEST_PREFIX}
...
uat_env/docker-compose.yml
...
  requisition:
    restart: always
    image: openlmis/requisition:${OPENLMIS_REFERENCEDATA_VERSION}${UAT_PREFIX}
...
  referencedata:
    restart: always
    image: openlmis/referencedata:${OPENLMIS_REQUISITION_VERSION}${UAT_PREFIX}
...

With this approach if for example the UAT server need to be update to use Release candidate versions of service a developer will need to only update single line (UAT_PREFIX) in the .env file. The current .env file will need to be renamed to settins.env. This name could be also configurable from the new .env file. 

Disadvantage of this solution is that a developer still need to update service version in each repository each time when the service version will be changed. This solution only combine all pieces needed to updat in the given repository to a single place.

Script

The docker hub expose API that could be used to find and update service version in the given repository. To retrieve a list of all docker images we need to only send a request to the following URL. The important thing is that this endpoint is accessible for everyone. Authentication is not needed.

https://hub.docker.com/v2/repositories/{user_name}/{service_name}/tags/[?page_size={size}]

Example output for openlmis/requisition image:

GET https://hub.docker.com/v2/repositories/openlmis/requisition/tags/
Response:
{
	"count": 21,
	"next": "https://hub.docker.com/v2/repositories/openlmis/requisition/tags/?page=2",
	"previous": null,
	"results": [{
			"name": "latest",
			"full_size": 156016370,
			"images": [{
				"size": 156016370,
				"architecture": "amd64",
				"variant": null,
				"features": null,
				"os": "linux",
				"os_version": null,
				"os_features": null
			}],
			"id": 3943643,
			"repository": 805409,
			"creator": 978314,
			"last_updater": 978314,
			"last_updated": "2017-11-15T07:24:51.328892Z",
			"image_id": null,
			"v2": true
		},
		{
			"name": "5.1.1-SNAPSHOT",
			"full_size": 156016370,
			"images": [{
				"size": 156016370,
				"architecture": "amd64",
				"variant": null,
				"features": null,
				"os": "linux",
				"os_version": null,
				"os_features": null
			}],
			"id": 17762421,
			"repository": 805409,
			"creator": 978314,
			"last_updater": 978314,
			"last_updated": "2017-11-15T07:24:50.713644Z",
			"image_id": null,
			"v2": true
		},
		...
	]
}

The proposition is to create a script (probably in bash or python) that will ask docker hub for docker images for the given OpenLMIS service and update the .env file (see Single version file section). The script should be able to find:

  • the latest version
  • the latest SNAPSHOT version (with -SNAPSHOT suffix)
  • the latest RELEASE version (without any suffix)
  • the latest Release Candidate version (with -RC{number} suffix)

Also the script should display information what is current service version and what version will be used now.

Disadvantage of this solution is that a the script will need to be placed in all repositories and if there will be a need to update the script a developer will need to update it in every repository. Solution is to have the script in one repository and other will retrieve it in the build process.

OpenLMIS: the global initiative for powerful LMIS software