From nobody Tue May 7 13:28:29 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) client-ip=205.139.110.61; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1588866159; cv=none; d=zohomail.com; s=zohoarc; b=DjtGzdlFYn1IbZF6BimVRK7npF+KJtcu0BQBzgabv0ffVnVo9sIixxCNX+jJATIJ0i4EFzWuPMaQz0VqBj0HIn8wLWfPjKFnUIUXCtaQW251wWPNaqH3XqrUZNESvqGR3DLY4djLM0pUlnCxD/AlGEktAujF+HHUZCRbvc3Ny3o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1588866159; h=Content-Type:Content-Transfer-Encoding:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=OCndo9aU68K59sVZPZB3jg7/ePwe0wYh78osLzk6DpA=; b=DWCToQb+KKDrXmDIoaBGiuaiPJMMOLzZUcRSmG5drvrjZr4ufMK8Y6sRCqPoVsj7IVW0AMIgydUgyaKn7ZaeN3SUwQ79v7z/Wjz0Fnlg4o1x+LJRsRYEQMJjcnJSTISF/XXfYGFNuoatNhe48U08f4wbEO9AUo7p0vNXLQzmQOM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by mx.zohomail.com with SMTPS id 1588866159096190.65903545646222; Thu, 7 May 2020 08:42:39 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-334-isKoQWDdMS-VcqRVt7fPqQ-1; Thu, 07 May 2020 11:42:35 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E202F15480; Thu, 7 May 2020 15:42:10 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CB54D1001DC2; Thu, 7 May 2020 15:42:08 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 437654CAA0; Thu, 7 May 2020 15:42:06 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 047Fg4Wm002183 for ; Thu, 7 May 2020 11:42:04 -0400 Received: by smtp.corp.redhat.com (Postfix) id 9FE5660C47; Thu, 7 May 2020 15:42:04 +0000 (UTC) Received: from kinshicho.usersys.redhat.com (unknown [10.40.194.140]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 984F260FB9 for ; Thu, 7 May 2020 15:42:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1588866157; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=OCndo9aU68K59sVZPZB3jg7/ePwe0wYh78osLzk6DpA=; b=gRn/3e7uPr0esd5pl3mq8eyW4NFBxk5ZRRfTV1A+hHMN+OXrWp8vi0tPFFWD4tt+2ZndLo oGFKUme/Ss8ws7F6/xYeoLHK4FbvZGSKFvp5IAqmbl8Nube1+Mz0uC70WNws0Fs1RsnHaS YsG+yFNVUBDVrEC9wHxxRK/94OvmqPM= X-MC-Unique: isKoQWDdMS-VcqRVt7fPqQ-1 From: Andrea Bolognani To: libvir-list@redhat.com Subject: [libvirt-ci PATCH] lcitool: Catch exceptions earlier Date: Thu, 7 May 2020 17:41:57 +0200 Message-Id: <20200507154157.852635-1-abologna@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Right now we catch and report properly only those exceptions that are raised by the Application.run() method: basically, we work under the assumption that nothing before that point can possibly fail. That's of course unrealistic: even now, creating an Inventory or Projects object can raise an exception, in which case we simply display a stack trace instead of a reasonable error message. This commit introduces a CommandLine class which takes over command line handling from the Application class, and moves all exception handling to the main() method so that, short of something going horribly wrong while parsing the command line, we will always manage to hide stack traces from the user. Signed-off-by: Andrea Bolognani Reviewed-by: Erik Skultety --- guests/lcitool | 56 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/guests/lcitool b/guests/lcitool index ab3b95f..ff58829 100755 --- a/guests/lcitool +++ b/guests/lcitool @@ -390,15 +390,9 @@ class Projects: return self._packages[project] =20 =20 -class Application: +class CommandLine: =20 def __init__(self): - self._config =3D Config() - self._inventory =3D Inventory() - self._projects =3D Projects() - - self._native_arch =3D Util.get_native_arch() - self._parser =3D argparse.ArgumentParser( conflict_handler=3D"resolve", description=3D"libvirt CI guest management tool", @@ -444,14 +438,14 @@ class Application: =20 installparser =3D subparsers.add_parser( "install", help=3D"perform unattended host installation") - installparser.set_defaults(func=3Dself._action_install) + installparser.set_defaults(action=3D"install") =20 add_hosts_arg(installparser) add_wait_arg(installparser) =20 updateparser =3D subparsers.add_parser( "update", help=3D"prepare hosts and keep them updated") - updateparser.set_defaults(func=3Dself._action_update) + updateparser.set_defaults(action=3D"update") =20 add_hosts_arg(updateparser) add_projects_arg(updateparser) @@ -459,7 +453,7 @@ class Application: =20 buildparser =3D subparsers.add_parser( "build", help=3D"build projects on hosts") - buildparser.set_defaults(func=3Dself._action_build) + buildparser.set_defaults(action=3D"build") =20 add_hosts_arg(buildparser) add_projects_arg(buildparser) @@ -467,20 +461,33 @@ class Application: =20 hostsparser =3D subparsers.add_parser( "hosts", help=3D"list all known hosts") - hostsparser.set_defaults(func=3Dself._action_hosts) + hostsparser.set_defaults(action=3D"hosts") =20 projectsparser =3D subparsers.add_parser( "projects", help=3D"list all known projects") - projectsparser.set_defaults(func=3Dself._action_projects) + projectsparser.set_defaults(action=3D"projects") =20 dockerfileparser =3D subparsers.add_parser( "dockerfile", help=3D"generate Dockerfile (doesn't access the = host)") - dockerfileparser.set_defaults(func=3Dself._action_dockerfile) + dockerfileparser.set_defaults(action=3D"dockerfile") =20 add_hosts_arg(dockerfileparser) add_projects_arg(dockerfileparser) add_cross_arch_arg(dockerfileparser) =20 + def parse(self): + return self._parser.parse_args() + + +class Application: + + def __init__(self): + self._config =3D Config() + self._inventory =3D Inventory() + self._projects =3D Projects() + + self._native_arch =3D Util.get_native_arch() + def _execute_playbook(self, playbook, hosts, projects, git_revision): base =3D Util.get_base() =20 @@ -1011,17 +1018,18 @@ class Application: varmap =3D self._dockerfile_build_varmap(facts, mappings, pip_mapp= ings, projects, cross_arch) self._dockerfile_format(facts, cross_arch, varmap) =20 - def run(self): - args =3D self._parser.parse_args() - if args.debug: - args.func(args) - else: - try: - args.func(args) - except Exception as err: - sys.stderr.write("{}: {}\n".format(sys.argv[0], err)) - sys.exit(1) + def run(self, args): + getattr(self, "_action_" + args.action)(args) =20 =20 if __name__ =3D=3D "__main__": - Application().run() + args =3D CommandLine().parse() + + if args.debug: + Application().run(args) + else: + try: + Application().run(args) + except Exception as err: + sys.stderr.write("{}: {}\n".format(sys.argv[0], err)) + sys.exit(1) --=20 2.25.4