Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/docs/administration/images.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The following parameters can be used to define a recipe:
| package | A string or list of strings of package names to install |
| file | Copy a file from the management node into the image. A string specifies a common source and destination. A mapping with `src` and `dst` can specify different paths |
| command | Run a command inside the image |
| osrelease | Write `IMAGE_ID` (recipe name) and `IMAGE_VERSION` (build tag) to `/etc/os-release`. Accepts a boolean to enable `IMAGE_ID` and `IMAGE_VERSION`, or a dictionary of additional os-release fields. `IMAGE_ID` and `IMAGE_VERSION` is always added. |


### Artifact Types
Expand Down Expand Up @@ -57,6 +58,7 @@ steps:
src: /root/hosts.mycluster
dst: /etc/hosts
- command: systemd-firstboot --timezone=America/New_York --locale=en_US.UTF-8 --locale-messages=en_US.UTF-8
- osrelease: true

artifacts:
- squashfs:
Expand Down
45 changes: 45 additions & 0 deletions lib/phoenix/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ def load_recipe(self, name):
self.steps.append(StepPackage(step['package']))
elif steptype == 'file':
self.steps.append(StepFile(step['file']))
elif steptype == 'osrelease':
self.steps.append(StepOsRelease(step['osrelease']))
else:
self.steps.append(step)
elif key == "artifacts":
Expand Down Expand Up @@ -443,6 +445,49 @@ def run(self, recipe):
logging.error("Could not copy file %s to %s", self.src, self.dst)
raise RuntimeError

class StepOsRelease(Step):
name = 'OsRelease'

def __init__(self, params):
# Optional mapping of additional os-release fields to set. IMAGE_ID
# and IMAGE_VERSION are always set from the recipe name and tag.
self.extra = dict()
if type(params) is dict:
self.extra = dict(params)

def __str__(self):
result = "IMAGE_ID=<name> IMAGE_VERSION=<tag>"
if self.extra:
result += " " + " ".join("%s=%s" % (k, v) for k, v in self.extra.items())
return result

def run(self, recipe):
osrelease = Path(recipe.root) / 'etc' / 'os-release'
fields = dict(self.extra)
fields['IMAGE_ID'] = recipe.name
fields['IMAGE_VERSION'] = recipe.tag
logging.info("Setting %s in %s",
" ".join("%s=%s" % (k, v) for k, v in fields.items()),
osrelease)

lines = []
if osrelease.is_file():
lines = osrelease.read_text().splitlines()

# Drop any pre-existing lines for the fields we are about to set
lines = [l for l in lines
if not any(l.startswith("%s=" % key) for key in fields)]

for key, value in fields.items():
lines.append('%s="%s"' % (key, value))

try:
osrelease.parent.mkdir(parents=True, exist_ok=True)
osrelease.write_text('\n'.join(lines) + '\n')
except OSError as e:
logging.error("Could not write %s: %s", osrelease, e)
raise RuntimeError

class Artifact(object):
pass

Expand Down