Introduction
The JS7 can be used to execute any scripts, executables and programs including Python® scripts.
- Python® is a frequently used scripting language available for Linux, MacOS, Windows and other platforms.
- Docker offers a Python® SDK to manage containers, see https://docs.docker.com/engine/api/sdk/
- This article explains how to use the Python® SDK for Docker® with JS7 job scripts.
Building Blocks
The following building blocks make up the solution:
Install the Python® SDK as available from https://github.com/docker/docker-py
Install docker-py pluginpip install docker
- Explanation:
- Python® has to be available on the machine that the JS7 Agent is operated for. This includes Agents operated on premises and with Docker® containers.
- This is just an example, there are more ways how to install the Python® SDK for Docker®.
- Explanation:
Create a workflow with a shell job that imports the Python® SDK like this:
Import docker-py plugin with Agents operated for Unix#!/usr/bin/python import docker client = docker.from_env() ...
Import docker-py plugin with Agents operated for Windows@@findstr/v "^@@f.*&" "%~f0"|python.exe -&goto:eof import docker client = docker.from_env() ...
Explanation:For details how to invoke Python from shell jobs see JS7 - How to run Python scripts from jobs.
- Create JS7 - Job Resources for your containers.
- Best practice is to use one Job Resource per container.
- This allows to specify any properties of a container such as image name, host name, container name, mounts etc. from variables of a Job Resource.
Examples
Examples make use of a Job Resource and a number of Workflows that are managed with the Configuration view like this:
Job Resource for a Container
Download (upload .json): agent-2-0-standalone.jobresource.json
When adding a Job Resource this offers two sub-views:
- The Arguments sub-view that allows to specify variables holding pairs of variable names and values.
- Arguments can be used for parameterization of JVM jobs and they can be used in workflow instructions such as the JS7 - If Instruction.
- The Environment Variables sub-view that allows to specify environment variables from pairs of names and values that are forwarded to shell jobs.
- Environment Variables can be used of parameterization of shell jobs.
- The below names and values are an example for frequently used parameters when setting up containers for example with the
docker run
command:repository_name
: Identifier of the repositoryimage_name
: Identifier of the image that is used to instantiate the container.container_name
: Name assigned the container.host_name
: Hostname (FQDN) assigned the container.- etc.
Consider the example of the Environment Variables sub-view:
- Names of environment variables can be freely chosen.
- The values of environment variables reference variables previously configured with the Arguments sub-view.
- This allows to use variables from both JVM jobs and shell jobs.
- As an alternative it is possible to directly assign strings to values of environment variables and not to use the Arguments sub-view.
Workflow to start a Container
The example makes use of a single job that runs on an Agent with access to the Docker® daemon.
- Download (upload .json): pdStartContainer.workflow.json
The job script of the single job in this workflow looks like this:
#!/usr/bin/python import docker from docker.types import Mount import os client = docker.from_env() container = client.containers.run( image=os.environ.get('REPOSITORY_NAME') + ':' + os.environ.get('IMAGE_NAME'), \ hostname=os.environ.get('HOST_NAME'), \ network=os.environ.get('NETWORK_NAME'), \ detach=True, \ environment={ \ 'RUN_JS_HTTP_PORT': 4445, \ 'RUN_JS_HTTPS_PORT': 4443, \ 'RUN_JS_JAVA_OPTIONS': os.environ.get('AGENT_JAVA_OPTIONS'), \ 'RUN_JS_JOB_JAVA_OPTIONS': os.environ.get('JOB_JAVA_OPTIONS'), \ 'RUN_JS_USER_ID': os.environ.get('USER_ID') \ }, \ mounts=[Mount(target="/var/sos-berlin.com/js7/agent/var_4445", source=os.environ.get('IMAGE_NAME') + "-var", type="volume")], \ name=os.environ.get('CONTAINER_NAME'), \ ports={ '4445/tcp': os.environ.get('HTTP_PORT'), '4443/tcp': os.environ.get('HTTPS_PORT') }, \ remove=True, \ tty=True \ ) print("Container started: ", container.id) print("Container logs:") print(container.logs())
Explanation:
- The job script looks fairly complex as it maps all options used to run a JS7 Agent from a Docker® container explained with JS7 - Agent Installation for Docker Containers.
- The relevant part is the
client.containers.run()
function that is parameterized with frequently used options to specify the image, the hostname, network etc. - The optional part includes to display log output created on start-up of the container using the
container.logs()
function.
Workflow to stop a Container
The example makes use of a single job that runs on an Agent with access to the Docker® daemon.
- Download (upload .json): pdStopContainer.workflow.json
- The job is assigned the
agent-2-0-standalone
Job Resource that holds the parameters that identify the container to be stopped.
The job script of the single job in this workflow looks like this:
#!/usr/bin/python import docker import os client = docker.from_env() container = client.containers.get( os.environ.get('CONTAINER_NAME') ) container.stop() print("container stopped: ", container.id)
Explanation:
- The job script reads the environment variable
CONTAINER_NAME
to identify the container to be stopped. - This environment variable is provided by the
agent-2-0-standalone
Job Resource.
Workflow to execute commands in a Container
The example makes use of a single job that runs on an Agent with access to the Docker® daemon.
- Download (upload .json): pdExecContainer.workflow.json
- The job is assigned the
agent-2-0-standalone
Job Resource that holds the parameters that identify the container to be stopped. - Consider the
command
workflow variable that holds the command to be executed in the container. Adding a variable from a workflow offers the flexibility that such variables can be updated for use with different values from each order that executes the workflow.
The job script of the single job in this workflow looks like this:
#!/usr/bin/python import docker import os client = docker.from_env() container = client.containers.get( os.environ.get('CONTAINER_NAME') ) rc = container.exec_run( \ cmd=os.environ.get('COMMAND'), \ environment={ \ 'JS7_AGENT_HOME': os.environ.get('JS7_AGENT_HOME'), \ 'JS7_AGENT_DATA': os.environ.get('JS7_AGENT_DATA') \ }, \ tty=True, \ user="jobscheduler" \ ) print("container exec return code: ", rc)
Explanation:
- The job script reads the environment variable
CONTAINER_NAME
to identify the container to be stopped. - This environment variable is provided by the
agent-2-0-secondary
Job Resource.