You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
10 KiB
375 lines
10 KiB
From 6d4180b5ed46cda544e008b242f024b2ab143a83 Mon Sep 17 00:00:00 2001 |
|
From: David Vossel <dvossel@redhat.com> |
|
Date: Thu, 23 Oct 2014 09:37:18 -0500 |
|
Subject: [PATCH] introducing docker agent |
|
|
|
--- |
|
doc/man/Makefile.am | 1 + |
|
heartbeat/Makefile.am | 1 + |
|
heartbeat/docker | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
3 files changed, 332 insertions(+) |
|
create mode 100755 heartbeat/docker |
|
|
|
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am |
|
index e97c7e9..ee29756 100644 |
|
--- a/doc/man/Makefile.am |
|
+++ b/doc/man/Makefile.am |
|
@@ -98,6 +98,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \ |
|
ocf_heartbeat_conntrackd.7 \ |
|
ocf_heartbeat_db2.7 \ |
|
ocf_heartbeat_dhcpd.7 \ |
|
+ ocf_heartbeat_docker.7 \ |
|
ocf_heartbeat_eDir88.7 \ |
|
ocf_heartbeat_ethmonitor.7 \ |
|
ocf_heartbeat_exportfs.7 \ |
|
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am |
|
index aab521f..f763533 100644 |
|
--- a/heartbeat/Makefile.am |
|
+++ b/heartbeat/Makefile.am |
|
@@ -65,6 +65,7 @@ ocf_SCRIPTS = ClusterMon \ |
|
conntrackd \ |
|
db2 \ |
|
dhcpd \ |
|
+ docker \ |
|
Delay \ |
|
eDir88 \ |
|
EvmsSCC \ |
|
diff --git a/heartbeat/docker b/heartbeat/docker |
|
new file mode 100755 |
|
index 0000000..546c423 |
|
--- /dev/null |
|
+++ b/heartbeat/docker |
|
@@ -0,0 +1,330 @@ |
|
+#!/bin/sh |
|
+# |
|
+# The docker HA resource agent creates and launches a docker container |
|
+# based off a supplied docker image. Containers managed by this agent |
|
+# are both created and removed upon the agent's start and stop actions. |
|
+# |
|
+# Copyright (c) 2014 David Vossel <dvossel@redhat.com> |
|
+# All Rights Reserved. |
|
+# |
|
+# This program is free software; you can redistribute it and/or modify |
|
+# it under the terms of version 2 of the GNU General Public License as |
|
+# published by the Free Software Foundation. |
|
+# |
|
+# This program is distributed in the hope that it would be useful, but |
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
+# |
|
+# Further, this software is distributed without any warranty that it is |
|
+# free of the rightful claim of any third person regarding infringement |
|
+# or the like. Any license provided herein, whether implied or |
|
+# otherwise, applies only to this software file. Patent licenses, if |
|
+# any, provided herein do not apply to combinations of this program with |
|
+# other software, or any other product whatsoever. |
|
+# |
|
+# You should have received a copy of the GNU General Public License |
|
+# along with this program; if not, write the Free Software Foundation, |
|
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
|
+# |
|
+ |
|
+####################################################################### |
|
+# Initialization: |
|
+ |
|
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} |
|
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs |
|
+ |
|
+####################################################################### |
|
+ |
|
+meta_data() |
|
+{ |
|
+ cat <<END |
|
+<?xml version="1.0"?> |
|
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> |
|
+<resource-agent name="docker" version="0.9"> |
|
+<version>1.0</version> |
|
+ |
|
+<longdesc lang="en"> |
|
+The docker HA resource agent creates and launches a docker container |
|
+based off a supplied docker image. Containers managed by this agent |
|
+are both created and removed upon the agent's start and stop actions. |
|
+</longdesc> |
|
+<shortdesc lang="en">Docker container resource agent.</shortdesc> |
|
+ |
|
+<parameters> |
|
+<parameter name="image" required="1" unique="0"> |
|
+<longdesc lang="en"> |
|
+The docker image to base this container off of. |
|
+</longdesc> |
|
+<shortdesc lang="en">docker image</shortdesc> |
|
+<content type="string"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="container" required="0" unique="0"> |
|
+<longdesc lang="en"> |
|
+The name to give the created container. By default this will |
|
+be that resource's instance name. |
|
+</longdesc> |
|
+<shortdesc lang="en">docker container name</shortdesc> |
|
+<content type="string"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="allow_pull" unique="0"> |
|
+<longdesc lang="en"> |
|
+Allow the image to be pulled from the configured docker registry when |
|
+the image does not exist locally. NOTE, this can drastically increase |
|
+the time required to start the container if the image repository is |
|
+pulled over the network. |
|
+</longdesc> |
|
+<shortdesc lang="en">Allow pulling non-local images</shortdesc> |
|
+<content type="boolean"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="run_opts" required="0" unique="0"> |
|
+<longdesc lang="en"> |
|
+Add options to be appended to the 'docker run' command which is used |
|
+when creating the container during the start action. This option allows |
|
+users to do things such as setting a custom entry point and injecting |
|
+environment variables into the newly created container. Note the '-d' |
|
+option is supplied regardless of this value to force containers to run |
|
+in the background. |
|
+</longdesc> |
|
+<shortdesc lang="en">run options</shortdesc> |
|
+<content type="string"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="run_cmd" required="0" unique="0"> |
|
+<longdesc lang="en"> |
|
+Specifiy a command to launch within the container once |
|
+it has initialized. |
|
+</longdesc> |
|
+<shortdesc lang="en">run command</shortdesc> |
|
+<content type="string"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="force_kill" required="0" unique="0"> |
|
+<longdesc lang="en"> |
|
+Kill a container immediately rather than waiting for it to gracefully |
|
+shutdown |
|
+</longdesc> |
|
+<shortdesc lang="en">force kill</shortdesc> |
|
+<content type="boolean"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="reuse" required="0" unique="0"> |
|
+<longdesc lang="en"> |
|
+Allow the container to be reused after stopping the container. By default |
|
+containers are removed after stop. With the reuse option containers |
|
+will persist after the container stops. |
|
+</longdesc> |
|
+<shortdesc lang="en">reuse container</shortdesc> |
|
+<content type="boolean"/> |
|
+</parameter> |
|
+ |
|
+</parameters> |
|
+ |
|
+<actions> |
|
+<action name="start" timeout="90" /> |
|
+<action name="stop" timeout="90" /> |
|
+<action name="monitor" timeout="30" interval="30" depth="0" /> |
|
+<action name="meta-data" timeout="5" /> |
|
+<action name="validate-all" timeout="30" /> |
|
+</actions> |
|
+</resource-agent> |
|
+END |
|
+} |
|
+ |
|
+####################################################################### |
|
+REQUIRE_IMAGE_PULL=0 |
|
+ |
|
+docker_usage() |
|
+{ |
|
+ cat <<END |
|
+usage: $0 {start|stop|monitor|validate-all|meta-data} |
|
+ |
|
+Expects to have a fully populated OCF RA-compliant environment set. |
|
+END |
|
+} |
|
+ |
|
+container_exists() |
|
+{ |
|
+ docker inspect $CONTAINER > /dev/null 2>&1 |
|
+} |
|
+ |
|
+remove_container() |
|
+{ |
|
+ if ocf_is_true "$OCF_RESKEY_reuse"; then |
|
+ # never remove the container if we have reuse enabled. |
|
+ return 0 |
|
+ fi |
|
+ |
|
+ ocf_log notice "Cleaning up inactive container, ${CONTAINER}." |
|
+ ocf_run docker rm $CONTAINER |
|
+} |
|
+ |
|
+docker_monitor() |
|
+{ |
|
+ local val |
|
+ |
|
+ container_exists |
|
+ if [ $? -ne 0 ]; then |
|
+ return $OCF_NOT_RUNNING |
|
+ fi |
|
+ |
|
+ # retrieve the 'Running' attribute for the container |
|
+ val=$(docker inspect --format {{.State.Running}} $CONTAINER 2>/dev/null) |
|
+ if [ $? -ne 0 ]; then |
|
+ #not running as a result of container not being found |
|
+ return $OCF_NOT_RUNNING |
|
+ fi |
|
+ |
|
+ if ocf_is_true "$val"; then |
|
+ # container exists and is running |
|
+ return $OCF_SUCCESS |
|
+ fi |
|
+ |
|
+ return $OCF_NOT_RUNNING |
|
+} |
|
+ |
|
+docker_start() |
|
+{ |
|
+ local run_opts="-d --name=${CONTAINER}" |
|
+ # check to see if the container has already started |
|
+ docker_monitor |
|
+ if [ $? -eq $OCF_SUCCESS ]; then |
|
+ return $OCF_SUCCESS |
|
+ fi |
|
+ |
|
+ if [ -n "$OCF_RESKEY_run_opts" ]; then |
|
+ run_opts="$run_opts $OCF_RESKEY_run_opts" |
|
+ fi |
|
+ |
|
+ if [ $REQUIRE_IMAGE_PULL -eq 1 ]; then |
|
+ ocf_log notice "Beginning pull of image, ${OCF_RESKEY_image}" |
|
+ docker pull "${OCF_RESKEY_image}" |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_exit_reason "failed to pull image ${OCF_RESKEY_image}" |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ fi |
|
+ |
|
+ if ocf_is_true "$OCF_RESKEY_reuse" && container_exists; then |
|
+ ocf_log info "starting existing container $CONTAINER." |
|
+ ocf_run docker start $CONTAINER |
|
+ else |
|
+ ocf_log info "running container $CONTAINER for the first time" |
|
+ ocf_run docker run $run_opts $OCF_RESKEY_image $OCF_RESKEY_run_cmd |
|
+ fi |
|
+ |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_exit_reason "docker failed to launch container" |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ docker_monitor |
|
+ if [ $? -ne $OCF_SUCCESS ]; then |
|
+ ocf_exit_reason "Newly created docker container exited after start" |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+docker_stop() |
|
+{ |
|
+ local timeout=60 |
|
+ docker_monitor |
|
+ if [ $? -eq $OCF_NOT_RUNNING ]; then |
|
+ return $OCF_SUCCESS |
|
+ fi |
|
+ |
|
+ if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then |
|
+ timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000) -10 )) |
|
+ if [ $timeout -lt 10 ]; then |
|
+ timeout=10 |
|
+ fi |
|
+ fi |
|
+ |
|
+ if ocf_is_true "$OCF_RESKEY_force_kill"; then |
|
+ ocf_run docker kill $CONTAINER |
|
+ else |
|
+ ocf_log debug "waiting $timeout second[s] before killing container" |
|
+ ocf_run docker stop -t=$timeout $CONTAINER |
|
+ fi |
|
+ |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_exit_reason "Failed to stop container, ${CONTAINER}, based on image, ${OCF_RESKEY_image}." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ remove_container |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_exit_reason "Failed to remove stopped container, ${CONTAINER}, based on image, ${OCF_RESKEY_image}." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+image_exists() |
|
+{ |
|
+ local res=1 |
|
+ |
|
+ |
|
+ echo "${OCF_RESKEY_image}" | grep -q ":" |
|
+ if [ $? -eq 0 ]; then |
|
+ docker images | awk '{print $1 ":" $2}' | grep "^${OCF_RESKEY_image}\$" > /dev/null 2>&1 |
|
+ else |
|
+ docker images | awk '{print $1}' | grep "^${OCF_RESKEY_image}\$" > /dev/null 2>&1 |
|
+ fi |
|
+ if [ $? -eq 0 ]; then |
|
+ return 0 |
|
+ fi |
|
+ if ocf_is_true "$OCF_RESKEY_allow_pull"; then |
|
+ REQUIRE_IMAGE_PULL=1 |
|
+ ocf_log notice "Image (${OCF_RESKEY_image}) does not exist locally but will be pulled during start" |
|
+ return 0 |
|
+ fi |
|
+ # image not found. |
|
+ return 1 |
|
+} |
|
+ |
|
+docker_validate() |
|
+{ |
|
+ check_binary docker |
|
+ if [ -z "$OCF_RESKEY_image" ]; then |
|
+ ocf_exit_reason "'image' option is required" |
|
+ exit $OCF_ERR_CONFIGURED |
|
+ fi |
|
+ |
|
+ image_exists |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_exit_reason "base image, ${OCF_RESKEY_image}, could not be found." |
|
+ exit $OCF_ERR_CONFIGURED |
|
+ fi |
|
+ |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+: ${OCF_RESKEY_container=${OCF_RESOURCE_INSTANCE}} |
|
+CONTAINER=$OCF_RESKEY_container |
|
+ |
|
+case $__OCF_ACTION in |
|
+meta-data) meta_data |
|
+ exit $OCF_SUCCESS;; |
|
+start) |
|
+ docker_validate |
|
+ docker_start;; |
|
+stop) docker_stop;; |
|
+monitor) docker_monitor;; |
|
+validate-all) docker_validate;; |
|
+usage|help) docker_usage |
|
+ exit $OCF_SUCCESS |
|
+ ;; |
|
+*) docker_usage |
|
+ exit $OCF_ERR_UNIMPLEMENTED |
|
+ ;; |
|
+esac |
|
+rc=$? |
|
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" |
|
+exit $rc |
|
+ |
|
-- |
|
1.8.4.2 |
|
|
|
|