diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/v1/app_shell.py b/sysinv/cgts-client/cgts-client/cgtsclient/v1/app_shell.py index efb6a04a21..58e8ede7c9 100644 --- a/sysinv/cgts-client/cgts-client/cgtsclient/v1/app_shell.py +++ b/sysinv/cgts-client/cgts-client/cgtsclient/v1/app_shell.py @@ -52,7 +52,8 @@ def do_application_upload(cc, args): raise exc.CommandError("Error: Tar file %s does not exist" % tarfile) if not tarfile.endswith('.tgz') and not tarfile.endswith('.tar.gz'): raise exc.CommandError("Error: File %s has unrecognizable tar file " - "extension." % tarfile) + "extension. Supported extensions are: .tgz " + "and .tar.gz" % tarfile) data = {'name': args.name, 'tarfile': tarfile} diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_app.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_app.py index 55158073b8..133fc112b0 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_app.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/kube_app.py @@ -122,19 +122,20 @@ class KubeAppController(rest.RestController): if app_name and app_tarfile: if not os.path.isfile(app_tarfile): raise wsme.exc.ClientSideError(_( - "Application-upload rejected: application tar file %s does " - "not exist." % app_tarfile)) + "Application-upload rejected: application tar file {} does " + "not exist.".format(app_tarfile))) if (not app_tarfile.endswith('.tgz') and not app_tarfile.endswith('.tar.gz')): raise wsme.exc.ClientSideError(_( - "Application-upload rejected: %s is not a tar file" % - app_tarfile)) + "Application-upload rejected: {} has unrecognizable tar file " + "extension. Supported extensions are: .tgz and .tar.gz.".format( + app_tarfile))) with TempDirectory() as app_path: if not cutils.extract_tarfile(app_path, app_tarfile): raise wsme.exc.ClientSideError(_( "Application-upload rejected: failed to extract tar file " - "%s." % os.path.basename(app_tarfile))) + "{}.".format(os.path.basename(app_tarfile)))) # If checksum file is included in the tarball, verify its contents. if not self._verify_checksum(app_path): @@ -146,16 +147,19 @@ class KubeAppController(rest.RestController): charts_dir = os.path.join(app_path, 'charts') if os.path.isdir(charts_dir): tar_filelist = cutils.get_files_matching(app_path, '.tgz') - if (len(os.listdir(charts_dir)) == 0 or - not tar_filelist): + if len(os.listdir(charts_dir)) == 0: raise wsme.exc.ClientSideError(_( - "Application-upload rejected: tar file " - "contains no Helm charts.")) + "Application-upload rejected: tar file contains no " + "Helm charts.")) + if not tar_filelist: + raise wsme.exc.ClientSideError(_( + "Application-upload rejected: tar file contains no " + "Helm charts of expected file extension (.tgz).")) for p, f in tar_filelist: if not cutils.extract_tarfile(p, os.path.join(p, f)): raise wsme.exc.ClientSideError(_( "Application-upload rejected: failed to extract tar " - "file %s" % os.path.basename(f))) + "file {}.".format(os.path.basename(f)))) LOG.info("Tar file of application %s verified." % app_name) return mname, mfile @@ -208,9 +212,16 @@ class KubeAppController(rest.RestController): for file in os.listdir(app_path): if file.endswith('.yaml'): yaml_file = os.path.join(app_path, file) - mname, mfile = _is_manifest(yaml_file) - if mfile: - mfiles.append((mname, mfile)) + try: + mname, mfile = _is_manifest(yaml_file) + if mfile: + mfiles.append((mname, mfile)) + except Exception as e: + # Included yaml file is corrupted + LOG.exception(e) + raise wsme.exc.ClientSideError(_( + "Application-upload rejected: failed to process " + "file {}.".format(file))) if mfiles: if len(mfiles) == 1: @@ -253,8 +264,8 @@ class KubeAppController(rest.RestController): try: objects.kube_app.get_by_name(pecan.request.context, name) raise wsme.exc.ClientSideError(_( - "Application-upload rejected: application %s already exists." % - name)) + "Application-upload rejected: application {} already exists.".format( + name))) except exception.KubeAppNotFound: pass @@ -295,7 +306,7 @@ class KubeAppController(rest.RestController): LOG.error("Received a request to %s app %s which does not exist." % (directive, name)) raise wsme.exc.ClientSideError(_( - "Application-%s rejected: application not found." % directive)) + "Application-{} rejected: application not found.".format(directive))) if directive == 'apply': if db_app.status == constants.APP_APPLY_IN_PROGRESS: @@ -307,7 +318,7 @@ class KubeAppController(rest.RestController): constants.APP_APPLY_SUCCESS]: raise wsme.exc.ClientSideError(_( "Application-apply rejected: operation is not allowed " - "while the current status is %s." % db_app.status)) + "while the current status is {}.".format(db_app.status))) db_app.status = constants.APP_APPLY_IN_PROGRESS db_app.save() pecan.request.rpcapi.perform_app_apply(pecan.request.context, @@ -315,11 +326,11 @@ class KubeAppController(rest.RestController): return KubeApp.convert_with_links(db_app) else: if db_app.status not in [constants.APP_APPLY_SUCCESS, - constants.APP_REMOVE_FAILURE, - constants.APP_APPLY_FAILURE]: + constants.APP_APPLY_FAILURE, + constants.APP_REMOVE_FAILURE]: raise wsme.exc.ClientSideError(_( "Application-remove rejected: operation is not allowed while " - "the current status is %s." % db_app.status)) + "the current status is {}.".format(db_app.status))) db_app.status = constants.APP_REMOVE_IN_PROGRESS db_app.save() pecan.request.rpcapi.perform_app_remove(pecan.request.context, diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py b/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py index 4a6d61ba6d..ca78b78f52 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/kube_app.py @@ -61,9 +61,8 @@ class AppOperator(object): def _cleanup(self, app): """" Remove application directories and override files """ try: - # TODO(tngo): Disable node labeling for system app for now until - # vim integration with sysinv for container support is ready - if not app.system_app and app.status != constants.APP_UPLOAD_FAILURE: + if (app.status != constants.APP_UPLOAD_FAILURE and + os.path.exists(os.path.join(app.path, 'metadata.yaml'))): self._process_node_labels(app, op=constants.LABEL_REMOVE_OP) if app.system_app and app.status != constants.APP_UPLOAD_FAILURE: self._remove_chart_overrides(app.mfile_abs) @@ -358,7 +357,10 @@ class AppOperator(object): name=app.name, reason="compute labels are malformed.") - # Add the default labels for system app + # Add the default labels for system app. They must exist for + # the app manifest to be applied successfully. If the nodes have + # been assigned these labels manually before, these + # reassignments are simply ignored. if app.system_app: controller_labels_set.add(constants.CONTROL_PLANE_LABEL) compute_labels_set.add(constants.COMPUTE_NODE_LABEL) @@ -496,10 +498,7 @@ class AppOperator(object): app = AppOperator.Application(rpc_app) LOG.info("Application (%s) apply started." % app.name) - # TODO(tngo): Disable node labeling for system app for now until - # vim integration with sysinv for container support is ready - if not app.system_app: - self._process_node_labels(app) + self._process_node_labels(app) overrides_str = '' ready = True