From e242cd8eb5b22d6e367083e5e2597a63183bb9fb Mon Sep 17 00:00:00 2001 From: XTao Date: Tue, 27 Dec 2016 16:56:20 +0800 Subject: [PATCH] Support stage yaml --- lain_cli/appversion.py | 5 +++-- lain_cli/attach.py | 5 +++-- lain_cli/backup.py | 26 +++++++++++++++++--------- lain_cli/build.py | 10 ++++++---- lain_cli/deploy.py | 7 ++++--- lain_cli/enter.py | 5 +++-- lain_cli/imagecheck.py | 2 +- lain_cli/logout.py | 2 +- lain_cli/maintainer.py | 8 ++++---- lain_cli/ps.py | 5 +++-- lain_cli/push.py | 5 +++-- lain_cli/reposit.py | 5 +++-- lain_cli/rmi.py | 5 +++-- lain_cli/scale.py | 14 ++++++++------ lain_cli/secret.py | 17 ++++++++++------- lain_cli/tag.py | 5 +++-- lain_cli/undeploy.py | 5 +++-- lain_cli/utils.py | 35 +++++++++++++++++++++++++---------- 18 files changed, 103 insertions(+), 63 deletions(-) diff --git a/lain_cli/appversion.py b/lain_cli/appversion.py index f96662d..ce43383 100644 --- a/lain_cli/appversion.py +++ b/lain_cli/appversion.py @@ -3,7 +3,7 @@ from lain_sdk.util import warn, info from lain_cli.auth import authorize_and_check -from lain_cli.utils import get_version_lists, lain_yaml, check_phase +from lain_cli.utils import get_version_lists, lain_yaml, check_phase, get_phase_stage @arg('phase', help="lain cluster phase id, can be added by lain config save") @@ -13,7 +13,8 @@ def appversion(phase): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) authorize_and_check(phase, yml.appname) version_list = get_version_lists(phase, yml.appname) diff --git a/lain_cli/attach.py b/lain_cli/attach.py index f573257..cc0946a 100644 --- a/lain_cli/attach.py +++ b/lain_cli/attach.py @@ -3,7 +3,7 @@ from entryclient import EntryClient from lain_sdk.util import error, info from lain_cli.auth import SSOAccess, authorize_and_check -from lain_cli.utils import check_phase, lain_yaml, get_domain +from lain_cli.utils import check_phase, lain_yaml, get_domain, get_phase_stage @arg('phase', help="lain cluster phase id, can be added by lain config save") @@ -14,7 +14,8 @@ def attach(phase, proc_name, instance_no, target=None): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) appname = target if target else yml.appname authorize_and_check(phase, appname) domain = get_domain(phase) diff --git a/lain_cli/backup.py b/lain_cli/backup.py index 6fe1cd1..9c9f823 100644 --- a/lain_cli/backup.py +++ b/lain_cli/backup.py @@ -5,7 +5,7 @@ from argh.decorators import arg, aliases from lain_sdk.util import warn -from lain_cli.utils import lain_yaml_data, check_phase +from lain_cli.utils import lain_yaml_data, check_phase, get_phase_stage from lain_cli.utils import TwoLevelCommandBase, get_domain @@ -30,7 +30,8 @@ def jobs(cls, phase): list backup jobs for this lain app """ check_phase(phase) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase) + appname = lain_yaml_data(stage=stage)['appname'] route = "api/v2/app/%s/cron/jobs" % appname data = cls._request('GET', phase, route, None) if data: @@ -46,7 +47,8 @@ def list(cls, phase, proc, path): list files in the incremental backup direcotry """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] route = "api/v2/app/%s/proc/%s/backups/%s?open=true" % (appname, proc[0], path[0]) data = cls._request('GET', phase[0], route, None) if data: @@ -63,7 +65,8 @@ def get(cls, phase, proc, volume): get all the backups of the given proc's volume """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] route = "api/v2/app/%s/proc/%s/backups?volume=%s" % (appname, proc[0], volume[0]) data = cls._request('GET', phase[0], route, None) if data: @@ -78,7 +81,8 @@ def delete(cls, phase, proc, files): delete a backup of a proc """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] route = "api/v2/app/%s/proc/%s/backups/actions/delete" % (appname, proc[0]) data = cls._request('POST', phase[0], route, {'files': files}) if data: @@ -94,7 +98,8 @@ def recover(cls, phase, proc, backup, files): recover the volume from given backup """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] if not files: route = "api/v2/app/%s/proc/%s/backups/%s/actions/recover" % (appname, proc[0], backup[0]) data = cls._request('POST', phase[0], route, None) @@ -116,7 +121,8 @@ def migrate(cls, phase, proc, backup, files, volume="", to=0): recover a instance's volume from other instance's backup """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] if not files: route = "api/v2/app/%s/proc/%s/backups/%s/actions/migrate" % (appname, proc[0], backup[0]) data = cls._request('POST', phase[0], route, {"volume": volume, "to": to}) @@ -135,7 +141,8 @@ def records(cls, phase, rid, num=10): list job records of this lain app """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] route = "api/v2/app/%s/cron/records" % appname if rid: route = "%s/%s" % (route, rid) @@ -153,7 +160,8 @@ def run(cls, phase, id): run a job right now """ check_phase(phase[0]) - appname = lain_yaml_data()['appname'] + stage = get_phase_stage(phase[0]) + appname = lain_yaml_data(stage=stage)['appname'] route = "api/v2/app/%s/cron/jobs/%s/actions/run" % (appname, id[0]) data = cls._request('POST', phase[0], route, None) if data: diff --git a/lain_cli/build.py b/lain_cli/build.py index 4b00fdb..5f55cd4 100644 --- a/lain_cli/build.py +++ b/lain_cli/build.py @@ -4,20 +4,22 @@ import lain_sdk.mydocker as docker from lain_sdk.util import error, warn, info -from lain_cli.utils import lain_yaml +from lain_cli.utils import lain_yaml, get_phase_stage from lain_cli.validate import validate_only_warning @arg('--release', help="build from build image if it exists") @arg('--push', help="tag release and meta image with version and push to registry") -def build(push=False, release=False): +@arg('--phase', help="lain cluster phase id, can be added by lain config save") +def build(phase=None, push=False, release=False): """ Build release and meta images """ info("Building meta and release images ...") validate_only_warning() - yml = lain_yaml() + stage = get_phase_stage(phase) if phase else None + yml = lain_yaml(stage=stage) meta_version = yml.repo_meta_version() use_prepare = docker.exist(yml.img_names['prepare']) use_build = release and docker.exist(yml.img_names['build']) @@ -38,4 +40,4 @@ def build(push=False, release=False): tag_meta_name = yml.tag_meta_version(meta_name) docker.tag(meta_name, tag_meta_name) docker.push(tag_meta_name) - info("Done lain build.") \ No newline at end of file + info("Done lain build.") diff --git a/lain_cli/deploy.py b/lain_cli/deploy.py index 313a896..4ba738d 100644 --- a/lain_cli/deploy.py +++ b/lain_cli/deploy.py @@ -8,7 +8,7 @@ from lain_sdk.util import error, info from lain_cli.auth import SSOAccess, authorize_and_check, get_auth_header -from lain_cli.utils import check_phase, get_domain, lain_yaml, is_resource_instance +from lain_cli.utils import check_phase, get_domain, lain_yaml, is_resource_instance, get_phase_stage from lain_cli.utils import reposit_app, get_version_lists, get_app_state from lain_cli.utils import render_app_status, render_proc_status @@ -24,7 +24,8 @@ def deploy(phase, version=None, target=None, proc=None, output='pretty'): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) appname = target if target else yml.appname authorize_and_check(phase, appname) @@ -62,7 +63,7 @@ def deploy_app(phase, appname, console, auth_header, version, output): deploy_params = {"meta_version": deploy_version} else: deploy_version = valid_version - + deploy_r = requests.put(app_url, headers=auth_header, json=deploy_params) elif app_r.status_code == 404: operation = "deploying" diff --git a/lain_cli/enter.py b/lain_cli/enter.py index c485d86..0b255da 100644 --- a/lain_cli/enter.py +++ b/lain_cli/enter.py @@ -3,7 +3,7 @@ from entryclient import EntryClient from lain_sdk.util import error from lain_cli.auth import SSOAccess, authorize_and_check -from lain_cli.utils import check_phase, lain_yaml, get_domain +from lain_cli.utils import check_phase, lain_yaml, get_domain, get_phase_stage import os @@ -16,7 +16,8 @@ def enter(phase, proc_name, instance_no, target=None): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) appname = target if target else yml.appname authorize_and_check(phase, appname) domain = get_domain(phase) diff --git a/lain_cli/imagecheck.py b/lain_cli/imagecheck.py index eaf783f..e565148 100644 --- a/lain_cli/imagecheck.py +++ b/lain_cli/imagecheck.py @@ -32,7 +32,7 @@ def _check_phase_tag(phase): @arg('phase', help="lain phase, can be added by lain config save") -def check(phase): +def check(phase): """ Check current version of release and meta images in the remote registry """ diff --git a/lain_cli/logout.py b/lain_cli/logout.py index f3aa5cd..7d7d118 100644 --- a/lain_cli/logout.py +++ b/lain_cli/logout.py @@ -17,7 +17,7 @@ def logout(phase): domain = get_domain(phase) logout_success = SSOAccess.clear_token(phase) if logout_success: - docker.logout('registry.%s'%domain) + docker.logout('registry.%s'%domain) info("Logout successfully!") else: warn('Logout failed!') diff --git a/lain_cli/maintainer.py b/lain_cli/maintainer.py index 48d02d0..4a6e623 100644 --- a/lain_cli/maintainer.py +++ b/lain_cli/maintainer.py @@ -33,7 +33,7 @@ def show(cls, phase, username=None): username: sso username """ - + check_phase(phase) yml = lain_yaml(ignore_prepare=True) authorize_and_check(phase, yml.appname) @@ -44,7 +44,7 @@ def show(cls, phase, username=None): console, yml.appname) if username: maintainer_url += '%s/' % username - + show_response = requests.get(maintainer_url, headers=auth_header) if show_response.status_code < 300: info("maintainer detail:") @@ -60,7 +60,7 @@ def add(cls, phase, username, role): """ add maintianer for different phase """ - + check_phase(phase) yml = lain_yaml(ignore_prepare=True) authorize_and_check(phase, yml.appname) @@ -91,7 +91,7 @@ def delete(cls, phase, username): authorize_and_check(phase, yml.appname) auth_header = get_auth_header(SSOAccess.get_token(phase)) console = "console.%s" % get_domain(phase) - + maintainer_url = "http://%s/api/v1/repos/%s/maintainers/%s/" % ( console, yml.appname, username) diff --git a/lain_cli/ps.py b/lain_cli/ps.py index 82b8bad..31ddd24 100644 --- a/lain_cli/ps.py +++ b/lain_cli/ps.py @@ -5,7 +5,7 @@ from lain_sdk.util import error from lain_cli.auth import SSOAccess, get_auth_header, authorize_and_check -from lain_cli.utils import check_phase, get_domain, lain_yaml +from lain_cli.utils import check_phase, get_domain, lain_yaml, get_phase_stage from lain_cli.utils import render_app_status @@ -17,7 +17,8 @@ def ps(phase, output='pretty'): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) authorize_and_check(phase, yml.appname) console = "console.%s" % get_domain(phase) diff --git a/lain_cli/push.py b/lain_cli/push.py index beb9693..a19043a 100644 --- a/lain_cli/push.py +++ b/lain_cli/push.py @@ -4,7 +4,7 @@ from lain_sdk.util import error, info import lain_sdk.mydocker as docker -from lain_cli.utils import check_phase, lain_yaml, get_domain +from lain_cli.utils import check_phase, lain_yaml, get_domain, get_phase_stage @arg('phase', help="lain cluster phase id, can be added by lain config save") @@ -15,7 +15,8 @@ def push(phase): check_phase(phase) info("Pushing meta and release images ...") - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) meta_version = yml.repo_meta_version() if meta_version is None: error("please git commit.") diff --git a/lain_cli/reposit.py b/lain_cli/reposit.py index e3710c8..997934e 100644 --- a/lain_cli/reposit.py +++ b/lain_cli/reposit.py @@ -3,7 +3,7 @@ from lain_sdk.util import info from lain_cli.auth import SSOAccess, get_auth_header, authorize_and_check -from lain_cli.utils import check_phase, lain_yaml, reposit_app, get_domain +from lain_cli.utils import check_phase, lain_yaml, reposit_app, get_domain, get_phase_stage from lain_cli.validate import validate_only_warning @@ -17,7 +17,8 @@ def reposit(phase): validate_only_warning() info("Repositing ...") - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) authorize_and_check(phase, yml.appname) access_token = SSOAccess.get_token(phase) diff --git a/lain_cli/rmi.py b/lain_cli/rmi.py index 2624420..c2ecd34 100644 --- a/lain_cli/rmi.py +++ b/lain_cli/rmi.py @@ -2,12 +2,13 @@ from argh.decorators import arg import lain_sdk.mydocker as docker -from lain_cli.utils import check_phase +from lain_cli.utils import check_phase, get_phase_stage from lain_cli.utils import lain_yaml, get_meta_versions_from_tags, get_domain def get_repo_tags_to_remove(phase): - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) domain = get_domain(phase) registry = "registry.%s" % domain all_tags = docker.get_tag_list_in_docker_daemon(registry, yml.appname) diff --git a/lain_cli/scale.py b/lain_cli/scale.py index 46a9631..5a9e9a1 100644 --- a/lain_cli/scale.py +++ b/lain_cli/scale.py @@ -6,7 +6,7 @@ from argh.decorators import arg from lain_sdk.util import error, warn, info -from lain_cli.utils import check_phase, lain_yaml, get_domain, render_proc_status, get_apptype +from lain_cli.utils import check_phase, lain_yaml, get_domain, render_proc_status, get_apptype, get_phase_stage from lain_cli.auth import SSOAccess, authorize_and_check, get_auth_header @@ -20,7 +20,8 @@ def scale(phase, proc, target=None, cpu=None, memory=None, numinstances=None, ou """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) appname = target if target else yml.appname authorize_and_check(phase, appname) @@ -74,7 +75,7 @@ def scale(phase, proc, target=None, cpu=None, memory=None, numinstances=None, ou 'payload': payload1, 'success': scale_r.status_code < 300 } - render_scale_result(scale_r, output) + render_scale_result(phase, scale_r, output) if numinstances is not None: payload2['num_instances'] = numinstances @@ -87,7 +88,7 @@ def scale(phase, proc, target=None, cpu=None, memory=None, numinstances=None, ou 'payload': payload2, 'success': scale_r.status_code < 300 } - render_scale_result(scale_r, output) + render_scale_result(phase, scale_r, output) info("Outline of scale result: ") for k, v in scale_results.iteritems(): @@ -136,13 +137,14 @@ def validate_parameters(cpu, memory, numinstances): return cpu, memory, numinstances -def render_scale_result(scale_result, output): +def render_scale_result(phase, scale_result, output): + stage = get_phase_stage(phase) try: result = scale_result.json() msg = result.pop('msg', '') if msg: print msg.decode('string_escape') info("proc status: ") - render_proc_status(result.get('proc'), get_apptype(), output=output) + render_proc_status(result.get('proc'), get_apptype(stage=stage), output=output) except Exception: pprint.pprint(scale_result.content) diff --git a/lain_cli/secret.py b/lain_cli/secret.py index b371bbc..a6115c1 100644 --- a/lain_cli/secret.py +++ b/lain_cli/secret.py @@ -5,12 +5,12 @@ from lain_sdk.util import info, error from lain_cli.auth import SSOAccess, get_auth_header, authorize_and_check -from lain_cli.utils import TwoLevelCommandBase, check_phase +from lain_cli.utils import TwoLevelCommandBase, check_phase, get_phase_stage from lain_cli.utils import lain_yaml, get_domain class SecretCommands(TwoLevelCommandBase): ''' - allow add secret files for app, lain will add the secret file into + allow add secret files for app, lain will add the secret file into image of the proc when deploying. ''' @@ -37,7 +37,8 @@ def show(cls, phase, procname, path=None): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) authorize_and_check(phase, yml.appname) auth_header = get_auth_header(SSOAccess.get_token(phase)) proc = yml.procs.get(procname, None) @@ -45,12 +46,12 @@ def show(cls, phase, procname, path=None): error('proc {} does not exist'.format(procname)) exit(1) - podgroup_name = "{}.{}.{}".format(yml.appname, proc.type.name, proc.name) + podgroup_name = "{}.{}.{}".format(yml.appname, proc.type.name, proc.name) lvault_url = "http://lvault.%s/v2/secrets?app=%s&proc=%s" % ( get_domain(phase), yml.appname, podgroup_name) if path: lvault_url += "&path=%s" % path - + show_response = requests.get(lvault_url, headers=auth_header) if show_response.status_code < 300: info("secret file detail:") @@ -83,7 +84,8 @@ def add(cls, phase, procname, path, content=None, file=None): exit(1) check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) authorize_and_check(phase, yml.appname) auth_header = get_auth_header(SSOAccess.get_token(phase)) proc = yml.procs.get(procname, None) @@ -112,7 +114,8 @@ def delete(cls, phase, procname, path): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) authorize_and_check(phase, yml.appname) auth_header = get_auth_header(SSOAccess.get_token(phase)) proc = yml.procs.get(procname, None) diff --git a/lain_cli/tag.py b/lain_cli/tag.py index d73ffdb..4167e55 100644 --- a/lain_cli/tag.py +++ b/lain_cli/tag.py @@ -3,7 +3,7 @@ import lain_sdk.mydocker as docker from lain_sdk.util import error, info -from lain_cli.utils import check_phase, lain_yaml, get_domain +from lain_cli.utils import check_phase, lain_yaml, get_domain, get_phase_stage @arg('phase', help="lain cluster phase id, can be added by lain config save") @@ -14,7 +14,8 @@ def tag(phase): check_phase(phase) info("Taging meta and relese image ...") - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) meta_version = yml.repo_meta_version() if meta_version is None: error("please git commit.") diff --git a/lain_cli/undeploy.py b/lain_cli/undeploy.py index f64dc72..9ea3836 100644 --- a/lain_cli/undeploy.py +++ b/lain_cli/undeploy.py @@ -4,7 +4,7 @@ from lain_sdk.util import error, warn, info from lain_cli.auth import SSOAccess, get_auth_header, authorize_and_check -from lain_cli.utils import check_phase, get_domain, lain_yaml +from lain_cli.utils import check_phase, get_domain, lain_yaml, get_phase_stage @arg('phase', help="lain cluster phase id, can be added by lain config save") @@ -16,7 +16,8 @@ def undeploy(phase, target=None, proc=None): """ check_phase(phase) - yml = lain_yaml(ignore_prepare=True) + stage = get_phase_stage(phase) + yml = lain_yaml(ignore_prepare=True, stage=stage) appname = target if target else yml.appname authorize_and_check(phase, appname) diff --git a/lain_cli/utils.py b/lain_cli/utils.py index 89e37bb..44e4dc5 100644 --- a/lain_cli/utils.py +++ b/lain_cli/utils.py @@ -20,6 +20,7 @@ VALID_TAG_PATERN = re.compile(r"^(meta)-(?P\S+-\S+)$") DOMAIN_KEY = user_config.domain_key +STAGE_KEY = user_config.stage_key PHASE_CHOICES = user_config.get_available_phases() requests.packages.urllib3.disable_warnings() @@ -41,20 +42,28 @@ def help_message(self): '''return help message string''' -def lain_yaml_data(): - if not os.path.exists(LAIN_YAML_PATH): - error('Missing lain.yaml under current directory') +def get_lain_yaml_path(stage=None): + if stage is None: + return LAIN_YAML_PATH + return "./lain.%s.yaml" % stage + + +def lain_yaml_data(stage=None): + lain_yaml_path = get_lain_yaml_path(stage=stage) + if not os.path.exists(lain_yaml_path): + error('Missing %s under current directory' % lain_yaml_path) sys.exit(1) - with open(LAIN_YAML_PATH) as f: + with open(lain_yaml_path) as f: data = f.read() return yaml.load(data) -def lain_yaml(ignore_prepare=False): - if not os.path.exists(LAIN_YAML_PATH): - error('Missing lain.yaml under current directory') +def lain_yaml(ignore_prepare=False, stage=None): + lain_yaml_path = get_lain_yaml_path(stage=stage) + if not os.path.exists(lain_yaml_path): + error('Missing %s under current directory' % lain_yaml_path) sys.exit(1) - return LainYaml(LAIN_YAML_PATH, ignore_prepare=ignore_prepare) + return LainYaml(lain_yaml_path, ignore_prepare=ignore_prepare) def check_phase(phase): @@ -73,8 +82,14 @@ def get_domain(phase): return domain -def get_apptype(): - with open(LAIN_YAML_PATH, 'r') as f: +def get_phase_stage(phase): + stage = user_config.get_config().get(phase, {}).get(STAGE_KEY, None) + return stage + + +def get_apptype(stage=None): + lain_yaml_path = get_lain_yaml_path(stage=stage) + with open(lain_yaml_path, 'r') as f: y = yaml.safe_load(f.read()) return y.get('apptype', 'app')