Merge ~pwlars/testflinger-cli:undo-undo-config into testflinger-cli:master

Proposed by Paul Larson
Status: Merged
Approved by: Paul Larson
Approved revision: aaaa5b133da4a10aeaa4f80734b78aaafd32e137
Merged at revision: cb4c3946c55a4a347698a2eda46af266c1784625
Proposed branch: ~pwlars/testflinger-cli:undo-undo-config
Merge into: testflinger-cli:master
Diff against target: 159 lines (+85/-8)
3 files modified
setup.py (+2/-3)
testflinger_cli/__init__.py (+36/-5)
testflinger_cli/config.py (+47/-0)
Reviewer Review Type Date Requested Status
Sheila Miguez (community) Approve
Review via email: mp+390630@code.launchpad.net

Description of the change

this is almost identical to the previous config branch, except we found out that the jenkins server where the cli is run from has problems with the current version of xdg, because it uses python3.5.

I'm restricting this to the previous xdg version for now, with a comment about when we can remove the restriction. I've also tested this *on* that system in a virtualenv to confirm it works.

To post a comment you must log in.
Revision history for this message
Sheila Miguez (codersquid) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/setup.py b/setup.py
2index 736eddc..ce13443 100755
3--- a/setup.py
4+++ b/setup.py
5@@ -1,5 +1,5 @@
6 #!/usr/bin/env python
7-# Copyright (C) 2017-2019 Canonical
8+# Copyright (C) 2017-2020 Canonical
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12@@ -16,7 +16,7 @@
13 #
14 from setuptools import setup
15
16-INSTALL_REQUIRES = ['pyyaml', 'requests']
17+INSTALL_REQUIRES = ['pyyaml', 'requests', 'xdg<4.0']
18 TEST_REQUIRES = []
19
20 setup(
21@@ -35,4 +35,3 @@ setup(
22 ''',
23
24 )
25-
26diff --git a/testflinger_cli/__init__.py b/testflinger_cli/__init__.py
27index a0fe783..e647e40 100644
28--- a/testflinger_cli/__init__.py
29+++ b/testflinger_cli/__init__.py
30@@ -22,7 +22,7 @@ import sys
31 import time
32
33 from argparse import ArgumentParser
34-from testflinger_cli import client
35+from testflinger_cli import (client, config)
36
37
38 # Make it easier to run from a checkout
39@@ -42,9 +42,19 @@ def cli():
40 class TestflingerCli:
41 def __init__(self):
42 self.get_args()
43- server = os.environ.get('TESTFLINGER_SERVER') or self.args.server
44+ self.config = config.TestflingerCliConfig(self.args.configfile)
45+ server = (
46+ self.args.server or
47+ self.config.get('server') or
48+ os.environ.get('TESTFLINGER_SERVER') or
49+ 'https://testflinger.canonical.com'
50+ )
51+ # Allow config subcommand without worrying about server or client
52+ if hasattr(self.args, 'func') and self.args.func == self.configure:
53+ return
54 if not server.startswith(('http://', 'https://')):
55- raise SystemExit('Server must start with "http://" or "https://"')
56+ raise SystemExit('Server must start with "http://" or "https://" '
57+ '- currently set to: "{}"'.format(server))
58 self.client = client.Client(server)
59
60 def run(self):
61@@ -54,8 +64,9 @@ class TestflingerCli:
62
63 def get_args(self):
64 parser = ArgumentParser()
65- parser.add_argument('--server',
66- default='https://testflinger.canonical.com',
67+ parser.add_argument('-c', '--configfile', default=None,
68+ help='Configuration file to use')
69+ parser.add_argument('--server', default=None,
70 help='Testflinger server to use')
71 sub = parser.add_subparsers()
72 arg_artifacts = sub.add_parser(
73@@ -68,6 +79,10 @@ class TestflingerCli:
74 'cancel', help='Tell the server to cancel a specified JOB_ID')
75 arg_cancel.set_defaults(func=self.cancel)
76 arg_cancel.add_argument('job_id')
77+ arg_config = sub.add_parser(
78+ 'config', help='Get or set configuration options')
79+ arg_config.set_defaults(func=self.configure)
80+ arg_config.add_argument('setting', nargs='?', help='setting=value')
81 arg_list_queues = sub.add_parser(
82 'list-queues',
83 help='List the advertised queues on the Testflinger server')
84@@ -153,6 +168,22 @@ class TestflingerCli:
85 'cancelled.'.format(self.args.job_id, job_state))
86 self.client.post_job_state(self.args.job_id, 'cancelled')
87
88+ def configure(self):
89+ if self.args.setting:
90+ setting = self.args.setting.split('=')
91+ if len(setting) == 2:
92+ self.config.set(*setting)
93+ return
94+ if len(setting) == 1:
95+ print("{} = {}".format(
96+ setting[0], self.config.get(setting[0])))
97+ return
98+ print("Current Configuration")
99+ print("---------------------")
100+ for k, v in self.config.data.items():
101+ print("{} = {}".format(k, v))
102+ print()
103+
104 def submit(self):
105 """Submit a new test job to the server"""
106 if self.args.filename == '-':
107diff --git a/testflinger_cli/config.py b/testflinger_cli/config.py
108new file mode 100644
109index 0000000..983699d
110--- /dev/null
111+++ b/testflinger_cli/config.py
112@@ -0,0 +1,47 @@
113+# Copyright (C) 2020 Canonical
114+#
115+# This program is free software: you can redistribute it and/or modify
116+# it under the terms of the GNU General Public License as published by
117+# the Free Software Foundation, either version 3 of the License, or
118+# (at your option) any later version.
119+#
120+# This program is distributed in the hope that it will be useful,
121+# but WITHOUT ANY WARRANTY; without even the implied warranty of
122+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
123+# GNU General Public License for more details.
124+#
125+# You should have received a copy of the GNU General Public License
126+# along with this program. If not, see <http://www.gnu.org/licenses/>.
127+#
128+
129+import configparser
130+import os
131+import xdg
132+from collections import OrderedDict
133+
134+
135+class TestflingerCliConfig:
136+ def __init__(self, configfile=None):
137+ config = configparser.ConfigParser()
138+ if not configfile:
139+ configfile = os.path.join(
140+ xdg.XDG_CONFIG_HOME, "testflinger-cli.conf")
141+ config.read(configfile)
142+ # Default empty config in case there's no config file
143+ self.data = OrderedDict()
144+ if 'testflinger-cli' in config.sections():
145+ self.data = OrderedDict(config['testflinger-cli'])
146+ self.configfile = configfile
147+
148+ def get(self, key):
149+ return self.data.get(key)
150+
151+ def set(self, key, value):
152+ self.data[key] = value
153+ self._save()
154+
155+ def _save(self):
156+ config = configparser.ConfigParser()
157+ config.read_dict({'testflinger-cli': self.data})
158+ with open(self.configfile, 'w') as f:
159+ config.write(f)

Subscribers

People subscribed via source and target branches