diff --git a/kiwi/container/oci.py b/kiwi/container/oci.py
index f5a3870c..e61750dd 100644
--- a/kiwi/container/oci.py
+++ b/kiwi/container/oci.py
@@ -52,7 +52,12 @@ class ContainerImageOCI(object):
'expose_ports': ['80', '42'],
'volumes': ['/var/log', '/tmp'],
'environment': {'PATH': '/bin'},
- 'labels': {'name': 'value'}
+ 'labels': {'name': 'value'},
+ 'history': {
+ 'created_by': 'some explanation here',
+ 'comment': 'some comment here',
+ 'author': 'tux'
+ }
}
"""
def __init__(self, root_dir, custom_args=None):
@@ -95,6 +100,12 @@ class ContainerImageOCI(object):
self.oci_config['entry_subcommand'] = \
Defaults.get_default_container_subcommand()
+ if 'history' not in self.oci_config:
+ self.oci_config['history'] = {}
+ if 'created_by' not in self.oci_config['history']:
+ self.oci_config['history']['created_by'] = \
+ Defaults.get_default_container_created_by()
+
self.oci = OCI(self.oci_config['container_tag'])
def create(self, filename, base_image):
@@ -117,7 +128,7 @@ class ContainerImageOCI(object):
image_tar = ArchiveTar(base_image)
image_tar.extract(self.oci.container_dir)
- self.oci.init_layout(base_image)
+ self.oci.init_layout(True if base_image else False)
self.oci.unpack(self.oci_root_dir)
oci_root = DataSync(
@@ -133,7 +144,7 @@ class ContainerImageOCI(object):
for tag in self.oci_config['additional_tags']:
self.oci.add_tag(tag)
- self.oci.set_config(self.oci_config)
+ self.oci.set_config(self.oci_config, True if base_image else False)
self.oci.garbage_collect()
diff --git a/kiwi/defaults.py b/kiwi/defaults.py
index 125730cf..3edb7862 100644
--- a/kiwi/defaults.py
+++ b/kiwi/defaults.py
@@ -25,7 +25,10 @@ from pkg_resources import resource_filename
# project
from .path import Path
-from .version import __githash__
+from .version import (
+ __githash__,
+ __version__
+)
class Defaults(object):
@@ -1173,6 +1176,17 @@ class Defaults(object):
"""
return ['/bin/bash']
+ @classmethod
+ def get_default_container_created_by(self):
+ """
+ Provides the default 'created by' history entry for containers.
+
+ :return: the specific kiwi version used for the build
+
+ :rtype: str
+ """
+ return 'KIWI {0}'.format(__version__)
+
@classmethod
def set_python_default_encoding_to_utf8(self):
"""
diff --git a/kiwi/oci_tools/base.py b/kiwi/oci_tools/base.py
index 0869d9b9..f5d654ef 100644
--- a/kiwi/oci_tools/base.py
+++ b/kiwi/oci_tools/base.py
@@ -17,6 +17,7 @@
#
import os
from tempfile import mkdtemp
+from datetime import datetime
# project
from kiwi.path import Path
@@ -51,6 +52,9 @@ class OCIBase(object):
self.container_name = ':'.join(
[self.container_dir, self.container_tag]
)
+ self.creation_date = datetime.utcnow().strftime(
+ '%Y-%m-%dT%H:%M:%S+00:00'
+ )
def init_layout(self, base_image=False):
"""
@@ -81,7 +85,6 @@ class OCIBase(object):
Implementation in specialized tool class
:param string oci_root_dir: root data directory
- :param string container_name: custom container_dir:tag specifier
"""
raise NotImplementedError
@@ -96,7 +99,7 @@ class OCIBase(object):
"""
raise NotImplementedError
- def set_config(self, oci_config):
+ def set_config(self, oci_config, base_image=False):
"""
Set list of meta data information such as entry_point,
maintainer, etc... to the container. The validation of
diff --git a/kiwi/oci_tools/umoci.py b/kiwi/oci_tools/umoci.py
index a0efb62f..10b0521d 100644
--- a/kiwi/oci_tools/umoci.py
+++ b/kiwi/oci_tools/umoci.py
@@ -15,7 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see
#
-from datetime import datetime
# project
from kiwi.oci_tools.base import OCIBase
@@ -36,16 +35,10 @@ class OCIUmoci(OCIBase):
The import and unpack of the base image is not a
responsibility of this class and done beforehead
- :param string base_image: True|False
+ :param bool base_image: True|False
"""
if base_image:
- Command.run(
- [
- 'umoci', 'config', '--image',
- '{0}:base_layer'.format(self.container_dir),
- '--tag', self.container_tag
- ]
- )
+ self.container_name = '{0}:base_layer'.format(self.container_dir)
else:
Command.run(
['umoci', 'init', '--layout', self.container_dir]
@@ -87,24 +80,30 @@ class OCIUmoci(OCIBase):
]
)
- def set_config(self, oci_config):
+ def set_config(self, oci_config, base_image=False):
"""
Set list of meta data information such as entry_point,
maintainer, etc... to the container.
:param list oci_config: meta data list
+ :param bool base_image: True|False
"""
config_args = self._process_oci_config_to_arguments(oci_config)
Command.run(
[
'umoci', 'config'
] + config_args + [
+ '--history.created', self.creation_date,
'--image', self.container_name,
- '--created', datetime.utcnow().strftime(
- '%Y-%m-%dT%H:%M:%S+00:00'
- )
+ '--tag', self.container_tag,
+ '--created', self.creation_date
]
)
+ if base_image:
+ Command.run(['umoci', 'rm', '--image', self.container_name])
+ self.container_name = self.container_name = ':'.join(
+ [self.container_dir, self.container_tag]
+ )
@classmethod # noqa:C091
def _process_oci_config_to_arguments(self, oci_config):
@@ -168,8 +167,27 @@ class OCIUmoci(OCIBase):
name, oci_config['labels'][name]
))
+ arguments.extend(self._process_oci_history_to_arguments(oci_config))
return arguments
+ @classmethod
+ def _process_oci_history_to_arguments(self, oci_config):
+ history_args = []
+ if 'history' in oci_config:
+ if 'comment' in oci_config['history']:
+ history_args.append('--history.comment={0}'.format(
+ oci_config['history']['comment']
+ ))
+ if 'created_by' in oci_config['history']:
+ history_args.append('--history.created_by={0}'.format(
+ oci_config['history']['created_by']
+ ))
+ if 'author' in oci_config['history']:
+ history_args.append('--history.author={0}'.format(
+ oci_config['history']['author']
+ ))
+ return history_args
+
def garbage_collect(self):
"""
Cleanup unused data from operations
diff --git a/kiwi/schema/kiwi.rnc b/kiwi/schema/kiwi.rnc
index 479fcc10..55ee246c 100644
--- a/kiwi/schema/kiwi.rnc
+++ b/kiwi/schema/kiwi.rnc
@@ -2207,7 +2207,8 @@ div {
k.expose? &
k.volumes? &
k.environment? &
- k.labels?
+ k.labels? &
+ k.history?
}
}
@@ -2400,6 +2401,32 @@ div {
}
}
+#==========================================
+# main block:
+#
+div {
+ k.history.created_by.attribute =
+ ## Specifies the 'created by' history record. By default set to 'KIWI'
+ attribute created_by { text }
+
+ k.history.author.attribute =
+ ## Specifies the 'author' history record.
+ attribute author { text }
+
+ k.history.attlist =
+ k.history.created_by.attribute? &
+ k.history.author.attribute?
+
+ k.history =
+ ## Provides details about the container history. Includes the
+ ## 'created by', 'author' as attributes and its content represents
+ ## the 'comment' entry.
+ element history {
+ k.history.attlist,
+ text
+ }
+}
+
#==========================================
# main block:
#
diff --git a/kiwi/schema/kiwi.rng b/kiwi/schema/kiwi.rng
index 5575d9db..622cf741 100644
--- a/kiwi/schema/kiwi.rng
+++ b/kiwi/schema/kiwi.rng
@@ -3427,6 +3427,9 @@ section provides globally useful container information.
+
+
+
@@ -3699,6 +3702,42 @@ At least one label must be configured
+
+
+
+
+ Specifies the 'created by' history record. By default set to 'KIWI'
+
+
+
+
+ Specifies the 'author' history record.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides details about the container history. Includes the
+'created by', 'author' as attributes and its content represents
+the 'comment' entry.
+
+
+
+
+