1
0
mirror of https://github.com/projectatomic/atomic.git synced 2026-02-05 18:45:01 +01:00

syscontainers: environment variable detection

Add functionality to detect environment variables in template files.
The variables that can be set by the user through --set is displayed
on 'atomic images info'. The variables with overridable default
values will either have their default value displayed, or shown as
{SET_BY_OS} if atomic sets them. Variables without default value
must be set by the user and is listed separately.

Currently install --system already checks for variables that have no
value after install, and will error out.

Signed-off-by: Yu Qi Zhang <jerzhang@redhat.com>

Closes: #752
Approved by: giuseppe
This commit is contained in:
yuqi-zhang
2016-11-09 17:04:14 +00:00
committed by Atomic Bot
parent 8a0a5c7cfc
commit bce4da585b
3 changed files with 85 additions and 0 deletions

View File

@@ -120,6 +120,16 @@ class Info(Atomic):
labels = manifest["Labels"]
for label in labels:
buf += ('\n{0}: {1}'.format(label, labels[label]))
template_variables, template_variables_to_set = self.syscontainers.get_template_variables(self.image)
buf += ("\n\nEnvironment variables with default value, but overridable with --set:")
for variable in template_variables.keys():
buf += ('\n{}: {}'.format(variable, template_variables.get(variable)))
if template_variables_to_set:
buf += ("\n\nEnvironment variables that has no default value, and must be set with --set:")
for variable in template_variables_to_set.keys():
buf += ('\n{}: {}'.format(variable, template_variables_to_set.get(variable)))
return buf
# Check if the input is an image id associated with more than one
# repotag. If so, error out.
@@ -141,6 +151,16 @@ class Info(Atomic):
labels = manifest["Labels"]
for label in labels:
buf += ('\n{0}: {1}'.format(label, labels[label]))
template_variables, template_variables_to_set = self.syscontainers.get_template_variables(self.image)
buf += ("\n\nEnvironment variables with default value, but overridable with --set:")
for variable in template_variables.keys():
buf += ('\n{}: {}'.format(variable, template_variables.get(variable)))
if template_variables_to_set:
buf += ("\n\nEnvironment variables that has no default value, and must be set with --set:")
for variable in template_variables_to_set.keys():
buf += ('\n{}: {}'.format(variable, template_variables_to_set.get(variable)))
return buf
else:
self._no_such_image()

View File

@@ -52,6 +52,9 @@ WorkingDirectory=$DESTDIR
[Install]
WantedBy=multi-user.target
"""
TEMPLATE_FORCED_VARIABLES = ["DESTDIR", "NAME", "EXEC_START", "EXEC_STOP",
"HOST_UID", "HOST_GID"]
TEMPLATE_OVERRIDABLE_VARIABLES = ["RUN_DIRECTORY", "STATE_DIRECTORY"]
class SystemContainers(object):
@@ -624,6 +627,66 @@ class SystemContainers(object):
ret.append(container)
return ret
def get_template_variables(self, image):
repo = self._get_ostree_repo()
_, commit_rev = self._resolve_image(repo, image)
if not commit_rev:
return
manifest = self._image_manifest(repo, commit_rev)
layers = SystemContainers.get_layers_from_manifest(json.loads(manifest))
templates = {}
manifest_template = None
for i in layers:
layer = i.replace("sha256:", "")
commit = repo.read_commit(repo.resolve_rev("%s%s" % (OSTREE_OCIIMAGE_PREFIX, layer), True)[1])[1]
exports = commit.get_root().get_child("exports")
if not exports.query_exists():
continue
children = exports.enumerate_children("", Gio.FileQueryInfoFlags.NONE, None)
for child in reversed(list(children)):
name = child.get_name()
if name == "manifest.json":
manifest_template = exports.get_child(name).read()
if name.endswith(".template"):
if name.startswith(".wh"):
name = name[4:]
templates.pop(name, None)
else:
templates[name] = exports.get_child(name).read()
variables = {}
for v in templates.values():
fd = v.get_fd()
with os.fdopen(fd) as f:
data = f.read()
template = Template(data)
for variable in ["".join(x) for x in template.pattern.findall(data)]: # pylint: disable=no-member
if variable not in TEMPLATE_FORCED_VARIABLES:
variables[variable] = variable
variables_with_default = {}
if manifest_template:
fd = manifest_template.get_fd()
with os.fdopen(fd) as f:
data = json.loads(f.read())
for variable in data['defaultValues']:
variables_with_default[variable] = data['defaultValues'][variable]
# Also include variables that are set by the OS
# but can be overriden by --set
for variable in TEMPLATE_OVERRIDABLE_VARIABLES:
variables_with_default[variable] = "{SET_BY_OS}"
variables_to_set = {}
for variable in variables:
if variable not in variables_with_default:
variables_to_set[variable] = "{DEF_VALUE}"
return variables_with_default, variables_to_set
def delete_image(self, image):
repo = self._get_ostree_repo()
if not repo:

View File

@@ -26,6 +26,8 @@ atomic images allows the user to view and operate on container images in a docke
Displays the LABEL fields within an image. By default, it will check first for a local image and then all configured registries.
For a system container image, this will also display the environment variables a user can set.
**help**
Displays a help file associated with a container or image.