Merge ~dannf/canonical-server-hwe-utils:pre-commit into canonical-server-hwe-utils:master

Proposed by dann frazier
Status: Merged
Approved by: Alexandre Erwin Ittner
Approved revision: fe32deedec72a723de836d21e49b32632e8c742a
Merged at revision: fe32deedec72a723de836d21e49b32632e8c742a
Proposed branch: ~dannf/canonical-server-hwe-utils:pre-commit
Merge into: canonical-server-hwe-utils:master
Diff against target: 2123 lines (+790/-499)
18 files modified
.pre-commit-config.yaml (+10/-0)
labkey (+95/-71)
lp-scripts/LaunchpadBugBucketer.py (+5/-5)
lp-scripts/bandera-bug-csv-summary.py (+8/-7)
lp-scripts/bugreport/bugreport.py (+143/-81)
lp-scripts/clone-project-milestones.py (+21/-18)
lp-scripts/dump-bug-subscribers.py (+26/-14)
lp-scripts/lp-bulk-action.py (+46/-41)
lp-scripts/pearl-biweekly-bug-report-csv4.py (+87/-47)
lp-scripts/pearl-biweekly-report-csv.py (+78/-40)
lp-scripts/pearl-biweekly-report.csv.py (+93/-53)
lp-scripts/pearl-bug-csv-summary.py (+8/-7)
lp-scripts/pearl-risky-patch-schedule.py (+12/-10)
lp-scripts/pearl2-biweekly-report.csv.py (+60/-44)
lp-scripts/pearl2-d06-18.04-patch-status.py (+18/-13)
lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py (+14/-10)
lp-scripts/project-bug-lint.py (+54/-26)
sysadmin-tools/gen_conserver_cf.py (+12/-12)
Reviewer Review Type Date Requested Status
Alexandre Erwin Ittner Approve
Review via email: mp+383616@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alexandre Erwin Ittner (aittner) wrote :

The python-black + pre-commit that we already agreed upon and code reformatting. Clear approval!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
0new file mode 1006440new file mode 100644
index 0000000..5f7fa9a
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,10 @@
1repos:
2 - repo: https://github.com/psf/black
3 rev: stable
4 hooks:
5 - id: black
6 language_version: python3.8
7 - repo: https://gitlab.com/pycqa/flake8
8 rev: master
9 hooks:
10 - id: flake8
diff --git a/labkey b/labkey
index fe3f4ae..47f996b 100755
--- a/labkey
+++ b/labkey
@@ -9,8 +9,8 @@ import sys
9import yaml9import yaml
1010
11ProgName = "labkey"11ProgName = "labkey"
12Config = os.path.join(os.environ['HOME'], '.config', ProgName)12Config = os.path.join(os.environ["HOME"], ".config", ProgName)
13ScaleBotLocal = os.path.join(Config, 'scalebot-repo')13ScaleBotLocal = os.path.join(Config, "scalebot-repo")
1414
1515
16def update(lpid, force):16def update(lpid, force):
@@ -22,34 +22,31 @@ def update(lpid, force):
22 shutil.rmtree(ScaleBotLocal)22 shutil.rmtree(ScaleBotLocal)
2323
24 ScaleBotRemote = "git+ssh://%sgit.launchpad.net/scalebot" % (user)24 ScaleBotRemote = "git+ssh://%sgit.launchpad.net/scalebot" % (user)
25 umaskSav = os.umask(int('077', 8))25 umaskSav = os.umask(int("077", 8))
26 if os.path.exists(ScaleBotLocal):26 if os.path.exists(ScaleBotLocal):
27 os.chdir(ScaleBotLocal)27 os.chdir(ScaleBotLocal)
28 subprocess.run(['git', 'pull'], check=True)28 subprocess.run(["git", "pull"], check=True)
29 else:29 else:
30 subprocess.run(['git', 'clone',30 subprocess.run(["git", "clone", ScaleBotRemote, ScaleBotLocal], check=True)
31 ScaleBotRemote, ScaleBotLocal],
32 check=True)
33 os.umask(umaskSav)31 os.umask(umaskSav)
3432
3533
36def loadLabs():34def loadLabs():
37 config = []35 config = []
38 labroot = os.path.join(ScaleBotLocal, 'labs')36 labroot = os.path.join(ScaleBotLocal, "labs")
39 for labdir in os.scandir(labroot):37 for labdir in os.scandir(labroot):
40 if not labdir.is_dir():38 if not labdir.is_dir():
41 continue39 continue
42 lab = None40 lab = None
43 machines = None41 machines = None
44 for f in os.scandir(labdir):42 for f in os.scandir(labdir):
45 if f.name == 'lab.yaml':43 if f.name == "lab.yaml":
46 with open(f.path, 'r') as stream:44 with open(f.path, "r") as stream:
47 lab = yaml.load(stream, Loader=yaml.SafeLoader)45 lab = yaml.load(stream, Loader=yaml.SafeLoader)
48 elif f.name == 'machines.yaml':46 elif f.name == "machines.yaml":
49 with open(f.path, 'r') as stream:47 with open(f.path, "r") as stream:
50 machines = yaml.load(stream, Loader=yaml.SafeLoader)48 machines = yaml.load(stream, Loader=yaml.SafeLoader)
51 config.append({'lab': lab,49 config.append({"lab": lab, "machines": machines})
52 'machines': machines})
53 return config50 return config
5451
5552
@@ -58,96 +55,123 @@ class Machine:
58 self.name = name55 self.name = name
59 labs = loadLabs()56 labs = loadLabs()
60 for lab in labs:57 for lab in labs:
61 if lab['machines'] is None:58 if lab["machines"] is None:
62 continue59 continue
63 if name in lab['machines'].keys():60 if name in lab["machines"].keys():
64 self.data = lab['machines'][name]61 self.data = lab["machines"][name]
65 self.labdata = lab['lab']62 self.labdata = lab["lab"]
66 return63 return
67 raise KeyError('Machine not found')64 raise KeyError("Machine not found")
6865
69 def __repr__(self):66 def __repr__(self):
70 return yaml.dump(self.data, default_flow_style=False)67 return yaml.dump(self.data, default_flow_style=False)
7168
72 def _do_ipmitool(self, cmd):69 def _do_ipmitool(self, cmd):
73 bmc = self.data['bmc']70 bmc = self.data["bmc"]
74 if bmc['type'] != "ipmi":71 if bmc["type"] != "ipmi":
75 raise KeyError('Machine has unknown power type')72 raise KeyError("Machine has unknown power type")
76 subprocess.run(['ipmitool', '-I', 'lanplus',73 subprocess.run(
77 '-H', bmc['address'],74 [
78 '-U', bmc['user'],75 "ipmitool",
79 '-P', bmc['password']] + cmd, check=True)76 "-I",
77 "lanplus",
78 "-H",
79 bmc["address"],
80 "-U",
81 bmc["user"],
82 "-P",
83 bmc["password"],
84 ]
85 + cmd,
86 check=True,
87 )
8088
81 def mc_reset(self):89 def mc_reset(self):
82 cmd = ['mc', 'reset', 'cold']90 cmd = ["mc", "reset", "cold"]
83 self._do_ipmitool(cmd)91 self._do_ipmitool(cmd)
8492
85 def power(self, state):93 def power(self, state):
86 cmd = ['chassis', 'power', state]94 cmd = ["chassis", "power", state]
87 self._do_ipmitool(cmd)95 self._do_ipmitool(cmd)
8896
89 def open_console(self):97 def open_console(self):
90 '''98 """
91 Open an interactive console session to the machine.99 Open an interactive console session to the machine.
92 Currently only supports conserver.100 Currently only supports conserver.
93 '''101 """
94 if self.labdata is None:102 if self.labdata is None:
95 raise KeyError('No lab.yaml associated with %s' % (self.name))103 raise KeyError("No lab.yaml associated with %s" % (self.name))
96 if 'conserver' not in self.labdata.keys():104 if "conserver" not in self.labdata.keys():
97 raise KeyError('No conserver defined for lab %s' %105 raise KeyError("No conserver defined for lab %s" % (self.labdata["name"]))
98 (self.labdata['name']))106 concfg = self.labdata["conserver"]
99 concfg = self.labdata['conserver']107 subprocess.run(
100 subprocess.run(['console', '-M%s' % (concfg['master']),108 [
101 '-p%s' % (concfg['port']),109 "console",
102 self.name],110 "-M%s" % (concfg["master"]),
103 stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)111 "-p%s" % (concfg["port"]),
104 subprocess.run(['console', '-M%s' % (concfg['master']),112 self.name,
105 '-p%s' % (concfg['port']),113 ],
106 self.name],114 stdin=sys.stdin,
107 capture_output=True)115 stdout=sys.stdout,
108116 stderr=sys.stderr,
109117 )
110if __name__ == '__main__':118 subprocess.run(
111 power_cmds = ['on', 'off', 'cycle', 'mc-reset', 'reset', 'status']119 [
112 machine_cmds = power_cmds + ['console', 'show']120 "console",
121 "-M%s" % (concfg["master"]),
122 "-p%s" % (concfg["port"]),
123 self.name,
124 ],
125 capture_output=True,
126 )
127
128
129if __name__ == "__main__":
130 power_cmds = ["on", "off", "cycle", "mc-reset", "reset", "status"]
131 machine_cmds = power_cmds + ["console", "show"]
113 cmd_help = {132 cmd_help = {
114 'show': "Show machine configuration",133 "show": "Show machine configuration",
115 'on': "Power machine on",134 "on": "Power machine on",
116 'off': "Power machine off",135 "off": "Power machine off",
117 'cycle': "Power cycle machine",136 "cycle": "Power cycle machine",
118 'mc-reset': "Perform cold reset of BMC",137 "mc-reset": "Perform cold reset of BMC",
119 'reset': "Hard reset machine",138 "reset": "Hard reset machine",
120 'console': "Open a console session",139 "console": "Open a console session",
121 'status': "Show machine power status",140 "status": "Show machine power status",
122 'update': "Update cached machine information",141 "update": "Update cached machine information",
123 }142 }
124143
125 d = 'Do things with machines in ScaleBot labs'144 d = "Do things with machines in ScaleBot labs"
126 parser = argparse.ArgumentParser(prog=ProgName, description=d)145 parser = argparse.ArgumentParser(prog=ProgName, description=d)
127 subparsers = parser.add_subparsers(help='sub-command help')146 subparsers = parser.add_subparsers(help="sub-command help")
128 update_parser = subparsers.add_parser('update', help=cmd_help['update'])147 update_parser = subparsers.add_parser("update", help=cmd_help["update"])
129 update_parser.add_argument('-u', dest='lpid', metavar='LPID',148 update_parser.add_argument(
130 required=False, help="Launchpad ID")149 "-u", dest="lpid", metavar="LPID", required=False, help="Launchpad ID"
131 update_parser.add_argument('-f', dest='force', action='store_true',150 )
132 required=False,151 update_parser.add_argument(
133 help="Flush machine cache before update")152 "-f",
134 update_parser.set_defaults(cmd='update')153 dest="force",
154 action="store_true",
155 required=False,
156 help="Flush machine cache before update",
157 )
158 update_parser.set_defaults(cmd="update")
135 for a in machine_cmds:159 for a in machine_cmds:
136 action_parser = subparsers.add_parser(a, help=cmd_help[a])160 action_parser = subparsers.add_parser(a, help=cmd_help[a])
137 action_parser.add_argument('machine', metavar='MACHINE')161 action_parser.add_argument("machine", metavar="MACHINE")
138 action_parser.set_defaults(cmd=a)162 action_parser.set_defaults(cmd=a)
139 args = parser.parse_args()163 args = parser.parse_args()
140164
141 if args.cmd == 'update':165 if args.cmd == "update":
142 update(lpid=args.lpid, force=args.force)166 update(lpid=args.lpid, force=args.force)
143 sys.exit(0)167 sys.exit(0)
144168
145 m = Machine(args.machine)169 m = Machine(args.machine)
146 if args.cmd == 'show':170 if args.cmd == "show":
147 print(m)171 print(m)
148 elif args.cmd == 'mc-reset':172 elif args.cmd == "mc-reset":
149 m.mc_reset()173 m.mc_reset()
150 elif args.cmd == 'console':174 elif args.cmd == "console":
151 m.open_console()175 m.open_console()
152 elif args.cmd in power_cmds:176 elif args.cmd in power_cmds:
153 m.power(args.cmd)177 m.power(args.cmd)
diff --git a/lp-scripts/LaunchpadBugBucketer.py b/lp-scripts/LaunchpadBugBucketer.py
index 7831132..81e9e99 100644
--- a/lp-scripts/LaunchpadBugBucketer.py
+++ b/lp-scripts/LaunchpadBugBucketer.py
@@ -49,7 +49,7 @@ class LaunchpadBugBucketer(collections.UserDict):
49 requiredTags (:obj:`list` of :obj:`str`): Only bucket bugs that49 requiredTags (:obj:`list` of :obj:`str`): Only bucket bugs that
50 have one or more tags from this list.50 have one or more tags from this list.
51 """51 """
52 self.lp = Launchpad.login_with('lpbugs', 'production', version='devel')52 self.lp = Launchpad.login_with("lpbugs", "production", version="devel")
53 self.project = self.lp.projects[project]53 self.project = self.lp.projects[project]
54 self.series = series54 self.series = series
55 self.requiredTags = requiredTags55 self.requiredTags = requiredTags
@@ -57,8 +57,8 @@ class LaunchpadBugBucketer(collections.UserDict):
57 collections.UserDict.__init__(self, self.buckets)57 collections.UserDict.__init__(self, self.buckets)
5858
59 def taskToBug(self, task):59 def taskToBug(self, task):
60 bugid = int(task.self_link.split('/')[-1])60 bugid = int(task.self_link.split("/")[-1])
61 return(self.lp.bugs[bugid])61 return self.lp.bugs[bugid]
6262
63 def _doBucketing(self):63 def _doBucketing(self):
64 methods = inspect.getmembers(self, predicate=inspect.ismethod)64 methods = inspect.getmembers(self, predicate=inspect.ismethod)
@@ -72,10 +72,10 @@ class LaunchpadBugBucketer(collections.UserDict):
72 if not set(self.requiredTags) & set(bug.tags):72 if not set(self.requiredTags) & set(bug.tags):
73 continue73 continue
74 for mName, mFunc in methods:74 for mName, mFunc in methods:
75 if not mName.startswith('is_'):75 if not mName.startswith("is_"):
76 continue76 continue
77 if mFunc(task):77 if mFunc(task):
78 b = mName[len('is_'):]78 b = mName[len("is_") :]
79 if b not in self.buckets.keys():79 if b not in self.buckets.keys():
80 self.buckets[b] = []80 self.buckets[b] = []
81 self.buckets[b].append(task)81 self.buckets[b].append(task)
diff --git a/lp-scripts/bandera-bug-csv-summary.py b/lp-scripts/bandera-bug-csv-summary.py
index 1fae696..05f84aa 100755
--- a/lp-scripts/bandera-bug-csv-summary.py
+++ b/lp-scripts/bandera-bug-csv-summary.py
@@ -7,18 +7,19 @@ from LaunchpadBugBucketer import LaunchpadBugBucketer
77
8class BanderaBugBucketer(LaunchpadBugBucketer):8class BanderaBugBucketer(LaunchpadBugBucketer):
9 def __init__(self):9 def __init__(self):
10 LaunchpadBugBucketer.__init__(self, 'bandera', 'ubuntu-16.04',10 LaunchpadBugBucketer.__init__(
11 requiredTags=['patchset'])11 self, "bandera", "ubuntu-16.04", requiredTags=["patchset"]
12 )
1213
13 def is_green(self, task):14 def is_green(self, task):
14 if task.status in ['Fix Committed', 'Fix Released']:15 if task.status in ["Fix Committed", "Fix Released"]:
15 return True16 return True
16 return False17 return False
1718
18 def is_amber(self, task):19 def is_amber(self, task):
19 if self.is_green(task):20 if self.is_green(task):
20 return False21 return False
21 elif task.milestone and task.milestone.name == 'ubuntu-16.04.3':22 elif task.milestone and task.milestone.name == "ubuntu-16.04.3":
22 return True23 return True
23 return False24 return False
2425
@@ -28,16 +29,16 @@ class BanderaBugBucketer(LaunchpadBugBucketer):
28 return True29 return True
2930
3031
31if __name__ == '__main__':32if __name__ == "__main__":
32 parser = argparse.ArgumentParser()33 parser = argparse.ArgumentParser()
33 parser.add_argument("-o", "--outfile")34 parser.add_argument("-o", "--outfile")
34 args = parser.parse_args()35 args = parser.parse_args()
3536
36 s = BanderaBugBucketer()37 s = BanderaBugBucketer()
3738
38 with open(args.outfile, 'w') as csvfile:39 with open(args.outfile, "w") as csvfile:
39 c = csv.writer(csvfile)40 c = csv.writer(csvfile)
40 c.writerow(['Title', 'Bug ID', 'Importance', 'Status', 'RAG Risk'])41 c.writerow(["Title", "Bug ID", "Importance", "Status", "RAG Risk"])
41 for bucket in s.keys():42 for bucket in s.keys():
42 for task in s[bucket]:43 for task in s[bucket]:
43 bug = s.taskToBug(task)44 bug = s.taskToBug(task)
diff --git a/lp-scripts/bugreport/bugreport.py b/lp-scripts/bugreport/bugreport.py
index bc347b9..ca9b5b1 100755
--- a/lp-scripts/bugreport/bugreport.py
+++ b/lp-scripts/bugreport/bugreport.py
@@ -3,7 +3,6 @@
3# License: GPLv33# License: GPLv3
4from launchpadlib.launchpad import Launchpad4from launchpadlib.launchpad import Launchpad
5from launchpadlib.uris import LPNET_SERVICE_ROOT5from launchpadlib.uris import LPNET_SERVICE_ROOT
6from launchpadlib.credentials import Credentials
7from optparse import OptionParser6from optparse import OptionParser
8from re import compile7from re import compile
9from datetime import datetime as dt8from datetime import datetime as dt
@@ -16,7 +15,7 @@ import sys
16def gen_bug_report(lp, lp_bugs, project, verbose):15def gen_bug_report(lp, lp_bugs, project, verbose):
17 bug_summary_info = coldict(dict)16 bug_summary_info = coldict(dict)
18 bug_details_info = coldict(dict)17 bug_details_info = coldict(dict)
19 url = compile('https://api.launchpad.net/1.0/~|/')18 url = compile("https://api.launchpad.net/1.0/~|/")
2019
21 for task in lp_bugs:20 for task in lp_bugs:
22 bug_info = {}21 bug_info = {}
@@ -27,13 +26,13 @@ def gen_bug_report(lp, lp_bugs, project, verbose):
27 else:26 else:
28 bug_summary_info[task.importance][task.status] = 127 bug_summary_info[task.importance][task.status] = 1
2928
30 if '#Bugs Processed' in bug_summary_info[task.importance]:29 if "#Bugs Processed" in bug_summary_info[task.importance]:
31 bug_summary_info[task.importance]['#Bugs Processed'] += 130 bug_summary_info[task.importance]["#Bugs Processed"] += 1
32 else:31 else:
33 bug_summary_info[task.importance]['#Bugs Processed'] = 132 bug_summary_info[task.importance]["#Bugs Processed"] = 1
3433
35 if '#Bugs Closed' not in bug_summary_info[task.importance]:34 if "#Bugs Closed" not in bug_summary_info[task.importance]:
36 bug_summary_info[task.importance]['#Bugs Closed'] = 035 bug_summary_info[task.importance]["#Bugs Closed"] = 0
3736
38 # A bug could affect multiple projects, we care only whether37 # A bug could affect multiple projects, we care only whether
39 # the project we are tracking is complete.38 # the project we are tracking is complete.
@@ -42,33 +41,40 @@ def gen_bug_report(lp, lp_bugs, project, verbose):
42 if bugtask.bug_target_name in project:41 if bugtask.bug_target_name in project:
43 bug_is_complete = bugtask.is_complete42 bug_is_complete = bugtask.is_complete
44 if verbose is True:43 if verbose is True:
45 bug_subtask.append(44 bug_subtask.append("%s: %s" % (bugtask.bug_target_name, bugtask.status))
46 '%s: %s' % (bugtask.bug_target_name, bugtask.status))
4745
48 if bug_is_complete is True:46 if bug_is_complete is True:
49 if '#Bugs Closed' in bug_summary_info[task.importance]:47 if "#Bugs Closed" in bug_summary_info[task.importance]:
50 bug_summary_info[task.importance]['#Bugs Closed'] += 148 bug_summary_info[task.importance]["#Bugs Closed"] += 1
5149
52 if verbose is True:50 if verbose is True:
53 inactive_days = 051 inactive_days = 0
54 if bug_is_complete is not True:52 if bug_is_complete is not True:
55 inactive_days = np.busday_count(53 inactive_days = np.busday_count(
56 task.bug.date_last_updated.strftime("%Y-%m-%d"),54 task.bug.date_last_updated.strftime("%Y-%m-%d"),
57 dt.now().strftime("%Y-%m-%d"))55 dt.now().strftime("%Y-%m-%d"),
56 )
5857
59 active_days = np.busday_count(58 active_days = np.busday_count(
60 task.bug.date_created.strftime("%Y-%m-%d"),59 task.bug.date_created.strftime("%Y-%m-%d"),
61 task.bug.date_last_updated.strftime("%Y-%m-%d"))60 task.bug.date_last_updated.strftime("%Y-%m-%d"),
61 )
6262
63 assignee = 'Unassigned' if task.assignee_link is None \63 assignee = (
64 else url.sub('', task.assignee_link)64 "Unassigned"
65 if task.assignee_link is None
66 else url.sub("", task.assignee_link)
67 )
6568
66 bug_info[task.bug.id] = [69 bug_info[task.bug.id] = [
67 task.bug.date_created.strftime("%Y-%m-%d"),70 task.bug.date_created.strftime("%Y-%m-%d"),
68 task.bug.date_last_updated.strftime("%Y-%m-%d"),71 task.bug.date_last_updated.strftime("%Y-%m-%d"),
69 active_days,72 active_days,
70 inactive_days, task.bug.message_count, assignee,73 inactive_days,
71 "''<br>''".join(bug_subtask)]74 task.bug.message_count,
75 assignee,
76 "''<br>''".join(bug_subtask),
77 ]
7278
73 bug_details_info[task.importance].update(bug_info)79 bug_details_info[task.importance].update(bug_info)
7480
@@ -76,95 +82,151 @@ def gen_bug_report(lp, lp_bugs, project, verbose):
7682
7783
78def main():84def main():
79 parser = OptionParser(usage='usage: %prog [options]', version='%prog 1.0')85 parser = OptionParser(usage="usage: %prog [options]", version="%prog 1.0")
80 parser.add_option('-d', '--date', dest='start_date', action='store',86 parser.add_option(
81 default='2017-01-01',87 "-d",
82 type='string', help='start date for bug search')88 "--date",
83 parser.add_option('-p', '--project', dest='project', action='store',89 dest="start_date",
84 default='ubuntu-power-systems',90 action="store",
85 type='string', help='name of the launchpad project')91 default="2017-01-01",
86 parser.add_option('-s', '--status', dest='bug_status', action='store',92 type="string",
87 default=('New,Opinion,Invalid,Won\'t Fix,Expired,'93 help="start date for bug search",
88 'Confirmed,Triaged,In Progress,Fix Committed,'94 )
89 'Fix Released,Incomplete'),95 parser.add_option(
90 type='string',96 "-p",
91 help='bug status (or quoted and comma seperated list)')97 "--project",
92 parser.add_option('-i', '--importance', dest='bug_importance',98 dest="project",
93 default=(99 action="store",
94 'Unknown,Undecided,Critical,High,Medium,Low,Wishlist'),100 default="ubuntu-power-systems",
95 type='string',101 type="string",
96 help='bug importance (or comma seperated list, no spaces)')102 help="name of the launchpad project",
97 parser.add_option('-t', '--tag', dest='bug_tag', default=None,103 )
98 help='bug tag (or quoted and comma seperated list)')104 parser.add_option(
99 parser.add_option('-m', '--modify', dest='bug_tag_modify', default='Any',105 "-s",
100 help='search any or all tags (valid args: any or all)')106 "--status",
101 parser.add_option('-v', '--verbose', dest='verbose', action='store_true',107 dest="bug_status",
102 help='verbose output with bug details')108 action="store",
103 parser.add_option('-a', '--author', dest='author',109 default=(
104 default='Manoj Iyer manoj.iyer@canonical.com',110 "New,Opinion,Invalid,Won't Fix,Expired,"
105 help='"Firstname Lastname first.last@canonical.com"')111 "Confirmed,Triaged,In Progress,Fix Committed,"
106 parser.add_option('-o', '--outfile', dest='outfile',112 "Fix Released,Incomplete"
107 help='filename to store output (default stdout)')113 ),
114 type="string",
115 help="bug status (or quoted and comma seperated list)",
116 )
117 parser.add_option(
118 "-i",
119 "--importance",
120 dest="bug_importance",
121 default=("Unknown,Undecided,Critical,High,Medium,Low,Wishlist"),
122 type="string",
123 help="bug importance (or comma seperated list, no spaces)",
124 )
125 parser.add_option(
126 "-t",
127 "--tag",
128 dest="bug_tag",
129 default=None,
130 help="bug tag (or quoted and comma seperated list)",
131 )
132 parser.add_option(
133 "-m",
134 "--modify",
135 dest="bug_tag_modify",
136 default="Any",
137 help="search any or all tags (valid args: any or all)",
138 )
139 parser.add_option(
140 "-v",
141 "--verbose",
142 dest="verbose",
143 action="store_true",
144 help="verbose output with bug details",
145 )
146 parser.add_option(
147 "-a",
148 "--author",
149 dest="author",
150 default="Manoj Iyer manoj.iyer@canonical.com",
151 help='"Firstname Lastname first.last@canonical.com"',
152 )
153 parser.add_option(
154 "-o",
155 "--outfile",
156 dest="outfile",
157 help="filename to store output (default stdout)",
158 )
108159
109 (options, args) = parser.parse_args()160 (options, args) = parser.parse_args()
110161
111 if len(args) is None:162 if len(args) is None:
112 parser.error("No arguments found!")163 parser.error("No arguments found!")
113164
114 script_name = sys.argv[0].split("/")[-1].split('.')[0]165 script_name = sys.argv[0].split("/")[-1].split(".")[0]
115 cachedir = os.path.expanduser('~/.launchpadlib/cache')166 cachedir = os.path.expanduser("~/.launchpadlib/cache")
116167
117 launchpad = Launchpad.login_with(script_name, LPNET_SERVICE_ROOT, cachedir)168 launchpad = Launchpad.login_with(script_name, LPNET_SERVICE_ROOT, cachedir)
118 lp_project = launchpad.projects[options.project]169 lp_project = launchpad.projects[options.project]
119170
120 lp_bugs = [171 lp_bugs = [
121 task for task in lp_project.searchTasks(172 task
122 created_since=None if options.start_date is None else173 for task in lp_project.searchTasks(
123 dt.strptime(options.start_date,174 created_since=None
124 '%Y-%m-%d').isoformat(),175 if options.start_date is None
125 status=options.bug_status.split(','),176 else dt.strptime(options.start_date, "%Y-%m-%d").isoformat(),
126 importance=options.bug_importance.title().replace(177 status=options.bug_status.split(","),
127 ' ', '').split(','),178 importance=options.bug_importance.title().replace(" ", "").split(","),
128 tags=None if options.bug_tag is None else179 tags=None if options.bug_tag is None else options.bug_tag.split(","),
129 options.bug_tag.split(','),180 tags_combinator=options.bug_tag_modify.title(),
130 tags_combinator=options.bug_tag_modify.title())]181 )
131182 ]
132 with (open(options.outfile, 'w') if options.outfile else sys.stdout) as f:183
133 f.write("Bug activity in %s project since %s\n\n\n" % (options.project,184 with (open(options.outfile, "w") if options.outfile else sys.stdout) as f:
134 options.start_date))185 f.write(
135 f.write(" || {:<35} | {:<20} |\n".format('Created By', 'Date'))186 "Bug activity in %s project since %s\n\n\n"
187 % (options.project, options.start_date)
188 )
189 f.write(" || {:<35} | {:<20} |\n".format("Created By", "Date"))
136 f.write(" | [%s]" % (options.author) + " | %%mtime(%A %B %d, %Y) |\n")190 f.write(" | [%s]" % (options.author) + " | %%mtime(%A %B %d, %Y) |\n")
137191
138 if f is not sys.stdout and options.verbose is True:192 if f is not sys.stdout and options.verbose is True:
139 sys.stdout.write("Bug activity in %s project since %s\n" %193 sys.stdout.write(
140 (options.project, options.start_date))194 "Bug activity in %s project since %s\n"
141 sys.stdout.write("Generating detailed report in %s \n" %195 % (options.project, options.start_date)
142 options.outfile)196 )
197 sys.stdout.write("Generating detailed report in %s \n" % options.outfile)
143 sys.stdout.write("Please wait...\n")198 sys.stdout.write("Please wait...\n")
144 sys.stdout.flush()199 sys.stdout.flush()
145200
146 summary_report, detailed_report = gen_bug_report(launchpad, lp_bugs,201 summary_report, detailed_report = gen_bug_report(
147 options.project,202 launchpad, lp_bugs, options.project, options.verbose
148 options.verbose)203 )
149204
150 for k, v in sorted(summary_report.iteritems()):205 for k, v in sorted(summary_report.iteritems()):
151 f.write("\n= Summary of %s bugs =\n" % k)206 f.write("\n= Summary of %s bugs =\n" % k)
152 f.write("|| {:<14} | {:<8} |\n".format('Status', 'Count'))207 f.write("|| {:<14} | {:<8} |\n".format("Status", "Count"))
153 for x, y in sorted(v.iteritems()):208 for x, y in sorted(v.iteritems()):
154 f.write("| {:<15} | {:<8} |\n".format(x, y))209 f.write("| {:<15} | {:<8} |\n".format(x, y))
155 if options.verbose is True:210 if options.verbose is True:
156 f.write("== Details on %s bugs ==\n" % k)211 f.write("== Details on %s bugs ==\n" % k)
157 f.write("|| Bug# | Created | Last Updated | Active Period "212 f.write(
158 "| Dormant Period | #Comments | Assignee | Status |\n")213 "|| Bug# | Created | Last Updated | Active Period "
159214 "| Dormant Period | #Comments | Assignee | Status |\n"
160 for a, b in sorted(detailed_report[k].iteritems(),215 )
161 key=lambda item: item[1][1], reverse=True):216
162 f.write("| [%s https://launchpad.net/bugs/%s] | %s |\n" %217 for a, b in sorted(
163 (a, a, ' | '.join(map(str, b))))218 detailed_report[k].iteritems(),
219 key=lambda item: item[1][1],
220 reverse=True,
221 ):
222 f.write(
223 "| [%s https://launchpad.net/bugs/%s] | %s |\n"
224 % (a, a, " | ".join(map(str, b)))
225 )
164226
165 if f is not sys.stdout:227 if f is not sys.stdout:
166 f.close()228 f.close()
167229
168230
169if __name__ == '__main__':231if __name__ == "__main__":
170 main()232 main()
diff --git a/lp-scripts/clone-project-milestones.py b/lp-scripts/clone-project-milestones.py
index b0783d2..39099ab 100755
--- a/lp-scripts/clone-project-milestones.py
+++ b/lp-scripts/clone-project-milestones.py
@@ -10,11 +10,11 @@ from launchpadlib.launchpad import Launchpad
1010
1111
12# These may contain proprietary content, skip them12# These may contain proprietary content, skip them
13IgnoredSeries = ['firmware', 'ppa-uose', 'silicon', 'trunk']13IgnoredSeries = ["firmware", "ppa-uose", "silicon", "trunk"]
1414
1515
16def clone_project_milestones(src, dest, dry_run):16def clone_project_milestones(src, dest, dry_run):
17 lp = Launchpad.login_with('lpbugs', 'production', version='devel')17 lp = Launchpad.login_with("lpbugs", "production", version="devel")
18 src_project = lp.projects[src]18 src_project = lp.projects[src]
19 dest_project = lp.projects[dest]19 dest_project = lp.projects[dest]
20 for src_series in src_project.series:20 for src_series in src_project.series:
@@ -22,46 +22,49 @@ def clone_project_milestones(src, dest, dry_run):
22 continue22 continue
23 dest_series = dest_project.getSeries(name=src_series.name)23 dest_series = dest_project.getSeries(name=src_series.name)
24 if dest_series:24 if dest_series:
25 logger.warning("Series %s already exists, skipping\n" %25 logger.warning("Series %s already exists, skipping\n" % (dest_series))
26 (dest_series))
27 else:26 else:
28 logger.info("Creating series %s" % (src_series.name))27 logger.info("Creating series %s" % (src_series.name))
29 if not dry_run:28 if not dry_run:
30 dest_series = dest_project.newSeries(29 dest_series = dest_project.newSeries(
31 name=src_series.name,30 name=src_series.name, summary=src_series.summary
32 summary=src_series.summary)31 )
33 for src_milestone in src_series.all_milestones:32 for src_milestone in src_series.all_milestones:
34 dest_milestone = dest_project.getMilestone(name=src_milestone.name)33 dest_milestone = dest_project.getMilestone(name=src_milestone.name)
35 if dest_milestone:34 if dest_milestone:
36 logger.warning(35 logger.warning(
37 "Project already has milestone %s, skipping\n" %36 "Project already has milestone %s, skipping\n"
38 (dest_milestone.name))37 % (dest_milestone.name)
38 )
39 else:39 else:
40 logger.info("Creating milestone %s" % (src_milestone.name))40 logger.info("Creating milestone %s" % (src_milestone.name))
41 if not dry_run:41 if not dry_run:
42 dest_milestone = dest_series.newMilestone(42 dest_milestone = dest_series.newMilestone(
43 name=src_milestone.name,43 name=src_milestone.name,
44 date_targeted=src_milestone.date_targeted)44 date_targeted=src_milestone.date_targeted,
45 )
45 dest_milestone.is_active = src_milestone.is_active46 dest_milestone.is_active = src_milestone.is_active
46 dest_milestone.lp_save()47 dest_milestone.lp_save()
47 src_release = src_milestone.release48 src_release = src_milestone.release
48 if src_release:49 if src_release:
49 logger.info("Releasing milestone %s on %s " %50 logger.info(
50 (src_milestone.name,51 "Releasing milestone %s on %s "
51 src_milestone.release.date_released))52 % (src_milestone.name, src_milestone.release.date_released)
53 )
52 if not dry_run:54 if not dry_run:
53 dest_milestone.createProductRelease(55 dest_milestone.createProductRelease(
54 date_released=src_milestone.release.date_released)56 date_released=src_milestone.release.date_released
57 )
5558
5659
57if __name__ == '__main__':60if __name__ == "__main__":
58 parser = argparse.ArgumentParser()61 parser = argparse.ArgumentParser()
59 parser.add_argument('-s', '--source', required=True)62 parser.add_argument("-s", "--source", required=True)
60 parser.add_argument('-d', '--dest', required=True)63 parser.add_argument("-d", "--dest", required=True)
61 parser.add_argument('--dry-run', action='store_true')64 parser.add_argument("--dry-run", action="store_true")
62 args = parser.parse_args()65 args = parser.parse_args()
6366
64 logger = logging.getLogger('clone-project-milestones')67 logger = logging.getLogger("clone-project-milestones")
65 logger.setLevel(logging.INFO)68 logger.setLevel(logging.INFO)
66 ch = logging.StreamHandler()69 ch = logging.StreamHandler()
67 formatter = logging.Formatter("%(levelname)s - %(message)s")70 formatter = logging.Formatter("%(levelname)s - %(message)s")
diff --git a/lp-scripts/dump-bug-subscribers.py b/lp-scripts/dump-bug-subscribers.py
index 061c539..70f8c72 100755
--- a/lp-scripts/dump-bug-subscribers.py
+++ b/lp-scripts/dump-bug-subscribers.py
@@ -8,42 +8,54 @@ import csv
8from launchpadlib.launchpad import Launchpad8from launchpadlib.launchpad import Launchpad
99
1010
11bugStatuses = ["New", "Opinion", "Invalid", "Won't Fix", "Expired",11bugStatuses = [
12 "Confirmed", "Triaged", "In Progress", "Fix Committed",12 "New",
13 "Fix Released", "Incomplete"]13 "Opinion",
14 "Invalid",
15 "Won't Fix",
16 "Expired",
17 "Confirmed",
18 "Triaged",
19 "In Progress",
20 "Fix Committed",
21 "Fix Released",
22 "Incomplete",
23]
1424
1525
16def taskToBug(task):26def taskToBug(task):
17 bugid = int(task.self_link.split('/')[-1])27 bugid = int(task.self_link.split("/")[-1])
18 return(lp.bugs[bugid])28 return lp.bugs[bugid]
1929
2030
21def getSubscriptionId(subscription_url):31def getSubscriptionId(subscription_url):
22 lpString = str(subscription_url)32 lpString = str(subscription_url)
23 lpPath = lpString.rsplit('/', 1)33 lpPath = lpString.rsplit("/", 1)
24 return lpPath[-1]34 return lpPath[-1]
2535
2636
27if __name__ == '__main__':37if __name__ == "__main__":
28 parser = argparse.ArgumentParser()38 parser = argparse.ArgumentParser()
29 parser.add_argument("project", help="Launchpad project from which \39 parser.add_argument(
30 subscribers will be dumped")40 "project",
41 help="Launchpad project from which \
42 subscribers will be dumped",
43 )
31 parser.add_argument("-o", "--outfile", help="Output file", required=True)44 parser.add_argument("-o", "--outfile", help="Output file", required=True)
32 args = parser.parse_args()45 args = parser.parse_args()
3346
34 lp = Launchpad.login_with('lpbugs', 'production', version='devel')47 lp = Launchpad.login_with("lpbugs", "production", version="devel")
35 project = lp.projects[args.project]48 project = lp.projects[args.project]
3649
37 with open(args.outfile, 'w') as csvfile:50 with open(args.outfile, "w") as csvfile:
38 c = csv.writer(csvfile)51 c = csv.writer(csvfile)
39 c.writerow(["Bug", "Title", "Subscribers"])52 c.writerow(["Bug", "Title", "Subscribers"])
40# no way to list all open/closed bugs, so iterate through bug states53 # no way to list all open/closed bugs, so iterate through bug states
41 for bugStatus in bugStatuses:54 for bugStatus in bugStatuses:
42 for task in project.searchTasks(status=bugStatus):55 for task in project.searchTasks(status=bugStatus):
43 output = []56 output = []
44 bug = taskToBug(task)57 bug = taskToBug(task)
45 output.append('=HYPERLINK("%s", "LP: #%d")' %58 output.append('=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id))
46 (task.web_link, bug.id))
47 output.append(bug.title)59 output.append(bug.title)
48 for subscription in bug.subscriptions:60 for subscription in bug.subscriptions:
49 output.append(getSubscriptionId(subscription))61 output.append(getSubscriptionId(subscription))
diff --git a/lp-scripts/lp-bulk-action.py b/lp-scripts/lp-bulk-action.py
index be1b047..acada01 100755
--- a/lp-scripts/lp-bulk-action.py
+++ b/lp-scripts/lp-bulk-action.py
@@ -5,14 +5,14 @@ import sys
5from launchpadlib.launchpad import Launchpad5from launchpadlib.launchpad import Launchpad
66
7Projects = [7Projects = [
8 'bandera',8 "bandera",
9 'kunpeng920',9 "kunpeng920",
10 'pearl',10 "pearl",
11 'pearl2',11 "pearl2",
12 'ubuntu-power-systems',12 "ubuntu-power-systems",
13 'ubuntu-z-systems',13 "ubuntu-z-systems",
14 'yarmouth',14 "yarmouth",
15 'yarmouth2',15 "yarmouth2",
16]16]
1717
1818
@@ -20,13 +20,15 @@ def createMilestone(lp, project, series, milestone, date):
20 p = lp.projects[project]20 p = lp.projects[project]
21 s = p.getSeries(name=series)21 s = p.getSeries(name=series)
22 if not s:22 if not s:
23 sys.stderr.write("Warning: Project %s has no series %s, skipping\n" %23 sys.stderr.write(
24 (project, series))24 "Warning: Project %s has no series %s, skipping\n" % (project, series)
25 )
25 return26 return
26 if p.getMilestone(name=milestone):27 if p.getMilestone(name=milestone):
27 sys.stderr.write(28 sys.stderr.write(
28 "Warning: Project %s already has milestone %s, skipping\n" %29 "Warning: Project %s already has milestone %s, skipping\n"
29 (project, milestone))30 % (project, milestone)
31 )
30 return32 return
31 s.newMilestone(name=milestone, date_targeted=date)33 s.newMilestone(name=milestone, date_targeted=date)
3234
@@ -36,13 +38,14 @@ def releaseMilestone(lp, project, milestone, date):
36 m = p.getMilestone(name=milestone)38 m = p.getMilestone(name=milestone)
37 if not m:39 if not m:
38 sys.stderr.write(40 sys.stderr.write(
39 "Warning: Project %s has no milestone %s, skipping\n" %41 "Warning: Project %s has no milestone %s, skipping\n" % (project, milestone)
40 (project, milestone))42 )
41 return43 return
42 if m.release:44 if m.release:
43 sys.stderr.write(45 sys.stderr.write(
44 "Warning: Milestone %s in project %s is already released\n" %46 "Warning: Milestone %s in project %s is already released\n"
45 (milestone, project))47 % (milestone, project)
48 )
46 return49 return
47 m.createProductRelease(date_released=date)50 m.createProductRelease(date_released=date)
4851
@@ -52,8 +55,9 @@ def updateMilestone(lp, project, milestone, date):
52 m = p.getMilestone(name=milestone)55 m = p.getMilestone(name=milestone)
53 if not m:56 if not m:
54 sys.stderr.write(57 sys.stderr.write(
55 "Warning: Project %s does not have milestone %s, skipping\n" %58 "Warning: Project %s does not have milestone %s, skipping\n"
56 (project, milestone))59 % (project, milestone)
60 )
57 return61 return
58 m.date_targeted = date62 m.date_targeted = date
59 m.lp_save()63 m.lp_save()
@@ -63,51 +67,52 @@ def createSeries(lp, project, series, summary):
63 p = lp.projects[project]67 p = lp.projects[project]
64 if p.getSeries(name=series):68 if p.getSeries(name=series):
65 sys.stderr.write(69 sys.stderr.write(
66 "Warning: Project %s already has series %s, skipping\n" %70 "Warning: Project %s already has series %s, skipping\n" % (project, series)
67 (project, series))71 )
68 return72 return
69 p.newSeries(name=series, summary=summary)73 p.newSeries(name=series, summary=summary)
7074
7175
72if __name__ == '__main__':76if __name__ == "__main__":
73 parser = argparse.ArgumentParser()77 parser = argparse.ArgumentParser()
74 subparsers = parser.add_subparsers(dest='cmd')78 subparsers = parser.add_subparsers(dest="cmd")
75 subparsers.required = True79 subparsers.required = True
76 createMilestoneParser = subparsers.add_parser('create-milestone',80 createMilestoneParser = subparsers.add_parser(
77 help="Create Milestone")81 "create-milestone", help="Create Milestone"
82 )
78 createMilestoneParser.add_argument("-s", "--series", required=True)83 createMilestoneParser.add_argument("-s", "--series", required=True)
79 createMilestoneParser.add_argument("-d", "--date", required=True)84 createMilestoneParser.add_argument("-d", "--date", required=True)
80 createMilestoneParser.add_argument("milestone")85 createMilestoneParser.add_argument("milestone")
81 createMilestoneParser.set_defaults(cmd='create-milestone')86 createMilestoneParser.set_defaults(cmd="create-milestone")
8287
83 releaseMilestoneParser = subparsers.add_parser('release-milestone',88 releaseMilestoneParser = subparsers.add_parser(
84 help="Release Milestone")89 "release-milestone", help="Release Milestone"
90 )
85 releaseMilestoneParser.add_argument("-d", "--date", required=True)91 releaseMilestoneParser.add_argument("-d", "--date", required=True)
86 releaseMilestoneParser.add_argument("milestone")92 releaseMilestoneParser.add_argument("milestone")
87 releaseMilestoneParser.set_defaults(cmd='release-milestone')93 releaseMilestoneParser.set_defaults(cmd="release-milestone")
8894
89 releaseMilestoneParser = subparsers.add_parser('update-milestone',95 releaseMilestoneParser = subparsers.add_parser(
90 help="Update Milestone")96 "update-milestone", help="Update Milestone"
97 )
91 releaseMilestoneParser.add_argument("-d", "--date", required=True)98 releaseMilestoneParser.add_argument("-d", "--date", required=True)
92 releaseMilestoneParser.add_argument("milestone")99 releaseMilestoneParser.add_argument("milestone")
93 releaseMilestoneParser.set_defaults(cmd='update-milestone')100 releaseMilestoneParser.set_defaults(cmd="update-milestone")
94101
95 createSeriesParser = subparsers.add_parser('create-series',102 createSeriesParser = subparsers.add_parser("create-series", help="Create Series")
96 help="Create Series")
97 createSeriesParser.add_argument("-s", "--summary", required=True)103 createSeriesParser.add_argument("-s", "--summary", required=True)
98 createSeriesParser.add_argument("series")104 createSeriesParser.add_argument("series")
99 createSeriesParser.set_defaults(cmd='create-series')105 createSeriesParser.set_defaults(cmd="create-series")
100 args = parser.parse_args()106 args = parser.parse_args()
101107
102 lp = Launchpad.login_with('lpbugs', 'production', version='devel')108 lp = Launchpad.login_with("lpbugs", "production", version="devel")
103109
104 for project in Projects:110 for project in Projects:
105 if args.cmd == 'create-milestone':111 if args.cmd == "create-milestone":
106 createMilestone(lp, project, args.series,112 createMilestone(lp, project, args.series, args.milestone, args.date)
107 args.milestone, args.date)113 elif args.cmd == "create-series":
108 elif args.cmd == 'create-series':
109 createSeries(lp, project, args.series, args.summary)114 createSeries(lp, project, args.series, args.summary)
110 elif args.cmd == 'release-milestone':115 elif args.cmd == "release-milestone":
111 releaseMilestone(lp, project, args.milestone, args.date)116 releaseMilestone(lp, project, args.milestone, args.date)
112 elif args.cmd == 'update-milestone':117 elif args.cmd == "update-milestone":
113 updateMilestone(lp, project, args.milestone, args.date)118 updateMilestone(lp, project, args.milestone, args.date)
diff --git a/lp-scripts/pearl-biweekly-bug-report-csv4.py b/lp-scripts/pearl-biweekly-bug-report-csv4.py
index 6590ecf..1295c43 100755
--- a/lp-scripts/pearl-biweekly-bug-report-csv4.py
+++ b/lp-scripts/pearl-biweekly-bug-report-csv4.py
@@ -1,74 +1,93 @@
1#!/usr/bin/python3
1# Change History2# Change History
2# Modify encode utf_8 to byte code in Rationale/Comment3# Modify encode utf_8 to byte code in Rationale/Comment
3# Add Date_created column for creating date for bug 4# Add Date_created column for creating date for bug
4# Add Scope column for showing impact for all arc or arch-arm64 or D05 Boad only5# Add Scope column for showing impact for all arc or arch-arm64 or D05 Boad only
56
6#!/usr/bin/python3
7
8import argparse7import argparse
9import csv8import csv
10from launchpadlib.launchpad import Launchpad9from launchpadlib.launchpad import Launchpad
1110
12rationaleSectionHeader="[16.04.3 Risk Comments]"11rationaleSectionHeader = "[16.04.3 Risk Comments]"
13rationaleBoilerplate="Still under investigation, not yet root-caused."12rationaleBoilerplate = "Still under investigation, not yet root-caused."
13
1414
15def taskToBug(task):15def taskToBug(task):
16 bugid = int(task.self_link.split('/')[-1])16 bugid = int(task.self_link.split("/")[-1])
17 return(lp.bugs[bugid])17 return lp.bugs[bugid]
18
1819
19def ownerFromStatus(status):20def ownerFromStatus(status):
20 if 'Incomplete' in status:21 if "Incomplete" in status:
21 owner='Huawei'22 owner = "Huawei"
22 else:23 else:
23 owner='Canonical'24 owner = "Canonical"
24 return(owner)25 return owner
26
2527
26def rationaleFromDescription(des):28def rationaleFromDescription(des):
27 export_rationale_flag=0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section29 export_rationale_flag = (
28 rationale=""30 0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
29 for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export31 )
32 rationale = ""
33 for (
34 des_line
35 ) in (
36 des.splitlines()
37 ): # Loop through the bug description line-by-line looking for sections to export
30 if des_line == rationaleSectionHeader:38 if des_line == rationaleSectionHeader:
31 export_rationale_flag=139 export_rationale_flag = 1
32 else:40 else:
33 if export_rationale_flag==1:41 if export_rationale_flag == 1:
34 if des_line=="":42 if des_line == "":
35 export_rationale_flag=043 export_rationale_flag = 0
36 else:44 else:
37 rationale+=des_line45 rationale += des_line
38 return(rationale)46 return rationale
3947
4048
41def checkScopeTags(tags):49def checkScopeTags(tags):
42 scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d05-only']50 scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d05-only"]
43 scope = set(scopeTags).intersection(tags)51 scope = set(scopeTags).intersection(tags)
44 for i in scope:52 for i in scope:
45 return(i)53 return i
4654
47 return('Unknown')55 return "Unknown"
4856
4957
50if __name__ == '__main__':58if __name__ == "__main__":
51 parser = argparse.ArgumentParser()59 parser = argparse.ArgumentParser()
52 parser.add_argument("-o", "--outfile", required=True)60 parser.add_argument("-o", "--outfile", required=True)
53 args = parser.parse_args()61 args = parser.parse_args()
5462
55 lp = Launchpad.login_with('lpbugs', 'production', version='devel')63 lp = Launchpad.login_with("lpbugs", "production", version="devel")
5664
57 pearl = lp.projects['pearl']65 pearl = lp.projects["pearl"]
5866
59 with open(args.outfile, 'w') as csvfile:67 with open(args.outfile, "w") as csvfile:
60 c = csv.writer(csvfile)68 c = csv.writer(csvfile)
61 c.writerow(["Title", "Link", "Status", "Milestone", "Scope","Rationale/Comment", "Owner", "DateCreated"])69 c.writerow(
62# First pass: patchset bugs70 [
71 "Title",
72 "Link",
73 "Status",
74 "Milestone",
75 "Scope",
76 "Rationale/Comment",
77 "Owner",
78 "DateCreated",
79 ]
80 )
81 # First pass: patchset bugs
63 for series in pearl.series:82 for series in pearl.series:
64 if series.name not in ['ubuntu-16.04']:83 if series.name not in ["ubuntu-16.04"]:
65 continue84 continue
66# First pass, phase one: search for the 'open' bugs85 # First pass, phase one: search for the 'open' bugs
67 for task in series.searchTasks(): 86 for task in series.searchTasks():
68 bug = taskToBug(task)87 bug = taskToBug(task)
69 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'88 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
70# if 'upstream-risky' not in bug.tags:89 # if 'upstream-risky' not in bug.tags:
71# continue90 # continue
72 if task.milestone is None:91 if task.milestone is None:
73 milestone = "TBD"92 milestone = "TBD"
74 else:93 else:
@@ -76,18 +95,29 @@ if __name__ == '__main__':
76 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)95 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
77 rationale = rationaleFromDescription(bug.description)96 rationale = rationaleFromDescription(bug.description)
78 if (not rationale) and (task.milestone is None):97 if (not rationale) and (task.milestone is None):
79 rationale=rationaleBoilerplate98 rationale = rationaleBoilerplate
80 scope = checkScopeTags(bug.tags)99 scope = checkScopeTags(bug.tags)
81 owner = ownerFromStatus(task.status)100 owner = ownerFromStatus(task.status)
82 date_created = bug.date_created.strftime("%Y/%m/%d")101 date_created = bug.date_created.strftime("%Y/%m/%d")
83 c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])102 c.writerow(
84103 [
85# First pass, phase two: Fix Released bugs104 bug.title,
105 link,
106 task.status,
107 milestone,
108 scope,
109 rationale.encode("utf_8"),
110 owner,
111 date_created,
112 ]
113 )
114
115 # First pass, phase two: Fix Released bugs
86 for task in series.searchTasks(status="Fix Released"):116 for task in series.searchTasks(status="Fix Released"):
87 bug = taskToBug(task)117 bug = taskToBug(task)
88 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'118 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
89# if not 'upstream-risky' not in bug.tags:119 # if not 'upstream-risky' not in bug.tags:
90# continue120 # continue
91 if task.milestone is None:121 if task.milestone is None:
92 milestone = "TBD"122 milestone = "TBD"
93 else:123 else:
@@ -95,9 +125,19 @@ if __name__ == '__main__':
95 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)125 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
96 rationale = rationaleFromDescription(bug.description)126 rationale = rationaleFromDescription(bug.description)
97 if (not rationale) and (task.milestone is None):127 if (not rationale) and (task.milestone is None):
98 rationale=rationaleBoilerplate128 rationale = rationaleBoilerplate
99 scope = checkScopeTags(bug.tags)129 scope = checkScopeTags(bug.tags)
100 owner = ownerFromStatus(task.status)130 owner = ownerFromStatus(task.status)
101 date_created = bug.date_created.strftime("%Y/%m/%d")131 date_created = bug.date_created.strftime("%Y/%m/%d")
102 c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])132 c.writerow(
103133 [
134 bug.title,
135 link,
136 task.status,
137 milestone,
138 scope,
139 rationale.encode("utf_8"),
140 owner,
141 date_created,
142 ]
143 )
diff --git a/lp-scripts/pearl-biweekly-report-csv.py b/lp-scripts/pearl-biweekly-report-csv.py
index 2006490..5da289d 100755
--- a/lp-scripts/pearl-biweekly-report-csv.py
+++ b/lp-scripts/pearl-biweekly-report-csv.py
@@ -4,57 +4,76 @@ import argparse
4import csv4import csv
5from launchpadlib.launchpad import Launchpad5from launchpadlib.launchpad import Launchpad
66
7rationaleSectionHeader="[16.04.3 Risk Comments]"7rationaleSectionHeader = "[16.04.3 Risk Comments]"
8rationaleBoilerplate="Still under investigation, not yet root-caused."8rationaleBoilerplate = "Still under investigation, not yet root-caused."
9
910
10def taskToBug(task):11def taskToBug(task):
11 bugid = int(task.self_link.split('/')[-1])12 bugid = int(task.self_link.split("/")[-1])
12 return(lp.bugs[bugid])13 return lp.bugs[bugid]
14
1315
14def ownerFromStatus(status):16def ownerFromStatus(status):
15 if 'Incomplete' in status:17 if "Incomplete" in status:
16 owner='Huawei'18 owner = "Huawei"
17 else:19 else:
18 owner='Canonical'20 owner = "Canonical"
19 return(owner)21 return owner
22
2023
21def rationaleFromDescription(des):24def rationaleFromDescription(des):
22 export_rationale_flag=0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section25 export_rationale_flag = (
23 rationale=""26 0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
24 for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export27 )
28 rationale = ""
29 for (
30 des_line
31 ) in (
32 des.splitlines()
33 ): # Loop through the bug description line-by-line looking for sections to export
25 if des_line == rationaleSectionHeader:34 if des_line == rationaleSectionHeader:
26 export_rationale_flag=135 export_rationale_flag = 1
27 else:36 else:
28 if export_rationale_flag==1:37 if export_rationale_flag == 1:
29 if des_line=="":38 if des_line == "":
30 export_rationale_flag=039 export_rationale_flag = 0
31 else:40 else:
32 rationale+=des_line41 rationale += des_line
33 return(rationale)42 return rationale
3443
35 44
36if __name__ == '__main__':45if __name__ == "__main__":
37 parser = argparse.ArgumentParser()46 parser = argparse.ArgumentParser()
38 parser.add_argument("-o", "--outfile", required=True)47 parser.add_argument("-o", "--outfile", required=True)
39 args = parser.parse_args()48 args = parser.parse_args()
4049
41 lp = Launchpad.login_with('lpbugs', 'production', version='devel')50 lp = Launchpad.login_with("lpbugs", "production", version="devel")
4251
43 pearl = lp.projects['pearl']52 pearl = lp.projects["pearl"]
4453
45 with open(args.outfile, 'w') as csvfile:54 with open(args.outfile, "w") as csvfile:
46 c = csv.writer(csvfile)55 c = csv.writer(csvfile)
47 c.writerow(["Title", "Link", "Status", "Milestone", "Rationale/Comment", "Owner", "DateCreated"])56 c.writerow(
48# First pass: patchset bugs57 [
58 "Title",
59 "Link",
60 "Status",
61 "Milestone",
62 "Rationale/Comment",
63 "Owner",
64 "DateCreated",
65 ]
66 )
67 # First pass: patchset bugs
49 for series in pearl.series:68 for series in pearl.series:
50 if series.name not in ['ubuntu-16.04']:69 if series.name not in ["ubuntu-16.04"]:
51 continue70 continue
52# First pass, phase one: search for the 'open' bugs71 # First pass, phase one: search for the 'open' bugs
53 for task in series.searchTasks(): 72 for task in series.searchTasks():
54 bug = taskToBug(task)73 bug = taskToBug(task)
55 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'74 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
56# if 'upstream-risky' not in bug.tags:75 # if 'upstream-risky' not in bug.tags:
57# continue76 # continue
58 if task.milestone is None:77 if task.milestone is None:
59 milestone = "TBD"78 milestone = "TBD"
60 else:79 else:
@@ -62,17 +81,27 @@ if __name__ == '__main__':
62 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)81 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
63 rationale = rationaleFromDescription(bug.description)82 rationale = rationaleFromDescription(bug.description)
64 if (not rationale) and (task.milestone is None):83 if (not rationale) and (task.milestone is None):
65 rationale=rationaleBoilerplate84 rationale = rationaleBoilerplate
66 owner = ownerFromStatus(task.status)85 owner = ownerFromStatus(task.status)
67 date_created = bug.date_created.strftime("%Y/%m/%d")86 date_created = bug.date_created.strftime("%Y/%m/%d")
68 c.writerow([bug.title, link, task.status, milestone, rationale.encode('utf_8'), owner, date_created])87 c.writerow(
88 [
89 bug.title,
90 link,
91 task.status,
92 milestone,
93 rationale.encode("utf_8"),
94 owner,
95 date_created,
96 ]
97 )
6998
70# First pass, phase two: Fix Released bugs99 # First pass, phase two: Fix Released bugs
71 for task in series.searchTasks(status="Fix Released"): 100 for task in series.searchTasks(status="Fix Released"):
72 bug = taskToBug(task)101 bug = taskToBug(task)
73 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'102 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
74# if not 'upstream-risky' not in bug.tags:103 # if not 'upstream-risky' not in bug.tags:
75# continue104 # continue
76 if task.milestone is None:105 if task.milestone is None:
77 milestone = "TBD"106 milestone = "TBD"
78 else:107 else:
@@ -80,8 +109,17 @@ if __name__ == '__main__':
80 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)109 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
81 rationale = rationaleFromDescription(bug.description)110 rationale = rationaleFromDescription(bug.description)
82 if (not rationale) and (task.milestone is None):111 if (not rationale) and (task.milestone is None):
83 rationale=rationaleBoilerplate112 rationale = rationaleBoilerplate
84 owner = ownerFromStatus(task.status)113 owner = ownerFromStatus(task.status)
85 date_created = bug.date_created.strftime("%Y/%m/%d")114 date_created = bug.date_created.strftime("%Y/%m/%d")
86 c.writerow([bug.title, link, task.status, milestone, rationale.encode('utf_8'), owner, date_created])115 c.writerow(
87116 [
117 bug.title,
118 link,
119 task.status,
120 milestone,
121 rationale.encode("utf_8"),
122 owner,
123 date_created,
124 ]
125 )
diff --git a/lp-scripts/pearl-biweekly-report.csv.py b/lp-scripts/pearl-biweekly-report.csv.py
index 454c993..bfebacc 100644
--- a/lp-scripts/pearl-biweekly-report.csv.py
+++ b/lp-scripts/pearl-biweekly-report.csv.py
@@ -1,80 +1,99 @@
1#!/usr/bin/python3
1# Change History2# Change History
2# Modify encode utf_8 to byte code in Rationale/Comment3# Modify encode utf_8 to byte code in Rationale/Comment
3# Add Date_created column for creating date for bug 4# Add Date_created column for creating date for bug
4# Add Scope column for showing impact for all arc or arch-arm64 or D05 Boad only5# Add Scope column for showing impact for all arc or arch-arm64 or D05 Boad only
56
6#!/usr/bin/python3
7
8import argparse7import argparse
9import csv8import csv
10from launchpadlib.launchpad import Launchpad9from launchpadlib.launchpad import Launchpad
1110
12rationaleSectionHeader="[16.04.3 Risk Comments]"11rationaleSectionHeader = "[16.04.3 Risk Comments]"
13rationaleBoilerplate="Still under investigation, not yet root-caused."12rationaleBoilerplate = "Still under investigation, not yet root-caused."
13
1414
15def taskToBug(task):15def taskToBug(task):
16 bugid = int(task.self_link.split('/')[-1])16 bugid = int(task.self_link.split("/")[-1])
17 return(lp.bugs[bugid])17 return lp.bugs[bugid]
18
1819
19def ownerFromStatus(status):20def ownerFromStatus(status):
20 if 'Incomplete' in status:21 if "Incomplete" in status:
21 owner='Huawei'22 owner = "Huawei"
22 else:23 else:
23 owner='Canonical'24 owner = "Canonical"
24 return(owner)25 return owner
26
2527
26def rationaleFromDescription(des):28def rationaleFromDescription(des):
27 export_rationale_flag=0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section29 export_rationale_flag = (
28 rationale=""30 0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
29 for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export31 )
32 rationale = ""
33 for (
34 des_line
35 ) in (
36 des.splitlines()
37 ): # Loop through the bug description line-by-line looking for sections to export
30 if des_line == rationaleSectionHeader:38 if des_line == rationaleSectionHeader:
31 export_rationale_flag=139 export_rationale_flag = 1
32 else:40 else:
33 if export_rationale_flag==1:41 if export_rationale_flag == 1:
34 if des_line=="":42 if des_line == "":
35 export_rationale_flag=043 export_rationale_flag = 0
36 else:44 else:
37 rationale+=des_line45 rationale += des_line
38 return(rationale)46 return rationale
3947
4048
41def checkScopeTags(tags):49def checkScopeTags(tags):
42 scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d05-only']50 scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d05-only"]
43 scope = set(scopeTags).intersection(tags)51 scope = set(scopeTags).intersection(tags)
44 for i in scope:52 for i in scope:
45 if i == 'scope-arch-all':53 if i == "scope-arch-all":
46 i = 'Generic'54 i = "Generic"
47 elif i == 'scope-arch-arm64':55 elif i == "scope-arch-arm64":
48 i = 'ARM64 generic'56 i = "ARM64 generic"
49 elif i == 'scope-d05-only':57 elif i == "scope-d05-only":
50 i = 'D05 only'58 i = "D05 only"
51 return(i)59 return i
5260
53 return('Unknown')61 return "Unknown"
5462
5563
56if __name__ == '__main__':64if __name__ == "__main__":
57 parser = argparse.ArgumentParser()65 parser = argparse.ArgumentParser()
58 parser.add_argument("-o", "--outfile", required=True)66 parser.add_argument("-o", "--outfile", required=True)
59 args = parser.parse_args()67 args = parser.parse_args()
6068
61 lp = Launchpad.login_with('lpbugs', 'production', version='devel')69 lp = Launchpad.login_with("lpbugs", "production", version="devel")
6270
63 pearl = lp.projects['pearl']71 pearl = lp.projects["pearl"]
6472
65 with open(args.outfile, 'w') as csvfile:73 with open(args.outfile, "w") as csvfile:
66 c = csv.writer(csvfile)74 c = csv.writer(csvfile)
67 c.writerow(["Title", "Link", "Status", "Milestone", "Scope","Rationale/Comment", "Owner", "DateCreated"])75 c.writerow(
68# First pass: patchset bugs76 [
77 "Title",
78 "Link",
79 "Status",
80 "Milestone",
81 "Scope",
82 "Rationale/Comment",
83 "Owner",
84 "DateCreated",
85 ]
86 )
87 # First pass: patchset bugs
69 for series in pearl.series:88 for series in pearl.series:
70 if series.name not in ['ubuntu-16.04']:89 if series.name not in ["ubuntu-16.04"]:
71 continue90 continue
72# First pass, phase one: search for the 'open' bugs91 # First pass, phase one: search for the 'open' bugs
73 for task in series.searchTasks(): 92 for task in series.searchTasks():
74 bug = taskToBug(task)93 bug = taskToBug(task)
75 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'94 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
76# if 'upstream-risky' not in bug.tags:95 # if 'upstream-risky' not in bug.tags:
77# continue96 # continue
78 if task.milestone is None:97 if task.milestone is None:
79 milestone = "TBD"98 milestone = "TBD"
80 else:99 else:
@@ -82,18 +101,29 @@ if __name__ == '__main__':
82 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)101 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
83 rationale = rationaleFromDescription(bug.description)102 rationale = rationaleFromDescription(bug.description)
84 if (not rationale) and (task.milestone is None):103 if (not rationale) and (task.milestone is None):
85 rationale=rationaleBoilerplate104 rationale = rationaleBoilerplate
86 scope = checkScopeTags(bug.tags)105 scope = checkScopeTags(bug.tags)
87 owner = ownerFromStatus(task.status)106 owner = ownerFromStatus(task.status)
88 date_created = bug.date_created.strftime("%Y/%m/%d")107 date_created = bug.date_created.strftime("%Y/%m/%d")
89 c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])108 c.writerow(
90109 [
91# First pass, phase two: Fix Released bugs110 bug.title,
111 link,
112 task.status,
113 milestone,
114 scope,
115 rationale.encode("utf_8"),
116 owner,
117 date_created,
118 ]
119 )
120
121 # First pass, phase two: Fix Released bugs
92 for task in series.searchTasks(status="Fix Released"):122 for task in series.searchTasks(status="Fix Released"):
93 bug = taskToBug(task)123 bug = taskToBug(task)
94 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'124 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
95# if not 'upstream-risky' not in bug.tags:125 # if not 'upstream-risky' not in bug.tags:
96# continue126 # continue
97 if task.milestone is None:127 if task.milestone is None:
98 milestone = "TBD"128 milestone = "TBD"
99 else:129 else:
@@ -101,9 +131,19 @@ if __name__ == '__main__':
101 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)131 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
102 rationale = rationaleFromDescription(bug.description)132 rationale = rationaleFromDescription(bug.description)
103 if (not rationale) and (task.milestone is None):133 if (not rationale) and (task.milestone is None):
104 rationale=rationaleBoilerplate134 rationale = rationaleBoilerplate
105 scope = checkScopeTags(bug.tags)135 scope = checkScopeTags(bug.tags)
106 owner = ownerFromStatus(task.status)136 owner = ownerFromStatus(task.status)
107 date_created = bug.date_created.strftime("%Y/%m/%d")137 date_created = bug.date_created.strftime("%Y/%m/%d")
108 c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])138 c.writerow(
109139 [
140 bug.title,
141 link,
142 task.status,
143 milestone,
144 scope,
145 rationale.encode("utf_8"),
146 owner,
147 date_created,
148 ]
149 )
diff --git a/lp-scripts/pearl-bug-csv-summary.py b/lp-scripts/pearl-bug-csv-summary.py
index a1a0b35..ad4a049 100755
--- a/lp-scripts/pearl-bug-csv-summary.py
+++ b/lp-scripts/pearl-bug-csv-summary.py
@@ -7,18 +7,19 @@ from LaunchpadBugBucketer import LaunchpadBugBucketer
77
8class PearlBugBucketer(LaunchpadBugBucketer):8class PearlBugBucketer(LaunchpadBugBucketer):
9 def __init__(self):9 def __init__(self):
10 LaunchpadBugBucketer.__init__(self, 'pearl', 'ubuntu-16.04',10 LaunchpadBugBucketer.__init__(
11 requiredTags=['upstream-risky'])11 self, "pearl", "ubuntu-16.04", requiredTags=["upstream-risky"]
12 )
1213
13 def is_green(self, task):14 def is_green(self, task):
14 if task.status in ['Fix Committed', 'Fix Released']:15 if task.status in ["Fix Committed", "Fix Released"]:
15 return True16 return True
16 return False17 return False
1718
18 def is_amber(self, task):19 def is_amber(self, task):
19 if self.is_green(task):20 if self.is_green(task):
20 return False21 return False
21 elif task.milestone and task.milestone.name == 'ubuntu-16.04.3':22 elif task.milestone and task.milestone.name == "ubuntu-16.04.3":
22 return True23 return True
23 return False24 return False
2425
@@ -28,16 +29,16 @@ class PearlBugBucketer(LaunchpadBugBucketer):
28 return True29 return True
2930
3031
31if __name__ == '__main__':32if __name__ == "__main__":
32 parser = argparse.ArgumentParser()33 parser = argparse.ArgumentParser()
33 parser.add_argument("-o", "--outfile")34 parser.add_argument("-o", "--outfile")
34 args = parser.parse_args()35 args = parser.parse_args()
3536
36 s = PearlBugBucketer()37 s = PearlBugBucketer()
3738
38 with open(args.outfile, 'w') as csvfile:39 with open(args.outfile, "w") as csvfile:
39 c = csv.writer(csvfile)40 c = csv.writer(csvfile)
40 c.writerow(['Title', 'Bug ID', 'Importance', 'Status', 'RAG Risk'])41 c.writerow(["Title", "Bug ID", "Importance", "Status", "RAG Risk"])
41 for bucket in s.keys():42 for bucket in s.keys():
42 for task in s[bucket]:43 for task in s[bucket]:
43 bug = s.taskToBug(task)44 bug = s.taskToBug(task)
diff --git a/lp-scripts/pearl-risky-patch-schedule.py b/lp-scripts/pearl-risky-patch-schedule.py
index a22f493..01d546e 100755
--- a/lp-scripts/pearl-risky-patch-schedule.py
+++ b/lp-scripts/pearl-risky-patch-schedule.py
@@ -4,29 +4,31 @@ import argparse
4import csv4import csv
5from launchpadlib.launchpad import Launchpad5from launchpadlib.launchpad import Launchpad
66
7
7def taskToBug(task):8def taskToBug(task):
8 bugid = int(task.self_link.split('/')[-1])9 bugid = int(task.self_link.split("/")[-1])
9 return(lp.bugs[bugid])10 return lp.bugs[bugid]
10 11
11if __name__ == '__main__':12
13if __name__ == "__main__":
12 parser = argparse.ArgumentParser()14 parser = argparse.ArgumentParser()
13 parser.add_argument("-o", "--outfile", required=True)15 parser.add_argument("-o", "--outfile", required=True)
14 args = parser.parse_args()16 args = parser.parse_args()
1517
16 lp = Launchpad.login_with('lpbugs', 'production', version='devel')18 lp = Launchpad.login_with("lpbugs", "production", version="devel")
1719
18 pearl = lp.projects['pearl']20 pearl = lp.projects["pearl"]
1921
20 with open(args.outfile, 'w') as csvfile:22 with open(args.outfile, "w") as csvfile:
21 c = csv.writer(csvfile)23 c = csv.writer(csvfile)
22 for series in pearl.series:24 for series in pearl.series:
23 if series.name not in ['ubuntu-17.04']:25 if series.name not in ["ubuntu-17.04"]:
24 continue26 continue
25 for task in series.searchTasks(): 27 for task in series.searchTasks():
26 bug = taskToBug(task)28 bug = taskToBug(task)
27 # All kernel patchset bugs in the pearl project are tagged29 # All kernel patchset bugs in the pearl project are tagged
28 # 'upstream-risky'30 # 'upstream-risky'
29 if 'upstream-risky' not in bug.tags:31 if "upstream-risky" not in bug.tags:
30 continue32 continue
31 if task.milestone is None:33 if task.milestone is None:
32 date = "TBD"34 date = "TBD"
diff --git a/lp-scripts/pearl2-biweekly-report.csv.py b/lp-scripts/pearl2-biweekly-report.csv.py
index b005620..a5a75d9 100755
--- a/lp-scripts/pearl2-biweekly-report.csv.py
+++ b/lp-scripts/pearl2-biweekly-report.csv.py
@@ -10,94 +10,110 @@ import argparse
10import csv10import csv
11from launchpadlib.launchpad import Launchpad11from launchpadlib.launchpad import Launchpad
1212
13rationaleSectionHeader="[18.04.1 Risk Comments]"13rationaleSectionHeader = "[18.04.1 Risk Comments]"
14rationaleBoilerplate="Still under investigation, not yet root-caused."14rationaleBoilerplate = "Still under investigation, not yet root-caused."
15
1516
16def taskToBug(task):17def taskToBug(task):
17 bugid = int(task.self_link.split('/')[-1])18 bugid = int(task.self_link.split("/")[-1])
18 return(lp.bugs[bugid])19 return lp.bugs[bugid]
20
1921
20def ownerFromStatus(status):22def ownerFromStatus(status):
21 if 'Incomplete' in status:23 if "Incomplete" in status:
22 owner='Huawei'24 owner = "Huawei"
23 else:25 else:
24 owner='Canonical'26 owner = "Canonical"
25 return(owner)27 return owner
28
2629
27def rationaleFromDescription(des):30def rationaleFromDescription(des):
28 export_rationale_flag=0 # Flag to detect the start of the "[18.04.1 Risk Comments]" section31 export_rationale_flag = (
29 rationale=""32 0 # Flag to detect the start of the "[18.04.1 Risk Comments]" section
30 for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export33 )
34 rationale = ""
35 for (
36 des_line
37 ) in (
38 des.splitlines()
39 ): # Loop through the bug description line-by-line looking for sections to export
31 if des_line == rationaleSectionHeader:40 if des_line == rationaleSectionHeader:
32 export_rationale_flag=141 export_rationale_flag = 1
33 else:42 else:
34 if export_rationale_flag==1:43 if export_rationale_flag == 1:
35 if des_line=="":44 if des_line == "":
36 export_rationale_flag=045 export_rationale_flag = 0
37 else:46 else:
38 rationale+=des_line47 rationale += des_line
39 return(rationale)48 return rationale
4049
4150
42def checkScopeTags(tags):51def checkScopeTags(tags):
43 scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d06-only']52 scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d06-only"]
44 scope = set(scopeTags).intersection(tags)53 scope = set(scopeTags).intersection(tags)
45 for i in scope:54 for i in scope:
46 if i == 'scope-arch-all':55 if i == "scope-arch-all":
47 i = 'Generic'56 i = "Generic"
48 elif i == 'scope-arch-arm64':57 elif i == "scope-arch-arm64":
49 i = 'ARM64 generic'58 i = "ARM64 generic"
50 elif i == 'scope-d06-only':59 elif i == "scope-d06-only":
51 i = 'D06 only'60 i = "D06 only"
52 return(i)61 return i
62
63 return "Unknown"
5364
54 return('Unknown')
5565
56def getMilestones(series_array):66def getMilestones(series_array):
57 milestones=[]67 milestones = []
58 for series in series_array:68 for series in series_array:
59 milestone_url=series['milestone_link']69 milestone_url = series["milestone_link"]
60 if milestone_url is not None:70 if milestone_url is not None:
61 milestone_name=milestone_url.rsplit('/',1)71 milestone_name = milestone_url.rsplit("/", 1)
62 milestones.append(milestone_name[-1])72 milestones.append(milestone_name[-1])
63 return milestones73 return milestones
6474
75
65def getUoseMilestone(series_array):76def getUoseMilestone(series_array):
66 milestones=getMilestones(series_array)77 milestones = getMilestones(series_array)
67 uose_milestone=""78 uose_milestone = ""
68 for milestone in milestones:79 for milestone in milestones:
69 if "uose" in milestone:80 if "uose" in milestone:
70 uose_milestone=milestone81 uose_milestone = milestone
71 return uose_milestone82 return uose_milestone
7283
7384
74if __name__ == '__main__':85if __name__ == "__main__":
75 parser = argparse.ArgumentParser()86 parser = argparse.ArgumentParser()
76 parser.add_argument("-o", "--outfile", required=True)87 parser.add_argument("-o", "--outfile", required=True)
77 args = parser.parse_args()88 args = parser.parse_args()
7889
79 lp = Launchpad.login_with('lpbugs', 'production', version='devel')90 lp = Launchpad.login_with("lpbugs", "production", version="devel")
8091
81 pearl = lp.projects['pearl2']92 pearl = lp.projects["pearl2"]
8293
83 with open(args.outfile, 'w') as csvfile:94 with open(args.outfile, "w") as csvfile:
84 c = csv.writer(csvfile)95 c = csv.writer(csvfile)
85 c.writerow(["Title", "Link", "Status", "Milestone", "Owner", "DateCreated","Comments"])96 c.writerow(
86# First pass: search for the 'open' bugs97 ["Title", "Link", "Status", "Milestone", "Owner", "DateCreated", "Comments"]
98 )
99 # First pass: search for the 'open' bugs
87 for task in pearl.searchTasks():100 for task in pearl.searchTasks():
88 uose_milestone=getUoseMilestone(task.related_tasks.entries)101 uose_milestone = getUoseMilestone(task.related_tasks.entries)
89 bug = taskToBug(task)102 bug = taskToBug(task)
90 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)103 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
91 owner = ownerFromStatus(task.status)104 owner = ownerFromStatus(task.status)
92 date_created = bug.date_created.strftime("%Y/%m/%d")105 date_created = bug.date_created.strftime("%Y/%m/%d")
93 c.writerow([bug.title, link, task.status, uose_milestone, owner, date_created])106 c.writerow(
107 [bug.title, link, task.status, uose_milestone, owner, date_created]
108 )
94109
95# Second pass: search for the 'Fix Released' bugs110 # Second pass: search for the 'Fix Released' bugs
96 for task in pearl.searchTasks(status="Fix Released"):111 for task in pearl.searchTasks(status="Fix Released"):
97 bug = taskToBug(task)112 bug = taskToBug(task)
98 uose_milestone=getUoseMilestone(task.related_tasks.entries)113 uose_milestone = getUoseMilestone(task.related_tasks.entries)
99 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)114 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
100 owner = ownerFromStatus(task.status)115 owner = ownerFromStatus(task.status)
101 date_created = bug.date_created.strftime("%Y/%m/%d")116 date_created = bug.date_created.strftime("%Y/%m/%d")
102 c.writerow([bug.title, link, task.status, uose_milestone, owner, date_created])117 c.writerow(
103118 [bug.title, link, task.status, uose_milestone, owner, date_created]
119 )
diff --git a/lp-scripts/pearl2-d06-18.04-patch-status.py b/lp-scripts/pearl2-d06-18.04-patch-status.py
index 2d56d05..79316bc 100755
--- a/lp-scripts/pearl2-d06-18.04-patch-status.py
+++ b/lp-scripts/pearl2-d06-18.04-patch-status.py
@@ -2,29 +2,34 @@
22
3import argparse3import argparse
4import csv4import csv
5import string
6from launchpadlib.launchpad import Launchpad5from launchpadlib.launchpad import Launchpad
76
7
8def taskToBug(task):8def taskToBug(task):
9 bugid = int(task.self_link.split('/')[-1])9 bugid = int(task.self_link.split("/")[-1])
10 return(lp.bugs[bugid])10 return lp.bugs[bugid]
1111
1212
13Pre18041Milestones = ['ubuntu-18.04-ga', 'ubuntu-18.04-sru-1',13Pre18041Milestones = [
14 'ubuntu-18.04-sru-2', 'ubuntu-18.04-sru-3',14 "ubuntu-18.04-ga",
15 'ubuntu-18.04-sru-4', 'ubuntu-18.04.1']15 "ubuntu-18.04-sru-1",
16 "ubuntu-18.04-sru-2",
17 "ubuntu-18.04-sru-3",
18 "ubuntu-18.04-sru-4",
19 "ubuntu-18.04.1",
20]
1621
17if __name__ == '__main__':22if __name__ == "__main__":
18 parser = argparse.ArgumentParser()23 parser = argparse.ArgumentParser()
19 parser.add_argument("-o", "--outfile", required=True)24 parser.add_argument("-o", "--outfile", required=True)
20 args = parser.parse_args()25 args = parser.parse_args()
2126
22 lp = Launchpad.login_with('lpbugs', 'production', version='devel')27 lp = Launchpad.login_with("lpbugs", "production", version="devel")
2328
24 pearl = lp.projects['pearl2']29 pearl = lp.projects["pearl2"]
25 series = pearl.getSeries(name='ubuntu-18.04')30 series = pearl.getSeries(name="ubuntu-18.04")
2631
27 with open(args.outfile, 'w') as csvfile:32 with open(args.outfile, "w") as csvfile:
28 c = csv.writer(csvfile)33 c = csv.writer(csvfile)
29 c.writerow(["Title", "Link", "Status", "Expected"])34 c.writerow(["Title", "Link", "Status", "Expected"])
30 for task in series.searchTasks(status=[]):35 for task in series.searchTasks(status=[]):
@@ -34,8 +39,8 @@ if __name__ == '__main__':
34 # patches will land in, or it should be tagged as risky.39 # patches will land in, or it should be tagged as risky.
35 if task.status in ["Invalid", "Won't Fix"]:40 if task.status in ["Invalid", "Won't Fix"]:
36 continue41 continue
37 if task.status == 'Incomplete':42 if task.status == "Incomplete":
38 if 'needs-sru-justification' in bug.tags:43 if "needs-sru-justification" in bug.tags:
39 expected = "Needs SRU Justification"44 expected = "Needs SRU Justification"
40 else:45 else:
41 expected = "Need input from HiSilicon"46 expected = "Need input from HiSilicon"
diff --git a/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py b/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py
index a29014e..01dc923 100755
--- a/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py
+++ b/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py
@@ -30,7 +30,7 @@ def get_risk(bug):
30 for r in RiskyTagMap.keys():30 for r in RiskyTagMap.keys():
31 if RiskyTagMap[r] in bug.tags:31 if RiskyTagMap[r] in bug.tags:
32 # Only one tag should be found32 # Only one tag should be found
33 assert(found is None)33 assert found is None
34 found = r34 found = r
35 return found35 return found
3636
@@ -42,8 +42,7 @@ def set_risk(bug, risk):
42 continue42 continue
43 rmtag = RiskyTagMap[r]43 rmtag = RiskyTagMap[r]
44 if rmtag in bug.tags:44 if rmtag in bug.tags:
45 sys.stderr.write("Removing %s tag from %s\n" %45 sys.stderr.write("Removing %s tag from %s\n" % (rmtag, bug.web_link))
46 (rmtag, bug.web_link))
47 newtags = list(bug.tags)46 newtags = list(bug.tags)
48 newtags.remove(rmtag)47 newtags.remove(rmtag)
49 bug.tags = newtags48 bug.tags = newtags
@@ -55,10 +54,10 @@ def set_risk(bug, risk):
55 bug.lp_save()54 bug.lp_save()
5655
5756
58if __name__ == '__main__':57if __name__ == "__main__":
59 lp = Launchpad.login_with('lpbugs', 'production', version='devel')58 lp = Launchpad.login_with("lpbugs", "production", version="devel")
6059
61 pearl2 = lp.projects['pearl2']60 pearl2 = lp.projects["pearl2"]
62 target_milestone = "ubuntu-18.04.3"61 target_milestone = "ubuntu-18.04.3"
63 target_date = None62 target_date = None
64 # Find the target date of our milestone. We can compare this with63 # Find the target date of our milestone. We can compare this with
@@ -68,9 +67,9 @@ if __name__ == '__main__':
68 if m.name in [target_milestone]:67 if m.name in [target_milestone]:
69 target_date = m.date_targeted68 target_date = m.date_targeted
70 break69 break
71 assert(target_date is not None)70 assert target_date is not None
7271
73 series = pearl2.getSeries(name='ubuntu-18.04-hwe')72 series = pearl2.getSeries(name="ubuntu-18.04-hwe")
74 for task in series.searchTasks():73 for task in series.searchTasks():
75 if task.milestone is not None:74 if task.milestone is not None:
76 tdelta = task.milestone.date_targeted - target_date75 tdelta = task.milestone.date_targeted - target_date
@@ -85,8 +84,13 @@ if __name__ == '__main__':
85 continue84 continue
86 # Now process the ones w/ no milestone set.85 # Now process the ones w/ no milestone set.
87 # These by definition should all have milestones set.86 # These by definition should all have milestones set.
88 assert(task.status not in ["Opinion", "Invalid", "Won't Fix",87 assert task.status not in [
89 "Fix Committed", "Fix Released"])88 "Opinion",
89 "Invalid",
90 "Won't Fix",
91 "Fix Committed",
92 "Fix Released",
93 ]
90 if task.status == "Incomplete":94 if task.status == "Incomplete":
91 set_risk(task.bug, Risky.HIGH)95 set_risk(task.bug, Risky.HIGH)
92 continue96 continue
diff --git a/lp-scripts/project-bug-lint.py b/lp-scripts/project-bug-lint.py
index 48f81db..5f62a01 100755
--- a/lp-scripts/project-bug-lint.py
+++ b/lp-scripts/project-bug-lint.py
@@ -8,33 +8,42 @@ import sys
8class BugProperty:8class BugProperty:
9 def __init__(self, property):9 def __init__(self, property):
10 self.index = self.PropertyList.index(property)10 self.index = self.PropertyList.index(property)
11 11
12 def __eq__(self, other):12 def __eq__(self, other):
13 return(self.index == other.index)13 return self.index == other.index
1414
15 def __ne__(self, other):15 def __ne__(self, other):
16 return(self.index != other.index)16 return self.index != other.index
1717
18 def __lt__(self, other):18 def __lt__(self, other):
19 return(self.index < other.index)19 return self.index < other.index
2020
21 def __le__(self, other):21 def __le__(self, other):
22 return(self.index <= other.index)22 return self.index <= other.index
2323
24 def __gt__(self, other):24 def __gt__(self, other):
25 return(self.index > other.index)25 return self.index > other.index
2626
27 def __ge__(self, other):27 def __ge__(self, other):
28 return(self.index >= other.index)28 return self.index >= other.index
2929
30 def __repr__(self):30 def __repr__(self):
31 return(self.PropertyList[self.index])31 return self.PropertyList[self.index]
3232
3333
34class BugStatus(BugProperty):34class BugStatus(BugProperty):
35 PropertyList = ['New', 'Incomplete', 'Opinion', 'Invalid',35 PropertyList = [
36 'Won\'t Fix', 'Confirmed', 'Triaged', 'In Progress',36 "New",
37 'Fix Committed', 'Fix Released']37 "Incomplete",
38 "Opinion",
39 "Invalid",
40 "Won't Fix",
41 "Confirmed",
42 "Triaged",
43 "In Progress",
44 "Fix Committed",
45 "Fix Released",
46 ]
3847
39 # min/max could ideally be in the baseclass, but I don't know48 # min/max could ideally be in the baseclass, but I don't know
40 # how to do that and stil refer to the correct PropertyList49 # how to do that and stil refer to the correct PropertyList
@@ -45,12 +54,12 @@ class BugStatus(BugProperty):
45 return BugStatus(BugStatus.PropertyList[-1])54 return BugStatus(BugStatus.PropertyList[-1])
4655
47 def isTerminalState(self):56 def isTerminalState(self):
48 terminalStates = ['Fix Released', 'Invalid', 'Won\'t Fix']57 terminalStates = ["Fix Released", "Invalid", "Won't Fix"]
49 return(self.PropertyList[self.index] in terminalStates)58 return self.PropertyList[self.index] in terminalStates
59
5060
51class BugImportance(BugProperty):61class BugImportance(BugProperty):
52 PropertyList = ['Undecided', 'Wishlist', 'Low',62 PropertyList = ["Undecided", "Wishlist", "Low", "Medium", "High", "Critical"]
53 'Medium', 'High', 'Critical']
5463
55 # min/max could ideally be in the baseclass, but I don't know64 # min/max could ideally be in the baseclass, but I don't know
56 # how to do that and stil refer to the correct PropertyList65 # how to do that and stil refer to the correct PropertyList
@@ -60,11 +69,13 @@ class BugImportance(BugProperty):
60 def max():69 def max():
61 return BugImportance(BugImportance.PropertyList[-1])70 return BugImportance(BugImportance.PropertyList[-1])
6271
72
63class BugTask:73class BugTask:
64 def __init__(self, lptask):74 def __init__(self, lptask):
65 self.status = BugStatus(lptask.status)75 self.status = BugStatus(lptask.status)
66 self.importance = BugImportance(lptask.importance)76 self.importance = BugImportance(lptask.importance)
6777
78
68class Bug:79class Bug:
69 def __init__(self):80 def __init__(self):
70 self.defaultTask = None81 self.defaultTask = None
@@ -80,24 +91,29 @@ class Bug:
80 self.targetedTasks[series] = BugTask(task)91 self.targetedTasks[series] = BugTask(task)
8192
82 def getTargetedTasks(self):93 def getTargetedTasks(self):
83 return(self.targetedTasks)94 return self.targetedTasks
95
8496
85def checkScopeTags(lpbug):97def checkScopeTags(lpbug):
86 scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d05-only']98 scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d05-only"]
87 common = set(scopeTags).intersection(lpbug.tags)99 common = set(scopeTags).intersection(lpbug.tags)
88 if len(common) == 0:100 if len(common) == 0:
89 sys.stdout.write("http://launchpad.net/bugs/%d has no scope tag\n" % (bugid))101 sys.stdout.write("http://launchpad.net/bugs/%d has no scope tag\n" % (bugid))
90 if len(common) > 1:102 if len(common) > 1:
91 sys.stdout.write("http://launchpad.net/bugs/%d has multiple scope tags\n" % (bugid))103 sys.stdout.write(
104 "http://launchpad.net/bugs/%d has multiple scope tags\n" % (bugid)
105 )
106
92107
93def taskToBugId(task):108def taskToBugId(task):
94 return(int(task.self_link.split('/')[-1]))109 return int(task.self_link.split("/")[-1])
110
95111
96if __name__ == '__main__':112if __name__ == "__main__":
97 parser = argparse.ArgumentParser()113 parser = argparse.ArgumentParser()
98 parser.add_argument("-p", "--project", required=True)114 parser.add_argument("-p", "--project", required=True)
99 args = parser.parse_args()115 args = parser.parse_args()
100 lp = Launchpad.login_with('lpbugs', 'production', version='devel')116 lp = Launchpad.login_with("lpbugs", "production", version="devel")
101 project = lp.projects[args.project]117 project = lp.projects[args.project]
102118
103 bugs = {}119 bugs = {}
@@ -114,7 +130,10 @@ if __name__ == '__main__':
114 if bugid in bugs.keys():130 if bugid in bugs.keys():
115 bugs[bugid].addTargetedTask(series.name, task)131 bugs[bugid].addTargetedTask(series.name, task)
116 else:132 else:
117 sys.stderr.write("WARNING: http://launchpad.net/bugs/%d does not have a default task\n" % (bugid))133 sys.stderr.write(
134 "WARNING: http://launchpad.net/bugs/%d does not have a default task\n"
135 % (bugid)
136 )
118137
119 # Now process them.138 # Now process them.
120 for bugid in bugs.keys():139 for bugid in bugs.keys():
@@ -123,7 +142,10 @@ if __name__ == '__main__':
123 if len(targetedTasks) == 0:142 if len(targetedTasks) == 0:
124 defaultStatus = bug.getDefaultTask().status143 defaultStatus = bug.getDefaultTask().status
125 if not defaultStatus.isTerminalState():144 if not defaultStatus.isTerminalState():
126 sys.stderr.write("WARNING: http://launchpad.net/bugs/%d only has a default task\n" % (bugid))145 sys.stderr.write(
146 "WARNING: http://launchpad.net/bugs/%d only has a default task\n"
147 % (bugid)
148 )
127 continue149 continue
128150
129 statusList = []151 statusList = []
@@ -144,10 +166,16 @@ if __name__ == '__main__':
144 currentStatus = defaultTask.status166 currentStatus = defaultTask.status
145 currentImportance = defaultTask.importance167 currentImportance = defaultTask.importance
146 if targetStatus and targetStatus != currentStatus:168 if targetStatus and targetStatus != currentStatus:
147 sys.stdout.write("http://launchpad.net/bugs/%d status %s -> %s\n" % (bugid, currentStatus, targetStatus))169 sys.stdout.write(
170 "http://launchpad.net/bugs/%d status %s -> %s\n"
171 % (bugid, currentStatus, targetStatus)
172 )
148 if targetImportance != currentImportance:173 if targetImportance != currentImportance:
149 sys.stdout.write("http://launchpad.net/bugs/%d importance %s -> %s\n" % (bugid, currentImportance, targetImportance))174 sys.stdout.write(
175 "http://launchpad.net/bugs/%d importance %s -> %s\n"
176 % (bugid, currentImportance, targetImportance)
177 )
150178
151 if args.project == 'pearl':179 if args.project == "pearl":
152 if not defaultTask.status.isTerminalState():180 if not defaultTask.status.isTerminalState():
153 checkScopeTags(lp.bugs[bugid])181 checkScopeTags(lp.bugs[bugid])
diff --git a/sysadmin-tools/gen_conserver_cf.py b/sysadmin-tools/gen_conserver_cf.py
index 065a30b..7153ed7 100755
--- a/sysadmin-tools/gen_conserver_cf.py
+++ b/sysadmin-tools/gen_conserver_cf.py
@@ -47,30 +47,30 @@ console {srv} {{
47 exec ipmitool -I lanplus -H {addr} -U {user} -P {pwd} sol activate;47 exec ipmitool -I lanplus -H {addr} -U {user} -P {pwd} sol activate;
48}}"""48}}"""
4949
50if __name__ == '__main__':50if __name__ == "__main__":
51 arg_parser = argparse.ArgumentParser()51 arg_parser = argparse.ArgumentParser()
52 arg_parser.add_argument("machines_yaml", help="Lab's machines.yaml file")52 arg_parser.add_argument("machines_yaml", help="Lab's machines.yaml file")
53 arg_parser.add_argument("-o", "--outfile", help="Output filename",53 arg_parser.add_argument("-o", "--outfile", help="Output filename", required=True)
54 required=True)
55 args = arg_parser.parse_args()54 args = arg_parser.parse_args()
5655
57 with open(args.machines_yaml) as f:56 with open(args.machines_yaml) as f:
58 machines = yaml.safe_load(f)57 machines = yaml.safe_load(f)
5958
60 with open(args.outfile, 'w') as outfile:59 with open(args.outfile, "w") as outfile:
61 outfile.write(header.format(progname=arg_parser.prog))60 outfile.write(header.format(progname=arg_parser.prog))
62 for server in machines:61 for server in machines:
63 # bmc is required for conserver to attach62 # bmc is required for conserver to attach
64 if ("bmc" not in machines[server]):63 if "bmc" not in machines[server]:
65 continue64 continue
66 bmc_info = machines[server]["bmc"]65 bmc_info = machines[server]["bmc"]
67 # type is required so the conserver knows how to attach66 # type is required so the conserver knows how to attach
68 if ("type" not in bmc_info):67 if "type" not in bmc_info:
69 continue68 continue
70 if (bmc_info["type"] == "ipmi"):69 if bmc_info["type"] == "ipmi":
71 addr = bmc_info["address"].replace('#', '\\#')70 addr = bmc_info["address"].replace("#", "\\#")
72 user = bmc_info["user"].replace('#', '\\#')71 user = bmc_info["user"].replace("#", "\\#")
73 pwd = bmc_info["password"].replace('#', '\\#')72 pwd = bmc_info["password"].replace("#", "\\#")
74 outfile.write(ipmi_sol_entry.format(srv=server, addr=addr,73 outfile.write(
75 user=user, pwd=pwd))74 ipmi_sol_entry.format(srv=server, addr=addr, user=user, pwd=pwd)
75 )
76 outfile.write(footer.format())76 outfile.write(footer.format())

Subscribers

People subscribed via source and target branches

to all changes: