Skip to content
This repository has been archived by the owner on Oct 10, 2020. It is now read-only.

Commit

Permalink
install: add --system-package
Browse files Browse the repository at this point in the history
Drop the hidden option ---generate-rpm in favor of --system-package.

The new option controls how a system container is installed to the host:

--generate-rpm=build build the rpm file without installing it.
--generate-rpm=yes build the rpm and install it, the rpm is deleted.
--generate-rpm=no do not attempt to build and install an rpm file.
--generate-rpm=auto install the rpm only if a .spec file is defined in
  the image.  This is the default.

Signed-off-by: Giuseppe Scrivano <[email protected]>

Closes: #767
Approved by: rhatdan
  • Loading branch information
giuseppe authored and rh-atomic-bot committed Mar 22, 2017
1 parent 54401c2 commit 5f3a498
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 15 deletions.
5 changes: 2 additions & 3 deletions Atomic/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ def cli(subparser):
system_xor_user.add_argument("--system", dest="system",
action='store_true', default=False,
help=_('install a system container'))
installp.add_argument("---generate-rpm", dest="generate_rpm",
action='store_true', default=False,
help=_('generate an rpm instead of installing the container'))
installp.add_argument("--system-package", dest="system_package", default="auto",
help=_('control how to install the package. It accepts `auto`, `yes`, `no`, `build`'))
installp.add_argument("--rootfs", dest="remote",
help=_("choose an existing exploded container/image to use "
"its rootfs as a remote, read-only rootfs for the "
Expand Down
67 changes: 55 additions & 12 deletions Atomic/syscontainers.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ def install_user_container(self, image, name):
# Same entrypoint
return self.install(image, name)

def _install_rpm(self, rpm_file):
if os.path.exists("/run/ostree-booted"):
raise ValueError("This doesn't work on Atomic Host yet")
elif os.path.exists("/usr/bin/dnf"):
util.check_call(["dnf", "install", "-y", rpm_file])
else:
util.check_call(["yum", "install", "-y", rpm_file])

def install(self, image, name):
repo = self._get_ostree_repo()
if not repo:
Expand All @@ -189,17 +197,42 @@ def install(self, image, name):
if self.args.system and self.user:
raise ValueError("Only root can use --system")

if self.args.generate_rpm:
if not self.args.system:
raise ValueError("Only --system can generate rpms")
return self.generate_rpm(repo, name, image)

image = self._pull_image_to_ostree(repo, image, False)
accepted_system_package_values = ['auto', 'build', 'no', 'yes']
if self.args.system_package not in accepted_system_package_values:
raise ValueError("Invalid --system-package mode. Accepted values: '%s'" % "', '".join(accepted_system_package_values))

if self.get_checkout(name):
util.write_out("%s already present" % (name))
return

image = self._pull_image_to_ostree(repo, image, False)

if self.args.system_package in ['build', 'yes', 'auto']:
if not self.args.system:
raise ValueError("Only --system can generate rpms")

rpm_file = None
tmp_dir = self.generate_rpm(repo, self.args.system_package == 'auto', name, image)
if tmp_dir:
try:
for root, _, files in os.walk(os.path.join(tmp_dir, "build")):
if rpm_file:
break
for f in files:
if f.endswith('.rpm'):
rpm_file = os.path.join(root, f)
break
# If we are only build'ing the rpm, copy it to the cwd and exit
if self.args.system_package == 'build':
destination = os.path.join(os.getcwd(), os.path.basename(rpm_file))
shutil.move(rpm_file, destination)
util.write_out("Generated rpm %s" % destination)
else:
self._install_rpm(rpm_file)
finally:
shutil.rmtree(tmp_dir)
return False

values = {}
if self.args.setvalues is not None:
setvalues = SystemContainers._split_set_args(self.args.setvalues)
Expand Down Expand Up @@ -797,6 +830,7 @@ def update_container(self, name, setvalues=None, rebase=None):
return

self._checkout(repo, name, image, next_deployment, True, values, remote=self.args.remote, installed_files=installed_files)
return

def rollback(self, name):
path = os.path.join(self._get_system_checkout_path(), name)
Expand Down Expand Up @@ -1596,25 +1630,26 @@ def get_out_checksum(obj): return obj.out_checksum if hasattr(obj, 'out_checksum
traverse(it)
return ret

def generate_rpm(self, repo, name, image):
def generate_rpm(self, repo, auto, name, image):
image_inspect = self.inspect_system_image(image)
temp_dir = tempfile.mkdtemp()
rpm_content = os.path.join(temp_dir, "rpmroot")
rootfs = os.path.join(rpm_content, "usr/lib/containers/atomic", name)
os.makedirs(rootfs)
success = False
try:
spec_file = os.path.join(temp_dir, "container.spec")
self._checkout(repo, name, image, 0, False, destination=rootfs, prefix=rpm_content)

if self.display:
return
return None

installed_files = None
with open(os.path.join(rootfs, "info"), "r") as info_file:
info = json.loads(info_file.read())
installed_files = info["installed-files"] if "installed-files" in info else None

labels = {k.lower() : v for k, v in image_inspect.get('Labels', {})}
labels = {k.lower() : v for k, v in image_inspect.get('Labels', {}).items()}
summary = labels.get('summary', name)
version = labels.get("version", "1.0")
release = labels.get("release", "1.0")
Expand All @@ -1630,6 +1665,9 @@ def generate_rpm(self, repo, name, image):
with open(os.path.join(rootfs, "rpm.spec"), "r") as f:
spec_content = f.read()
else:
# If there is no spec file and 'auto' is used, do not install an rpm
if auto:
return None
spec_content = self._generate_spec_file(rpm_content, name, summary, license_, version=version,
release=release, url=url, source0=source0, requires=requires,
provides=provides, conflicts=conflicts, description=description,
Expand All @@ -1639,20 +1677,25 @@ def generate_rpm(self, repo, name, image):
f.write(spec_content)

cwd = os.getcwd()
result_dir = os.path.join(temp_dir, "build")
if not os.path.exists(result_dir):
os.makedirs(result_dir)
cmd = ["rpmbuild", "--noclean", "-bb", spec_file,
"--define", "_sourcedir %s" % temp_dir,
"--define", "_specdir %s" % temp_dir,
"--define", "_builddir %s" % temp_dir,
"--define", "_srcrpmdir %s" % cwd,
"--define", "_rpmdir %s" % cwd,
"--define", "_rpmdir %s" % result_dir,
"--build-in-place",
"--buildroot=%s" % rpm_content]
util.write_out(" ".join(cmd))
if not self.display:
util.check_call(cmd)
return False
success = True
return temp_dir
finally:
shutil.rmtree(temp_dir)
if not success:
shutil.rmtree(temp_dir)

def _generate_spec_file(self, destdir, name, summary, license_, version="1.0", release="1", url=None,
source0=None, requires=None, conflicts=None, provides=None, description=None,
Expand Down
1 change: 1 addition & 0 deletions bash/atomic
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ _atomic_install() {
--rootfs
--storage
--system
--system-package
--set
--user
"
Expand Down
13 changes: 13 additions & 0 deletions docs/atomic-install.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ atomic-install - Execute Image Install Method
[**--rootfs**=*ROOTFS*]
[**--set**=*NAME*=*VALUE*]
[**--storage**]
[**--system-package=auto|build|yes|no**]
[**--system**]
IMAGE [ARG...]

Expand Down Expand Up @@ -96,6 +97,18 @@ Note: If the image being pulled contains a label of `system.type=ostree`,
atomic will automatically substitute the storage backend to be ostree. This
can be overridden with the --storage option.

**--system-package=auto|build|no|yes**
Control how the container will be installed to the system.

*auto* generates an rpm and install it to the system when the
image defines a .spec file. This is the default.

*build* build only the software package, without installing it.

*no* do not generate an rpm package to install the container.

*yes* generate an rpm package and install it to the system.

**--user**
If running as non-root, specify to install the image from the current
OSTree repository and manage it through systemd and bubblewrap.
Expand Down

0 comments on commit 5f3a498

Please sign in to comment.