fix run error issue for parser repomd.xml when here is group type
[tools/mic.git] / mic / utils / misc.py
index bf377b4..399fd4e 100755 (executable)
@@ -41,6 +41,7 @@ except ImportError:
 xmlparse = cElementTree.parse
 
 from mic import msger
+from mic.archive import get_archive_suffixes
 from mic.utils.errors import CreatorError, SquashfsError
 from mic.utils.fs_related import find_binary_path, makedirs
 from mic.utils.grabber import myurlgrab
@@ -159,7 +160,7 @@ def hide_loopdev_presentation():
         pass
 
 def unhide_loopdev_presentation():
-    global _LOOP_RULE_PTH
+    #global _LOOP_RULE_PTH
 
     if not _LOOP_RULE_PTH:
         return
@@ -301,7 +302,7 @@ def normalize_ksfile(ksconf, release, arch):
     def remove_temp_ks():
         try:
             os.unlink(ksconf)
-        except OSError, err:
+        except OSError as err:
             msger.warning('Failed to remove temp ks file:%s:%s' % (ksconf, err))
 
     import atexit
@@ -568,7 +569,8 @@ def get_metadata_from_repos(repos, cachedir):
                 break
 
         for elm in root.getiterator("%sdata" % ns):
-            if elm.attrib["type"] in ("group_gz", "group"):
+            #"group" type has no "open-checksum" filed, remove it.
+            if elm.attrib["type"] == "group_gz":
                 filepaths['comps'] = elm.find("%slocation" % ns).attrib['href']
                 checksums['comps'] = elm.find("%sopen-checksum" % ns).text
                 sumtypes['comps'] = elm.find("%sopen-checksum" % ns).attrib['type']
@@ -619,7 +621,8 @@ def get_metadata_from_repos(repos, cachedir):
                                  "proxies":proxies,
                                  "patterns":filepaths['patterns'],
                                  "comps":filepaths['comps'],
-                                 "repokey":repokey})
+                                 "repokey":repokey,
+                                 "priority":repo.priority})
 
     return my_repo_metadata
 
@@ -697,6 +700,7 @@ def get_arch(repometadata):
 
 def get_package(pkg, repometadata, arch = None):
     ver = ""
+    priority = 99
     target_repo = None
     if not arch:
         arches = []
@@ -712,16 +716,25 @@ def get_package(pkg, repometadata, arch = None):
             ns = root.getroot().tag
             ns = ns[0:ns.rindex("}")+1]
             for elm in root.getiterator("%spackage" % ns):
-                if elm.find("%sname" % ns).text == pkg:
-                    if elm.find("%sarch" % ns).text in arches:
-                        version = elm.find("%sversion" % ns)
-                        tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
-                        if tmpver > ver:
-                            ver = tmpver
+                if elm.find("%sname" % ns).text == pkg and elm.find("%sarch" % ns).text in arches:
+                    if repo["priority"] != None:
+                        tmpprior = int(repo["priority"])
+                        if tmpprior < priority:
+                            priority = tmpprior
                             location = elm.find("%slocation" % ns)
                             pkgpath = "%s" % location.attrib['href']
                             target_repo = repo
-                        break
+                            break
+                        elif tmpprior > priority:
+                            break
+                    version = elm.find("%sversion" % ns)
+                    tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
+                    if tmpver > ver:
+                        ver = tmpver
+                        location = elm.find("%slocation" % ns)
+                        pkgpath = "%s" % location.attrib['href']
+                        target_repo = repo
+                    break
         if repo["primary"].endswith(".sqlite"):
             con = sqlite.connect(repo["primary"])
             if arch:
@@ -885,7 +898,38 @@ def get_pkglist_in_comps(group, comps):
 def is_statically_linked(binary):
     return ", statically linked, " in runner.outs(['file', binary])
 
+def get_qemu_arm_binary(arch):
+    if arch == "aarch64":
+        node = "/proc/sys/fs/binfmt_misc/aarch64"
+        if os.path.exists("/usr/bin/qemu-arm64") and is_statically_linked("/usr/bin/qemu-arm64"):
+            arm_binary = "qemu-arm64"
+        elif os.path.exists("/usr/bin/qemu-aarch64") and is_statically_linked("/usr/bin/qemu-aarch64"):
+            arm_binary = "qemu-aarch64"
+        elif os.path.exists("/usr/bin/qemu-arm64-static"):
+            arm_binary = "qemu-arm64-static"
+        elif os.path.exists("/usr/bin/qemu-aarch64-static"):
+            arm_binary = "qemu-aarch64-static"
+        else:
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+    elif arch == "mipsel":
+        node = "/proc/sys/fs/binfmt_misc/mipsel"
+        arm_binary = "qemu-mipsel"
+        if not os.path.exists("/usr/bin/%s" % arm_binary) or not is_statically_linked("/usr/bin/%s"):
+            arm_binary = "qemu-mipsel-static"
+        if not os.path.exists("/usr/bin/%s" % arm_binary):
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+    else:
+        node = "/proc/sys/fs/binfmt_misc/arm"
+        arm_binary = "qemu-arm"
+        if not os.path.exists("/usr/bin/qemu-arm") or not is_statically_linked("/usr/bin/qemu-arm"):
+            arm_binary = "qemu-arm-static"
+        if not os.path.exists("/usr/bin/%s" % arm_binary):
+            raise CreatorError("Please install a statically-linked %s" % arm_binary)
+
+    return (arm_binary, node)
+
 def setup_qemu_emulator(rootdir, arch):
+    qemu_emulators = []
     # mount binfmt_misc if it doesn't exist
     if not os.path.exists("/proc/sys/fs/binfmt_misc"):
         modprobecmd = find_binary_path("modprobe")
@@ -896,44 +940,50 @@ def setup_qemu_emulator(rootdir, arch):
 
     # qemu_emulator is a special case, we can't use find_binary_path
     # qemu emulator should be a statically-linked executable file
-    if arch == "aarch64":
-        arm_binary = "qemu-arm64"
-        node = "/proc/sys/fs/binfmt_misc/aarch64"
-    else:
-        arm_binary = "qemu-arm"
-        node = "/proc/sys/fs/binfmt_misc/arm"
-
+    arm_binary, node = get_qemu_arm_binary(arch)
     qemu_emulator = "/usr/bin/%s" % arm_binary
-    if not os.path.exists(qemu_emulator) or not is_statically_linked(qemu_emulator):
-        qemu_emulator = "/usr/bin/%s-static" % arm_binary
-    if not os.path.exists(qemu_emulator):
-        raise CreatorError("Please install a statically-linked %s" % arm_binary)
 
     if not os.path.exists(rootdir + "/usr/bin"):
         makedirs(rootdir + "/usr/bin")
     shutil.copy(qemu_emulator, rootdir + qemu_emulator)
+    qemu_emulators.append(qemu_emulator)
 
     # disable selinux, selinux will block qemu emulator to run
     if os.path.exists("/usr/sbin/setenforce"):
         msger.info('Try to disable selinux')
         runner.show(["/usr/sbin/setenforce", "0"])
 
-    # unregister it if it has been registered and is a dynamically-linked executable
-    if os.path.exists(node):
-        qemu_unregister_string = "-1\n"
-        with open(node, "w") as fd:
-            fd.write(qemu_unregister_string)
-
     # register qemu emulator for interpreting other arch executable file
     if not os.path.exists(node):
         if arch == "aarch64":
             qemu_arm_string = ":aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:%s:\n" % qemu_emulator
+        elif arch == "mipsel":
+            qemu_arm_string = ":mipsel:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x08\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xfe\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:%s:\n" % qemu_emulator
         else:
             qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator
+
         with open("/proc/sys/fs/binfmt_misc/register", "w") as fd:
             fd.write(qemu_arm_string)
-
-    return qemu_emulator
+    else:
+        flags = ""
+        interpreter = ""
+        with open(node, "r") as fd:
+            for line in fd.readlines():
+                if line.startswith("flags:"):
+                    flags = line[len("flags:"):].strip()
+                elif line.startswith("interpreter"):
+                    interpreter = line[len("interpreter"):].strip()
+
+        if flags == "P" and interpreter.endswith("-binfmt"):
+            # copy binfmt wrapper when preserve-argv[0] flag is enabled
+            shutil.copy(os.path.realpath(interpreter), rootdir + interpreter)
+            qemu_emulators.append(interpreter)
+        elif not flags and interpreter != qemu_emulator:
+            # create symlink as registered qemu emulator
+            os.symlink(qemu_emulator, rootdir + interpreter)
+            qemu_emulators.append(interpreter)
+
+    return qemu_emulators
 
 def SrcpkgsDownload(pkgs, repometadata, instroot, cachedir):
     def get_source_repometadata(repometadata):
@@ -999,3 +1049,11 @@ def strip_end(text, suffix):
     if not text.endswith(suffix):
         return text
     return text[:-len(suffix)]
+
+def strip_archive_suffix(filename):
+    for suffix in get_archive_suffixes():
+        if filename.endswith(suffix):
+            return filename[:-len(suffix)]
+    else:
+        msger.warning("Not supported archive file format: %s" % filename)
+    return None