From a6200cb8abadf322a838e0fc6773e79d92e6d557 Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Tue, 2 Feb 2021 20:33:38 +0100 Subject: [PATCH] refactor dokku_clone module reuse functionality from dokku_app --- README.md | 29 +------------ library/dokku_app.py | 64 ++-------------------------- library/dokku_clone.py | 88 ++++++++++++++++++++------------------- module_utils/dokku_app.py | 63 ++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 129 deletions(-) create mode 100644 module_utils/dokku_app.py diff --git a/README.md b/README.md index 5482738..f84b85b 100644 --- a/README.md +++ b/README.md @@ -215,33 +215,7 @@ Manages ssl configuration for an app. ### dokku_clone -Deploys a repository to an undeployed application. - -#### Parameters - -|Parameter|Choices/Defaults|Comments| -|---------|----------------|--------| -|app
*required*||The name of the app| -|repository
*required*||Git repository url| -|version||Git tree (tag or branch name)| - -#### Example - -```yaml -- name: clone a git repository - dokku_clone: - app: hello-world - repository: https://github.com/hello-world/hello-world.git -- name: clone specific tag of a git repository - dokku_clone: - app: hello-world - repository: https://github.com/hello-world/hello-world.git - version: v1.0 -``` - -### dokku_clone - -Deploys a repository to an undeployed application. +Clone repository and deploy app. #### Parameters @@ -249,6 +223,7 @@ Deploys a repository to an undeployed application. |---------|----------------|--------| |app
*required*||The name of the app| |repository
*required*||Git repository url| +|version||Git tree (tag or branch name). If not provided, default branch is used.| #### Example diff --git a/library/dokku_app.py b/library/dokku_app.py index 062184e..1d6d0ef 100644 --- a/library/dokku_app.py +++ b/library/dokku_app.py @@ -1,8 +1,10 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# from ansible.module_utils.basic import * from ansible.module_utils.basic import AnsibleModule -import subprocess +from ansible.module_utils.dokku_app import ( + dokku_app_present, + dokku_app_absent, +) DOCUMENTATION = """ --- @@ -38,64 +40,6 @@ """ -def dokku_apps_exists(app): - exists = False - error = None - command = "dokku --quiet apps:exists {0}".format(app) - try: - subprocess.check_call(command, shell=True) - exists = True - except subprocess.CalledProcessError as e: - error = str(e) - return exists, error - - -def dokku_app_present(data): - is_error = True - has_changed = False - meta = {"present": False} - - exists, error = dokku_apps_exists(data["app"]) - if exists: - is_error = False - meta["present"] = True - return (is_error, has_changed, meta) - - command = "dokku apps:create {0}".format(data["app"]) - try: - subprocess.check_call(command, shell=True) - is_error = False - has_changed = True - meta["present"] = True - except subprocess.CalledProcessError as e: - meta["error"] = str(e) - - return (is_error, has_changed, meta) - - -def dokku_app_absent(data=None): - is_error = True - has_changed = False - meta = {"present": True} - - exists, error = dokku_apps_exists(data["app"]) - if not exists: - is_error = False - meta["present"] = False - return (is_error, has_changed, meta) - - command = "dokku --force apps:destroy {0}".format(data["app"]) - try: - subprocess.check_call(command, shell=True) - is_error = False - has_changed = True - meta["present"] = False - except subprocess.CalledProcessError as e: - meta["error"] = str(e) - - return (is_error, has_changed, meta) - - def main(): fields = { "app": {"required": True, "type": "str"}, diff --git a/library/dokku_clone.py b/library/dokku_clone.py index 57eb57f..ae2b6e8 100644 --- a/library/dokku_clone.py +++ b/library/dokku_clone.py @@ -2,14 +2,16 @@ # -*- coding: utf-8 -*- # from ansible.module_utils.basic import * from ansible.module_utils.basic import AnsibleModule -import os +from ansible.module_utils.dokku_app import ( + dokku_app_present, +) import subprocess DOCUMENTATION = """ --- module: dokku_clone -short_description: Deploys a repository to an undeployed application. +short_description: Clone repository and deploy app. options: app: description: @@ -29,12 +31,6 @@ required: False default: null aliases: [] - build: - description: - - Whether to build the app (only when repository changes) - required: False - default: True - aliases: [] author: Jose Diaz-Gonzalez """ @@ -50,54 +46,63 @@ """ -def get_state(b_path): - """ Find out current state """ +def dokku_git_sha(data): + """Get SHA of current app repository. - if os.path.lexists(b_path): - if os.path.islink(b_path): - return "link" - elif os.path.isdir(b_path): - return "directory" - elif os.stat(b_path).st_nlink > 1: - return "hard" - # could be many other things, but defaulting to file - return "file" + Returns `None` if app does not exist. + """ + command_git_report = "dokku git:report {app} --git-sha".format(app=data["app"]) + try: + sha = subprocess.check_output( + command_git_report, stderr=subprocess.STDOUT, shell=True + ) + except subprocess.CalledProcessError: + sha = None - return "absent" + return sha def dokku_clone(data): - is_error = True - has_changed = False - meta = {"present": False} - - index_state = get_state("/home/dokku/{0}/HEAD".format(data["app"])) - if index_state == "file": - is_error = False - meta["present"] = True - return (is_error, has_changed, meta) - if index_state != "absent": - meta["error"] = "git HEAD for app {0} is of file type {1}".format( - data["app"], index_state - ) + # create app (if not exists) + is_error, has_changed, meta = dokku_app_present(data) + meta[ + "present" + ] = False # should indicate that requested *version* of app is present + if is_error: return (is_error, has_changed, meta) - command = "dokku git:sync" - if data["build"]: - command += " --build" + sha_old = dokku_git_sha(data) - command += " {app} {repository}".format( + # sync with remote repository + command_git_sync = "dokku git:sync {app} {repository}".format( app=data["app"], repository=data["repository"] ) - if data["version"]: - command += command + " {version}".format(version=data["version"]) - + command_git_sync += command_git_sync + " {version}".format( + version=data["version"] + ) try: - subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) + subprocess.check_output(command_git_sync, stderr=subprocess.STDOUT, shell=True) is_error = False + except subprocess.CalledProcessError as e: + is_error = True + meta["error"] = e.output + return (is_error, has_changed, meta) + + sha_new = dokku_git_sha(data) + if sha_new == sha_old: + meta["present"] = True + return (is_error, has_changed, meta) + else: has_changed = True + + # rebuild app + command_ps_rebuild = "dokku ps:rebuild {app}".format(app=data["app"]) + try: + subprocess.check_output( + command_ps_rebuild, stderr=subprocess.STDOUT, shell=True + ) meta["present"] = True except subprocess.CalledProcessError as e: is_error = True @@ -111,7 +116,6 @@ def main(): "app": {"required": True, "type": "str"}, "repository": {"required": True, "type": "str"}, "version": {"required": False, "type": "str"}, - "build": {"required": False, "type": "bool"}, } module = AnsibleModule(argument_spec=fields, supports_check_mode=False) diff --git a/module_utils/dokku_app.py b/module_utils/dokku_app.py new file mode 100644 index 0000000..edc9b04 --- /dev/null +++ b/module_utils/dokku_app.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +import subprocess + + +def dokku_apps_exists(app): + exists = False + error = None + command = "dokku --quiet apps:exists {0}".format(app) + try: + subprocess.check_call(command, shell=True) + exists = True + except subprocess.CalledProcessError as e: + error = str(e) + return exists, error + + +def dokku_app_present(data): + """Create app if it does not exist.""" + is_error = True + has_changed = False + meta = {"present": False} + + exists, error = dokku_apps_exists(data["app"]) + if exists: + is_error = False + meta["present"] = True + return (is_error, has_changed, meta) + + command = "dokku apps:create {0}".format(data["app"]) + try: + subprocess.check_call(command, shell=True) + is_error = False + has_changed = True + meta["present"] = True + except subprocess.CalledProcessError as e: + meta["error"] = str(e) + + return (is_error, has_changed, meta) + + +def dokku_app_absent(data=None): + """Remove app if it exists.""" + is_error = True + has_changed = False + meta = {"present": True} + + exists, error = dokku_apps_exists(data["app"]) + if not exists: + is_error = False + meta["present"] = False + return (is_error, has_changed, meta) + + command = "dokku --force apps:destroy {0}".format(data["app"]) + try: + subprocess.check_call(command, shell=True) + is_error = False + has_changed = True + meta["present"] = False + except subprocess.CalledProcessError as e: + meta["error"] = str(e) + + return (is_error, has_changed, meta)