Introduction
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 containers.
- This is just an example, there are more ways of installing 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 on how to invoke Python® from shell jobs see the JS7 - How to run Python scripts from jobs article.
- Create JS7 - Job Resources for your containers.
- Best practice is to use a Job Resource per container.
- This allows specification of any properties of a container such as image name, host name, container name, mounts etc. from variables of a Job Resource.
Examples
The 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 managing a Job Resource this view offers two sub-views:
- The Arguments sub-view allows specifying variables which hold 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 allows specifying environment variables from pairs of names and values that are forwarded to shell jobs.
- Environment Variables can be used for parameterization of shell jobs.
- The following names and values are examples of 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 following example of the Environment Variables sub-view:
- Names of environment variables can be freely chosen within the limits of the operating system. Names are stored with uppercase letters.
- The values of environment variables reference variables previously configured with the Arguments sub-view.
- This allows the use of variables from both JVM jobs and shell jobs.
- As an alternative it is possible to directly assign strings to the values of environment variables and not to use the Arguments sub-view.
Workflow to start a Container
The example uses a single job that runs on an Agent with access to the Docker® daemon.
- Download (upload .json): pdStartContainer.workflow.json
- The job is assigned the
agent-2-0-standalone
Job Resource that holds the parameterization of the container that should be started.
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 uses a number of parameters as it maps all options used to run a JS7 Agent from a container as explained in the JS7 - Agent Installation for Containers article.
- The relevant part is the
client.containers.run()
function which is parameterized with frequently used options for specifying the image name, hostname, network name etc. - Environment variables are available from the assigned Job Resource.
- The optional part includes displaying log output created on start-up of the container using the
container.logs()
function.
Workflow to stop a Container
The example uses a single job which 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 which holds the parameters that identify the container to be stopped.
The job script of the 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 which identify the container to be stopped. - Consider the
command
workflow variable which holds the command to be executed in the container. Adding a variable from a workflow increases flexibility by allowing such variables to 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.