create new composition or load existing

This commit is contained in:
Yusef Napora 2020-06-22 10:26:59 -04:00
parent e262320348
commit 6eae66728b
5 changed files with 151 additions and 438 deletions

90
composer/app/app.py Normal file
View File

@ -0,0 +1,90 @@
import param
import panel as pn
import toml
from .util import get_plans, get_manifest
from .composition import Composition
STAGE_WELCOME = 'Welcome'
STAGE_CONFIG_COMPOSITION = 'Configure'
class Welcome(param.Parameterized):
composition = param.Parameter()
composition_picker = pn.widgets.FileInput(accept='.toml')
plan_picker = param.Selector()
ready = param.Boolean()
def __init__(self, **params):
super().__init__(**params)
self.composition_picker.param.watch(self._composition_updated, 'value')
self.param.watch(self._plan_selected, 'plan_picker')
self.param['plan_picker'].objects = ['Select a Plan'] + get_plans()
def panel(self):
tabs = pn.Tabs(
('New Compostion', self.param['plan_picker']),
('Existing Composition', self.composition_picker),
)
return pn.Column(
"Either choose an existing composition or select a plan to create a new composition:",
tabs,
)
def _composition_updated(self, *args):
print('composition updated')
content = self.composition_picker.value.decode('utf8')
comp_toml = toml.loads(content)
manifest = get_manifest(comp_toml['global']['plan'])
self.composition = Composition.from_dict(comp_toml, manifest=manifest)
print('existing composition: {}'.format(self.composition))
self.ready = True
def _plan_selected(self, evt):
if evt.new == 'Select a Plan':
return
print('plan selected: {}'.format(evt.new))
manifest = get_manifest(evt.new)
self.composition = Composition(manifest=manifest)
print('new composition: ', self.composition)
self.ready = True
class ConfigureComposition(param.Parameterized):
composition = param.Parameter()
@param.depends('composition')
def panel(self):
if self.composition is None:
return pn.Pane("no composition :(")
print('composition: ', self.composition)
return self.composition.panel()
class WorkflowPipeline(object):
def __init__(self):
stages = [
(STAGE_WELCOME, Welcome(), dict(ready_parameter='ready')),
(STAGE_CONFIG_COMPOSITION, ConfigureComposition())
]
self.pipeline = pn.pipeline.Pipeline(debug=True, stages=stages)
def panel(self):
return pn.Column(
pn.Row(
self.pipeline.title,
self.pipeline.network,
self.pipeline.prev_button,
self.pipeline.next_button,
),
self.pipeline.stage,
)
class App(object):
def __init__(self):
self.workflow = WorkflowPipeline()
def ui(self):
return self.workflow.panel().servable("Testground Composer")

View File

@ -1,31 +1,7 @@
import param
import panel as pn
import toml
import os
import sys
def parse_manifest(manifest_path):
with open(manifest_path, 'rt') as f:
return toml.load(f)
def tg_home():
return os.environ.get('TESTGROUND_HOME',
os.path.join(os.environ['HOME'], 'testground'))
def get_plans():
return list(os.listdir(os.path.join(tg_home(), 'plans')))
def get_manifest(plan_name):
manifest_path = os.path.join(tg_home(), 'plans', plan_name, 'manifest.toml')
return parse_manifest(manifest_path)
def print_err(*args):
print(*args, file=sys.stderr)
from .util import get_manifest, print_err
def value_dict(parameterized, renames=None):
@ -241,7 +217,10 @@ class Composition(param.Parameterized):
add_group_button = pn.widgets.Button(name='Add Group')
add_group_button.on_click(self._add_group)
group_panel = self.groups.panel()
if self.groups is None:
group_panel = pn.Column()
else:
group_panel = self.groups.panel()
if self.groups_ui is None:
self.groups_ui = pn.Column(
add_group_button,

26
composer/app/util.py Normal file
View File

@ -0,0 +1,26 @@
import toml
import os
import sys
def parse_manifest(manifest_path):
with open(manifest_path, 'rt') as f:
return toml.load(f)
def tg_home():
return os.environ.get('TESTGROUND_HOME',
os.path.join(os.environ['HOME'], 'testground'))
def get_plans():
return list(os.listdir(os.path.join(tg_home(), 'plans')))
def get_manifest(plan_name):
manifest_path = os.path.join(tg_home(), 'plans', plan_name, 'manifest.toml')
return parse_manifest(manifest_path)
def print_err(*args):
print(*args, file=sys.stderr)

File diff suppressed because one or more lines are too long

View File

@ -80,7 +80,8 @@ cleanup () {
trap "{ cleanup; }" EXIT
# make sure we have the commands we need
require_cmds jq docker
require_cmds jq dockerimport param
import panel as pn
# make temp dir for manifests
temp_base="/tmp"