Beispiel #1
0
def ensure_tag_exists(kctx: kitipy.Context, tag: str):
    """Check if the given Git tag exists on both local copy and remote origin.
    This is mostly useful to ensure no invalid tag is going to be deployed.
    
    Args:
        kctx (kitipy.Context): Kitipy context.
        tag (str): Git tag to verify.
    
    Raises:
        ValueError: If the given Git tag does not exist either on local or
            remote origin.
    """
    res = kctx.local(
        'git ls-remote --exit-code --tags origin refs/tags/%s >/dev/null 2>&1'
        % (tag),
        check=False)
    if res.returncode != 0:
        kctx.fail("The given tag is not available on Git remote origin.")

    res = kctx.local(
        'git ls-remote --exit-code --tags ./. refs/tags/%s >/dev/null 2>&1' %
        (tag),
        check=False)
    if res.returncode != 0:
        kctx.fail(
            "The given tag is not available in your local Git repo. Please fetch remote tags before running this task again."
        )
Beispiel #2
0
def run_playbook(kctx: Context,
                 inventory: str,
                 playbook: str,
                 hosts: Optional[Tuple[str]] = None,
                 tags: Optional[Tuple[str]] = None,
                 ask_become_pass: bool = False):
    """Run a given Ansible playbook using ``ansible-playbook``.

    Args:
        kctx (kitipy.Context):
            Context to use to run the playbook.
        inventory (str):
            Path to Ansible host inventory.
        playbook (str):
            Path to the Ansible playbook to run.
        hosts (Optional[Tuple[str]]):
            List of targeted hosts. Use None to target all hosts (default value).
        tags (Optional[Tuple[str]]):
            List of targeted tags. Use None to apply all the tags (default value).
        ask_become_pass (bool):
            Whether ``--ask-become-pass`` should be added to the ``ansible-playbook``
            command.
    """
    cmd = 'ansible-playbook -i %s' % (inventory)
    if hosts is not None and len(hosts) > 0:
        cmd += ' -l ' + ','.join(hosts)
    if tags is not None and len(tags) > 0:
        cmd += ' -t ' + ','.join(tags)
    if ask_become_pass:
        cmd += ' --ask-become-pass'

    cmd += ' ' + playbook

    kctx.local(cmd)
Beispiel #3
0
def test_unit(kctx: kitipy.Context, report: bool, coverage: bool):
    # Be sure the SSH container used for tests purpose is up and running.
    # @TODO: add a common way to kitipy to wait for a port to be open
    kctx.invoke(kitipy.docker.tasks.up)

    expected_services = len(kctx.stack.config['services'])
    # @TODO: this won't work as is with Swarm, find how to generalize that sort of tests
    tester = lambda kctx: expected_services == kctx.stack.count_running_services(
    )
    kitipy.wait_for(tester,
                    interval=1,
                    max_checks=5,
                    label="Waiting for services start up...")

    # Host key might change if docker-compose down is used between two test run,
    # thus we start by removing any existing host key.
    kctx.local("ssh-keygen -R '[127.0.0.1]:2022' 1>/dev/null 2>&1")
    kctx.local("ssh-keygen -R '[127.0.0.1]:2023' 1>/dev/null 2>&1")
    kctx.local("ssh-keygen -R testhost 1>/dev/null 2>&1")

    # Ensure the private key has the right chmod or the task might fail.
    os.chmod("tests/.ssh/id_rsa", 0o0600)

    # Ensure first that we're actually able to connect to SSH hosts, or
    # tests will fail anyway.
    kctx.local('ssh -F tests/.ssh/config testhost /bin/true 1>/dev/null 2>&1')
    kctx.local('ssh -F tests/.ssh/config jumphost /bin/true 1>/dev/null 2>&1')
    kctx.local(
        'ssh -F tests/.ssh/config testhost-via-jumphost /bin/true 1>/dev/null 2>&1'
    )

    report_name = 'unit.xml' if report else None
    pytest(kctx, report_name, coverage, 'tests/unit/ -vv')
Beispiel #4
0
def pytest(kctx: kitipy.Context, report_name: Optional[str], coverage: bool,
           cmd: str, **args):
    env = os.environ.copy()
    env['PYTHONPATH'] = os.getcwd()
    args.setdefault('env', env)

    basecmd = 'pytest'
    if report_name:
        if not kctx.path_exists('.test-results'):
            os.mkdir('.test-results')
        basecmd += ' --junitxml=.test-results/%s' % (report_name)
    if coverage:
        basecmd += ' --cov=kitipy/'

    kctx.local('%s %s' % (basecmd, cmd), **args)
Beispiel #5
0
def format(kctx: kitipy.Context, show_diff, fix):
    """Run yapf to detect style divergences and fix them."""
    if not show_diff and not fix:
        kctx.fail(
            "You can't use both --no-diff and --no-fix at the same time.")

    confirm_msg = 'Do you want to reformat your code using yapf?'

    dry_run = lambda: kctx.local('yapf --diff -r kitipy/ tests/ tasks*.py',
                                 check=False)
    apply = lambda: kctx.local('yapf -vv -p -i -r kitipy/ tests/ tasks*.py')

    kitipy.confirm_and_apply(dry_run,
                             confirm_msg,
                             apply,
                             show_dry_run=show_diff,
                             ask_confirm=fix is None,
                             should_apply=fix if fix is not None else True)
Beispiel #6
0
def ensure_tag_is_recent(kctx: kitipy.Context, tag: str, last: int = 5):
    """Check if the given Git tag is recent enough (by default, one of the
    last five).

    Args:
        kctx (kitipy.Context): Kitipy Context.
        tag (str): Tag to look for.
    """
    res = kctx.local(
        "git for-each-ref --format='%%(refname:strip=2)' --sort=committerdate 'refs/tags/*' 2>/dev/null | tail -n%d | grep %s >/dev/null 2>&1"
        % (last, tag),
        check=False,
    )
    if res.returncode != 0:
        kctx.fail(
            'This tag seems too old: at least %d new tags have been released since %s.'
            % (last, tag))
Beispiel #7
0
def lint(kctx: kitipy.Context):
    """Run mypy, a static type checker, to detect type errors."""
    kctx.local('mypy -p kitipy')