From nobody Mon Feb 9 13:58:32 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1532017942554586.3535499672545; Thu, 19 Jul 2018 09:32:22 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6A649811BF; Thu, 19 Jul 2018 16:32:20 +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 B8B263001648; Thu, 19 Jul 2018 16:32:19 +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 2572F24600; Thu, 19 Jul 2018 16:32:18 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w6JGWG62003713 for ; Thu, 19 Jul 2018 12:32:16 -0400 Received: by smtp.corp.redhat.com (Postfix) id 0B8041C5B7; Thu, 19 Jul 2018 16:32:16 +0000 (UTC) Received: from inaba.usersys.redhat.com (unknown [10.43.2.44]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A06D11C5B8 for ; Thu, 19 Jul 2018 16:32:15 +0000 (UTC) From: Andrea Bolognani To: libvir-list@redhat.com Date: Thu, 19 Jul 2018 18:32:01 +0200 Message-Id: <20180719163208.23126-2-abologna@redhat.com> In-Reply-To: <20180719163208.23126-1-abologna@redhat.com> References: <20180719163208.23126-1-abologna@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com Subject: [libvirt] [jenkins-ci PATCH 1/8] lcitool: Make the script location-independent 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 19 Jul 2018 16:32:21 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Up until now, the only way to run lcitool has been from the same directory it lives. After this patch, the script is able to figure out its own location and adjust all paths accordingly. Suggested-by: Katerina Koukiou Signed-off-by: Andrea Bolognani Reviewed-by: Erik Skultety --- guests/lcitool | 61 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/guests/lcitool b/guests/lcitool index 22b08dd..5526a27 100755 --- a/guests/lcitool +++ b/guests/lcitool @@ -43,6 +43,10 @@ class Error(Exception): =20 class Util: =20 + @staticmethod + def get_base(): + return os.path.dirname(os.path.abspath(__file__)) + @staticmethod def mksalt(): alphabeth =3D string.ascii_letters + string.digits @@ -83,8 +87,8 @@ class Config: try: config_dir =3D os.environ["XDG_CONFIG_HOME"] except KeyError: - config_dir =3D os.path.join(os.environ["HOME"], ".config/") - config_dir =3D os.path.join(config_dir, "lcitool/") + config_dir =3D os.path.join(os.environ["HOME"], ".config") + config_dir =3D os.path.join(config_dir, "lcitool") =20 # Create the directory if it doesn't already exist if not os.path.exists(config_dir): @@ -179,13 +183,18 @@ class Config: class Inventory: =20 def __init__(self): + base =3D Util.get_base() + ansible_cfg_path =3D os.path.join(base, "ansible.cfg") + try: parser =3D configparser.SafeConfigParser() - parser.read("./ansible.cfg") + parser.read(ansible_cfg_path) inventory_path =3D parser.get("defaults", "inventory") except Exception: raise Error("Can't find inventory location in ansible.cfg") =20 + inventory_path =3D os.path.join(base, inventory_path) + self._facts =3D {} try: # We can only deal with trivial inventories, but that's @@ -217,12 +226,19 @@ class Inventory: facts[fact] =3D some_facts[fact] =20 def _read_all_facts(self, host): + base =3D Util.get_base() + + sources =3D [ + os.path.join(base, "group_vars", "all"), + os.path.join(base, "host_vars", host), + ] + facts =3D {} =20 # We load from group_vars/ first and host_vars/ second, sorting # files alphabetically; doing so should result in our view of # the facts matching Ansible's - for source in ["./group_vars/all/", "./host_vars/{}/".format(host)= ]: + for source in sources: for item in sorted(os.listdir(source)): yaml_path =3D os.path.join(source, item) if not os.path.isfile(yaml_path): @@ -243,15 +259,20 @@ class Inventory: class Projects: =20 def __init__(self): + base =3D Util.get_base() + + mappings_path =3D os.path.join(base, "vars", "mappings.yml") + try: - with open("./vars/mappings.yml", "r") as infile: + with open(mappings_path, "r") as infile: mappings =3D yaml.load(infile) self._mappings =3D mappings["mappings"] except Exception: raise Error("Can't load mappings") =20 + source =3D os.path.join(base, "vars", "projects") + self._packages =3D {} - source =3D "./vars/projects/" for item in os.listdir(source): yaml_path =3D os.path.join(source, item) if not os.path.isfile(yaml_path): @@ -338,6 +359,8 @@ class Application: print(project) =20 def _action_install(self, hosts, _projects): + base =3D Util.get_base() + flavor =3D self._config.get_flavor() =20 for host in self._inventory.expand_pattern(hosts): @@ -358,6 +381,8 @@ class Application: facts["install_network"], ) =20 + install_config =3D os.path.join(base, facts["install_config"]) + # preseed files must use a well-known name to be picked up by # d-i; for kickstart files, we can use whatever name we please # but we need to point anaconda in the right direction through @@ -381,7 +406,7 @@ class Application: "--graphics", "none", "--console", "pty", "--sound", "none", - "--initrd-inject", facts["install_config"], + "--initrd-inject", install_config, "--extra-args", extra_arg, "--wait", "0", ] @@ -396,28 +421,38 @@ class Application: raise Error("Failed to install '{}'".format(host)) =20 def _action_update(self, hosts, _projects): + base =3D Util.get_base() + flavor =3D self._config.get_flavor() vault_pass_file =3D self._config.get_vault_password_file() root_pass_file =3D self._config.get_root_password_file() =20 ansible_hosts =3D ",".join(self._inventory.expand_pattern(hosts)) =20 + ansible_cfg_path =3D os.path.join(base, "ansible.cfg") + playbook_path =3D os.path.join(base, "site.yml") + extra_vars =3D "flavor=3D{} root_password_file=3D{}".format( flavor, root_pass_file, ) =20 - cmd =3D ["ansible-playbook"] + cmd =3D [ + "ansible-playbook", + "--limit", ansible_hosts, + "--extra-vars", extra_vars, + ] =20 # Provide the vault password if available if vault_pass_file is not None: cmd +=3D ["--vault-password-file", vault_pass_file] =20 - cmd +=3D [ - "--limit", ansible_hosts, - "--extra-vars", extra_vars, - "./site.yml", - ] + cmd +=3D [playbook_path] + + # We need to point Ansible to the correct configuration file, + # and for some reason this has to be done using the environment + # rather than through the command line + os.environ["ANSIBLE_CONFIG"] =3D ansible_cfg_path =20 try: subprocess.check_call(cmd) --=20 2.17.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list