Skip to content

Commit

Permalink
Merge branch 'release/1.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
lueschem committed Jan 13, 2020
2 parents abca4d4 + 8fcf58a commit 522fba9
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 15 deletions.
7 changes: 7 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
edi (1.2.0) bionic; urgency=medium

[ Matthias Lüscher ]
* Allow configurations that just have postprocessing commands.

-- Matthias Luescher <lueschem@gmail.com> Mon, 13 Jan 2020 13:57:25 +0100

edi (1.1.17) bionic; urgency=medium

[ Matthias Lüscher ]
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
# built documents.
#
# The short X.Y version.
version = '1.1.17'
release = '1.1.17'
version = '1.2.0'
release = '1.2.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
21 changes: 15 additions & 6 deletions edi/commands/imagecommands/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with edi. If not, see <http://www.gnu.org/licenses/>.

import logging
from edi.commands.image import Image
from edi.commands.lxccommands.export import Export
from edi.lib.commandrunner import CommandRunner
Expand Down Expand Up @@ -50,7 +51,8 @@ def dry_run(self, config_file):

def _dry_run(self):
plugins = {}
plugins.update(Export().dry_run(self.config.get_base_config_file()))
if self._input_artifact() is not None:
plugins.update(Export().dry_run(self.config.get_base_config_file()))
command_runner = CommandRunner(self.config, self.section, self._input_artifact())
plugins.update(command_runner.get_plugin_report())
return plugins
Expand All @@ -64,14 +66,18 @@ def _run(self):
if command_runner.require_root():
self._require_sudo()

Export().run(self.config.get_base_config_file())
if self._input_artifact() is not None:
Export().run(self.config.get_base_config_file())
else:
logging.info("Creating new image without bootstrapping other artifacts.")

print("Going to post process image - be patient.")

result = command_runner.run()

print_success(("Completed the image creation post processing commands.\n"
"The following artifacts are now available:\n- {}".format('\n- '.join(result))))
if result:
print_success(("Completed the image creation post processing commands.\n"
"The following artifacts are now available:\n- {}".format('\n- '.join(result))))
return result

def clean_recursive(self, config_file, depth):
Expand All @@ -87,7 +93,7 @@ def _clean(self):
self._require_sudo()
command_runner.clean()

if self.clean_depth > 0:
if self.clean_depth > 0 and self._input_artifact() is not None:
Export().clean_recursive(self.config.get_base_config_file(), self.clean_depth - 1)

def _dispatch(self, config_file, run_method):
Expand All @@ -96,4 +102,7 @@ def _dispatch(self, config_file, run_method):
return run_method()

def _input_artifact(self):
return Export().result(self.config.get_base_config_file())
if self.config.has_bootstrap_node():
return Export().result(self.config.get_base_config_file())
else:
return None
2 changes: 2 additions & 0 deletions edi/commands/qemucommands/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ def _get_qemu_binary_name(self):
return 'qemu-{}-static'.format(qemu_arch)

def _needs_qemu(self):
if not self.config.has_bootstrap_node():
return False
host_architecture = get_debian_architecture()
container_architecture = self.config.get_bootstrap_architecture()
if host_architecture == container_architecture:
Expand Down
4 changes: 3 additions & 1 deletion edi/lib/commandrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,7 @@ def _result(self, commands):

if all_artifacts:
return all_artifacts
else:
elif self.input_artifact is not None:
return [self.input_artifact]
else:
return []
18 changes: 16 additions & 2 deletions edi/lib/configurationparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ def get_config(self):
def get_load_time_dictionary(self):
return self._get_load_time_dictionary()

def has_bootstrap_node(self):
return self._has_node("bootstrap")

def get_plugins(self, plugin_section):
result = {}

Expand All @@ -142,7 +145,10 @@ def get_configuration_name(self):
return self.config_id

def get_bootstrap_repository(self):
return self._get_bootstrap_item("repository", None)
repository = self._get_bootstrap_item("repository", None)
if not repository:
raise FatalError('''Missing mandatory element 'repository' in section 'bootstrap'.''')
return repository

def get_bootstrap_architecture(self):
architecture = self._get_bootstrap_item("architecture", None)
Expand Down Expand Up @@ -382,7 +388,9 @@ def _get_node_dictionary(self, node):
"lxcif0")
node_dict["edi_config_management_user_name"] = self._get_general_item("edi_config_management_user_name",
"edicfgmgmt")
node_dict['edi_bootstrap_architecture'] = self.get_bootstrap_architecture()

if self.has_bootstrap_node():
node_dict['edi_bootstrap_architecture'] = self.get_bootstrap_architecture()

general_parameters = self.get_general_parameters()
if general_parameters:
Expand Down Expand Up @@ -412,3 +420,9 @@ def _resolve_path(self, path):
raise FatalError(("'{0}' not found in the "
"following locations:\n{1}"
).format(path, "\n".join(locations)))

def _has_node(self, node_name):
if self._get_config().get(node_name, {}):
return True
else:
return False
2 changes: 1 addition & 1 deletion edi/lib/versionhelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

# The do_release script will update this version!
# During launchpad debuild neither the git version nor the package version is available.
edi_fallback_version = '1.1.17'
edi_fallback_version = '1.2.0'


def get_edi_version():
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
setup(
name='edi',

version='1.1.17',
version='1.2.0',

description='Embedded Development Infrastructure - edi',
long_description=long_description,
Expand Down
16 changes: 15 additions & 1 deletion tests/commands/imagecommands/test_image_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from tests.libtesting.optins import requires_lxc, requires_ansible, requires_debootstrap, requires_sudo
from tests.libtesting.contextmanagers.workspace import workspace
import os
from tests.libtesting.helpers import get_random_string, get_project_root
from tests.libtesting.helpers import get_random_string, get_project_root, suppress_chown_during_debuild
from edi.lib.shellhelpers import run, get_debian_architecture
from edi.lib.lxchelpers import (get_server_image_compression_algorithm, lxc_exec,
get_file_extension_from_image_compression_algorithm)
Expand Down Expand Up @@ -91,3 +91,17 @@ def test_create_buster_image(capsys):
result = run(lxc_image_list_cmd, stdout=subprocess.PIPE)
for image_store_item in image_store_items:
assert image_store_item not in result.stdout


def test_empty_configuration(empty_config_file, monkeypatch):
with open(empty_config_file, "r") as main_file:
suppress_chown_during_debuild(monkeypatch)

create_cmd = Create()
result = create_cmd.run(main_file)
assert result == []

result = create_cmd.dry_run(main_file)
assert result == {}

create_cmd.clean_recursive(main_file, 100)
35 changes: 35 additions & 0 deletions tests/commands/test_clean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Matthias Luescher
#
# Authors:
# Matthias Luescher
#
# This file is part of edi.
#
# edi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# edi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with edi. If not, see <http://www.gnu.org/licenses/>.


from tests.libtesting.contextmanagers.workspace import workspace
from edi.commands.clean import Clean
from tests.libtesting.helpers import suppress_chown_during_debuild
from tests.libtesting.optins import requires_lxc


@requires_lxc
def test_clean_empty_config(empty_config_file, monkeypatch):
suppress_chown_during_debuild(monkeypatch)
with workspace():
with open(empty_config_file, "r") as main_file:
clean_cmd = Clean()
clean_cmd.run(main_file)
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def datadir(tmpdir, request):
param1: keep
param2: do_overwrite
qemu:
package: qemu-user-static
shared_folders:
skip_me:
folder: skip
Expand Down
22 changes: 22 additions & 0 deletions tests/lib/test_configurationparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with edi. If not, see <http://www.gnu.org/licenses/>.

import pytest
from edi.lib.helpers import FatalError
from aptsources.sourceslist import SourceEntry
from edi.lib.configurationparser import ConfigurationParser, command_context

Expand Down Expand Up @@ -122,3 +124,23 @@ def test_command_context():
assert ConfigurationParser.command_context.get('edi_current_context') is None
assert ConfigurationParser.command_context.get('edi_create_distributable_image') is False
assert ConfigurationParser.command_context.get('edi_current_context') is None


def test_config_nodes_presence(config_files):
with open(config_files, "r") as main_file:
parser = ConfigurationParser(main_file)
assert parser.has_bootstrap_node()
assert parser.get_bootstrap_repository()
assert parser.get_bootstrap_architecture()


def test_config_nodes_absence(empty_config_file):
with open(empty_config_file, "r") as main_file:
parser = ConfigurationParser(main_file)
assert not parser.has_bootstrap_node()
with pytest.raises(FatalError) as error:
parser.get_bootstrap_repository()
assert "repository" in error.value.message
with pytest.raises(FatalError) as error:
parser.get_bootstrap_architecture()
assert "architecture" in error.value.message
3 changes: 2 additions & 1 deletion travis/travis-build
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ then
if [ ! -f "${GPG_ARCHIVE}" ]
then
>&2 echo "Error: Missing ${GPG_ARCHIVE}."
>&2 echo -e "\nError: Missing credential archive ${GPG_ARCHIVE}."
exit 1
fi
sudo -u ${TESTUSER} git clean -dxf
Expand Down

0 comments on commit 522fba9

Please sign in to comment.