We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[RPM M1] Add a new block to call the generation code for RPM
Tasks | Estimate | Status | Notes | Dependencies
-- | -- | -- | -- | --
The generation code should pull the artifacts from the build workflow to a temporary location | 1 | Complete |   | Build workflow must provide usable artifacts
The code will call existing install function to install plugins on min artifacts | 1 | Complete |   |  
After installation, the code will execute a tool or utility to wrap all the content into a RPM package | 5 | Complete | Require writing a script to utilize FPM to start with and later implement in pure python code. <br><br>20220204: We might change to rpmbuild directly without using FPM. See comments. | FPM usages
The code will also add dependencies to the RPM package so that things like JDK and additional libs for plugins can be installed and pulled separately | 5 | Complete | Need to study on RPM dependency setups | RPM Build Dependencies and the locations of each dependent artifact
The code will move the RPM package from the temp location to dist folder | 2 | Complete |   |  



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/assemble_workflow/bundle_rpm.py`
Content:
```
1 # SPDX-License-Identifier: Apache-2.0
2 #
3 # The OpenSearch Contributors require contributions made to
4 # this file be licensed under the Apache-2.0 license or a
5 # compatible open source license.
6 
7 import logging
8 import os
9 import shutil
10 import subprocess
11 
12 from manifests.build_manifest import BuildManifest
13 from system.os import rpm_architecture
14 
15 
16 class BundleRpm:
17 
18     def __init__(self, filename: str, package_path: str, min_path: str) -> None:
19         self.filename = filename
20         self.package_path = package_path
21         self.min_path = min_path
22 
23     def extract(self, dest: str) -> None:
24         cpio_basename = os.path.splitext(os.path.basename(self.package_path))[0]
25         cpio_path = os.path.join(dest, f"{cpio_basename}.cpio")
26         min_source_path = os.path.join(dest, 'usr', 'share', self.filename)
27         min_dest_path = os.path.join(dest, self.min_path)
28         min_config_path = os.path.join(dest, 'etc', self.filename)
29         min_bin_env_path = os.path.join(min_dest_path, 'bin', f"{self.filename}-env")
30 
31         # Convert rpm to cpio so we can extract the content
32         logging.info(f"Convert rpm to cpio for extraction: {self.package_path} to {cpio_path}")
33         with open(cpio_path, 'wb') as fp:
34             subprocess.check_call(
35                 [
36                     'rpm2cpio',
37                     self.package_path,
38                 ],
39                 stdout=fp,
40                 cwd=dest,
41             )
42 
43         # Extract cpio archive based on the rpm package
44         logging.info(f"Extract cpio {cpio_path} content to {dest}")
45         with open(cpio_path, 'rb') as fp:
46             subprocess.check_call(
47                 [
48                     'cpio',
49                     '-imdv',
50                 ],
51                 stdin=fp,
52                 stdout=subprocess.DEVNULL,
53                 stderr=subprocess.STDOUT,
54                 cwd=dest,
55             )
56 
57         # Move core folder destination so plugin install can proceed
58         logging.info(f"Move {min_source_path} to {min_dest_path} for plugin installation")
59         shutil.move(min_source_path, min_dest_path)
60 
61         # Multiple modifications and env vars setups before install plugins
62         # As bin/opensearch-env is different between archive and package
63         # https://github.com/opensearch-project/OpenSearch/issues/2092
64         os.environ[f"{self.filename.upper()}_PATH_CONF"] = min_config_path
65 
66         if os.path.exists(min_bin_env_path):
67             # Backup original file
68             shutil.copy2(min_bin_env_path, f"{min_bin_env_path}.backup")
69             # Prevent sourcing as file is only in place after rpm installation
70             # So that min can install plugin zips
71             # Have to decode then encode back to ascii due to mypy complains TextIO not equals to BinaryIO
72             with open(min_bin_env_path, 'rb') as fp:
73                 min_bin_env_lines = fp.read().decode('ascii')
74 
75             with open(min_bin_env_path, 'wb') as fp:
76                 fp.write(min_bin_env_lines.replace('source', '#source').encode('ascii'))
77 
78     def build(self, name: str, dest: str, archive_path: str, build_cls: BuildManifest.Build) -> None:
79         # extract dest and build dest are not the same, this is restoring the extract dest
80         # mainly due to rpm requires several different setups compares to tarball and zip
81         ext_dest = os.path.dirname(archive_path)
82         min_source_path = os.path.join(ext_dest, 'usr', 'share', self.filename)
83         min_dest_path = os.path.join(ext_dest, self.min_path)
84         min_bin_env_path = os.path.join(min_dest_path, 'bin', f"{self.filename}-env")
85         bundle_artifact_path: str = None
86 
87         # Remove env var
88         logging.info('Organize folder structure before generating rpm')
89         os.environ.pop('OPENSEARCH_PATH_CONF', None)
90 
91         # Restore config file and core folder to original location
92         shutil.move(f"{min_bin_env_path}.backup", min_bin_env_path)
93         shutil.move(min_dest_path, min_source_path)
94 
95         # Run bundle rpmbuild
96         bundle_cmd = " ".join(
97             [
98                 'rpmbuild',
99                 '-bb',
100                 f"--define '_topdir {ext_dest}'",
101                 f"--define '_version {build_cls.version}'",
102                 f"--define '_architecture_alt {rpm_architecture(build_cls.architecture)}'",
103                 f"{self.filename}.rpm.spec",
104             ]
105         )
106 
107         logging.info(f"Execute {bundle_cmd} in {ext_dest}")
108         subprocess.check_call(bundle_cmd, cwd=ext_dest, shell=True)
109 
110         # Move artifact to repo root before being published to {dest}
111         for dirpath, dirnames, filenames in os.walk(os.path.join(ext_dest, 'RPMS')):
112             for filename in [file for file in filenames if file.endswith('.rpm')]:
113                 bundle_artifact_path = os.path.join(dirpath, filename)
114                 break
115 
116         shutil.move(bundle_artifact_path, name)
117
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/assemble_workflow/bundle_rpm.py b/src/assemble_workflow/bundle_rpm.py
--- a/src/assemble_workflow/bundle_rpm.py
+++ b/src/assemble_workflow/bundle_rpm.py
@@ -99,7 +99,7 @@
                 '-bb',
                 f"--define '_topdir {ext_dest}'",
                 f"--define '_version {build_cls.version}'",
-                f"--define '_architecture_alt {rpm_architecture(build_cls.architecture)}'",
+                f"--define '_architecture {rpm_architecture(build_cls.architecture)}'",
                 f"{self.filename}.rpm.spec",
             ]
         )

{"golden_diff": "diff --git a/src/assemble_workflow/bundle_rpm.py b/src/assemble_workflow/bundle_rpm.py\n--- a/src/assemble_workflow/bundle_rpm.py\n+++ b/src/assemble_workflow/bundle_rpm.py\n@@ -99,7 +99,7 @@\n                 '-bb',\n                 f\"--define '_topdir {ext_dest}'\",\n                 f\"--define '_version {build_cls.version}'\",\n-                f\"--define '_architecture_alt {rpm_architecture(build_cls.architecture)}'\",\n+                f\"--define '_architecture {rpm_architecture(build_cls.architecture)}'\",\n                 f\"{self.filename}.rpm.spec\",\n             ]\n         )\n", "issue": "[RPM M1] Add a new block to call the generation code for RPM\nTasks | Estimate | Status | Notes | Dependencies\r\n-- | -- | -- | -- | --\r\nThe generation code should pull the artifacts from the build workflow to a temporary location | 1 | Complete | \u00a0 | Build workflow must provide usable artifacts\r\nThe code will call existing install function to install plugins on min artifacts | 1 | Complete | \u00a0 | \u00a0\r\nAfter installation, the code will execute a tool or utility to wrap all the content into a RPM package | 5 | Complete | Require writing a script to utilize FPM to start with and later implement in pure python code. <br><br>20220204: We might change to rpmbuild directly without using FPM. See comments. | FPM usages\r\nThe code will also add dependencies to the RPM package so that things like JDK and additional libs for plugins can be installed and pulled separately | 5 | Complete | Need to study on RPM dependency setups | RPM Build Dependencies and the locations of each dependent artifact\r\nThe code will move the RPM package from the temp location to dist folder | 2 | Complete | \u00a0 | \u00a0\r\n\r\n\n", "before_files": [{"content": "# SPDX-License-Identifier: Apache-2.0\n#\n# The OpenSearch Contributors require contributions made to\n# this file be licensed under the Apache-2.0 license or a\n# compatible open source license.\n\nimport logging\nimport os\nimport shutil\nimport subprocess\n\nfrom manifests.build_manifest import BuildManifest\nfrom system.os import rpm_architecture\n\n\nclass BundleRpm:\n\n    def __init__(self, filename: str, package_path: str, min_path: str) -> None:\n        self.filename = filename\n        self.package_path = package_path\n        self.min_path = min_path\n\n    def extract(self, dest: str) -> None:\n        cpio_basename = os.path.splitext(os.path.basename(self.package_path))[0]\n        cpio_path = os.path.join(dest, f\"{cpio_basename}.cpio\")\n        min_source_path = os.path.join(dest, 'usr', 'share', self.filename)\n        min_dest_path = os.path.join(dest, self.min_path)\n        min_config_path = os.path.join(dest, 'etc', self.filename)\n        min_bin_env_path = os.path.join(min_dest_path, 'bin', f\"{self.filename}-env\")\n\n        # Convert rpm to cpio so we can extract the content\n        logging.info(f\"Convert rpm to cpio for extraction: {self.package_path} to {cpio_path}\")\n        with open(cpio_path, 'wb') as fp:\n            subprocess.check_call(\n                [\n                    'rpm2cpio',\n                    self.package_path,\n                ],\n                stdout=fp,\n                cwd=dest,\n            )\n\n        # Extract cpio archive based on the rpm package\n        logging.info(f\"Extract cpio {cpio_path} content to {dest}\")\n        with open(cpio_path, 'rb') as fp:\n            subprocess.check_call(\n                [\n                    'cpio',\n                    '-imdv',\n                ],\n                stdin=fp,\n                stdout=subprocess.DEVNULL,\n                stderr=subprocess.STDOUT,\n                cwd=dest,\n            )\n\n        # Move core folder destination so plugin install can proceed\n        logging.info(f\"Move {min_source_path} to {min_dest_path} for plugin installation\")\n        shutil.move(min_source_path, min_dest_path)\n\n        # Multiple modifications and env vars setups before install plugins\n        # As bin/opensearch-env is different between archive and package\n        # https://github.com/opensearch-project/OpenSearch/issues/2092\n        os.environ[f\"{self.filename.upper()}_PATH_CONF\"] = min_config_path\n\n        if os.path.exists(min_bin_env_path):\n            # Backup original file\n            shutil.copy2(min_bin_env_path, f\"{min_bin_env_path}.backup\")\n            # Prevent sourcing as file is only in place after rpm installation\n            # So that min can install plugin zips\n            # Have to decode then encode back to ascii due to mypy complains TextIO not equals to BinaryIO\n            with open(min_bin_env_path, 'rb') as fp:\n                min_bin_env_lines = fp.read().decode('ascii')\n\n            with open(min_bin_env_path, 'wb') as fp:\n                fp.write(min_bin_env_lines.replace('source', '#source').encode('ascii'))\n\n    def build(self, name: str, dest: str, archive_path: str, build_cls: BuildManifest.Build) -> None:\n        # extract dest and build dest are not the same, this is restoring the extract dest\n        # mainly due to rpm requires several different setups compares to tarball and zip\n        ext_dest = os.path.dirname(archive_path)\n        min_source_path = os.path.join(ext_dest, 'usr', 'share', self.filename)\n        min_dest_path = os.path.join(ext_dest, self.min_path)\n        min_bin_env_path = os.path.join(min_dest_path, 'bin', f\"{self.filename}-env\")\n        bundle_artifact_path: str = None\n\n        # Remove env var\n        logging.info('Organize folder structure before generating rpm')\n        os.environ.pop('OPENSEARCH_PATH_CONF', None)\n\n        # Restore config file and core folder to original location\n        shutil.move(f\"{min_bin_env_path}.backup\", min_bin_env_path)\n        shutil.move(min_dest_path, min_source_path)\n\n        # Run bundle rpmbuild\n        bundle_cmd = \" \".join(\n            [\n                'rpmbuild',\n                '-bb',\n                f\"--define '_topdir {ext_dest}'\",\n                f\"--define '_version {build_cls.version}'\",\n                f\"--define '_architecture_alt {rpm_architecture(build_cls.architecture)}'\",\n                f\"{self.filename}.rpm.spec\",\n            ]\n        )\n\n        logging.info(f\"Execute {bundle_cmd} in {ext_dest}\")\n        subprocess.check_call(bundle_cmd, cwd=ext_dest, shell=True)\n\n        # Move artifact to repo root before being published to {dest}\n        for dirpath, dirnames, filenames in os.walk(os.path.join(ext_dest, 'RPMS')):\n            for filename in [file for file in filenames if file.endswith('.rpm')]:\n                bundle_artifact_path = os.path.join(dirpath, filename)\n                break\n\n        shutil.move(bundle_artifact_path, name)\n", "path": "src/assemble_workflow/bundle_rpm.py"}], "after_files": [{"content": "# SPDX-License-Identifier: Apache-2.0\n#\n# The OpenSearch Contributors require contributions made to\n# this file be licensed under the Apache-2.0 license or a\n# compatible open source license.\n\nimport logging\nimport os\nimport shutil\nimport subprocess\n\nfrom manifests.build_manifest import BuildManifest\nfrom system.os import rpm_architecture\n\n\nclass BundleRpm:\n\n    def __init__(self, filename: str, package_path: str, min_path: str) -> None:\n        self.filename = filename\n        self.package_path = package_path\n        self.min_path = min_path\n\n    def extract(self, dest: str) -> None:\n        cpio_basename = os.path.splitext(os.path.basename(self.package_path))[0]\n        cpio_path = os.path.join(dest, f\"{cpio_basename}.cpio\")\n        min_source_path = os.path.join(dest, 'usr', 'share', self.filename)\n        min_dest_path = os.path.join(dest, self.min_path)\n        min_config_path = os.path.join(dest, 'etc', self.filename)\n        min_bin_env_path = os.path.join(min_dest_path, 'bin', f\"{self.filename}-env\")\n\n        # Convert rpm to cpio so we can extract the content\n        logging.info(f\"Convert rpm to cpio for extraction: {self.package_path} to {cpio_path}\")\n        with open(cpio_path, 'wb') as fp:\n            subprocess.check_call(\n                [\n                    'rpm2cpio',\n                    self.package_path,\n                ],\n                stdout=fp,\n                cwd=dest,\n            )\n\n        # Extract cpio archive based on the rpm package\n        logging.info(f\"Extract cpio {cpio_path} content to {dest}\")\n        with open(cpio_path, 'rb') as fp:\n            subprocess.check_call(\n                [\n                    'cpio',\n                    '-imdv',\n                ],\n                stdin=fp,\n                stdout=subprocess.DEVNULL,\n                stderr=subprocess.STDOUT,\n                cwd=dest,\n            )\n\n        # Move core folder destination so plugin install can proceed\n        logging.info(f\"Move {min_source_path} to {min_dest_path} for plugin installation\")\n        shutil.move(min_source_path, min_dest_path)\n\n        # Multiple modifications and env vars setups before install plugins\n        # As bin/opensearch-env is different between archive and package\n        # https://github.com/opensearch-project/OpenSearch/issues/2092\n        os.environ[f\"{self.filename.upper()}_PATH_CONF\"] = min_config_path\n\n        if os.path.exists(min_bin_env_path):\n            # Backup original file\n            shutil.copy2(min_bin_env_path, f\"{min_bin_env_path}.backup\")\n            # Prevent sourcing as file is only in place after rpm installation\n            # So that min can install plugin zips\n            # Have to decode then encode back to ascii due to mypy complains TextIO not equals to BinaryIO\n            with open(min_bin_env_path, 'rb') as fp:\n                min_bin_env_lines = fp.read().decode('ascii')\n\n            with open(min_bin_env_path, 'wb') as fp:\n                fp.write(min_bin_env_lines.replace('source', '#source').encode('ascii'))\n\n    def build(self, name: str, dest: str, archive_path: str, build_cls: BuildManifest.Build) -> None:\n        # extract dest and build dest are not the same, this is restoring the extract dest\n        # mainly due to rpm requires several different setups compares to tarball and zip\n        ext_dest = os.path.dirname(archive_path)\n        min_source_path = os.path.join(ext_dest, 'usr', 'share', self.filename)\n        min_dest_path = os.path.join(ext_dest, self.min_path)\n        min_bin_env_path = os.path.join(min_dest_path, 'bin', f\"{self.filename}-env\")\n        bundle_artifact_path: str = None\n\n        # Remove env var\n        logging.info('Organize folder structure before generating rpm')\n        os.environ.pop('OPENSEARCH_PATH_CONF', None)\n\n        # Restore config file and core folder to original location\n        shutil.move(f\"{min_bin_env_path}.backup\", min_bin_env_path)\n        shutil.move(min_dest_path, min_source_path)\n\n        # Run bundle rpmbuild\n        bundle_cmd = \" \".join(\n            [\n                'rpmbuild',\n                '-bb',\n                f\"--define '_topdir {ext_dest}'\",\n                f\"--define '_version {build_cls.version}'\",\n                f\"--define '_architecture {rpm_architecture(build_cls.architecture)}'\",\n                f\"{self.filename}.rpm.spec\",\n            ]\n        )\n\n        logging.info(f\"Execute {bundle_cmd} in {ext_dest}\")\n        subprocess.check_call(bundle_cmd, cwd=ext_dest, shell=True)\n\n        # Move artifact to repo root before being published to {dest}\n        for dirpath, dirnames, filenames in os.walk(os.path.join(ext_dest, 'RPMS')):\n            for filename in [file for file in filenames if file.endswith('.rpm')]:\n                bundle_artifact_path = os.path.join(dirpath, filename)\n                break\n\n        shutil.move(bundle_artifact_path, name)\n", "path": "src/assemble_workflow/bundle_rpm.py"}]}