Skip to content

Commit

Permalink
Migrated boostrao from bash to python (pozgo#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
pozgo authored Mar 6, 2020
1 parent 1a84b6c commit cf76188
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 76 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/.jenkins
/.vscode
/.vscode
.idea
16 changes: 8 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
FROM alpine:latest

ENV MKDOCS_VERSION=1.0.4 \
GIT_REPO='false' \
DOCS_DIRECTORY='/mkdocs' \
LIVE_RELOAD_SUPPORT='false' \
ADD_MODULES='false'
ADD_MODULES='false' \
FAST_MODE='false'

ADD bootstrap/ /bootstrap

RUN \
apk add --update \
Expand All @@ -15,12 +18,9 @@ RUN \
python3-dev && \
pip3 install --upgrade pip && \
pip install mkdocs==${MKDOCS_VERSION} && \
cd /bootstrap && pip install -e /bootstrap && \
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*

COPY container-files /

RUN chmod +x /bootstrap.sh

WORKDIR /workdir
WORKDIR ${DOCS_DIRECTORY}

ENTRYPOINT ["/bootstrap.sh"]
CMD ["/usr/bin/bootstrap", "start"]
11 changes: 11 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.8"
30 changes: 10 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ Workdir is set to `/workdir`

### Environmental Variables

|Variable|Notes|
|:--|:--|
|`GIT_REPO`|Remote git based repository - requires mounted keys *see examples below*|
|`LIVE_RELOAD_SUPPORT`|Support for live reload feature. Default set to `false` - Use if auto reload needed|
|`ADD_MODULES`|List of module to install. Default set to `false`|
|Variable|Notes|Default|
|:--|:--|---|
|`LIVE_RELOAD_SUPPORT`|Support for live reload feature. |`false`|
|`ADD_MODULES`|List of module to install.|`false`|
|`FAST_MODE`|Enable fast mode. Rebuilds only changed/added files|`false`|
|`DOCS_DIRECTORY`|Directory in which documentation is mounted inside of container|`/mkdocs`|

### Usage

Expand All @@ -44,25 +45,14 @@ docker run \
-ti \
--name mkdocs \
-p 80:8000 \
-e INSTALL_THEMES='mkdocs-bootstrap mkdocs-gitbook mkdocs-bootstrap4' \
-e ADD_MODULES=mkdocs-bootstrap mkdocs-gitbook mkdocs-bootstrap4 \
-e LIVE_RELOAD_SUPPORT=true \
-e FAST_MODE=true \
-e DOCS_DIRECTORY=/workdir \
-v /my_docs_dir:/workdir \
polinux/mkdocs
```

Fetch from git repository with ssh keys shared from host os

```bash
docker run \
-ti \
--name mkdocs \
-e GIT_REPO='[email protected]:username/my-repo.git' \
-e LIVE_RELOAD_SUPPORT='true' \
-v ~/.ssh:/root/.ssh:ro \
polinux/mkdocs
```

`-v ~/.ssh:/root/.ssh:ro` - Mouts ssh keys from host OS and sets `read-only` permissions

Docker Compose file contains default settings for deploying in local directory and it's set to bind port `8000` to localhost.

### Build
Expand Down
12 changes: 12 additions & 0 deletions bootstrap/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
click = "*"

[requires]
python_version = "3.8"
30 changes: 30 additions & 0 deletions bootstrap/app/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing import Callable
from app.mkdocs import common
import click
import os

"""CLI commands interface
These are the primitive operation wrappers that the CLI
will expose and be available to invoke.
In order to do so, the comprehensive Click library is used to
create commands, subcommands, parameters, flags...
.. _Click CLI library docs:
https://click.palletsprojects.com/en/7.x/#documentation
"""


@click.group(chain=True)
def cli() -> None:
"""
Bootstrap CLI
"""


@cli.command('start', help='Start Application')
def start():
modules = os.environ['ADD_MODULES']
if modules != 'false':
common.install_modules(modules)
common.start()
75 changes: 75 additions & 0 deletions bootstrap/app/mkdocs/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import shlex
import subprocess


class Command:
"""Representation of a shell command with its execution and output.
This class enables the ability to wrap any command line utility, run it
and capture its output for further processing.
Attributes:
executable_with_arguments (str): Full command line as it would typed
in a shell, including arguments, flags...
cmd_output (str): the captured output of the command after it's run
suppress_output (bool): whether or not to output in the console the
result of running this command
Note:
See https://janakiev.com/blog/python-shell-commands/ for more details
"""
def __init__(self, executable_with_arguments: str,
suppress_output: bool = False,
working_dir: str = None) -> None:
self.executable_with_arguments = executable_with_arguments
self.suppress_output = suppress_output
self.cmd_output = ""
self.working_dir = working_dir

def run(self):
""" Executes a command instance, printing its progress
on stdout as it runs.
The result of the command is buffered as a string and saved.
Any errors in execution are surfaced and redirected
to stdout for easy identification
"""
commandline = shlex.split(self.executable_with_arguments)
print(f"Executing [ {self.executable_with_arguments} ]:\n")

if self.working_dir is not None:
print(f"About to start process at working dir {self.working_dir}")
# redirect stderr to stdout
process = subprocess.Popen(commandline,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
cwd=self.working_dir)
else:
# redirect stderr to stdout
process = subprocess.Popen(commandline,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)

result: str = ""

while True:
output = process.stdout.readline()
line = str(output.strip())
result += line + "\n"
print(line)
return_code = process.poll()
if return_code is not None:
if not self.suppress_output:
print('Process finished with return code', return_code)
print(f"Output: \n{result}")
self.cmd_output = result
break





74 changes: 74 additions & 0 deletions bootstrap/app/mkdocs/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from app.mkdocs.command import Command
import os
from termcolor import colored

docks_dir = os.environ['DOCS_DIRECTORY']


def start():
"""
Start mkdocs server
:return:
"""
_check_previous_installation()
print('Starting MKDocs')
Command(f'mkdocs serve -a 0.0.0.0:8000 {_live_reload()} {_fast_mode()}').run()


def install_modules(modules):
"""
Install Additionale Modules
:param modules: str - Lust of modules to install
:return:
"""
print(f'Installing python modules: {modules}')
Command(f'pip install -q {modules}')
print(colored(f'Modules installed.', 'green'))


def _check_previous_installation():
"""
Check if previous installation present
Creates empty documentation if none detected
:return:
"""
if not os.path.exists(docks_dir + '/mkdocs.yml'):
print(colored(f'No documentation found in ({docks_dir}). Creating new one.', 'yellow'))
if not os.path.exists(docks_dir):
os.mkdir(docks_dir)
print(colored(f'Starting fresh installation', 'green'))
Command(f'mkdocs new {docks_dir}/').run()
else:
print(colored(f'Detected previous installation in ({docks_dir}).', 'green'))


def _live_reload():
"""
Live Reload
Auto Reload on file change
:return:
"""
if os.environ['LIVE_RELOAD_SUPPORT'] == 'false':
print(colored(f'LIVE RELOAD - [ DISABLED ]', 'red'))
reload = '--no-livereload'
else:
print(colored(f'LIVE RELOAD - [ ENABLED ]', 'green'))
reload = ''
return reload


def _fast_mode():
"""
Fast Mode
Enables/Disables fast reload.
Enabled: build only files that got changed
Disabled: builds all files regardless of changes
:return:
"""
if os.environ['FAST_MODE'] == 'false':
print(colored(f'FAST_MODE - [ DISABLED ]', 'red'))
fast = ''
else:
print(colored(f'FAST_MODE - [ ENABLED ]', 'green'))
fast = '--dirtyreload'
return fast
4 changes: 4 additions & 0 deletions bootstrap/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from app.cli import cli

if __name__ == '__main__':
cli()
15 changes: 15 additions & 0 deletions bootstrap/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from setuptools import setup

setup(
name='bootstrap',
version='0.0.1',
py_modules=['bootstrap'],
include_package_data=True,
install_requires=[
'click', 'termcolor',
],
entry_points='''
[console_scripts]
bootstrap=app.cli:cli
''',
)
47 changes: 0 additions & 47 deletions container-files/bootstrap.sh

This file was deleted.

0 comments on commit cf76188

Please sign in to comment.