Hello community,

here is the log from the commit of package python-kiwi for openSUSE:Factory 
checked in at 2017-03-20 17:08:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-kiwi (Old)
 and      /work/SRC/openSUSE:Factory/.python-kiwi.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-kiwi"

Mon Mar 20 17:08:56 2017 rev:2 rq:479991 version:9.4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-kiwi/python-kiwi.changes  2017-03-16 
09:50:56.174879810 +0100
+++ /work/SRC/openSUSE:Factory/.python-kiwi.new/python-kiwi.changes     
2017-03-20 17:08:57.646970456 +0100
@@ -1,0 +2,49 @@
+Thu Mar 16 09:45:14 CET 2017 - m...@suse.com
+
+- Bump version: 9.3.3 → 9.4.0
+  
+-------------------------------------------------------------------
+Wed Mar 15 17:27:38 CET 2017 - m...@suse.com
+  
+- Allow https location as repository source
+  
+-------------------------------------------------------------------
+Wed Mar 15 09:47:35 CET 2017 - dcass...@suse.com
+  
+- Refactor RootImport to keep images with a default name
+  
+  RootImport has been refactored so the image is kept with a known
+  name that can be obtained with the Defaults class.
+  
+-------------------------------------------------------------------
+Tue Mar 14 16:14:52 CET 2017 - m...@suse.com
+  
+- Added SLE13 distribution matcher
+  
+-------------------------------------------------------------------
+Tue Mar 14 16:14:17 CET 2017 - m...@suse.com
+  
+- Update distribution matcher in spec file
+  
+-------------------------------------------------------------------
+Tue Mar 14 10:22:59 CET 2017 - m...@suse.com
+  
+- Refactor ContainerBuilder
+  
+  Use Checksum instance to run a checksum match
+  Check for existence of base image at earliest opportunity
+  when constructing a ContainerBuilder
+  
+-------------------------------------------------------------------
+Tue Mar 14 10:22:06 CET 2017 - m...@suse.com
+  
+- Added checksum matcher method to Checksum class
+  
+-------------------------------------------------------------------
+Tue Mar 14 10:20:44 CET 2017 - m...@suse.com
+  
+- Delete unused code
+  
+  Also fixed corresponding unit test
+  
+-------------------------------------------------------------------
@@ -6,0 +56,5 @@
+Mon Mar 13 15:45:32 CET 2017 - m...@suse.com
+  
+- Handle derived image as Uri instance
+  
+-------------------------------------------------------------------
@@ -33,0 +88,11 @@
+Thu Mar  9 13:46:05 CET 2017 - dcass...@suse.com
+  
+- Refactored RootImport and included checksum validation
+  
+  First, commit refactors RootImport in order to also copy
+  the imported image after sychronizing the import.
+  
+  Second, it includes a checksum of the copied image which is
+  validated in later steps.
+  
+-------------------------------------------------------------------
@@ -56,0 +122,9 @@
+  
+-------------------------------------------------------------------
+Wed Mar  8 09:32:02 CET 2017 - dcass...@suse.com
+  
+- Support for layered docker images
+  
+  This commit includes support for building layered docker. A new
+  layer is added on top of the base image referenced by `derived_from`
+  attribute.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-kiwi.spec ++++++
--- /var/tmp/diff_new_pack.zFWKb4/_old  2017-03-20 17:09:00.250602824 +0100
+++ /var/tmp/diff_new_pack.zFWKb4/_new  2017-03-20 17:09:00.254602259 +0100
@@ -1,7 +1,7 @@
 #
-# spec file for package kiwi
+# spec file for package python-kiwi
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -11,35 +11,49 @@
 # case the license is the MIT License). An "Open Source License" is a
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
-# Please submit bugfixes or comments via:
-#
-#       https://github.com/SUSE/kiwi/issues
-#
+
+
 %{!?python2_sitelib:%global python2_sitelib %{python_sitelib}}
 
 # translate version id to distribution name as it is used in kiwi
+# generic approach
 %if 0%{?suse_version}
 %define distro %(echo `export VER=%{suse_version}; echo 
"suse-${VER:0:2}.${VER:2:1}"`)
-# redefine for the SLES case if no sles_version exists
+%endif
+
 # SLE12:
 %if 0%{?suse_version} == 1315 && !0%{?is_opensuse}
 %define distro suse-SLES12
 %endif
-# Leap 42.1:
-%if 0%{?suse_version} == 1315 && 0%{?is_opensuse}
+
+# SLE13:
+%if 0%{?sle_version} == 130000 && !0%{?is_opensuse}
+%define distro suse-SLES13
+%endif
+
+# Leap 42.1(openSUSE product based on SLE 12SP1):
+%if 0%{?is_opensuse} && 0%{?sle_version} == 120100
 %define distro suse-leap42.1
 %endif
+
 # Leap 42.2:
-%if 0%{?suse_version} == 1316 && 0%{?is_opensuse}
+%if 0%{?leap_version} == 420200
 %define distro suse-leap42.2
 %endif
+
+# Leap 42.3:
+%if 0%{?leap_version} == 420300
+%define distro suse-leap42.3
+%endif
+
 # Tumbleweed:
 # Current Tumbleweed version, moving target
 %if 0%{?suse_version} == 1330
 %define distro suse-tumbleweed
 %endif
-%endif
 
 # SLES with sles_version macro
 %if 0%{?sles_version}
@@ -52,11 +66,10 @@
 %define distro rhel-07.0
 %endif
 
-
 Name:           python-kiwi
-Version:        9.3.3
-Provides:       kiwi-schema = 6.5
+Version:        9.4.0
 Release:        0
+Provides:       kiwi-schema = 6.5
 Url:            https://github.com/SUSE/kiwi
 Summary:        KIWI - Appliance Builder Next Generation
 License:        GPL-3.0+
@@ -65,13 +78,13 @@
 Source1:        %{name}-boot-packages
 Source2:        %{name}-rpmlintrc
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildRequires:  python3-devel
-BuildRequires:  python3-setuptools
+BuildRequires:  fdupes
 BuildRequires:  python-devel
 BuildRequires:  python-setuptools
-BuildRequires:  fdupes
-BuildRequires:  update-alternatives
+BuildRequires:  python3-devel
+BuildRequires:  python3-setuptools
 BuildRequires:  shadow
+BuildRequires:  update-alternatives
 
 %description
 The KIWI Image System provides an operating system image builder
@@ -82,47 +95,47 @@
 %package -n python2-kiwi
 Summary:        KIWI - Appliance Builder Next Generation
 Group:          Development/Languages/Python
-Provides:       python-kiwi = %{version}-%{release}
-Provides:       kiwi-image:tbz
 Provides:       kiwi-image:docker
 Provides:       kiwi-image:iso
-Provides:       kiwi-image:vmx
-Provides:       kiwi-image:pxe
 Provides:       kiwi-image:oem
-Requires:       update-alternatives
+Provides:       kiwi-image:pxe
+Provides:       kiwi-image:tbz
+Provides:       kiwi-image:vmx
+Provides:       python-kiwi = %{version}-%{release}
 Requires:       python-docopt
-Requires:       python-setuptools
+Requires:       python-future
 Requires:       python-lxml
-Requires:       python-xattr
+Requires:       python-setuptools
 Requires:       python-six
-Requires:       python-future
+Requires:       python-xattr
+Requires:       update-alternatives
 Requires(post): update-alternatives
 Requires(postun): update-alternatives
 # tools used by kiwi
 %if 0%{?suse_version}
-Requires:       zypper
 Requires:       squashfs
+Requires:       zypper
 Provides:       kiwi-packagemanager:zypper
 %endif
 %if 0%{?rhel_version} || 0%{?centos_version}
-Requires:       yum
 Requires:       squashfs-tools
+Requires:       yum
 Provides:       kiwi-packagemanager:yum
 %endif
-Requires:       genisoimage
-Requires:       kiwi-tools
-Requires:       kiwi-man-pages
-Requires:       rsync
-Requires:       tar >= 1.2.7
-Requires:       gptfdisk
-Requires:       qemu-tools
 Requires:       dosfstools
 Requires:       e2fsprogs
-Requires:       lvm2
-Requires:       parted
-Requires:       multipath-tools
+Requires:       genisoimage
+Requires:       gptfdisk
 Requires:       grub2
+Requires:       kiwi-man-pages
+Requires:       kiwi-tools
+Requires:       lvm2
 Requires:       mtools
+Requires:       multipath-tools
+Requires:       parted
+Requires:       qemu-tools
+Requires:       rsync
+Requires:       tar >= 1.2.7
 %ifarch %arm aarch64
 Requires:       u-boot-tools
 %endif
@@ -142,46 +155,46 @@
 %package -n python3-kiwi
 Summary:        KIWI - Appliance Builder Next Generation
 Group:          Development/Languages/Python
-Provides:       kiwi-image:tbz
 Provides:       kiwi-image:docker
 Provides:       kiwi-image:iso
-Provides:       kiwi-image:vmx
-Provides:       kiwi-image:pxe
 Provides:       kiwi-image:oem
-Requires:       update-alternatives
+Provides:       kiwi-image:pxe
+Provides:       kiwi-image:tbz
+Provides:       kiwi-image:vmx
 Requires:       python3-docopt
-Requires:       python3-setuptools
+Requires:       python3-future
 Requires:       python3-lxml
-Requires:       python3-xattr
+Requires:       python3-setuptools
 Requires:       python3-six
-Requires:       python3-future
+Requires:       python3-xattr
+Requires:       update-alternatives
 Requires(post): update-alternatives
 Requires(postun): update-alternatives
 # tools used by kiwi
 %if 0%{?suse_version}
-Requires:       zypper
 Requires:       squashfs
+Requires:       zypper
 Provides:       kiwi-packagemanager:zypper
 %endif
 %if 0%{?rhel_version} || 0%{?centos_version}
-Requires:       yum
 Requires:       squashfs-tools
+Requires:       yum
 Provides:       kiwi-packagemanager:yum
 %endif
-Requires:       genisoimage
-Requires:       kiwi-tools
-Requires:       kiwi-man-pages
-Requires:       rsync
-Requires:       tar >= 1.2.7
-Requires:       gptfdisk
-Requires:       qemu-tools
 Requires:       dosfstools
 Requires:       e2fsprogs
-Requires:       lvm2
-Requires:       parted
-Requires:       multipath-tools
+Requires:       genisoimage
+Requires:       gptfdisk
 Requires:       grub2
+Requires:       kiwi-man-pages
+Requires:       kiwi-tools
+Requires:       lvm2
 Requires:       mtools
+Requires:       multipath-tools
+Requires:       parted
+Requires:       qemu-tools
+Requires:       rsync
+Requires:       tar >= 1.2.7
 %ifarch %arm aarch64
 Requires:       u-boot-tools
 %endif
@@ -199,7 +212,6 @@
 
 %package -n kiwi-tools
 Summary:        KIWI - Collection of Boot Helper Tools
-License:        GPL-3.0+
 Group:          System/Management
 
 %description -n kiwi-tools
@@ -211,9 +223,8 @@
 %ifarch %ix86 x86_64
 %package -n kiwi-pxeboot
 Summary:        KIWI - PXE boot structure
-Requires:       syslinux
-License:        GPL-3.0+
 Group:          System/Management
+Requires:       syslinux
 
 %description -n kiwi-pxeboot
 This package contains the basic PXE directory structure which is
@@ -222,22 +233,21 @@
 
 %package -n kiwi-boot-requires
 Summary:        KIWI - buildservice package requirements for boot images
+Group:          System/Management
 Provides:       kiwi-boot:isoboot
-Provides:       kiwi-boot:vmxboot
 Provides:       kiwi-boot:netboot
 Provides:       kiwi-boot:oemboot
+Provides:       kiwi-boot:vmxboot
 Provides:       kiwi-filesystem:btrfs
-Provides:       kiwi-filesystem:xfs
 Provides:       kiwi-filesystem:ext3
 Provides:       kiwi-filesystem:ext4
 Provides:       kiwi-filesystem:squashfs
+Provides:       kiwi-filesystem:xfs
 Requires:       btrfsprogs
 Requires:       e2fsprogs
-Requires:       xfsprogs
 Requires:       python3-kiwi = %{version}
+Requires:       xfsprogs
 Requires:       %(echo `cat %{S:1}|grep %{_target_cpu}:%{distro}:|cut -f3- 
-d:`)
-License:        GPL-3.0+
-Group:          System/Management
 
 %description -n kiwi-boot-requires
 Meta package for the buildservice to pull in all required packages in
@@ -248,7 +258,6 @@
 
 %package -n kiwi-man-pages
 Summary:        KIWI - manual pages
-License:        GPL-3.0+
 Group:          System/Management
 
 %description -n kiwi-man-pages

++++++ python-kiwi.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/.bumpversion.cfg 
new/kiwi-9.4.0/.bumpversion.cfg
--- old/kiwi-9.3.3/.bumpversion.cfg     2017-03-13 14:47:47.000000000 +0100
+++ new/kiwi-9.4.0/.bumpversion.cfg     2017-03-16 09:45:14.000000000 +0100
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 9.3.3
+current_version = 9.4.0
 commit = True
 tag = True
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/PKG-INFO new/kiwi-9.4.0/PKG-INFO
--- old/kiwi-9.3.3/PKG-INFO     2017-03-13 17:00:48.000000000 +0100
+++ new/kiwi-9.4.0/PKG-INFO     2017-03-16 09:50:29.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: kiwi
-Version: 9.3.3
+Version: 9.4.0
 Summary: KIWI - Appliance Builder (next generation)
 Home-page: http://suse.github.io/kiwi
 Author: Marcus Schaefer
Binary files old/kiwi-9.3.3/boot_arch.tgz and new/kiwi-9.4.0/boot_arch.tgz 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi.2 
new/kiwi-9.4.0/doc/build/man/kiwi.2
--- old/kiwi-9.3.3/doc/build/man/kiwi.2 2017-03-13 17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi.2 2017-03-16 09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi \- Creating Operating System Images
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::image::info.2 
new/kiwi-9.4.0/doc/build/man/kiwi::image::info.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::image::info.2    2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::image::info.2    2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::IMAGE::INFO" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::IMAGE::INFO" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::image::info \- Provide detailed information about an image description
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::image::resize.2 
new/kiwi-9.4.0/doc/build/man/kiwi::image::resize.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::image::resize.2  2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::image::resize.2  2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::IMAGE::RESIZE" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::IMAGE::RESIZE" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::image::resize \- Resize disk images to new geometry
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::result::bundle.2 
new/kiwi-9.4.0/doc/build/man/kiwi::result::bundle.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::result::bundle.2 2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::result::bundle.2 2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::RESULT::BUNDLE" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::RESULT::BUNDLE" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::result::bundle \- Bundle build results
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::result::list.2 
new/kiwi-9.4.0/doc/build/man/kiwi::result::list.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::result::list.2   2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::result::list.2   2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::RESULT::LIST" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::RESULT::LIST" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::result::list \- List build results
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::system::build.2 
new/kiwi-9.4.0/doc/build/man/kiwi::system::build.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::system::build.2  2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::system::build.2  2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::SYSTEM::BUILD" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::SYSTEM::BUILD" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::system::build \- Build image in combined prepare and create step
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::system::create.2 
new/kiwi-9.4.0/doc/build/man/kiwi::system::create.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::system::create.2 2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::system::create.2 2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::SYSTEM::CREATE" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::SYSTEM::CREATE" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::system::create \- Create image from prepared root system
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::system::prepare.2 
new/kiwi-9.4.0/doc/build/man/kiwi::system::prepare.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::system::prepare.2        2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::system::prepare.2        2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::SYSTEM::PREPARE" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::SYSTEM::PREPARE" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::system::prepare \- Prepare image root system
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/build/man/kiwi::system::update.2 
new/kiwi-9.4.0/doc/build/man/kiwi::system::update.2
--- old/kiwi-9.3.3/doc/build/man/kiwi::system::update.2 2017-03-13 
17:00:43.000000000 +0100
+++ new/kiwi-9.4.0/doc/build/man/kiwi::system::update.2 2017-03-16 
09:50:23.000000000 +0100
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KIWI::SYSTEM::UPDATE" "2" "Mar 13, 2017" "9.3.3" "kiwi"
+.TH "KIWI::SYSTEM::UPDATE" "2" "Mar 16, 2017" "9.4.0" "kiwi"
 .SH NAME
 kiwi::system::update \- Update/Upgrade image root system
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/doc/source/conf.py 
new/kiwi-9.4.0/doc/source/conf.py
--- old/kiwi-9.3.3/doc/source/conf.py   2017-03-13 14:47:47.000000000 +0100
+++ new/kiwi-9.4.0/doc/source/conf.py   2017-03-16 09:45:14.000000000 +0100
@@ -92,7 +92,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = u'9.3.3'
+version = u'9.4.0'
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/builder/container.py 
new/kiwi-9.4.0/kiwi/builder/container.py
--- old/kiwi-9.3.3/kiwi/builder/container.py    2017-03-13 16:49:00.000000000 
+0100
+++ new/kiwi-9.4.0/kiwi/builder/container.py    2017-03-16 09:44:58.000000000 
+0100
@@ -16,6 +16,7 @@
 # along with kiwi.  If not, see <http://www.gnu.org/licenses/>
 #
 import platform
+import os
 
 # project
 from kiwi.container import ContainerImage
@@ -23,6 +24,9 @@
 from kiwi.system.setup import SystemSetup
 from kiwi.logger import log
 from kiwi.system.result import Result
+from kiwi.utils.checksum import Checksum
+from kiwi.defaults import Defaults
+from kiwi.exceptions import KiwiContainerBuilderError
 
 
 class ContainerBuilder(object):
@@ -57,6 +61,31 @@
         self.target_dir = target_dir
         self.container_config = xml_state.get_container_config()
         self.requested_container_type = xml_state.get_build_type_name()
+        self.base_image = None
+        self.base_image_md5 = None
+
+        if xml_state.get_derived_from_image_uri():
+            # The base image is expected to be unpacked by the kiwi
+            # prepare step and stored inside of the root_dir/image directory.
+            # In addition a md5 file of the image is expected too
+            self.base_image = Defaults.get_imported_root_image(
+                self.root_dir
+            )
+            self.base_image_md5 = ''.join([self.base_image, '.md5'])
+
+            if not os.path.exists(self.base_image):
+                raise KiwiContainerBuilderError(
+                    'Unpacked Base image {0} not found'.format(
+                        self.base_image
+                    )
+                )
+            if not os.path.exists(self.base_image_md5):
+                raise KiwiContainerBuilderError(
+                    'Base image MD5 sum {0} not found at'.format(
+                        self.base_image_md5
+                    )
+                )
+
         self.system_setup = SystemSetup(
             xml_state=xml_state, root_dir=self.root_dir
         )
@@ -80,13 +109,23 @@
 
         * image="docker"
         """
-        log.info(
-            'Setting up %s container', self.requested_container_type
-        )
-        container_setup = ContainerSetup(
-            self.requested_container_type, self.root_dir, self.container_config
-        )
-        container_setup.setup()
+        if not self.base_image:
+            log.info(
+                'Setting up %s container', self.requested_container_type
+            )
+            container_setup = ContainerSetup(
+                self.requested_container_type, self.root_dir,
+                self.container_config
+            )
+            container_setup.setup()
+        else:
+            checksum = Checksum(self.base_image)
+            if not checksum.matches(checksum.md5(), self.base_image_md5):
+                raise KiwiContainerBuilderError(
+                    'base image file {0} checksum validation failed'.format(
+                        self.base_image
+                    )
+                )
 
         log.info(
             '--> Creating container image'
@@ -95,7 +134,7 @@
             self.requested_container_type, self.root_dir, self.container_config
         )
         container_image.create(
-            self.filename
+            self.filename, self.base_image
         )
         self.result.add(
             key='container',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/container/docker.py 
new/kiwi-9.4.0/kiwi/container/docker.py
--- old/kiwi-9.3.3/kiwi/container/docker.py     2017-03-13 16:49:00.000000000 
+0100
+++ new/kiwi-9.4.0/kiwi/container/docker.py     2017-03-16 09:44:58.000000000 
+0100
@@ -92,11 +92,13 @@
         if not self.entry_command and not self.entry_subcommand:
             self.entry_subcommand = ['--config.cmd=/bin/bash']
 
-    def create(self, filename):
+    def create(self, filename, base_image):
         """
         Create compressed docker system container tar archive
 
         :param string filename: archive file name
+
+        :param string base_image: archive used as a base image
         """
         exclude_list = [
             'image', '.profile', '.kconfig', 'boot', 'dev', 'sys', 'proc',
@@ -113,12 +115,20 @@
             [container_dir, self.container_tag]
         )
 
-        Command.run(
-            ['umoci', 'init', '--layout', container_dir]
-        )
-        Command.run(
-            ['umoci', 'new', '--image', container_name]
-        )
+        if base_image:
+            Command.run([
+                'skopeo', 'copy',
+                'docker-archive:{0}'.format(base_image),
+                'oci:{0}'.format(container_name)
+            ])
+        else:
+            Command.run(
+                ['umoci', 'init', '--layout', container_dir]
+            )
+            Command.run(
+                ['umoci', 'new', '--image', container_name]
+            )
+
         Command.run(
             ['umoci', 'unpack', '--image', container_name, 
self.docker_root_dir]
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/defaults.py 
new/kiwi-9.4.0/kiwi/defaults.py
--- old/kiwi-9.3.3/kiwi/defaults.py     2017-03-07 11:23:36.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/defaults.py     2017-03-16 09:44:58.000000000 +0100
@@ -720,6 +720,21 @@
         """
         return resource_filename('kiwi', filename)
 
+    @classmethod
+    def get_imported_root_image(self, root_dir):
+        """
+        Returns the path of the image used to import a root during
+        the prepare task. This is the filename expected to be
+        found during the create step if derived_from attribute is
+        present.
+
+        :param string root_dir: is the root directory of the current build
+
+        :return: file name of the image
+        :rtype: string
+        """
+        return os.sep.join([root_dir, 'image', 'imported_root'])
+
     def get(self, key):
         """
         Implements get method for profile elements
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/exceptions.py 
new/kiwi-9.4.0/kiwi/exceptions.py
--- old/kiwi-9.3.3/kiwi/exceptions.py   2017-03-13 16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/exceptions.py   2017-03-16 09:44:58.000000000 +0100
@@ -752,3 +752,10 @@
     Exception is raised when something fails during the root import
     procedure.
     """
+
+
+class KiwiContainerBuilderError(KiwiError):
+    """
+    Exception is raised when something fails during a container image
+    build procedure.
+    """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/system/prepare.py 
new/kiwi-9.4.0/kiwi/system/prepare.py
--- old/kiwi-9.3.3/kiwi/system/prepare.py       2017-03-13 16:49:00.000000000 
+0100
+++ new/kiwi-9.4.0/kiwi/system/prepare.py       2017-03-16 09:44:58.000000000 
+0100
@@ -67,7 +67,7 @@
             root_dir, allow_existing
         )
         root.create()
-        image_uri = xml_state.build_type.get_derived_from()
+        image_uri = xml_state.get_derived_from_image_uri()
         if image_uri:
             root_import = RootImport(
                 root_dir, image_uri, xml_state.build_type.get_image()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/system/root_import/base.py 
new/kiwi-9.4.0/kiwi/system/root_import/base.py
--- old/kiwi-9.3.3/kiwi/system/root_import/base.py      2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/system/root_import/base.py      2017-03-16 
09:44:58.000000000 +0100
@@ -16,9 +16,12 @@
 # along with kiwi.  If not, see <http://www.gnu.org/licenses/>
 #
 import os
+import shutil
 
 # project
-from kiwi.system.uri import Uri
+from kiwi.path import Path
+from kiwi.utils.checksum import Checksum
+from kiwi.defaults import Defaults
 from kiwi.exceptions import KiwiRootImportError
 
 
@@ -29,27 +32,26 @@
     * :attr:`root_dir`
         root directory path name
 
-    * :attr:`image_file`
-        local image file to import
-
-    * :attr:`tmp_root_dir`
-        temporary directory where image_file is extracted
+    * :attr:`image_uri`
+        Uri object to store source location
     """
     def __init__(self, root_dir, image_uri):
-        uri = Uri(image_uri)
-        if uri.is_remote():
-            raise KiwiRootImportError(
-                'Only local imports are supported'
-            )
-        else:
-            self.image_file = uri.translate()
+        try:
+            if image_uri.is_remote():
+                raise KiwiRootImportError(
+                    'Only local imports are supported'
+                )
+
+            self.image_file = image_uri.translate()
+
             if not os.path.exists(self.image_file):
                 raise KiwiRootImportError(
                     'Could not stat base image file: 
{0}'.format(self.image_file)
                 )
 
-        self.root_dir = root_dir
-        self.post_init()
+            self.root_dir = root_dir
+        finally:
+            self.post_init()
 
     def post_init(self):
         """
@@ -66,3 +68,10 @@
         Implementation in specialized root import class
         """
         raise NotImplementedError
+
+    def _copy_image(self, image):
+        image_copy = Defaults.get_imported_root_image(self.root_dir)
+        Path.create(os.path.dirname(image_copy))
+        shutil.copy(image, image_copy)
+        checksum = Checksum(image_copy)
+        checksum.md5(''.join([image_copy, '.md5']))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/system/root_import/docker.py 
new/kiwi-9.4.0/kiwi/system/root_import/docker.py
--- old/kiwi-9.3.3/kiwi/system/root_import/docker.py    2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/system/root_import/docker.py    2017-03-16 
09:44:58.000000000 +0100
@@ -63,6 +63,12 @@
         )
         synchronizer.sync_data(options=['-a', '-H', '-X', '-A'])
 
+        # A copy of the uncompressed image and its checksum are
+        # kept inside the root_dir in order to ensure the later steps
+        # i.e. system create are atomic and don't need any third
+        # party archive.
+        self._copy_image(self.uncompressed_image)
+
     def __del__(self):
         if self.oci_layout_dir:
             Path.wipe(self.oci_layout_dir)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/system/uri.py 
new/kiwi-9.4.0/kiwi/system/uri.py
--- old/kiwi-9.3.3/kiwi/system/uri.py   2017-03-13 14:47:47.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/system/uri.py   2017-03-16 09:44:58.000000000 +0100
@@ -113,7 +113,7 @@
             return self._suse_buildservice_path(
                 ''.join([uri.netloc, uri.path])
             )
-        elif uri.scheme == 'http' or uri.scheme == 'ftp':
+        elif uri.scheme == 'http' or uri.scheme == 'https' or uri.scheme == 
'ftp':
             return ''.join([uri.scheme, '://', uri.netloc, uri.path])
         else:
             raise KiwiUriStyleUnknown(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/utils/checksum.py 
new/kiwi-9.4.0/kiwi/utils/checksum.py
--- old/kiwi-9.3.3/kiwi/utils/checksum.py       2017-03-07 15:11:03.000000000 
+0100
+++ new/kiwi-9.4.0/kiwi/utils/checksum.py       2017-03-16 09:44:58.000000000 
+0100
@@ -48,6 +48,27 @@
         self.source_filename = source_filename
         self.checksum_filename = None
 
+    def matches(self, checksum, filename):
+        """
+        Compare given checksum with reference checksum stored
+        in the provided filename. If the checksum matches the
+        method returns True, or False in case it does not match
+
+        :param string checksum: checksum string to compare
+        :param string filename: filename containing checksum
+        """
+        if not os.path.exists(filename):
+            return False
+        with open(filename) as checksum_file:
+            checksum_from_file = checksum_file.read()
+            # checksum is expected to be stored in the first field
+            # separated by space, other information might contain
+            # the filename or blocklist data which is not of interest
+            # for the plain checksum match
+            if checksum_from_file.split(' ')[0] == checksum:
+                return True
+        return False
+
     def md5(self, filename=None):
         """
         Create md5 checksum
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/version.py 
new/kiwi-9.4.0/kiwi/version.py
--- old/kiwi-9.3.3/kiwi/version.py      2017-03-13 16:55:55.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/version.py      2017-03-16 09:45:14.000000000 +0100
@@ -18,5 +18,5 @@
 """
 Global version information used in kiwi and the package
 """
-__version__ = '9.3.3'
-__githash__ = '2b2bb847eb2383a5318dd67ad285c400114edf5b'
+__version__ = '9.4.0'
+__githash__ = 'd62ae5e31ef3e13d6a234e1559178c3ed2a137ec'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi/xml_state.py 
new/kiwi-9.4.0/kiwi/xml_state.py
--- old/kiwi-9.3.3/kiwi/xml_state.py    2017-03-13 16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/kiwi/xml_state.py    2017-03-16 09:44:58.000000000 +0100
@@ -22,6 +22,7 @@
 
 # project
 from . import xml_parse
+from .system.uri import Uri
 from .defaults import Defaults
 
 from .exceptions import (
@@ -1474,6 +1475,21 @@
 
         return option_list
 
+    def get_derived_from_image_uri(self):
+        """
+        Uri object of derived image if configured
+
+        Specific image types can be based on a master image.
+        This method returns the location of this image when
+        configured in the XML description
+
+        :return: Instance of Uri
+        :rtype: object
+        """
+        derived_image = self.build_type.get_derived_from()
+        if derived_image:
+            return Uri(derived_image)
+
     def _used_profiles(self, profiles=None):
         """
             return list of profiles to use. The method looks up the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/kiwi.egg-info/PKG-INFO 
new/kiwi-9.4.0/kiwi.egg-info/PKG-INFO
--- old/kiwi-9.3.3/kiwi.egg-info/PKG-INFO       2017-03-13 17:00:44.000000000 
+0100
+++ new/kiwi-9.4.0/kiwi.egg-info/PKG-INFO       2017-03-16 09:50:24.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: kiwi
-Version: 9.3.3
+Version: 9.4.0
 Summary: KIWI - Appliance Builder (next generation)
 Home-page: http://suse.github.io/kiwi
 Author: Marcus Schaefer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/package/python-kiwi-spec-template 
new/kiwi-9.4.0/package/python-kiwi-spec-template
--- old/kiwi-9.3.3/package/python-kiwi-spec-template    2017-03-13 
16:55:55.000000000 +0100
+++ new/kiwi-9.4.0/package/python-kiwi-spec-template    2017-03-15 
16:57:42.000000000 +0100
@@ -19,27 +19,41 @@
 %{!?python2_sitelib:%global python2_sitelib %{python_sitelib}}
 
 # translate version id to distribution name as it is used in kiwi
+# generic approach
 %if 0%{?suse_version}
 %define distro %(echo `export VER=%{suse_version}; echo 
"suse-${VER:0:2}.${VER:2:1}"`)
-# redefine for the SLES case if no sles_version exists
+%endif
+
 # SLE12:
 %if 0%{?suse_version} == 1315 && !0%{?is_opensuse}
 %define distro suse-SLES12
 %endif
-# Leap 42.1:
-%if 0%{?suse_version} == 1315 && 0%{?is_opensuse}
+
+# SLE13:
+%if 0%{?sle_version} == 130000 && !0%{?is_opensuse}
+%define distro suse-SLES13
+%endif
+
+# Leap 42.1(openSUSE product based on SLE 12SP1):
+%if 0%{?is_opensuse} && 0%{?sle_version} == 120100
 %define distro suse-leap42.1
 %endif
+
 # Leap 42.2:
-%if 0%{?suse_version} == 1316 && 0%{?is_opensuse}
+%if 0%{?leap_version} == 420200
 %define distro suse-leap42.2
 %endif
+
+# Leap 42.3:
+%if 0%{?leap_version} == 420300
+%define distro suse-leap42.3
+%endif
+
 # Tumbleweed:
 # Current Tumbleweed version, moving target
 %if 0%{?suse_version} == 1330
 %define distro suse-tumbleweed
 %endif
-%endif
 
 # SLES with sles_version macro
 %if 0%{?sles_version}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/setup.cfg new/kiwi-9.4.0/setup.cfg
--- old/kiwi-9.3.3/setup.cfg    2017-03-13 17:00:48.000000000 +0100
+++ new/kiwi-9.4.0/setup.cfg    2017-03-16 09:50:29.000000000 +0100
@@ -18,6 +18,6 @@
 
 [egg_info]
 tag_build = 
-tag_svn_revision = 0
 tag_date = 0
+tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/builder_container_test.py 
new/kiwi-9.4.0/test/unit/builder_container_test.py
--- old/kiwi-9.3.3/test/unit/builder_container_test.py  2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/test/unit/builder_container_test.py  2017-03-16 
09:44:58.000000000 +0100
@@ -3,28 +3,36 @@
 import mock
 import kiwi
 
+from .test_helper import raises, patch_open
+
+from kiwi.system.uri import Uri
 from kiwi.builder.container import ContainerBuilder
+from kiwi.exceptions import KiwiContainerBuilderError
 
 
 class TestContainerBuilder(object):
     @patch('platform.machine')
-    def setup(self, mock_machine):
+    @patch('os.path.exists')
+    def setup(self, mock_exists, mock_machine):
+        mock_exists.return_value = True
         mock_machine.return_value = 'x86_64'
-        xml_state = mock.Mock()
+        self.uri = Uri('file:///image_file.tar.xz')
+        self.xml_state = mock.Mock()
+        self.xml_state.get_derived_from_image_uri.return_value = self.uri
         self.container_config = {
             'container_name': 'my-container',
             'entry_command': ["--config.cmd='/bin/bash'"]
         }
-        xml_state.get_container_config = mock.Mock(
+        self.xml_state.get_container_config = mock.Mock(
             return_value=self.container_config
         )
-        xml_state.get_image_version = mock.Mock(
+        self.xml_state.get_image_version = mock.Mock(
             return_value='1.2.3'
         )
-        xml_state.get_build_type_name = mock.Mock(
+        self.xml_state.get_build_type_name = mock.Mock(
             return_value='docker'
         )
-        xml_state.xml_data.get_name = mock.Mock(
+        self.xml_state.xml_data.get_name = mock.Mock(
             return_value='image_name'
         )
         self.setup = mock.Mock()
@@ -32,10 +40,59 @@
             return_value=self.setup
         )
         self.container = ContainerBuilder(
-            xml_state, 'target_dir', 'root_dir'
+            self.xml_state, 'target_dir', 'root_dir'
         )
         self.container.result = mock.Mock()
 
+    @patch('os.path.exists')
+    def test_init_derived(self, mock_exists):
+        mock_exists.return_value = True
+        builder = ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+        assert builder.base_image == 'root_dir/image/imported_root'
+
+    @patch('os.path.exists')
+    @raises(KiwiContainerBuilderError)
+    def test_init_derived_base_image_not_existing(self, mock_exists):
+        mock_exists.return_value = False
+        ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+
+    @patch('os.path.exists')
+    @raises(KiwiContainerBuilderError)
+    def test_init_derived_base_image_md5_not_existing(self, mock_exists):
+        exists_results = [False, True]
+
+        def side_effect(self):
+            return exists_results.pop()
+
+        mock_exists.side_effect = side_effect
+        ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+
+    @patch('kiwi.builder.container.Checksum')
+    @patch('kiwi.builder.container.ContainerImage')
+    @patch('os.path.exists')
+    @raises(KiwiContainerBuilderError)
+    def test_create_derived_checksum_match_failed(
+        self, mock_exists, mock_image, mock_checksum
+    ):
+        mock_exists.return_value = True
+        container = ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+        container.result = mock.Mock()
+
+        checksum = mock.Mock()
+        checksum.matches = mock.Mock(
+            return_value=False
+        )
+        mock_checksum.return_value = checksum
+        container.create()
+
     @patch('kiwi.builder.container.ContainerSetup')
     @patch('kiwi.builder.container.ContainerImage')
     def test_create(self, mock_image, mock_setup):
@@ -45,6 +102,7 @@
         mock_image.return_value = container_image
         self.setup.export_rpm_package_verification.return_value = '.verified'
         self.setup.export_rpm_package_list.return_value = '.packages'
+        self.container.base_image = None
         self.container.create()
         mock_setup.assert_called_once_with(
             'docker', 'root_dir', self.container_config
@@ -54,7 +112,7 @@
             'docker', 'root_dir', self.container_config
         )
         container_image.create.assert_called_once_with(
-            'target_dir/image_name.x86_64-1.2.3.docker.tar.xz'
+            'target_dir/image_name.x86_64-1.2.3.docker.tar.xz', None
         )
         assert self.container.result.add.call_args_list == [
             call(
@@ -85,3 +143,109 @@
         self.setup.export_rpm_package_list.assert_called_once_with(
             'target_dir'
         )
+
+    @patch('kiwi.builder.container.Checksum')
+    @patch('kiwi.builder.container.ContainerImage')
+    @patch('os.path.exists')
+    def test_create_derived(self, mock_exists, mock_image, mock_checksum):
+        mock_exists.return_value = True
+        container = ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+        container.result = mock.Mock()
+
+        checksum = mock.Mock()
+        checksum.md5 = mock.Mock(
+            return_value='checksumvalue'
+        )
+        mock_checksum.return_value = checksum
+
+        container_image = mock.Mock()
+        mock_image.return_value = container_image
+        self.setup.export_rpm_package_verification.return_value = '.verified'
+        self.setup.export_rpm_package_list.return_value = '.packages'
+
+        container.create()
+
+        mock_checksum.assert_called_once_with('root_dir/image/imported_root')
+        checksum.matches.assert_called_once_with(
+            'checksumvalue', 'root_dir/image/imported_root.md5'
+        )
+
+        mock_image.assert_called_once_with(
+            'docker', 'root_dir', self.container_config
+        )
+        container_image.create.assert_called_once_with(
+            'target_dir/image_name.x86_64-1.2.3.docker.tar.xz',
+            'root_dir/image/imported_root'
+        )
+        assert container.result.add.call_args_list == [
+            call(
+                key='container',
+                filename='target_dir/image_name.x86_64-1.2.3.docker.tar.xz',
+                use_for_bundle=True,
+                compress=False,
+                shasum=True
+            ),
+            call(
+                key='image_packages',
+                filename='.packages',
+                use_for_bundle=True,
+                compress=False,
+                shasum=False
+            ),
+            call(
+                key='image_verified',
+                filename='.verified',
+                use_for_bundle=True,
+                compress=False,
+                shasum=False
+            )
+        ]
+        self.setup.export_rpm_package_verification.assert_called_once_with(
+            'target_dir'
+        )
+        self.setup.export_rpm_package_list.assert_called_once_with(
+            'target_dir'
+        )
+
+    @patch_open
+    @patch('kiwi.builder.container.Checksum')
+    @raises(KiwiContainerBuilderError)
+    def test_create_derived_with_different_md5(self, mock_md5, mock_open):
+        container = ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+
+        md5 = mock.Mock()
+        md5.md5.return_value = 'diffchecksumvalue'
+        mock_md5.return_value = md5
+
+        context_manager_mock = mock.Mock()
+        file_mock = mock.Mock()
+        file_mock.read.return_value = 'checksumvalue and someotherstuff\n'
+        enter_mock = mock.Mock()
+        exit_mock = mock.Mock()
+        enter_mock.return_value = file_mock
+        setattr(context_manager_mock, '__enter__', enter_mock)
+        setattr(context_manager_mock, '__exit__', exit_mock)
+        mock_open.return_value = context_manager_mock
+
+        container.create()
+
+    @patch_open
+    @patch('kiwi.builder.container.Checksum')
+    @raises(Exception)
+    def test_create_derived_fail_open(self, mock_md5, mock_open):
+        container = ContainerBuilder(
+            self.xml_state, 'target_dir', 'root_dir'
+        )
+
+        context_manager_mock = mock.Mock()
+        enter_mock = mock.Mock(side_effect=Exception('open failed!'))
+        exit_mock = mock.Mock()
+        setattr(context_manager_mock, '__enter__', enter_mock)
+        setattr(context_manager_mock, '__exit__', exit_mock)
+        mock_open.return_value = context_manager_mock
+
+        container.create()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/container_image_docker_test.py 
new/kiwi-9.4.0/test/unit/container_image_docker_test.py
--- old/kiwi-9.3.3/test/unit/container_image_docker_test.py     2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/test/unit/container_image_docker_test.py     2017-03-16 
09:44:58.000000000 +0100
@@ -51,10 +51,9 @@
 
     @patch('kiwi.container.docker.Path.wipe')
     def test_del(self, mock_wipe):
-        docker = ContainerImageDocker('root_dir')
-        docker.docker_dir = 'dir_a'
-        docker.docker_root_dir = 'dir_b'
-        docker.__del__()
+        self.docker.docker_dir = 'dir_a'
+        self.docker.docker_root_dir = 'dir_b'
+        self.docker.__del__()
         assert mock_wipe.call_args_list == [
             call('dir_a'), call('dir_b')
         ]
@@ -64,9 +63,12 @@
     @patch('kiwi.container.docker.DataSync')
     @patch('kiwi.container.docker.mkdtemp')
     @patch('kiwi.container.docker.Path.wipe')
+    @patch('kiwi.container.docker.Defaults.get_shared_cache_location')
     def test_create(
-        self, mock_wipe, mock_mkdtemp, mock_sync, mock_command, mock_compress
+        self, mock_cache, mock_wipe, mock_mkdtemp,
+        mock_sync, mock_command, mock_compress
     ):
+        mock_cache.return_value = 'var/cache/kiwi'
         compressor = mock.Mock()
         mock_compress.return_value = compressor
         docker_root = mock.Mock()
@@ -78,7 +80,7 @@
 
         mock_mkdtemp.side_effect = call_mkdtemp
 
-        self.docker.create('result.tar.xz')
+        self.docker.create('result.tar.xz', None)
 
         mock_wipe.assert_called_once_with('result.tar')
 
@@ -93,6 +95,70 @@
             ]),
             call([
                 'umoci', 'unpack', '--image',
+                'kiwi_docker_dir/umoci_layout:latest', 'kiwi_docker_root_dir'
+            ]),
+            call([
+                'umoci', 'repack', '--image',
+                'kiwi_docker_dir/umoci_layout:latest', 'kiwi_docker_root_dir'
+            ]),
+            call([
+                'umoci', 'config', '--config.cmd=/bin/bash', '--image',
+                'kiwi_docker_dir/umoci_layout:latest', '--tag', 'latest'
+            ]),
+            call([
+                'umoci', 'gc', '--layout', 'kiwi_docker_dir/umoci_layout'
+            ]),
+            call([
+                'skopeo', 'copy', 'oci:kiwi_docker_dir/umoci_layout:latest',
+                'docker-archive:result.tar:foo/bar:latest'
+            ])
+        ]
+        mock_sync.assert_called_once_with(
+            'root_dir/', 'kiwi_docker_root_dir/rootfs'
+        )
+        docker_root.sync_data.assert_called_once_with(
+            exclude=[
+                'image', '.profile', '.kconfig', 'boot', 'dev', 'sys', 'proc',
+                'var/cache/kiwi'
+            ],
+            options=['-a', '-H', '-X', '-A']
+        )
+        mock_compress.assert_called_once_with('result.tar')
+        compressor.xz.assert_called_once_with()
+
+    @patch('kiwi.container.docker.Compress')
+    @patch('kiwi.container.docker.Command.run')
+    @patch('kiwi.container.docker.DataSync')
+    @patch('kiwi.container.docker.mkdtemp')
+    @patch('kiwi.container.docker.Path.wipe')
+    @patch('kiwi.container.docker.Defaults.get_shared_cache_location')
+    def test_create_derived(
+        self, mock_cache, mock_wipe, mock_mkdtemp,
+        mock_sync, mock_command, mock_compress
+    ):
+        mock_cache.return_value = 'var/cache/kiwi'
+        compressor = mock.Mock()
+        mock_compress.return_value = compressor
+        docker_root = mock.Mock()
+        mock_sync.return_value = docker_root
+        tmpdirs = ['kiwi_docker_root_dir', 'kiwi_docker_dir']
+
+        def call_mkdtemp(prefix):
+            return tmpdirs.pop()
+
+        mock_mkdtemp.side_effect = call_mkdtemp
+
+        self.docker.create('result.tar.xz', 'root_dir/image/image_file')
+
+        mock_wipe.assert_called_once_with('result.tar')
+
+        assert mock_command.call_args_list == [
+            call([
+                'skopeo', 'copy', 'docker-archive:root_dir/image/image_file',
+                'oci:kiwi_docker_dir/umoci_layout:latest'
+            ]),
+            call([
+                'umoci', 'unpack', '--image',
                 'kiwi_docker_dir/umoci_layout:latest', 'kiwi_docker_root_dir'
             ]),
             call([
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/system_prepare_test.py 
new/kiwi-9.4.0/test/unit/system_prepare_test.py
--- old/kiwi-9.3.3/test/unit/system_prepare_test.py     2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/test/unit/system_prepare_test.py     2017-03-16 
09:44:58.000000000 +0100
@@ -79,6 +79,11 @@
         state = XMLState(
             xml, profiles=['vmxFlavour'], build_type='docker'
         )
+        uri = mock.Mock()
+        get_derived_from_image_uri = mock.Mock(
+            return_value=uri
+        )
+        state.get_derived_from_image_uri = get_derived_from_image_uri
         SystemPrepare(
             xml_state=state, root_dir='root_dir',
         )
@@ -87,7 +92,7 @@
         )
         root_init.create.assert_called_once_with()
         mock_root_import.assert_called_once_with(
-            'root_dir', 'file:///image.tar.xz',
+            'root_dir', uri,
             state.build_type.get_image()
         )
         root_import.sync_data.assert_called_once_with()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/system_root_import_base_test.py 
new/kiwi-9.4.0/test/unit/system_root_import_base_test.py
--- old/kiwi-9.3.3/test/unit/system_root_import_base_test.py    2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/test/unit/system_root_import_base_test.py    2017-03-16 
09:44:58.000000000 +0100
@@ -2,6 +2,7 @@
 
 from .test_helper import raises
 
+from kiwi.system.uri import Uri
 from kiwi.system.root_import.base import RootImportBase
 from kiwi.exceptions import KiwiRootImportError
 
@@ -10,23 +11,23 @@
     @patch('os.path.exists')
     def test_init(self, mock_path):
         mock_path.return_value = True
-        RootImportBase('root_dir', 'file:///image.tar.xz')
+        RootImportBase('root_dir', Uri('file:///image.tar.xz'))
         mock_path.assert_called_once_with('/image.tar.xz')
 
     @raises(KiwiRootImportError)
     def test_init_remote_uri(self):
-        RootImportBase('root_dir', 'http://example.com/image.tar.xz')
+        RootImportBase('root_dir', Uri('http://example.com/image.tar.xz'))
 
     @patch('os.path.exists')
     @raises(KiwiRootImportError)
     def test_init_non_existing(self, mock_path):
         mock_path.return_value = False
-        RootImportBase('root_dir', 'file:///image.tar.xz')
+        RootImportBase('root_dir', Uri('file:///image.tar.xz'))
         mock_path.assert_called_once_with('/image.tar.xz')
 
     @raises(NotImplementedError)
     @patch('os.path.exists')
     def test_data_sync(self, mock_path):
         mock_path.return_value = True
-        root_import = RootImportBase('root_dir', 'file:///image.tar.xz')
+        root_import = RootImportBase('root_dir', Uri('file:///image.tar.xz'))
         root_import.sync_data()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kiwi-9.3.3/test/unit/system_root_import_docker_test.py 
new/kiwi-9.4.0/test/unit/system_root_import_docker_test.py
--- old/kiwi-9.3.3/test/unit/system_root_import_docker_test.py  2017-03-13 
16:49:00.000000000 +0100
+++ new/kiwi-9.4.0/test/unit/system_root_import_docker_test.py  2017-03-16 
09:44:58.000000000 +0100
@@ -2,7 +2,11 @@
 from mock import patch
 from mock import call
 
+from .test_helper import raises
+
+from kiwi.system.uri import Uri
 from kiwi.system.root_import.docker import RootImportDocker
+from kiwi.exceptions import KiwiRootImportError
 
 
 class TestRootImportDocker(object):
@@ -10,16 +14,28 @@
     def setup(self, mock_path):
         mock_path.return_value = True
         self.docker_import = RootImportDocker(
-            'root_dir', 'file:///image.tar.xz'
+            'root_dir', Uri('file:///image.tar.xz')
         )
         assert self.docker_import.image_file == '/image.tar.xz'
 
+    @patch('os.path.exists')
+    @raises(KiwiRootImportError)
+    def test_failed_init(self, mock_path):
+        mock_path.return_value = False
+        RootImportDocker(
+            'root_dir', Uri('file:///image.tar.xz')
+        )
+
+    @patch('kiwi.system.root_import.base.shutil.copy')
+    @patch('kiwi.system.root_import.base.Checksum')
+    @patch('kiwi.system.root_import.base.Path.create')
     @patch('kiwi.system.root_import.docker.Compress')
     @patch('kiwi.system.root_import.docker.Command.run')
     @patch('kiwi.system.root_import.docker.DataSync')
     @patch('kiwi.system.root_import.docker.mkdtemp')
     def test_sync_data(
-        self, mock_mkdtemp, mock_sync, mock_run, mock_compress
+        self, mock_mkdtemp, mock_sync, mock_run,
+        mock_compress, mock_path, mock_md5, mock_copy
     ):
         uncompress = mock.Mock()
         uncompress.uncompressed_filename = 'tmp_uncompressed'
@@ -35,6 +51,9 @@
         sync = mock.Mock()
         mock_sync.return_value = sync
 
+        md5 = mock.Mock()
+        mock_md5.return_value = mock.Mock()
+
         self.docker_import.sync_data()
 
         mock_compress.assert_called_once_with('/image.tar.xz')
@@ -57,6 +76,12 @@
         sync.sync_data.assert_called_once_with(
             options=['-a', '-H', '-X', '-A']
         )
+        mock_md5.assert_called_once_with('root_dir/image/imported_root')
+        md5.md5.called_once_with('root_dir/image/imported_root.md5')
+        mock_copy.assert_called_once_with(
+            'tmp_uncompressed', 'root_dir/image/imported_root'
+        )
+        mock_path.assert_called_once_with('root_dir/image')
 
     @patch('kiwi.system.root_import.docker.Path.wipe')
     def test_del(self, mock_path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/system_uri_test.py 
new/kiwi-9.4.0/test/unit/system_uri_test.py
--- old/kiwi-9.3.3/test/unit/system_uri_test.py 2017-03-07 15:11:03.000000000 
+0100
+++ new/kiwi-9.4.0/test/unit/system_uri_test.py 2017-03-16 09:44:58.000000000 
+0100
@@ -101,6 +101,10 @@
         uri = Uri('http://example.com/foo', 'rpm-md')
         assert uri.translate() == 'http://example.com/foo'
 
+    def test_translate_https_path(self):
+        uri = Uri('https://example.com/foo', 'rpm-md')
+        assert uri.translate() == 'https://example.com/foo'
+
     def test_translate_ftp_path(self):
         uri = Uri('ftp://example.com/foo', 'rpm-md')
         assert uri.translate() == 'ftp://example.com/foo'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/utils_checksum_test.py 
new/kiwi-9.4.0/test/unit/utils_checksum_test.py
--- old/kiwi-9.3.3/test/unit/utils_checksum_test.py     2017-03-07 
15:11:03.000000000 +0100
+++ new/kiwi-9.4.0/test/unit/utils_checksum_test.py     2017-03-16 
09:44:58.000000000 +0100
@@ -35,6 +35,22 @@
     def test_checksum_file_not_found(self):
         Checksum('some-file')
 
+    @patch('os.path.exists')
+    def test_matches_checksum_file_does_not_exist(self, mock_exists):
+        mock_exists.return_value = False
+        assert self.checksum.matches('sum', 'some-file') is False
+
+    @patch('os.path.exists')
+    @patch_open
+    def test_matches(self, mock_open, mock_exists):
+        mock_exists.return_value = True
+        mock_open.return_value = self.context_manager_mock
+        self.file_mock.read.side_effect = None
+        self.file_mock.read.return_value = 'sum'
+        assert self.checksum.matches('sum', 'some-file') is True
+        mock_open.assert_called_once_with('some-file')
+        assert self.checksum.matches('foo', 'some-file') is False
+
     @patch('kiwi.path.Path.which')
     @patch('kiwi.utils.checksum.Compress')
     @patch('hashlib.md5')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kiwi-9.3.3/test/unit/xml_state_test.py 
new/kiwi-9.4.0/test/unit/xml_state_test.py
--- old/kiwi-9.3.3/test/unit/xml_state_test.py  2017-03-13 16:49:00.000000000 
+0100
+++ new/kiwi-9.4.0/test/unit/xml_state_test.py  2017-03-16 09:44:58.000000000 
+0100
@@ -576,3 +576,9 @@
 
     def test_get_spare_part(self):
         assert self.state.get_build_type_spare_part_size() == 200
+
+    def test_get_derived_from_image_uri(self):
+        description = XMLDescription('../data/example_config.xml')
+        xml_data = description.load()
+        state = XMLState(xml_data, ['vmxFlavour'], 'docker')
+        assert state.get_derived_from_image_uri().translate() == 
'/image.tar.xz'


Reply via email to