Skip to content

Commit be5619c

Browse files
committed
Adding support for a new Stackbuild specific schema
Signed-off-by: David Cassany <[email protected]>
1 parent 1ce52f9 commit be5619c

File tree

15 files changed

+842
-37
lines changed

15 files changed

+842
-37
lines changed

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ install:
2525
install -m 644 README.rst \
2626
${buildroot}${docdir}/python-kiwi_stackbuild_plugin/README
2727

28+
kiwi_stackbuild_plugin/schema.rng: kiwi_stackbuild_plugin/schema.rnc
29+
# whenever the schema is changed this target will convert
30+
# the short form of the RelaxNG schema to the format used
31+
# in code and auto generates the python data structures
32+
@type -p trang &>/dev/null || \
33+
(echo "ERROR: trang not found in path: $(PATH)"; exit 1)
34+
trang -I rnc -O rng kiwi_stackbuild_plugin/schema.rnc kiwi_stackbuild_plugin/schema.rng
35+
2836
build: clean tox
2937
# create setup.py variant for rpm build.
3038
# delete module versions from setup.py for building an rpm

kiwi_stackbuild_plugin/defaults.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
# along with kiwi-stackbuild. If not, see <http://www.gnu.org/licenses/>
1717
#
1818
import re
19+
import importlib
20+
from importlib.resources import as_file
1921

2022
from kiwi.defaults import Defaults
2123
from typing import (
@@ -95,3 +97,31 @@ def get_container_config(
9597
'author': maintainer
9698
}
9799
}
100+
101+
@staticmethod
102+
def project_file(filename):
103+
"""
104+
Provides the python module base directory search path
105+
106+
The method uses the importlib.resources.path method to identify
107+
files and directories from the application
108+
109+
:param string filename: relative project file
110+
111+
:return: absolute file path name
112+
113+
:rtype: str
114+
"""
115+
with as_file(importlib.resources.files('kiwi_stackbuild_plugin')) as path:
116+
return f'{path}/{filename}'
117+
118+
@staticmethod
119+
def get_schema_file():
120+
"""
121+
Provides file path to kiwi RelaxNG schema
122+
123+
:return: file path
124+
125+
:rtype: str
126+
"""
127+
return StackBuildDefaults.project_file('schema.rng')

kiwi_stackbuild_plugin/exceptions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,10 @@ class KiwiStackBuildPluginRootSyncFailed(KiwiError):
4141
Exception raised if the rsync process to sync the stash into
4242
the root-tree failed
4343
"""
44+
45+
46+
class KiwiStackBuildPluginSchemaValidationFailed(KiwiError):
47+
"""
48+
Exception raised if the provided XML description is not compliant with
49+
the stack build image schema
50+
"""
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#==========================================
2+
# Fake rnc file used only to convert
3+
# stackbuild schema.rnc file to schema.rng
4+
# without requiring the actual KIWI schema
5+
# file
6+
#
7+
start =
8+
## The start pattern of an image
9+
k.image
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0">
3+
<!--
4+
==========================================
5+
Fake rnc file used only to convert
6+
stackbuild schema.rnc file to schema.rng
7+
without requiring the actual KIWI schema
8+
file
9+
10+
-->
11+
<start>
12+
<ref name="k.image">
13+
<a:documentation>The start pattern of an image</a:documentation>
14+
</ref>
15+
</start>
16+
</grammar>

kiwi_stackbuild_plugin/schema.rnc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#================
2+
# FILE : schema.rnc
3+
#****************
4+
# PROJECT : KIWI - Stack Build Plugin
5+
# COPYRIGHT : (c) 2021 SUSE LINUX Products GmbH
6+
# :
7+
# AUTHOR : David Cassany <[email protected]>
8+
# :
9+
# BELONGS TO : Operating System images
10+
# :
11+
# DESCRIPTION : This is the RELAX NG Schema for KIWI Rebuild Images
12+
# : plugin configuration files. The schema is maintained
13+
# : in the relax compact syntax. Any changes should
14+
# : made in !! *** schema.rnc *** !!
15+
# :
16+
# :
17+
# STATUS : Development
18+
#****************
19+
20+
namespace rng = "http://relaxng.org/ns/structure/1.0"
21+
22+
# The real include value is computed and replaced in memory at runtime
23+
# to match the actual KIWI schema of the KIWI module being loaded
24+
include "kiwi-fake-schema.rnc" {
25+
k.image.schemaversion.attribute =
26+
## The allowed Schema version (fixed value)
27+
attribute schemaversion { "0.1" }
28+
29+
k.image.attlist = k.image.name.attribute
30+
& k.image.stackbuild.attribute
31+
& k.image.displayname.attribute?
32+
& k.image.id?
33+
& k.image.schemaversion.attribute
34+
& ( k.image.noNamespaceSchemaLocation.attribute?
35+
| k.image.schemaLocation.attribute? )?
36+
37+
k.image =
38+
## The root element of the configuration file
39+
element image {
40+
k.image.attlist &
41+
k.description? &
42+
k.preferences* &
43+
k.profiles? &
44+
k.users* &
45+
k.drivers* &
46+
k.strip* &
47+
k.repository* &
48+
k.packages*
49+
}
50+
}
51+
52+
div{
53+
k.image.stackbuild.attribute =
54+
## Identifies description as a stackbuild XML
55+
attribute stackbuild { "true" }
56+
}

kiwi_stackbuild_plugin/schema.rng

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
================
4+
FILE : schema.rnc
5+
****************
6+
PROJECT : KIWI - Stack Build Plugin
7+
COPYRIGHT : (c) 2021 SUSE LINUX Products GmbH
8+
:
9+
AUTHOR : David Cassany <[email protected]>
10+
:
11+
BELONGS TO : Operating System images
12+
:
13+
DESCRIPTION : This is the RELAX NG Schema for KIWI Rebuild Images
14+
: plugin configuration files. The schema is maintained
15+
: in the relax compact syntax. Any changes should
16+
: made in !! *** schema.rnc *** !!
17+
:
18+
:
19+
STATUS : Development
20+
****************
21+
-->
22+
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:rng="http://relaxng.org/ns/structure/1.0" xmlns="http://relaxng.org/ns/structure/1.0">
23+
<!--
24+
The real include value is computed and replaced in memory at runtime
25+
to match the actual KIWI schema of the KIWI module being loaded
26+
-->
27+
<include href="kiwi-fake-schema.rng">
28+
<define name="k.image.schemaversion.attribute">
29+
<attribute name="schemaversion">
30+
<a:documentation>The allowed Schema version (fixed value)</a:documentation>
31+
<value>0.1</value>
32+
</attribute>
33+
</define>
34+
<define name="k.image.attlist">
35+
<interleave>
36+
<ref name="k.image.name.attribute"/>
37+
<ref name="k.image.stackbuild.attribute"/>
38+
<optional>
39+
<ref name="k.image.displayname.attribute"/>
40+
</optional>
41+
<optional>
42+
<ref name="k.image.id"/>
43+
</optional>
44+
<ref name="k.image.schemaversion.attribute"/>
45+
<optional>
46+
<choice>
47+
<optional>
48+
<ref name="k.image.noNamespaceSchemaLocation.attribute"/>
49+
</optional>
50+
<optional>
51+
<ref name="k.image.schemaLocation.attribute"/>
52+
</optional>
53+
</choice>
54+
</optional>
55+
</interleave>
56+
</define>
57+
<define name="k.image">
58+
<element name="image">
59+
<a:documentation>The root element of the configuration file</a:documentation>
60+
<interleave>
61+
<ref name="k.image.attlist"/>
62+
<optional>
63+
<ref name="k.description"/>
64+
</optional>
65+
<zeroOrMore>
66+
<ref name="k.preferences"/>
67+
</zeroOrMore>
68+
<optional>
69+
<ref name="k.profiles"/>
70+
</optional>
71+
<zeroOrMore>
72+
<ref name="k.users"/>
73+
</zeroOrMore>
74+
<zeroOrMore>
75+
<ref name="k.drivers"/>
76+
</zeroOrMore>
77+
<zeroOrMore>
78+
<ref name="k.strip"/>
79+
</zeroOrMore>
80+
<zeroOrMore>
81+
<ref name="k.repository"/>
82+
</zeroOrMore>
83+
<zeroOrMore>
84+
<ref name="k.packages"/>
85+
</zeroOrMore>
86+
</interleave>
87+
</element>
88+
</define>
89+
</include>
90+
<div>
91+
<define name="k.image.stackbuild.attribute">
92+
<attribute name="stackbuild">
93+
<a:documentation>Identifies description as a stackbuild XML</a:documentation>
94+
<value>true</value>
95+
</attribute>
96+
</define>
97+
</div>
98+
</grammar>

kiwi_stackbuild_plugin/tasks/system_stackbuild.py

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import logging
6666
from mock import patch
6767
from docopt import docopt
68+
from tempfile import TemporaryDirectory
6869
from typing import (
6970
Dict, List
7071
)
@@ -82,9 +83,10 @@
8283
from kiwi.utils.sync import DataSync
8384
from kiwi.defaults import Defaults
8485

86+
from kiwi_stackbuild_plugin.xml_merge import XMLMerge
8587
from kiwi_stackbuild_plugin.exceptions import (
8688
KiwiStackBuildPluginTargetDirExists,
87-
KiwiStackBuildPluginRootSyncFailed
89+
KiwiStackBuildPluginRootSyncFailed,
8890
)
8991

9092
log = logging.getLogger('kiwi')
@@ -150,34 +152,57 @@ def process(self) -> None:
150152
)
151153

152154
if self.command_args.get('--description'):
153-
with patch.object(
154-
sys, 'argv', self._validate_kiwi_build_command(
155-
[
156-
'system', 'build',
157-
'--description', self.command_args['--description'],
158-
'--target-dir', self.command_args['--target-dir'],
159-
'--allow-existing-root'
160-
]
161-
)
162-
):
163-
kiwi_task = SystemBuildTask(
164-
should_perform_task_setup=False
165-
)
155+
merger = XMLMerge(self.command_args['--description'])
156+
if merger.is_stackbuild_description():
157+
merger.validate_schema()
158+
with TemporaryDirectory(
159+
prefix='kiwi_description.'
160+
) as temp_desc:
161+
merger.merge_description(
162+
f'{image_root_dir}/image', temp_desc
163+
)
164+
self._kiwi_build_task(
165+
temp_desc, self.command_args['--target-dir']
166+
).process()
167+
168+
else:
169+
self._kiwi_build_task(
170+
self.command_args['--description'],
171+
self.command_args['--target-dir']
172+
).process()
166173
else:
167-
with patch.object(
168-
sys, 'argv', self._validate_kiwi_create_command(
169-
[
170-
'system', 'create',
171-
'--root', image_root_dir,
172-
'--target-dir', self.command_args['--target-dir']
173-
]
174-
)
175-
):
176-
kiwi_task = SystemCreateTask(
177-
should_perform_task_setup=False
178-
)
174+
self._kiwi_create_task(
175+
image_root_dir, self.command_args['--target-dir']
176+
).process()
179177

180-
kiwi_task.process()
178+
def _kiwi_build_task(self, description: str, target_dir: str) -> SystemBuildTask:
179+
with patch.object(
180+
sys, 'argv', self._validate_kiwi_build_command(
181+
[
182+
'system', 'build',
183+
'--description', description,
184+
'--target-dir', target_dir,
185+
'--allow-existing-root'
186+
]
187+
)
188+
):
189+
return SystemBuildTask(
190+
should_perform_task_setup=False
191+
)
192+
193+
def _kiwi_create_task(self, root_dir: str, target_dir: str) -> SystemCreateTask:
194+
with patch.object(
195+
sys, 'argv', self._validate_kiwi_create_command(
196+
[
197+
'system', 'create',
198+
'--root', root_dir,
199+
'--target-dir', target_dir
200+
]
201+
)
202+
):
203+
return SystemCreateTask(
204+
should_perform_task_setup=False
205+
)
181206

182207
def _validate_kiwi_create_command(
183208
self, kiwi_create_command: List[str]

kiwi_stackbuild_plugin/tasks/system_stash.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ def process(self) -> None:
8989
)
9090
description = XMLDescription(kiwi_description)
9191
xml_state = XMLState(
92-
xml_data=description.load()
92+
description.load(),
93+
self.global_args['--profile'],
94+
self.global_args['--type']
9395
)
9496
contact_info = xml_state.get_description_section()
9597
image_name = self.command_args['--container-name'] or \

0 commit comments

Comments
 (0)