summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2018-04-08 13:15:51 +0300
committerLars Wirzenius <liw@liw.fi>2018-04-08 13:15:51 +0300
commit124939fc94bb08a02207750fd017209f6e8edb46 (patch)
tree3c23d23812ebc16e30b78341ce830a50e9e61593
parentb9171928c024fde56789846233a539ccd0ffee48 (diff)
parent186cf88fa34b54d6f2cd82d8eab8160be015ba5f (diff)
downloadick2-124939fc94bb08a02207750fd017209f6e8edb46.tar.gz
Merge: improve icktool
-rw-r--r--NEWS3
-rw-r--r--ick2/client.py17
-rwxr-xr-xicktool108
-rwxr-xr-xworker_manager37
4 files changed, 158 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 12f49a7..b416527 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
Version 0.35+git, not yet released
----------------------------------
+* `icktool` is again mostly functional. Deleting resources (projects,
+ pipelines, etc) hasn't been implemented yet. Neither has handling
+ blobs. These will be added later, when some one needs them.
Version 0.35, released 2018-04-07
----------------------------------
diff --git a/ick2/client.py b/ick2/client.py
index ec2a113..533b8cd 100644
--- a/ick2/client.py
+++ b/ick2/client.py
@@ -214,6 +214,23 @@ class ControllerClient:
url = self.url(path)
return self._api.post(url, body=obj)
+ def trigger(self, project_name, pipeline_name): # pragma: no cover
+ path = '/projects/{}/pipelines/{}/+trigger'.format(
+ project_name, pipeline_name)
+ url = self.url(path)
+ return self._api.get_blob(url)
+
+ def get_build_status(
+ self, project_name, pipeline_name): # pragma: no cover
+ path = '/projects/{}/pipelines/{}'.format(project_name, pipeline_name)
+ url = self.url(path)
+ return self._api.get_dict(url)
+
+ def get_log(self, build_id): # pragma: no cover
+ path = '/logs/{}'.format(build_id)
+ url = self.url(path)
+ return self._api.get_blob(url)
+
class AuthClient:
diff --git a/icktool b/icktool
index 6d0b4e2..79fcb48 100755
--- a/icktool
+++ b/icktool
@@ -125,6 +125,16 @@ class Icktool(cliapp.Application):
version = api.get_version()
self._prettyson(version)
+ def cmd_trigger(self, args):
+ project_name = args[0]
+ pipeline_name = args[1]
+
+ token = self._new_token()
+ api = self._new_api()
+ api.set_token(token)
+ result = api.trigger(project_name, pipeline_name)
+ self._prettyson(result)
+
def cmd_make_it_so(self, argv):
obj = self._read_object()
@@ -156,6 +166,76 @@ class Icktool(cliapp.Application):
objs = api.show('/' + kind)
self._prettyson(objs)
+ def cmd_status(self, args):
+ token = self._new_token()
+ api = self._new_api()
+ api.set_token(token)
+
+ rows = []
+ projects = api.show('/projects')['projects']
+ projects = sorted(projects, key=lambda p: p.get('project'))
+
+ builds = api.show('/builds')['builds']
+
+ for project in projects:
+ pipeline_names = sorted(project['pipelines'])
+ for pipeline_name in pipeline_names:
+ build = self._get_latest_build(
+ project['project'], pipeline_name, builds)
+
+ if build is None:
+ build = {
+ 'build_id': 'never',
+ 'log': 'none',
+ 'status': 'n/a',
+ }
+
+ status = api.get_build_status(
+ project['project'], pipeline_name)
+
+ row = {
+ 'project': project['project'],
+ 'pipeline': pipeline_name,
+ 'build_id': build['build_id'],
+ 'status': status['status'],
+ 'build_status': build['status'],
+ 'log': build['log'],
+ }
+ rows.append(row)
+ self._pretty_table(
+ rows, ['project', 'pipeline', 'status', 'build_status', 'log'])
+
+ def _get_latest_build(self, project_name, pipeline_name, builds):
+ wanted = [
+ b for b in builds
+ if b['project'] == project_name and b['pipeline'] == pipeline_name
+ ]
+ if wanted:
+ return wanted[-1]
+ return None
+
+ def cmd_show_latest_log(self, args):
+ token = self._new_token()
+ api = self._new_api()
+ api.set_token(token)
+
+ project_name = args[0]
+ builds = api.show('/builds')['builds']
+ project_builds = [b for b in builds if b['project'] == project_name]
+ if project_builds:
+ b = project_builds[-1]
+ log = api.get_log(b['build_id'])
+ self.output.write(log.decode('UTF-8'))
+
+ def cmd_show_log(self, args):
+ token = self._new_token()
+ api = self._new_api()
+ api.set_token(token)
+
+ build_id = args[0]
+ log = api.get_log(build_id)
+ self.output.write(log.decode('UTF-8'))
+
def _new_api(self):
api = ick2.ControllerClient()
api.set_verify_tls(self.settings['verify-tls'])
@@ -192,6 +272,34 @@ class Icktool(cliapp.Application):
json.dump(obj, self.output, indent=4, sort_keys=True)
self.output.write('\n')
+ def _pretty_table(self, rows, columns):
+ headings = {
+ column: column
+ for column in columns
+ }
+
+ widths = {
+ column: 0
+ for column in columns
+ }
+
+ for row in [headings] + rows:
+ for column in columns:
+ widths[column] = max(widths[column], len(str(row[column])))
+
+ underlines = {
+ column: '-' * widths[column]
+ for column in columns
+ }
+
+ for row in [headings, underlines] + rows:
+ self.output.write(
+ '{}\n'.format(self._pretty_row(widths, row, columns)))
+
+ def _pretty_row(self, widths, row, columns):
+ parts = ['%*s' % (widths[c], row[c]) for c in columns]
+ return ' | '.join(parts)
+
class Command:
diff --git a/worker_manager b/worker_manager
index 6fd556c..1590109 100755
--- a/worker_manager
+++ b/worker_manager
@@ -35,14 +35,20 @@ class WorkerManager(cliapp.Application):
def add_settings(self):
self.settings.string(
- ['controller'],
- 'base URL for the controller',
- metavar='URL',
+ ['client-id'],
+ 'use ID as the client id when authenticatin to IDP',
+ metavar='ID',
+ )
+
+ self.settings.string(
+ ['client-secret-cmd'],
+ 'run CMD to gget the client secret when authentication to IDP',
+ metavar='CMD',
)
self.settings.string(
- ['name'],
- 'name of this worker',
+ ['controller'],
+ 'base URL for the controller',
metavar='URL',
)
@@ -82,16 +88,20 @@ class WorkerManager(cliapp.Application):
raise
def main_program(self, args):
- self.settings.require('name')
+ self.settings.require('client-id')
+ self.settings.require('client-secret-cmd')
self.settings.require('controller')
- name = self.settings['name']
+ name = self.settings['client-id']
url = self.settings['controller']
workspace = self.settings['workspace']
systree = self.settings['systree']
+ secret = self.get_client_secret()
+
api = ControllerAPI(name, url)
api.set_verify_tls(self.settings['verify-tls'])
+ api.set_client_creds(name, secret)
worker = Worker(name, api, workspace, systree)
logging.info('Worker manager %s starts, controller is %s', name, url)
@@ -108,6 +118,12 @@ class WorkerManager(cliapp.Application):
secs = self.settings['sleep']
time.sleep(secs)
+ def get_client_secret(self):
+ cmd = self.settings['client-secret-cmd']
+ output = cliapp.runcmd(['sh', '-c', cmd])
+ lines = output.splitlines()
+ return lines[0].strip()
+
class ControllerAPI:
@@ -126,13 +142,20 @@ class ControllerAPI:
self._cc.set_controller_url(url)
self._ac = None
self._blobs = None
+ self._client_id = None
+ self._client_secret = None
def set_verify_tls(self, verify):
self._cc.set_verify_tls(verify)
+ def set_client_creds(self, client_id, client_secret):
+ self._client_id = client_id
+ self._client_secret = client_secret
+
def get_token(self):
if self._ac is None:
self._ac = self._cc.get_auth_client()
+ self._ac.set_client_creds(self._client_id, self._client_secret)
return self._ac.get_token(self._scopes)
def register(self):