|
Jakub Filak |
2164d6 |
From aa503cf6722fffa2dbf3d400a4e2bbeac2f78d65 Mon Sep 17 00:00:00 2001
|
|
Jakub Filak |
2164d6 |
From: Jakub Filak <jfilak@redhat.com>
|
|
Jakub Filak |
2164d6 |
Date: Thu, 23 Oct 2014 16:37:14 +0200
|
|
Jakub Filak |
2164d6 |
Subject: [PATCH] a-a-g-machine-id: add systemd's machine id
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
The dmidecode based algorithm may not work on all architectures.
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
man machine-id
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
Related to rhbz#1140044
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
Jakub Filak |
2164d6 |
---
|
|
Jakub Filak |
2164d6 |
src/plugins/abrt-action-generate-machine-id | 165 ++++++++++++++++++++++++++--
|
|
Jakub Filak |
2164d6 |
1 file changed, 153 insertions(+), 12 deletions(-)
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
diff --git a/src/plugins/abrt-action-generate-machine-id b/src/plugins/abrt-action-generate-machine-id
|
|
Jakub Filak |
2164d6 |
index 0aea787..b2de822 100644
|
|
Jakub Filak |
2164d6 |
--- a/src/plugins/abrt-action-generate-machine-id
|
|
Jakub Filak |
2164d6 |
+++ b/src/plugins/abrt-action-generate-machine-id
|
|
Jakub Filak |
2164d6 |
@@ -1,14 +1,47 @@
|
|
Jakub Filak |
2164d6 |
#!/usr/bin/python
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+## Copyright (C) 2014 ABRT team <abrt-devel-list@redhat.com>
|
|
Jakub Filak |
2164d6 |
+## Copyright (C) 2014 Red Hat, Inc.
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+## This program is free software; you can redistribute it and/or modify
|
|
Jakub Filak |
2164d6 |
+## it under the terms of the GNU General Public License as published by
|
|
Jakub Filak |
2164d6 |
+## the Free Software Foundation; either version 2 of the License, or
|
|
Jakub Filak |
2164d6 |
+## (at your option) any later version.
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+## This program is distributed in the hope that it will be useful,
|
|
Jakub Filak |
2164d6 |
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Jakub Filak |
2164d6 |
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Jakub Filak |
2164d6 |
+## GNU General Public License for more details.
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+## You should have received a copy of the GNU General Public License
|
|
Jakub Filak |
2164d6 |
+## along with this program; if not, write to the Free Software
|
|
Jakub Filak |
2164d6 |
+## Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+"""This module provides algorithms for generating Machine IDs.
|
|
Jakub Filak |
2164d6 |
+"""
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+import sys
|
|
Jakub Filak |
2164d6 |
from argparse import ArgumentParser
|
|
Jakub Filak |
2164d6 |
+import logging
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
-import dmidecode
|
|
Jakub Filak |
2164d6 |
import hashlib
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
+def generate_machine_id_dmidecode():
|
|
Jakub Filak |
2164d6 |
+ """Generate a machine_id based off dmidecode fields
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
-# Generate a machine_id based off dmidecode fields
|
|
Jakub Filak |
2164d6 |
-def generate_machine_id():
|
|
Jakub Filak |
2164d6 |
- dmixml = dmidecode.dmidecodeXML()
|
|
Jakub Filak |
2164d6 |
+ The function generates the same result as sosreport-uploader
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Returns a machine ID as string or throws RuntimeException
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ """
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
+ try:
|
|
Jakub Filak |
2164d6 |
+ import dmidecode
|
|
Jakub Filak |
2164d6 |
+ except ImportError as ex:
|
|
Jakub Filak |
2164d6 |
+ raise RuntimeError("Could not import dmidecode module: {0}"
|
|
Jakub Filak |
2164d6 |
+ .format(str(ex)))
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ dmixml = dmidecode.dmidecodeXML()
|
|
Jakub Filak |
2164d6 |
# Fetch all DMI data into a libxml2.xmlDoc object
|
|
Jakub Filak |
2164d6 |
dmixml.SetResultType(dmidecode.DMIXML_DOC)
|
|
Jakub Filak |
2164d6 |
xmldoc = dmixml.QuerySection('all')
|
|
Jakub Filak |
2164d6 |
@@ -38,20 +71,128 @@ def generate_machine_id():
|
|
Jakub Filak |
2164d6 |
return machine_id.hexdigest()
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
-if __name__ == "__main__":
|
|
Jakub Filak |
2164d6 |
- CMDARGS = ArgumentParser(description = "Generate a machine_id based off dmidecode fields")
|
|
Jakub Filak |
2164d6 |
- CMDARGS.add_argument('-o', '--output', type=str, help='Output file')
|
|
Jakub Filak |
2164d6 |
+def generate_machine_id_systemd():
|
|
Jakub Filak |
2164d6 |
+ """Generate a machine_id equals to a one generated by systemd
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ This function returns contents of /etc/machine-id
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Returns a machine ID as string or throws RuntimeException.
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ """
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ try:
|
|
Jakub Filak |
2164d6 |
+ with open('/etc/machine-id', 'r') as midf:
|
|
Jakub Filak |
2164d6 |
+ return "".join((l.strip() for l in midf))
|
|
Jakub Filak |
2164d6 |
+ except IOError as ex:
|
|
Jakub Filak |
2164d6 |
+ raise RuntimeError("Could not use systemd's machine-id: {0}"
|
|
Jakub Filak |
2164d6 |
+ .format(str(ex)))
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+GENERATORS = { 'sosreport_uploader-dmidecode' : generate_machine_id_dmidecode,
|
|
Jakub Filak |
2164d6 |
+ 'systemd' : generate_machine_id_systemd }
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+def generate_machine_id(generators):
|
|
Jakub Filak |
2164d6 |
+ """Generates all requested machine id with all required generators
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Keyword arguments:
|
|
Jakub Filak |
2164d6 |
+ generators -- a list of generator names
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Returns a dictionary where keys are generators and associated values are
|
|
Jakub Filak |
2164d6 |
+ products of those generators.
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ """
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ ids = {}
|
|
Jakub Filak |
2164d6 |
+ workers = GENERATORS
|
|
Jakub Filak |
2164d6 |
+ for sd in generators:
|
|
Jakub Filak |
2164d6 |
+ try:
|
|
Jakub Filak |
2164d6 |
+ ids[sd] = workers[sd]()
|
|
Jakub Filak |
2164d6 |
+ except RuntimeError as ex:
|
|
Jakub Filak |
2164d6 |
+ logging.error("Machine-ID generator '{0}' failed: {1}"
|
|
Jakub Filak |
2164d6 |
+ .format(sd, ex.message))
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ return ids
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+def print_result(ids, outfile, prefixed):
|
|
Jakub Filak |
2164d6 |
+ """Writes a dictionary of machine ids to a file
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Each dictionary entry is written on a single line and the last line does
|
|
Jakub Filak |
2164d6 |
+ not have new line character. The new line character is omitted as it is a
|
|
Jakub Filak |
2164d6 |
+ common approach in ABRT.
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Keyword arguments:
|
|
Jakub Filak |
2164d6 |
+ ids -- a dictionary [generator name: machine ids]
|
|
Jakub Filak |
2164d6 |
+ outfile -- output file
|
|
Jakub Filak |
2164d6 |
+ prefixed -- use 'generator name=' prefix or not
|
|
Jakub Filak |
2164d6 |
+ """
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ fmt = '{0}={1}' if prefixed else '{1}'
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ items_iter = ids.iteritems()
|
|
Jakub Filak |
2164d6 |
+ try:
|
|
Jakub Filak |
2164d6 |
+ sd, mid = items_iter.next()
|
|
Jakub Filak |
2164d6 |
+ outfile.write(fmt.format(sd, mid))
|
|
Jakub Filak |
2164d6 |
+ except StopIteration:
|
|
Jakub Filak |
2164d6 |
+ return
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ fmt = '\n' + fmt
|
|
Jakub Filak |
2164d6 |
+ for sd, mid in items_iter:
|
|
Jakub Filak |
2164d6 |
+ outfile.write(fmt.format(sd,mid))
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+def print_generators(outfile=None):
|
|
Jakub Filak |
2164d6 |
+ """Prints requested generators
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ Keyword arguments:
|
|
Jakub Filak |
2164d6 |
+ outfile -- output file (default: sys.stdout)
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ """
|
|
Jakub Filak |
2164d6 |
+ if outfile is None:
|
|
Jakub Filak |
2164d6 |
+ outfile = sys.stdout
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ for sd in GENERATORS.iterkeys():
|
|
Jakub Filak |
2164d6 |
+ outfile.write("{0}\n".format(sd))
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+if __name__ == '__main__':
|
|
Jakub Filak |
2164d6 |
+ CMDARGS = ArgumentParser(description = "Generate a machine_id")
|
|
Jakub Filak |
2164d6 |
+ CMDARGS.add_argument('-o', '--output', type=str,
|
|
Jakub Filak |
2164d6 |
+ help="Output file")
|
|
Jakub Filak |
2164d6 |
+ CMDARGS.add_argument('-g', '--generators', nargs='+', type=str,
|
|
Jakub Filak |
2164d6 |
+ help="Use given generators only")
|
|
Jakub Filak |
2164d6 |
+ CMDARGS.add_argument('-l', '--list-generators', action='store_true',
|
|
Jakub Filak |
2164d6 |
+ default=False, help="Print out a list of usable generators")
|
|
Jakub Filak |
2164d6 |
+ CMDARGS.add_argument('-n', '--noprefix', action='store_true',
|
|
Jakub Filak |
2164d6 |
+ default=False, help="Do not use generator name as prefix for IDs")
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
OPTIONS = CMDARGS.parse_args()
|
|
Jakub Filak |
2164d6 |
ARGS = vars(OPTIONS)
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
- machineid = generate_machine_id()
|
|
Jakub Filak |
2164d6 |
+ logging.basicConfig(format='%(message)s')
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ if ARGS['list_generators']:
|
|
Jakub Filak |
2164d6 |
+ print_generators()
|
|
Jakub Filak |
2164d6 |
+ sys.exit(0)
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ requested_generators = None
|
|
Jakub Filak |
2164d6 |
+ if ARGS['generators']:
|
|
Jakub Filak |
2164d6 |
+ requested_generators = ARGS['generators']
|
|
Jakub Filak |
2164d6 |
+ else:
|
|
Jakub Filak |
2164d6 |
+ requested_generators = GENERATORS.keys()
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ machineids = generate_machine_id(requested_generators)
|
|
Jakub Filak |
2164d6 |
|
|
Jakub Filak |
2164d6 |
if ARGS['output']:
|
|
Jakub Filak |
2164d6 |
try:
|
|
Jakub Filak |
2164d6 |
- with open(ARGS['output'], 'w') as outfile:
|
|
Jakub Filak |
2164d6 |
- outfile.write(machineid)
|
|
Jakub Filak |
2164d6 |
+ with open(ARGS['output'], 'w') as fout:
|
|
Jakub Filak |
2164d6 |
+ print_result(machineids, fout, not ARGS['noprefix'])
|
|
Jakub Filak |
2164d6 |
except IOError as ex:
|
|
Jakub Filak |
2164d6 |
- print ex
|
|
Jakub Filak |
2164d6 |
+ logging.error("Could not open output file: {0}".format(str(ex)))
|
|
Jakub Filak |
2164d6 |
+ sys.exit(1)
|
|
Jakub Filak |
2164d6 |
else:
|
|
Jakub Filak |
2164d6 |
- print machineid
|
|
Jakub Filak |
2164d6 |
+ print_result(machineids, sys.stdout, not ARGS['noprefix'])
|
|
Jakub Filak |
2164d6 |
+ sys.stdout.write('\n')
|
|
Jakub Filak |
2164d6 |
+
|
|
Jakub Filak |
2164d6 |
+ sys.exit(len(requested_generators) - len(machineids.keys()))
|
|
Jakub Filak |
2164d6 |
--
|
|
Jakub Filak |
2164d6 |
2.1.0
|
|
Jakub Filak |
2164d6 |
|