From 6424cbc7cef9185564c5e3574575b4a5e617b9cb Mon Sep 17 00:00:00 2001 From: "bozo.kopic" Date: Fri, 18 Aug 2017 15:24:16 +0200 Subject: documentation --- README.rst | 12 +-- docs/conf.py | 1 + docs/functionality.rst | 32 ++++++++ docs/index.rst | 3 + docs/installation.rst | 2 + docs/schemas.rst | 19 +++++ requirements.pip.dev.txt | 7 ++ requirements.pip.doc.txt | 1 + requirements.pip.run.txt | 5 ++ requirements.pip.txt | 7 -- schemas_json/project.yaml | 185 +++++++++++++++++++++++----------------------- src_py/hatter/executor.py | 29 ++++---- 12 files changed, 186 insertions(+), 117 deletions(-) create mode 100644 docs/functionality.rst create mode 100644 docs/installation.rst create mode 100644 docs/schemas.rst create mode 100644 requirements.pip.dev.txt create mode 100644 requirements.pip.doc.txt create mode 100644 requirements.pip.run.txt delete mode 100644 requirements.pip.txt diff --git a/README.rst b/README.rst index 533ade8..015e8a7 100644 --- a/README.rst +++ b/README.rst @@ -18,8 +18,9 @@ Runtime requirements -------------------- * python >=3.6 +* libvirt -Additional required python packages are listed in `requirements.pip.txt`. +Additional required python packages are listed in `requirements.pip.run.txt`. Development requirements @@ -28,20 +29,22 @@ Development requirements * nodejs >=7 * yarn +Additional required python packages are listed in `requirements.pip.dev.txt`. + Documentation ------------- -Online documentation available at `http://hatter.readthedocs.io`. +Online documentation available at ``_. Build ----- -Build tool used for Hatter is pydoit (`http://pydoit.org/`). It can be +Build tool used for Hatter is pydoit (``_). It can be installed together with other python dependencies by running:: - $ pip install -r requirements.pip.txt + $ pip install -r requirements.pip.dev.txt For listing available doit tasks, use:: @@ -71,6 +74,5 @@ TODO * other - * documentation * write complete setup.py * distribution diff --git a/docs/conf.py b/docs/conf.py index 1d6265f..bc23583 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -7,6 +7,7 @@ extensions = ['sphinx.ext.imgmath', project = 'Hatter' version = '0.0.1' +copyright = '2017, Božo Kopić' master_doc = 'index' html_theme = 'sphinx_rtd_theme' diff --git a/docs/functionality.rst b/docs/functionality.rst new file mode 100644 index 0000000..6943f14 --- /dev/null +++ b/docs/functionality.rst @@ -0,0 +1,32 @@ +Functionality +============= + +Hatter is CI tool with emphasis on simple workflow based on virtual machine +work executors. In contrast to most other CI tools, Hatter doesn't have +specialized executors that need to be installed on machines that execute +user defined commands. Each executor is generic VM with SSH daemon which +is used for file transfer and execution of user defined commands. Therefore, +Hatter is implemented as single daemon that orchestrates VMs lifecycle and +remote command execution. + + +Server +------ + +Hatter server daemon provides project execution orchestrator facility with +web-based administration interface. It is configured with single YAML +configuration defined by :ref:`JSON Schema `. Single +server instance can support automation of multiple projects. + + +Project +------- + +Hatter project is represented by single git repository containing project +configuration file - `.hatter.yml`. Configuration file is defined by +:ref:`JSON Schema `. This configuration can define +multiple execution environments with appropriate execution commands. + + +Execution environment +--------------------- diff --git a/docs/index.rst b/docs/index.rst index df3c1d3..3ae48eb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,3 +5,6 @@ Content :includehidden: introduction + functionality + installation + schemas diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..11e4437 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,2 @@ +Installation +============ diff --git a/docs/schemas.rst b/docs/schemas.rst new file mode 100644 index 0000000..4425ce3 --- /dev/null +++ b/docs/schemas.rst @@ -0,0 +1,19 @@ +JSON Schemas +============ + +.. _project-configuration: + +Project configuration +--------------------- + +.. literalinclude:: ../schemas_json/project.yaml + + +.. _server-configuration: + +Server configuration +-------------------- + +.. literalinclude:: ../schemas_json/server.yaml + +.. literalinclude:: ../schemas_json/logging.yaml diff --git a/requirements.pip.dev.txt b/requirements.pip.dev.txt new file mode 100644 index 0000000..764e73e --- /dev/null +++ b/requirements.pip.dev.txt @@ -0,0 +1,7 @@ +doit +aiohttp +libvirt-python +pyyaml +paramiko +setuptools +sphinx diff --git a/requirements.pip.doc.txt b/requirements.pip.doc.txt new file mode 100644 index 0000000..6966869 --- /dev/null +++ b/requirements.pip.doc.txt @@ -0,0 +1 @@ +sphinx diff --git a/requirements.pip.run.txt b/requirements.pip.run.txt new file mode 100644 index 0000000..2471761 --- /dev/null +++ b/requirements.pip.run.txt @@ -0,0 +1,5 @@ +aiohttp +libvirt-python +pyyaml +paramiko +setuptools diff --git a/requirements.pip.txt b/requirements.pip.txt deleted file mode 100644 index 764e73e..0000000 --- a/requirements.pip.txt +++ /dev/null @@ -1,7 +0,0 @@ -doit -aiohttp -libvirt-python -pyyaml -paramiko -setuptools -sphinx diff --git a/schemas_json/project.yaml b/schemas_json/project.yaml index cb3506b..7a66914 100644 --- a/schemas_json/project.yaml +++ b/schemas_json/project.yaml @@ -3,97 +3,100 @@ id: "hatter://project.yaml#" title: Project description: Project configuration -type: object -required: - - vm - - ssh - - script -properties: - vm: - title: VM - description: VM configuration - type: object - required: - - domain - properties: - uri: - title: URI - description: Libvirt URI - type: string - default: "qemu:///system" - domain: - title: Domain - description: | - Domain registered with libvirt used as execution - environment - type: string - snapshot: - title: Snapshot - description: | - Snapshot used as initial execution environment state - type: string - temp_snapshot: - title: Temporary snapshot - description: | - Snapshot used for storing initial domain state - type: string - default: temp_hatter - get_address_retry_count: - title: Get address retry count - description: | - Maximum number of retries for obtaining running VM guest - IP address - type: integer - default: 10 - get_address_delay: - title: Get address delay +type: array +items: + type: object + description: Single execution environment + required: + - vm + - ssh + - script + properties: + vm: + title: VM + description: VM configuration + type: object + required: + - domain + properties: + uri: + title: URI + description: Libvirt URI + type: string + default: "qemu:///system" + domain: + title: Domain + description: | + Domain registered with libvirt used as execution + environment + type: string + snapshot: + title: Snapshot + description: | + Snapshot used as initial execution environment state + type: string + temp_snapshot: + title: Temporary snapshot + description: | + Snapshot used for storing initial domain state + type: string + default: temp_hatter + get_address_retry_count: + title: Get address retry count + description: | + Maximum number of retries for obtaining running VM guest + IP address + type: integer + default: 10 + get_address_delay: + title: Get address delay + description: | + Delay in seconds between successive get address requests + type: number + default: 5 + ssh: + title: SSH + description: VM guest SSH daemon configuration + type: object + required: + - username + - password + properties: + username: + title: Username + description: Username for connecting to VM guest SSH daemon + type: string + password: + title: Password + description: Password for connecting to VM guest SSH daemon + type: string + connect_retry_count: + title: Connect retry count + description: | + Maximum number of connect retries + type: integer + default: 10 + connect_delay: + title: Connect delay + description: | + Delay in seconds between successive connect calls + type: number + default: 5 + connect_timeout: + title: Connect timeout + description: | + Single connect's TCP connect timeout and authenticate + timeout in seconds + type: number + default: 1 + script: + title: Script + description: | + List of shell commands executed inside VM guest + type: array + items: + title: Command description: | - Delay in seconds between successive get address requests - type: number - default: 5 - ssh: - title: SSH - description: VM guest SSH daemon configuration - type: object - required: - - username - - password - properties: - username: - title: Username - description: Username for connecting to VM guest SSH daemon + Single shell command type: string - password: - title: Password - description: Password for connecting to VM guest SSH daemon - type: string - connect_retry_count: - title: Connect retry count - description: | - Maximum number of connect retries - type: integer - default: 10 - connect_delay: - title: Connect delay - description: | - Delay in seconds between successive connect calls - type: number - default: 5 - connect_timeout: - title: Connect timeout - description: | - Single connect's TCP connect timeout and authenticate - timeout in seconds - type: number - default: 1 - script: - title: Script - description: | - List of shell commands executed inside VM guest - type: array - items: - title: Command - description: | - Single shell command - type: string ... diff --git a/src_py/hatter/executor.py b/src_py/hatter/executor.py index 271d60d..2d1ae2a 100644 --- a/src_py/hatter/executor.py +++ b/src_py/hatter/executor.py @@ -23,20 +23,21 @@ def run(log, repo_path, commit='HEAD', archive_name='hatter_archive'): _git_archive(repo_path, commit, archive_path) log.info('loading project configuration') conf = _load_conf(archive_path) - log.info('starting virtual machine') - with contextlib.closing(_VM(conf['vm'])) as vm: - log.info('creating SSH connection') - with contextlib.closing(_SSH(conf['ssh'], vm.address)) as ssh: - log.info('transfering repository to virtual machine') - ssh.execute('rm -rf {} {}'.format(archive_file_name, - archive_name)) - ssh.upload(archive_path, archive_file_name) - ssh.execute('mkdir {}'.format(archive_name)) - ssh.execute('tar xf {} -C {}'.format(archive_file_name, - archive_name)) - log.info('executing scripts') - for script in conf['scripts']: - ssh.execute(script, archive_name, log) + for i in conf: + log.info('starting virtual machine') + with contextlib.closing(_VM(i['vm'])) as vm: + log.info('creating SSH connection') + with contextlib.closing(_SSH(i['ssh'], vm.address)) as ssh: + log.info('transfering repository to virtual machine') + ssh.execute('rm -rf {} {}'.format(archive_file_name, + archive_name)) + ssh.upload(archive_path, archive_file_name) + ssh.execute('mkdir {}'.format(archive_name)) + ssh.execute('tar xf {} -C {}'.format(archive_file_name, + archive_name)) + log.info('executing scripts') + for script in i['scripts']: + ssh.execute(script, archive_name, log) t_end = time.monotonic() log.info('executor finished (duration: {}s)'.format(t_end - t_begin)) -- cgit v1.2.3-70-g09d2