From 256950db729a9b85758b064b29e698be15c5d5ac Mon Sep 17 00:00:00 2001 From: Promaethius Date: Sun, 23 Sep 2018 19:45:42 -0700 Subject: [PATCH 01/16] Init PR Add dnf bindings for python --- deps.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deps.txt b/deps.txt index 52ce40edd7..01f2a55359 100644 --- a/deps.txt +++ b/deps.txt @@ -11,6 +11,9 @@ rpm-ostree # rpmdistro-gitoverlay deps dnf-plugins-core createrepo_c dnf-utils fedpkg openssh-clients rpmdistro-gitoverlay +# coreos-assembler analyze +python3-dnf + # Currently a transitive req of rpmdistro-gitoverlay via mock, but we # expect people to use these explicitly in their repo configurations. distribution-gpg-keys From cd1437e2e30c009ed109ecb4809ff52aa49e0e09 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 24 Sep 2018 15:47:18 -0700 Subject: [PATCH 02/16] Create cmd-analyze shell script to act as interface between init filesystem and the dnf python program. analyze.py will take a list of comma separated packages, repos, and output formatting flags. --- src/cmd-analyze | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/cmd-analyze diff --git a/src/cmd-analyze b/src/cmd-analyze new file mode 100644 index 0000000000..3a0b60cd4f --- /dev/null +++ b/src/cmd-analyze @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +dn=$(dirname $0) +. ${dn}/cmdlib.sh + +print_help() { + cat 1>&2 <<'EOF' +Usage: coreos-assembler analyze --help + +EOF +} + +# Call getopt to validate the provided input. +options=$(getopt --options hf --longoptions help,force -- "$@") +[ $? -eq 0 ] || { + print_help + exit 1 +} +eval set -- "$options" +while true; do + case "$1" in + -h | --help) + print_help + exit 0 + ;; + *) + print_help + fatal "init: unrecognized option: $1" + exit 1 + ;; + esac + shift +done + +# LOOP: if rpm-ostree-entrypoint.yaml exist; do +# append PKG[] with "*.yaml"."packages*" +# if "*.yaml"."include" exist; LOOP +# else; improper coreos-assembler init + +# analyze.py $PKG $REPOS $FLAGS From 67e1890901d4c236419b99520b7c9b99b8841979 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 24 Sep 2018 15:52:12 -0700 Subject: [PATCH 03/16] analyze: Build command Added analyze to the build command list --- coreos-assembler | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreos-assembler b/coreos-assembler index 18b99d8935..0749f030fd 100755 --- a/coreos-assembler +++ b/coreos-assembler @@ -19,7 +19,7 @@ if [ -e /sys/fs/selinux/status ]; then fi cmd=${1:-} -build_commands="init fetch build run clean" +build_commands="init fetch analyze build run clean" other_commands="shell" utility_commands="gf-oemid virt-install" if [ -z "${cmd}" ]; then From fe6890833f16e0d1f8afd7740e5a6cceb1698636 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 24 Sep 2018 15:55:29 -0700 Subject: [PATCH 04/16] analyze: Create dnf python script placeholder This script uses the libdnf library to download repo metadata into a sack and run queries off of the packages. Specifically, the tree sizes, repetition, and interpreted language dependencies. --- src/dnf-analyze | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/dnf-analyze diff --git a/src/dnf-analyze b/src/dnf-analyze new file mode 100644 index 0000000000..dce7acb266 --- /dev/null +++ b/src/dnf-analyze @@ -0,0 +1,3 @@ +#!/usr/bin/python + +# PLACEHOLDER From 0fbb53cf013d9c29c3fc06e28b08b67b3d5e7214 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 24 Sep 2018 16:04:33 -0700 Subject: [PATCH 05/16] analyze: Args Flesh out the arguments required for dnf-analyze --- src/dnf-analyze | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index dce7acb266..2f8d7ec30d 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -1,3 +1,22 @@ -#!/usr/bin/python +#!/usr/bin/python3 + +import dnf,argparse,sys + +def fatal(msg): + print('error: {}'.format(msg), file=sys.stderr) + raise SystemExit(1) + +parser = argparse.ArgumentParser() +parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", + action='store', required=True) +parser.add_argument("--repo-dir", help="Directory which stores all .repo definitions.", + action='store', required=True) +parser.add_argument("--log", help="If set, log to file and stdout.", + action='store') +parser.add_argument("--size", help="Display total dependency tree size.", + action='store_true') +parser.add_argument("--exit-on", help="Emphasize interpreted dependencies through 'exit 1'", + action='store_true') +args = parser.parse_args() # PLACEHOLDER From b01b69199cefe6b7edb76507106430bad932ff36 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 24 Sep 2018 19:52:10 -0700 Subject: [PATCH 06/16] analyze: WIP Continuation --- src/dnf-analyze | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/dnf-analyze b/src/dnf-analyze index 2f8d7ec30d..03e4d85c86 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -19,4 +19,20 @@ parser.add_argument("--exit-on", help="Emphasize interpreted dependencies throug action='store_true') args = parser.parse_args() +# Split comma delimited packages into an array. +base_packages = args.packages.split(",") + +# Init dnf config. +base_config = dnf.conf.Conf +base_config.assumeyes = true +base_config.best = true +if args.log: + base_config.logdir = args.log +else: + base_config.logdir = "/dev/null" +base_config.reposdir = args.repo_dir + +base = dnf.Base() +base.fill_sack([load_system_repo=False, load_available_repos=True]) + # PLACEHOLDER From b83d081a337fdbe7b7a095a4062de8eb05b014a9 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 24 Sep 2018 22:25:17 -0700 Subject: [PATCH 07/16] analyze: config, repos, fill sack Finished base.conf which searches for .repo files to add in the passed --repo-dir. Fill sack based off those repos. --- src/dnf-analyze | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index 03e4d85c86..e765b9d232 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -6,6 +6,8 @@ def fatal(msg): print('error: {}'.format(msg), file=sys.stderr) raise SystemExit(1) +def + parser = argparse.ArgumentParser() parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", action='store', required=True) @@ -22,17 +24,27 @@ args = parser.parse_args() # Split comma delimited packages into an array. base_packages = args.packages.split(",") -# Init dnf config. -base_config = dnf.conf.Conf +# Init dnf object. +base = dnf.Base() + +# Dnf config. +base_config = base.conf base_config.assumeyes = true base_config.best = true +base_config.cachedir = "/tmp/dnf" if args.log: base_config.logdir = args.log else: base_config.logdir = "/dev/null" base_config.reposdir = args.repo_dir -base = dnf.Base() +print("Repos Enabled:") +for x in base.repos.all(): + print(x) + +print("Filling Sack...") base.fill_sack([load_system_repo=False, load_available_repos=True]) +q = base.sack.query() + # PLACEHOLDER From 976ecb761ada5b429d30de4ae1c513f024d8c74b Mon Sep 17 00:00:00 2001 From: Promaethius Date: Tue, 25 Sep 2018 13:46:38 -0700 Subject: [PATCH 08/16] analyze: WIP --- src/dnf-analyze | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index e765b9d232..64430aaba6 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -6,8 +6,6 @@ def fatal(msg): print('error: {}'.format(msg), file=sys.stderr) raise SystemExit(1) -def - parser = argparse.ArgumentParser() parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", action='store', required=True) @@ -29,8 +27,8 @@ base = dnf.Base() # Dnf config. base_config = base.conf -base_config.assumeyes = true -base_config.best = true +base_config.assumeyes = "true" +base_config.best = "true" base_config.cachedir = "/tmp/dnf" if args.log: base_config.logdir = args.log @@ -38,13 +36,8 @@ else: base_config.logdir = "/dev/null" base_config.reposdir = args.repo_dir -print("Repos Enabled:") -for x in base.repos.all(): - print(x) - -print("Filling Sack...") -base.fill_sack([load_system_repo=False, load_available_repos=True]) - -q = base.sack.query() +# Parse repos in dir and fill sack. +base.read_all_repos() +base.fill_sack() # PLACEHOLDER From 306074bd7c5ee305e347dff501c2692e8e0654f7 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Wed, 26 Sep 2018 14:28:59 -0700 Subject: [PATCH 09/16] analyze: Node Tree Implement a node tree which prevents infinite recursive dependency loops. Class type contains a list of children, a generation number (for printed tree indentation), and pkg_meta which contains dnf.package.Package class. --- src/dnf-analyze | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index 64430aaba6..48d21ce8f1 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -2,9 +2,31 @@ import dnf,argparse,sys -def fatal(msg): - print('error: {}'.format(msg), file=sys.stderr) - raise SystemExit(1) +# type(self.children) = type(self.pkg_meta) = type(dnf.package.Package) +# https://dnf.readthedocs.io/en/latest/api_package.html#dnf.package.Package +# type(self.name) = str +# type(self.generation) = int +class Package(object): + def findChildren(self): + # First, prevent recursive scans i.e. glib requires glib translations which require glib. + # However, this cannot be done in a way where each node is aware of the rest of the tree; this would result in an incomplete dependency tree. + toScan = [] + for x in self.pkg_meta.requires: + if x not in self.scanned: + self.scanned.append(x) + toScan.append(x) + # Scan the packages which do not already exist in this tree path but pass in the whole tree path to the next child. + for x in toScan: + self.children.append(Package(self.query, self.generation, x, self.scanned) + + def __init__(self, query, generation, pkg, scanned): + self.generation = generation + 1 + #TODO: depending on types, use the passed query object to find more dnf.package.Package types. + self.pkg_meta = pkg + self.children = [] + self.scanned = scanned + findChildren() + parser = argparse.ArgumentParser() parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", @@ -40,4 +62,8 @@ base_config.reposdir = args.repo_dir base.read_all_repos() base.fill_sack() +query = base.sack.query() + + + # PLACEHOLDER From c42327197d406668b9035f59a4164d698ccddc8c Mon Sep 17 00:00:00 2001 From: Promaethius Date: Wed, 26 Sep 2018 14:36:50 -0700 Subject: [PATCH 10/16] analyze: interpretation discovery --- src/dnf-analyze | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index 48d21ce8f1..2e6d33199e 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -2,6 +2,8 @@ import dnf,argparse,sys +interpretedPkg = ["python", "perl"] + # type(self.children) = type(self.pkg_meta) = type(dnf.package.Package) # https://dnf.readthedocs.io/en/latest/api_package.html#dnf.package.Package # type(self.name) = str @@ -17,14 +19,25 @@ class Package(object): toScan.append(x) # Scan the packages which do not already exist in this tree path but pass in the whole tree path to the next child. for x in toScan: - self.children.append(Package(self.query, self.generation, x, self.scanned) + self.children.append(Package(self.query, self.generation, x, self.scanned)) + + def interpreted(self): + # For each package listed as examples for interpreted languages... + for x in interpretedPkg: + # If one is found in the Package.pkg_meta.name, then label this Package object as an interpreted object. + if x in self.pkg_meta.name: + self.interpreted = "true" def __init__(self, query, generation, pkg, scanned): self.generation = generation + 1 - #TODO: depending on types, use the passed query object to find more dnf.package.Package types. self.pkg_meta = pkg self.children = [] self.scanned = scanned + self.interpreted = "false" + + #TODO: query logic + + interpreted() findChildren() From 52fe7761b28be3f3cbc50de136db625a8f1f1ccd Mon Sep 17 00:00:00 2001 From: Promaethius Date: Thu, 27 Sep 2018 00:06:21 -0700 Subject: [PATCH 11/16] analyze: printChildren Display the children in a tree --- src/dnf-analyze | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index 2e6d33199e..c3046acabf 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -1,6 +1,6 @@ #!/usr/bin/python3 -import dnf,argparse,sys +import dnf,argparse,sys,math interpretedPkg = ["python", "perl"] @@ -9,6 +9,14 @@ interpretedPkg = ["python", "perl"] # type(self.name) = str # type(self.generation) = int class Package(object): + def printChildren(self): + # For each child of the type Package(object) + for x in self.children: + # Print a dash according to the generation and then the child's name contained in the package definition. + printColor('-' * self.generation, x.pkg_meta.name, ' size: ', x.pkg_meta.downloadsize / 2^20 ) + # Then call each child's children causing a tree. + x.printChildren() + def findChildren(self): # First, prevent recursive scans i.e. glib requires glib translations which require glib. # However, this cannot be done in a way where each node is aware of the rest of the tree; this would result in an incomplete dependency tree. @@ -29,6 +37,7 @@ class Package(object): self.interpreted = "true" def __init__(self, query, generation, pkg, scanned): + # VARS self.generation = generation + 1 self.pkg_meta = pkg self.children = [] @@ -37,6 +46,7 @@ class Package(object): #TODO: query logic + # INIT LOGIC interpreted() findChildren() From 4d3151ad9df789d6d2d357cb045f2a05b220d5de Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 1 Oct 2018 17:21:31 -0700 Subject: [PATCH 12/16] analyze: Globals, hawkey.reqdep Reformatted how the hawkey objects are handled. Query is now global which saves memory space per package. --- src/dnf-analyze | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index c3046acabf..6696bbb925 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -1,13 +1,11 @@ #!/usr/bin/python3 +# GLOBAL import dnf,argparse,sys,math - interpretedPkg = ["python", "perl"] +query = dnf.query.Query -# type(self.children) = type(self.pkg_meta) = type(dnf.package.Package) -# https://dnf.readthedocs.io/en/latest/api_package.html#dnf.package.Package -# type(self.name) = str -# type(self.generation) = int +# CLASS class Package(object): def printChildren(self): # For each child of the type Package(object) @@ -22,12 +20,15 @@ class Package(object): # However, this cannot be done in a way where each node is aware of the rest of the tree; this would result in an incomplete dependency tree. toScan = [] for x in self.pkg_meta.requires: - if x not in self.scanned: - self.scanned.append(x) - toScan.append(x) + # Convert hawkey.ReqDep to string. + i = str(x) + if i not in self.scanned: + self.scanned.append(i) + toScan.append(i) # Scan the packages which do not already exist in this tree path but pass in the whole tree path to the next child. for x in toScan: - self.children.append(Package(self.query, self.generation, x, self.scanned)) + j = query.filter(name=x,latest=True) + self.children.append(Package(query,self.generation,j[0],self.scanned)) def interpreted(self): # For each package listed as examples for interpreted languages... @@ -36,21 +37,19 @@ class Package(object): if x in self.pkg_meta.name: self.interpreted = "true" - def __init__(self, query, generation, pkg, scanned): - # VARS + def __init__(self,generation,pkg,scanned): + # ATTR self.generation = generation + 1 self.pkg_meta = pkg self.children = [] self.scanned = scanned self.interpreted = "false" - #TODO: query logic - - # INIT LOGIC + # METHOD interpreted() findChildren() - +# CLI ENTRYPOINT parser = argparse.ArgumentParser() parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", action='store', required=True) @@ -78,15 +77,20 @@ base_config.cachedir = "/tmp/dnf" if args.log: base_config.logdir = args.log else: - base_config.logdir = "/dev/null" + base_config.logdir = "/var/log" base_config.reposdir = args.repo_dir -# Parse repos in dir and fill sack. +# Parse repos in dir and fill sack without system rpm scanning. base.read_all_repos() -base.fill_sack() +base.fill_sack(load_system_repo=False,load_available_repos=True) +# Init query object on new sack. From here on out, no changes are made to query. query = base.sack.query() - - -# PLACEHOLDER +# Replace each element in the base_packages array with a Packages object. +for x in range(0,len(base_packages)): + i = base_packages[x] + # Assuming best first, get latest package. + j = query.filter(name=i,latest=True) + # Use first item in j JIC. + base_packages[x] = Package(query,0,j[0],"") From 9da54d40c07512a7a865e34edaf6030a431c4dc4 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 1 Oct 2018 17:57:15 -0700 Subject: [PATCH 13/16] analyze: misc, globals, printTree Miscellaneous corrections. Global variables and classes. Changed printChildren to printTree for a cleaner traversal. --- src/dnf-analyze | 70 +++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index 6696bbb925..900536c281 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -2,18 +2,40 @@ # GLOBAL import dnf,argparse,sys,math -interpretedPkg = ["python", "perl"] +interpretedLabel = ["python", "perl"] +interpretedPkg = [] query = dnf.query.Query +# CLI ENTRYPOINT +parser = argparse.ArgumentParser() +parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", + action='store', required=True) +parser.add_argument("--repo-dir", help="Directory which stores all .repo definitions.", + action='store', required=True) +parser.add_argument("--log", help="If set, log to file and stdout.", + action='store') +parser.add_argument("--size", help="Display total dependency tree size.", + action='store_true') +parser.add_argument("--exit-on", help="Emphasize interpreted dependencies through 'exit 1'", + action='store_true') +args = parser.parse_args() + # CLASS class Package(object): - def printChildren(self): - # For each child of the type Package(object) + def printTree(self): + # Make an indentation format for easier read. + ind = '-' * self.generation + # Print dnf.package.Package.name. + print(ind + self.pkg_meta.name) + # Print size in MB if args.size. + if args.size: + print(ind + 'size: ' + (self.pkg_meta.downloadsize / 2^20)) + # Print number of depends. + print(ind + 'depends: ' + len(self.children)) + # Print if it is interpreted. + print(ind + 'isInterpreted: ' + str(self.interpreted)) for x in self.children: - # Print a dash according to the generation and then the child's name contained in the package definition. - printColor('-' * self.generation, x.pkg_meta.name, ' size: ', x.pkg_meta.downloadsize / 2^20 ) - # Then call each child's children causing a tree. - x.printChildren() + x.printTree() def findChildren(self): # First, prevent recursive scans i.e. glib requires glib translations which require glib. @@ -32,10 +54,13 @@ class Package(object): def interpreted(self): # For each package listed as examples for interpreted languages... - for x in interpretedPkg: + for x in interpretedLabel: # If one is found in the Package.pkg_meta.name, then label this Package object as an interpreted object. if x in self.pkg_meta.name: - self.interpreted = "true" + self.interpreted = True + # If this package already hasn't been scanned, labeled interpreted, and placed in interpretedPkg, place in interpretedPkg. + if self.pkg_meta.name not in interpretedPkg: + interpretedPkg.append(self.pkg_meta.name) def __init__(self,generation,pkg,scanned): # ATTR @@ -43,33 +68,19 @@ class Package(object): self.pkg_meta = pkg self.children = [] self.scanned = scanned - self.interpreted = "false" + self.interpreted = False # METHOD interpreted() findChildren() - -# CLI ENTRYPOINT -parser = argparse.ArgumentParser() -parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", - action='store', required=True) -parser.add_argument("--repo-dir", help="Directory which stores all .repo definitions.", - action='store', required=True) -parser.add_argument("--log", help="If set, log to file and stdout.", - action='store') -parser.add_argument("--size", help="Display total dependency tree size.", - action='store_true') -parser.add_argument("--exit-on", help="Emphasize interpreted dependencies through 'exit 1'", - action='store_true') -args = parser.parse_args() # Split comma delimited packages into an array. base_packages = args.packages.split(",") -# Init dnf object. +# Init DNF object. base = dnf.Base() -# Dnf config. +# DNF config. base_config = base.conf base_config.assumeyes = "true" base_config.best = "true" @@ -94,3 +105,10 @@ for x in range(0,len(base_packages)): j = query.filter(name=i,latest=True) # Use first item in j JIC. base_packages[x] = Package(query,0,j[0],"") + +# Major print functions. +for x in base_backages: + x.printTree() +for x in interpreted: + print('Interpreted Package: ' + x) +print('Total Interpreted Packages: ' + len(interpreted)) From 965816268fbefb3e590a413107dcab7a4029a30b Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 1 Oct 2018 18:09:52 -0700 Subject: [PATCH 14/16] analyze: TODO Print: Base packages introduce interpreted dependencies. Packages which require interpreted dependencies. --- src/dnf-analyze | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dnf-analyze b/src/dnf-analyze index 900536c281..f31189204d 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -112,3 +112,5 @@ for x in base_backages: for x in interpreted: print('Interpreted Package: ' + x) print('Total Interpreted Packages: ' + len(interpreted)) +# TODO: print which base packages introduce interpreted dependencies. +# TODO: print which packages require interpreted dependencies. From 8bf6f45ae895fda3fba0bc349e70d6975e38c46a Mon Sep 17 00:00:00 2001 From: Promaethius Date: Mon, 1 Oct 2018 19:59:22 -0700 Subject: [PATCH 15/16] analyze: CLI Validation, exit Added validation for CLI inputs except for the string representing the package list. Added exit commands for CLI exceptions and --exit-on --- src/dnf-analyze | 50 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index f31189204d..a7d67a2493 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -1,25 +1,40 @@ #!/usr/bin/python3 # GLOBAL -import dnf,argparse,sys,math +import dnf,argparse,os,math interpretedLabel = ["python", "perl"] interpretedPkg = [] query = dnf.query.Query # CLI ENTRYPOINT parser = argparse.ArgumentParser() -parser.add_argument("--packages", help="Comma Separated list of packages to analyze.", - action='store', required=True) -parser.add_argument("--repo-dir", help="Directory which stores all .repo definitions.", - action='store', required=True) -parser.add_argument("--log", help="If set, log to file and stdout.", - action='store') -parser.add_argument("--size", help="Display total dependency tree size.", - action='store_true') -parser.add_argument("--exit-on", help="Emphasize interpreted dependencies through 'exit 1'", - action='store_true') +parser.add_argument('--packages',help='Comma Separated list of packages to analyze.',action='store', required=True) +parser.add_argument('--repo-dir',help='Directory which stores all .repo definitions.',action='store', required=True) +parser.add_argument('--log-dir',help='If set, log to file and stdout.',action='store') +parser.add_argument('--size',help="Display total dependency tree size.",action='store_true') +parser.add_argument('--exit-on',help="Emphasize interpreted dependencies through 'exit 1'",action='store_true') args = parser.parse_args() +# CLI VERIFY +def directoryExists(path): + if os.path.isdir(path): + if os.access(path, os.W_OK): + return True + return False + +if not directoryExists(args.repo_dir): + print('Bad Repo Directory.') + exit(1) +if not directoryExists(args.log-dir): + print('Bad Log Directory.') + exit(1) +if (args.size != True) or (args.size != False): + print('Size must be set to True or False.') + exit(1) +if (args.exit_on != True) or (args.exit_on != False): + print('Exit On must be set to True or False.') + exit(1) + # CLASS class Package(object): def printTree(self): @@ -109,8 +124,15 @@ for x in range(0,len(base_packages)): # Major print functions. for x in base_backages: x.printTree() -for x in interpreted: - print('Interpreted Package: ' + x) -print('Total Interpreted Packages: ' + len(interpreted)) + +if len(interpreted) > 0: + for x in interpreted: + print('Interpreted Package: ' + x) + print('Total Interpreted Packages: ' + len(interpreted)) + if args.exit_on: + exit(1) + # TODO: print which base packages introduce interpreted dependencies. # TODO: print which packages require interpreted dependencies. + +exit(0) From 21e48476ec52952fcaa8662ee827f7e297273be2 Mon Sep 17 00:00:00 2001 From: Promaethius Date: Tue, 2 Oct 2018 12:23:34 -0700 Subject: [PATCH 16/16] analyze: log-dir, cache dir Change log-dir logic to default during validation. Changed cache dir to system default (prevents having to download metadata twice). --- src/dnf-analyze | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/dnf-analyze b/src/dnf-analyze index a7d67a2493..71efb96b82 100644 --- a/src/dnf-analyze +++ b/src/dnf-analyze @@ -25,9 +25,9 @@ def directoryExists(path): if not directoryExists(args.repo_dir): print('Bad Repo Directory.') exit(1) -if not directoryExists(args.log-dir): - print('Bad Log Directory.') - exit(1) +if not directoryExists(args.log_dir): + print('Bad Log Directory: Defaulting to /var/log') + args.log_dir = '/var/log' if (args.size != True) or (args.size != False): print('Size must be set to True or False.') exit(1) @@ -99,11 +99,8 @@ base = dnf.Base() base_config = base.conf base_config.assumeyes = "true" base_config.best = "true" -base_config.cachedir = "/tmp/dnf" -if args.log: - base_config.logdir = args.log -else: - base_config.logdir = "/var/log" +base_config.cachedir = "/var/cache/dnf" +base_config.logdir = args.log base_config.reposdir = args.repo_dir # Parse repos in dir and fill sack without system rpm scanning.