[node-patches] Change in ovirt-node[node-3.0]: spec: Add minimizer subpackage
fabiand at fedoraproject.org
fabiand at fedoraproject.org
Tue Apr 1 19:06:24 UTC 2014
Fabian Deutsch has uploaded a new change for review.
Change subject: spec: Add minimizer subpackage
......................................................................
spec: Add minimizer subpackage
This subpackage bundles the image-minimizer tool to make it available on
el6.
Change-Id: I1de0066fdc7bf5ca9c441f6a65b495eb73754c40
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M ovirt-node.spec.in
M tools/Makefile.am
M tools/edit-node
A tools/image-minimizer
4 files changed, 240 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/41/26341/1
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index a9ee25b..d5ee35f 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -14,6 +14,9 @@
# Igor can only be shipped on Fedora (because of python-uinput)
%define with_igor 0%{?is_min_f19}
+# The minimizer is only bundled on el6, because it is available on Fedora
+%define with_minimizer 0%{?is_el6}
+
Summary: The %{product_family} daemons/scripts
Name: ovirt-node
@@ -120,7 +123,7 @@
%else
Requires: livecd-tools >= 1:16.0
%endif
-Requires: appliance-tools-minimizer
+Requires: ovirt-node-minimizer
Requires: libselinux-python
%define tools_root %{_datadir}/ovirt-node-tools
@@ -354,6 +357,24 @@
%endif
+#
+# minimizer subpackage
+#
+%if 0%{?with_minimizer}
+%package minimizer
+Summary: The image-minimizer tool
+Group: Applications/System
+Obsoletes: appliance-tools-minimizer
+
+
+%description minimizer
+This package ships the image-minimizer tool.
+This tool is used to remove unneeded rpms and files from a filesystem tree.
+
+# </minimizer subpackage>
+%endif
+
+
%prep
%setup -q
@@ -423,6 +444,11 @@
%{buildroot}/usr/libexec/ovirt-node-igor-slave
%endif
+# Remove minimizer if unneeded
+%if ! 0%{?with_minimizer}
+rm -vf %{buildroot}/%{_sbindir}/image-minimizer
+%endif
+
%clean
%{__rm} -rf %{buildroot}
@@ -472,6 +498,11 @@
# remove symlink to keep original redhat-release
rm -f /etc/system-release
echo "%{product_family} release %{product_release}" > /etc/system-release
+
+# Remove minimizer if not needed
+%if ! 0%{?with_minimizer}
+rm -v %{buildroot}/%{_sbindir}/image-minimizer
+%endif
# Remove igor stuff if not needed
%if ! 0%{?with_igor}
@@ -593,6 +624,12 @@
%{_datadir}/selinux/*/%{modulename}.pp
+%if 0%{?with_minimizer}
+%files minimizer
+%{_sbindir}/image-minimizer
+%endif
+
+
%files
%defattr(-,root,root)
%config(noreplace) %attr(0644,root,root) %{_sysconfdir}/default/ovirt
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 600353d..ddcb01a 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -17,7 +17,8 @@
dist_sbin_SCRIPTS = \
edit-node \
- testable-node
+ testable-node \
+ image-minimizer
EXTRA_DIST = \
edit-node.8
diff --git a/tools/edit-node b/tools/edit-node
index 582a811..b57fb4a 100755
--- a/tools/edit-node
+++ b/tools/edit-node
@@ -1047,8 +1047,9 @@
def _minimize(self):
print "Running Minimizer"
- minimizer = "/usr/bin/image-minimizer"
- if os.path.exists(minimizer):
+ minimizer = "image-minimizer"
+ if (os.path.exists("/usr/bin/" + minimizer) or
+ os.path.exists("/usr/sbin/" + minimizer)):
print glob.glob("%s/etc/ovirt-plugins.d/*.minimize"
% self._instroot)
for f in glob.glob("%s/etc/ovirt-plugins.d/*.minimize"
diff --git a/tools/image-minimizer b/tools/image-minimizer
new file mode 100755
index 0000000..8ed1808
--- /dev/null
+++ b/tools/image-minimizer
@@ -0,0 +1,197 @@
+#!/usr/bin/python
+#
+# image-minimizer: removes files and packages on the filesystem
+#
+# Copyright 2007-2010 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+import glob
+import optparse
+import os
+import shutil
+import sys
+import rpm
+
+class ImageMinimizer:
+ filename = ''
+ dryrun = False
+ verbose = False
+ prefix = None
+ drops = set()
+ visited = set()
+ drops_rpm = set()
+ ts = None
+
+ def __init__(self, filename, root, dryrun, verbose):
+ self.filename = filename
+ self.prefix = root
+ self.dryrun = dryrun
+ self.verbose = verbose
+ self.ts = None
+
+ # Recursively adds all files and directories.
+ # This is done becuase globbing does not allow
+ # ** for arbitrary nesting.
+ def add_directory(self, files, dirname):
+ self.visited.add(dirname)
+ for root, dirs, items in os.walk(dirname):
+ for dir in dirs:
+ self.visited.add(os.path.join(root, dir))
+ for name in items:
+ files.add(os.path.join(root, name))
+
+ def add_pattern(self, files, pattern):
+ globs = glob.glob(pattern)
+ if self.verbose and len(globs) == 0:
+ print "%s file not found" % pattern
+ for g in globs:
+ if os.path.isdir(g):
+ self.add_directory(files, g)
+ else:
+ files.add(g)
+
+ def add_pattern_rpm(self, rpms, pattern):
+ if self.ts is None:
+ if self.prefix is None:
+ raise Exception ('Must specify installation root for droprpm/keeprpm')
+ self.ts = rpm.TransactionSet(self.prefix)
+ mi = self.ts.dbMatch()
+ mi.pattern('name', rpm.RPMMIRE_GLOB, pattern)
+ not_found = True
+ for hdr in mi:
+ not_found = False
+ rpms.add(hdr['name'])
+ if self.verbose and not_found:
+ print "%s package not found" % pattern
+
+ # Parses each line in the ifle
+ def parse_line(self, line):
+ command = ""
+ pattern = ""
+ tok = line.split(None,1)
+ if len(tok) > 0:
+ command = tok[0].lower()
+ if len(tok) > 1:
+ pattern = tok[1].strip()
+
+ # Strip out all the comments and blank lines
+ if not (command.startswith('#') or command==''):
+ if command == 'keep':
+ if self.prefix is not None :
+ pattern = pattern.lstrip('/')
+ pattern = os.path.join(self.prefix, pattern)
+ keeps = set()
+ self.add_pattern(keeps, pattern)
+ self.drops.difference_update(keeps)
+ keeps = None
+ elif command == 'drop':
+ if self.prefix is not None :
+ pattern = pattern.lstrip('/')
+ pattern = os.path.join(self.prefix, pattern)
+ self.add_pattern(self.drops, pattern)
+ elif command == 'keeprpm':
+ keeps_rpm = set()
+ self.add_pattern_rpm(keeps_rpm, pattern)
+ self.drops_rpm.difference_update(keeps_rpm)
+ keeps_rpm = None
+ elif command == 'droprpm':
+ self.add_pattern_rpm(self.drops_rpm, pattern)
+ else:
+ raise Exception ('Unknown Command: ' + command)
+
+ def remove(self):
+ for tag in sorted(self.drops, reverse=True):
+ self.visited.add(os.path.split(tag)[0])
+ if os.path.isdir(tag):
+ self.visited.add(tag)
+ else:
+ if self.dryrun:
+ print 'rm ' + tag
+ else:
+ if self.verbose:
+ print 'rm ' + tag
+ os.remove(tag)
+
+ #remove all empty directory. Every 8k counts!
+ for dir in sorted(self.visited, reverse=True):
+ if len(os.listdir(dir)) == 0:
+ if self.dryrun:
+ print 'rm -rf ' + dir
+ else:
+ if self.verbose:
+ print 'rm -rf ' + dir
+ os.rmdir(dir)
+
+ def remove_rpm(self):
+
+ def runCallback(reason, amount, total, key, client_data):
+ if self.verbose and reason == rpm.RPMCALLBACK_UNINST_STOP:
+ print key, "erased"
+
+ if len(self.drops_rpm) == 0:
+ return
+
+ for pkg in self.drops_rpm:
+ if self.dryrun:
+ print "erasing ", pkg
+ else:
+ self.ts.addErase(pkg)
+ if not self.dryrun:
+ # skip ts.check(), equivalent to --nodeps
+ self.ts.run(runCallback, "erase")
+
+ def filter(self):
+ for line in (open(self.filename).readlines()):
+ self.parse_line(line.strip())
+ self.remove()
+ self.remove_rpm()
+
+
+def parse_options():
+ usage = "usage: %prog [options] filename"
+ parser = optparse.OptionParser(usage=usage)
+
+ parser.set_defaults(root=os.environ.get('INSTALL_ROOT'), dry_run=False)
+
+ parser.add_option("-i", "--installroot", type="string", dest="root",
+ help="Root path to prepend to all file patterns and installation root for RPM operations. Defaults to INSTALL_ROOT")
+
+ parser.add_option("--dryrun", action="store_true", dest="dryrun",
+ help="If set, no filesystem changes are made.")
+
+ parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+ help="Display every action as it is performed.")
+
+ (options, args) = parser.parse_args()
+ if len(args) == 0:
+ parser.print_help()
+ sys.exit(1)
+
+ return (options, args)
+
+
+if __name__ == "__main__":
+ try:
+ (options, args) = parse_options()
+ filename = args[0]
+ minimizer = ImageMinimizer(filename, options.root, options.dryrun,
+ options.verbose)
+ minimizer.filter()
+ except SystemExit, e:
+ sys.exit(e.code)
+ except KeyboardInterrupt, e:
+ print >> sys.stderr, _("Aborted at user request")
+ except Exception, e:
+ print e
+ sys.exit(1)
--
To view, visit http://gerrit.ovirt.org/26341
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1de0066fdc7bf5ca9c441f6a65b495eb73754c40
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: node-3.0
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>
More information about the node-patches
mailing list