From 4c7db9f4d85f05e1ba022164bc3d854bbee56a11 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 18:08:00 +0300 Subject: Drop: --auth-url, fix --secrets description, default --- icktool | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'icktool') diff --git a/icktool b/icktool index c54e3df..32cce94 100755 --- a/icktool +++ b/icktool @@ -72,16 +72,11 @@ class Icktool(cliapp.Application): metavar='URL', ) - self.settings.string( - ['auth-url'], - 'use URL as the authentication URL', - metavar='URL', - ) - self.settings.string( ['secrets'], - 'use URL as the controller base URL', - metavar='URL', + 'use FILE for credentials for authentication server', + metavar='FILE', + default=os.path.expanduser('~/.config/icktool/credentials.conf') ) self.settings.boolean( -- cgit v1.2.1 From 4c4663f8a67d38020e4da8629e87c5dbc5fb8d33 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 18:08:19 +0300 Subject: Fix: add import os --- icktool | 1 + 1 file changed, 1 insertion(+) (limited to 'icktool') diff --git a/icktool b/icktool index 32cce94..383d364 100755 --- a/icktool +++ b/icktool @@ -18,6 +18,7 @@ import configparser import json import logging +import os import sys import cliapp -- cgit v1.2.1 From a5b936709740ab5b4a101155d6b99b423dff440b Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 18:08:41 +0300 Subject: Change: _new_auth should be given API so it can fetch token --- icktool | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'icktool') diff --git a/icktool b/icktool index 383d364..100f08a 100755 --- a/icktool +++ b/icktool @@ -156,8 +156,8 @@ class Icktool(cliapp.Application): api.set_controller_url(self.settings['controller']) return api - def _new_auth(self): - url = self.settings['auth-url'] + def _new_auth(self, api): + url = api.get_auth_url() client_id, client_secret = self._get_client_creds(url) ac = ick2.AuthClient() @@ -165,10 +165,10 @@ class Icktool(cliapp.Application): ac.set_client_creds(client_id, client_secret) return ac - def _new_token(self): + def _new_token(self, api): if self.settings['token']: return self.settings['token'] - ac = self._new_auth() + ac = self._new_auth(api) scopes = ' '.join(self.settings['scope']) return ac.get_token(scopes) -- cgit v1.2.1 From 659bc5b577097a451b162c9c552e803e3a824e39 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 18:09:20 +0300 Subject: Change: adjust to _new_token change, add status and trigger commands --- icktool | 56 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 19 deletions(-) (limited to 'icktool') diff --git a/icktool b/icktool index 100f08a..81dd035 100755 --- a/icktool +++ b/icktool @@ -109,21 +109,47 @@ class Icktool(cliapp.Application): self.output.write('{}\n'.format(scope)) def cmd_token(self, args): - token = self._new_token() + api = self._new_api() + token = self._new_token(api) self.output.write('{}\n'.format(token)) def cmd_version(self, args): - token = self._new_token() api = self._new_api() + token = self._new_token(api) api.set_token(token) version = api.get_version() self._prettyson(version) + def cmd_status(self, args): + api = self._new_api() + token = self._new_token(api) + api.set_token(token) + projects = api.show('/projects') + builds = api.show('/builds') + for project in projects['projects']: + project_name = project['project'] + status = api.show('/projects/{}/status'.format(project_name)) + build = self._latest_build(project_name, builds) + self._prettyson(builds) + if build: + actions = build['actions'] + current = build['current_action'] + log = build['log'] + print(project_name, status['status'], log, actions[current]) + else: + print(project_name, status['status'], 'no builds') + + def _latest_build(self, project_name, builds): + builds = [b for b in builds['builds'] if b['project'] == project_name] + if builds: + return builds[-1] + return None + def cmd_make_it_so(self, argv): obj = self._read_object() - token = self._new_token() api = self._new_api() + token = self._new_token(api) api.set_token(token) self._create_resources(api, '/projects', obj.get('projects', [])) @@ -136,9 +162,16 @@ class Icktool(cliapp.Application): for obj in objs: api.create(path, obj) + def cmd_trigger(self, args): + project = args[0] + api = self._new_api() + token = self._new_token(api) + api.set_token(token) + self._prettyson(api.trigger(project)) + def cmd_show(self, args): - token = self._new_token() api = self._new_api() + token = self._new_token(api) api.set_token(token) if not args: args = [ @@ -184,19 +217,4 @@ class Icktool(cliapp.Application): self.output.write('\n') -class Command: - - def __init__(self, api): - self._api = api - - def execute(self): - raise NotImplementedError() - - -class VersionCommand(Command): - - def execute(self): - self._api.get_version() - - Icktool(version=ick2.__version__).run() -- cgit v1.2.1 From b5f373fad21a9ae97f02933ac216d65e98645928 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 18:41:18 +0300 Subject: Change: icktool status tabular output --- icktool | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 8 deletions(-) (limited to 'icktool') diff --git a/icktool b/icktool index 81dd035..a6cfa1f 100755 --- a/icktool +++ b/icktool @@ -121,23 +121,37 @@ class Icktool(cliapp.Application): self._prettyson(version) def cmd_status(self, args): + table = Table() + table.set_columns('project', 'status', 'build_status', 'log_id') + api = self._new_api() token = self._new_token(api) api.set_token(token) + projects = api.show('/projects') builds = api.show('/builds') + for project in projects['projects']: project_name = project['project'] - status = api.show('/projects/{}/status'.format(project_name)) + project_status = api.show( + '/projects/{}/status'.format(project_name)) + + row = { + 'project': project_name, + 'status': project_status['status'], + 'build_status': 'n/a', + 'log_id': 'n/a' + } + + build = self._latest_build(project_name, builds) - self._prettyson(builds) if build: - actions = build['actions'] - current = build['current_action'] - log = build['log'] - print(project_name, status['status'], log, actions[current]) - else: - print(project_name, status['status'], 'no builds') + row['build_status'] = build['status'] + row['log_id'] = build['log'] + + table.append_row(**row) + + self.output.write(table.format()) def _latest_build(self, project_name, builds): builds = [b for b in builds['builds'] if b['project'] == project_name] @@ -217,4 +231,58 @@ class Icktool(cliapp.Application): self.output.write('\n') +class Table: + + def __init__(self): + self._column_names = None + self._rows = [] + + def set_columns(self, *column_names): + self._column_names = column_names + + def append_row(self, **kwargs): + self._rows.append(kwargs) + + def format(self): + assert self._column_names is not None + headings = { + key: key + for key in self._column_names + } + self._rows.insert(0, headings) + widths = self._column_widths() + underlines = { + key: '-' * widths[key] + for key in self._column_names + } + self._rows.insert(1, underlines) + lines = [self._format_row(widths, row) for row in self._rows] + return ''.join('{}\n'.format(line) for line in lines) + + def _format_headings(self, widths): + row = { + key: key + for key in self._column_names + } + return self._format_row(widths, row) + + def _format_row(self, widths, row): + return ' | '.join( + self._format_cell(widths[x], row[x]) + for x in self._column_names + ) + + def _format_cell(self, width, value): + return '%*s' % (width, value) + + def _column_widths(self): + return { + key: self._width(key) + for key in self._column_names + } + + def _width(self, column_name): + return max(len(str(row[column_name])) for row in self._rows) + + Icktool(version=ick2.__version__).run() -- cgit v1.2.1 From 8c7870e45cc5894fc211a67cb4e7ad73c6ceb5b8 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 18:41:40 +0300 Subject: Fix: remove empty line --- icktool | 1 - 1 file changed, 1 deletion(-) (limited to 'icktool') diff --git a/icktool b/icktool index a6cfa1f..7a74c94 100755 --- a/icktool +++ b/icktool @@ -143,7 +143,6 @@ class Icktool(cliapp.Application): 'log_id': 'n/a' } - build = self._latest_build(project_name, builds) if build: row['build_status'] = build['status'] -- cgit v1.2.1 From 911d18e983555ce94012b3765c1cb5f842f416aa Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 19:11:20 +0300 Subject: Add: icktool build-graph command --- icktool | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'icktool') diff --git a/icktool b/icktool index 7a74c94..6e493d1 100755 --- a/icktool +++ b/icktool @@ -153,11 +153,80 @@ class Icktool(cliapp.Application): self.output.write(table.format()) def _latest_build(self, project_name, builds): - builds = [b for b in builds['builds'] if b['project'] == project_name] + builds = self._find_builds(project_name, builds) if builds: return builds[-1] return None + def _find_builds(self, project_name, builds): + return [b for b in builds['builds'] if b['project'] == project_name] + + def _find_build(self, builds, build_id): + for build in builds: + if build['build_id'] == build_id: + return build + return None + + def cmd_build_graph(self, args): + api = self._new_api() + token = self._new_token(api) + api.set_token(token) + + project_name = args[0] + if len(args) > 1: + build_id = args[1] + else: + build_id = 'latest' + + builds = api.show('/builds') + builds = self._find_builds(project_name, builds) + if not builds: + sys.exit('No such build %s' % build_id) + + if build_id == 'latest': + build = builds[-1] + else: + build = self._find_build(builds, build_id) + + actions = build['actions'] + current = build['current_action'] + status = build['status'] + + styles = { + 'done': ('rectangle', '#ffffff'), + 'building': ('ellipse', '#00ff00'), + 'blocked': ('ellipse', '#bbbbbb'), + } + + node_tmpl = 'a{} [label="{}" shape={} style=filled fillcolor="{}"]\n' + + f = self.output + f.write('digraph "build_graph" {\n') + for i, action in enumerate(actions): + if current is None: + shape, color = styles['done'] + elif i < current: + shape, color = styles['done'] + elif i == current: + shape, color = styles['building'] + elif i > current: + shape, color = styles['blocked'] + f.write( + node_tmpl.format( + i, self._describe_action(action), shape, color)) + if i > 0: + f.write('a{} -> a{}\n'.format(i-1, i)) + f.write('}\n') + + def _describe_action(self, action): + for key in ['action', 'archive']: + if key in action: + return '{}: {}'.format(key, action[key]) + for key in ['debootstrap', 'shell', 'python']: + if key in action: + return key + return str(action) + def cmd_make_it_so(self, argv): obj = self._read_object() -- cgit v1.2.1 From 186ec3f89806fc3d5532b171c7ae34b06059c491 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 20 Apr 2018 19:21:40 +0300 Subject: Refactor: icktool --- icktool | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'icktool') diff --git a/icktool b/icktool index 6e493d1..7be5bc1 100755 --- a/icktool +++ b/icktool @@ -192,31 +192,30 @@ class Icktool(cliapp.Application): current = build['current_action'] status = build['status'] + f = self.output + f.write('digraph "build_graph" {\n') + for i, action in enumerate(actions): + self._describe_node(f, i, current, action) + f.write('}\n') + + def _describe_node(self, f, i, current, action): styles = { 'done': ('rectangle', '#ffffff'), 'building': ('ellipse', '#00ff00'), 'blocked': ('ellipse', '#bbbbbb'), } - node_tmpl = 'a{} [label="{}" shape={} style=filled fillcolor="{}"]\n' - - f = self.output - f.write('digraph "build_graph" {\n') - for i, action in enumerate(actions): - if current is None: - shape, color = styles['done'] - elif i < current: - shape, color = styles['done'] - elif i == current: - shape, color = styles['building'] - elif i > current: - shape, color = styles['blocked'] - f.write( - node_tmpl.format( - i, self._describe_action(action), shape, color)) - if i > 0: - f.write('a{} -> a{}\n'.format(i-1, i)) - f.write('}\n') + if current is None: + shape, color = styles['done'] + elif i < current: + shape, color = styles['done'] + elif i == current: + shape, color = styles['building'] + elif i > current: + shape, color = styles['blocked'] + + tmpl = 'a{} [label="{}" shape={} style=filled fillcolor="{}"]\n' + f.write(tmpl.format(i, self._describe_action(action), shape, color)) def _describe_action(self, action): for key in ['action', 'archive']: -- cgit v1.2.1