Repository: opensearch-project/opensearch-build

Issue:
Resolving RPM/DEB IntegTest having config modify issues.
Hi,

There are issues modifying the config yml files in RPM/DEB if you dont use sudo/root to run test.sh.
However, the issue being that certain OS process and integTest cannot run on root, thus catch 22.

This issue would be resolved if we assume the current running user of test.sh has sudo permission, while still able to change settings without using root.

Thanks.

------

Even when you have everything on root seems like integTest class is still asking the gradle run to happen on non-root:
```

»    ↓ errors and warnings from /tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/logs/opensearch.stdout.log ↓
» ERROR][o.o.b.OpenSearchUncaughtExceptionHandler] [integTest-0] uncaught exception in thread [main]
»  org.opensearch.bootstrap.StartupException: java.lang.RuntimeException: can not run opensearch as root
»       at org.opensearch.bootstrap.OpenSearch.init(OpenSearch.java:184) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.bootstrap.OpenSearch.execute(OpenSearch.java:171) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:104) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.cli.Command.mainWithoutErrorHandling(Command.java:138) ~[opensearch-cli-2.5.0.jar:2.5.0]
»       at org.opensearch.cli.Command.main(Command.java:101) ~[opensearch-cli-2.5.0.jar:2.5.0]
»       at org.opensearch.bootstrap.OpenSearch.main(OpenSearch.java:137) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.bootstrap.OpenSearch.main(OpenSearch.java:103) ~[opensearch-2.5.0.jar:2.5.0]
»  Caused by: java.lang.RuntimeException: can not run opensearch as root
»       at org.opensearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:124) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.bootstrap.Bootstrap.setup(Bootstrap.java:191) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.bootstrap.Bootstrap.init(Bootstrap.java:404) ~[opensearch-2.5.0.jar:2.5.0]
»       at org.opensearch.bootstrap.OpenSearch.init(OpenSearch.java:180) ~[opensearch-2.5.0.jar:2.5.0]
»       ... 6 more
»   ↓ last 40 non error or warning messages from /tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/logs/opensearch.stdout.log ↓
» [2023-01-30T20:10:26.670011235Z] [BUILD] Configuring custom cluster specific distro directory: /tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/distro/2.5.0-ARCHIVE
» [2023-01-30T20:10:26.710573952Z] [BUILD] Copying additional config files from distro [/tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/distro/2.5.0-ARCHIVE/config/log4j2.properties, /tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/distro/2.5.0-ARCHIVE/config/jvm.options.d, /tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/distro/2.5.0-ARCHIVE/config/opensearch.yml, /tmp/tmp9niemi8p/geospatial/build/testclusters/integTest-0/distro/2.5.0-ARCHIVE/config/jvm.options]
» [2023-01-30T20:10:26.711812308Z] [BUILD] installing 1 plugins in a single transaction
» [2023-01-30T20:10:28.341404943Z] [BUILD] installed plugins
» [2023-01-30T20:10:28.341674400Z] [BUILD] Creating opensearch keystore with password set to []
» [2023-01-30T20:10:29.386451250Z] [BUILD] Starting OpenSearch process
» [2023-01-30T20:10:31.909907707Z] [BUILD] Stopping node
```

------

Part of #2994.


Discussion:

Resolving patch:
diff --git a/src/system/process.py b/src/system/process.py
--- a/src/system/process.py
+++ b/src/system/process.py
@@ -16,18 +16,21 @@
 class Process:
     def __init__(self) -> None:
         self.process: subprocess.Popen[bytes] = None
+        self.require_sudo: bool = False
         self.stdout: Any = None
         self.stderr: Any = None
         self.__stdout_data__: str = None
         self.__stderr_data__: str = None
 
-    def start(self, command: str, cwd: str) -> None:
+    def start(self, command: str, cwd: str, require_sudo: bool = False) -> None:
         if self.started:
             raise ProcessStartedError(self.pid)
 
         self.stdout = tempfile.NamedTemporaryFile(mode="r+", delete=False)
         self.stderr = tempfile.NamedTemporaryFile(mode="r+", delete=False)
 
+        self.require_sudo = require_sudo
+
         self.process = subprocess.Popen(
             command,
             cwd=cwd,
@@ -47,10 +50,10 @@ def terminate(self) -> int:
             logging.debug(f"Found child process with pid {child.pid}")
             if child.pid != self.process.pid:
                 logging.debug(f"Sending SIGKILL to {child.pid} ")
-                child.kill()
+                child.kill() if self.require_sudo is False else subprocess.check_call(f"sudo kill -9 {child.pid}", shell=True)
         logging.info(f"Sending SIGKILL to PID {self.process.pid}")
 
-        self.process.kill()
+        self.process.kill() if self.require_sudo is False else subprocess.check_call(f"sudo kill -9 {self.process.pid}", shell=True)
 
         logging.info(f"Process killed with exit code {self.process.returncode}")
 


Test patch:
diff --git a/src/test_workflow/integ_test/distribution.py b/src/test_workflow/integ_test/distribution.py
--- a/src/test_workflow/integ_test/distribution.py
+++ b/src/test_workflow/integ_test/distribution.py
@@ -16,6 +16,7 @@ def __init__(self, filename: str, version: str, work_dir: str) -> None:
         self.filename = filename
         self.version = version
         self.work_dir = work_dir
+        self.require_sudo = False
 
     @property
     @abstractmethod
@@ -25,11 +26,18 @@ def install_dir(self) -> str:
         """
         pass
 
+    @property
+    def config_filename(self) -> str:
+        """
+        Return the config filename for the distribution
+        """
+        return f"{self.filename.replace('-', '_')}.yml"
+
     @property
     @abstractmethod
-    def config_dir(self) -> str:
+    def config_path(self) -> str:
         """
-        Return the config directory for the distribution
+        Return the config path for the distribution
         """
         pass
 
diff --git a/src/test_workflow/integ_test/distribution_deb.py b/src/test_workflow/integ_test/distribution_deb.py
--- a/src/test_workflow/integ_test/distribution_deb.py
+++ b/src/test_workflow/integ_test/distribution_deb.py
@@ -15,35 +15,40 @@
 class DistributionDeb(Distribution):
     def __init__(self, filename: str, version: str, work_dir: str) -> None:
         super().__init__(filename, version, work_dir)
+        self.require_sudo = True
 
     @property
     def install_dir(self) -> str:
         return os.path.join(os.sep, "usr", "share", self.filename)
 
     @property
-    def config_dir(self) -> str:
-        return os.path.join(os.sep, "etc", self.filename)
+    def config_path(self) -> str:
+        return os.path.join(os.sep, "etc", self.filename, self.config_filename)
 
     def install(self, bundle_name: str) -> None:
         logging.info(f"Installing {bundle_name} in {self.install_dir}")
         logging.info("deb installation requires sudo, script will exit if current user does not have sudo access")
         deb_install_cmd = " ".join(
             [
+                'sudo',
                 'dpkg',
                 '--purge',
                 self.filename,
                 '&&',
+                'sudo',
                 'dpkg',
                 '--install',
-                bundle_name
+                bundle_name,
+                '&&',
+                f'sudo chmod 0666 {self.config_path}'
             ]
         )
         subprocess.check_call(deb_install_cmd, cwd=self.work_dir, shell=True)
 
     @property
     def start_cmd(self) -> str:
-        return f"systemctl start {self.filename}"
+        return f"sudo systemctl start {self.filename}"
 
     def uninstall(self) -> None:
         logging.info(f"Uninstall {self.filename} package after the test")
-        subprocess.check_call(f"dpkg --purge {self.filename}", shell=True)
+        subprocess.check_call(f"sudo dpkg --purge {self.filename}", shell=True)
diff --git a/src/test_workflow/integ_test/distribution_rpm.py b/src/test_workflow/integ_test/distribution_rpm.py
--- a/src/test_workflow/integ_test/distribution_rpm.py
+++ b/src/test_workflow/integ_test/distribution_rpm.py
@@ -15,37 +15,42 @@
 class DistributionRpm(Distribution):
     def __init__(self, filename: str, version: str, work_dir: str) -> None:
         super().__init__(filename, version, work_dir)
+        self.require_sudo = True
 
     @property
     def install_dir(self) -> str:
         return os.path.join(os.sep, "usr", "share", self.filename)
 
     @property
-    def config_dir(self) -> str:
-        return os.path.join(os.sep, "etc", self.filename)
+    def config_path(self) -> str:
+        return os.path.join(os.sep, "etc", self.filename, self.config_filename)
 
     def install(self, bundle_name: str) -> None:
         logging.info(f"Installing {bundle_name} in {self.install_dir}")
         logging.info("rpm installation requires sudo, script will exit if current user does not have sudo access")
         rpm_install_cmd = " ".join(
             [
+                'sudo',
                 'yum',
                 'remove',
                 '-y',
                 self.filename,
                 '&&',
+                'sudo',
                 'yum',
                 'install',
                 '-y',
-                bundle_name
+                bundle_name,
+                '&&',
+                f'sudo chmod 0666 {self.config_path}'
             ]
         )
         subprocess.check_call(rpm_install_cmd, cwd=self.work_dir, shell=True)
 
     @property
     def start_cmd(self) -> str:
-        return f"systemctl start {self.filename}"
+        return f"sudo systemctl start {self.filename}"
 
     def uninstall(self) -> None:
         logging.info(f"Uninstall {self.filename} package after the test")
-        subprocess.check_call(f"yum remove -y {self.filename}", shell=True)
+        subprocess.check_call(f"sudo yum remove -y {self.filename}", shell=True)
diff --git a/src/test_workflow/integ_test/distribution_tar.py b/src/test_workflow/integ_test/distribution_tar.py
--- a/src/test_workflow/integ_test/distribution_tar.py
+++ b/src/test_workflow/integ_test/distribution_tar.py
@@ -22,8 +22,8 @@ def install_dir(self) -> str:
         return os.path.join(self.work_dir, f"{self.filename}-{self.version}")
 
     @property
-    def config_dir(self) -> str:
-        return os.path.join(self.install_dir, "config")
+    def config_path(self) -> str:
+        return os.path.join(self.install_dir, "config", self.config_filename)
 
     def install(self, bundle_name: str) -> None:
         logging.info(f"Installing {bundle_name} in {self.install_dir}")
diff --git a/src/test_workflow/integ_test/distribution_zip.py b/src/test_workflow/integ_test/distribution_zip.py
--- a/src/test_workflow/integ_test/distribution_zip.py
+++ b/src/test_workflow/integ_test/distribution_zip.py
@@ -22,8 +22,8 @@ def install_dir(self) -> str:
         return os.path.join(self.work_dir, f"{self.filename}-{self.version}")
 
     @property
-    def config_dir(self) -> str:
-        return os.path.join(self.install_dir, "config")
+    def config_path(self) -> str:
+        return os.path.join(self.install_dir, "config", self.config_filename)
 
     def install(self, bundle_name: str) -> None:
         logging.info(f"Installing {bundle_name} in {self.install_dir}")
diff --git a/src/test_workflow/integ_test/service_opensearch.py b/src/test_workflow/integ_test/service_opensearch.py
--- a/src/test_workflow/integ_test/service_opensearch.py
+++ b/src/test_workflow/integ_test/service_opensearch.py
@@ -22,7 +22,7 @@ class ServiceOpenSearch(Service):
     dist: Distribution
     dependency_installer: DependencyInstaller
     install_dir: str
-    opensearch_yml_dir: str
+    opensearch_yml_path: str
     security_plugin_dir: str
 
     def __init__(
@@ -44,7 +44,7 @@ def __init__(
     def start(self) -> None:
         self.dist.install(self.download())
 
-        self.opensearch_yml_dir = os.path.join(self.dist.config_dir, "opensearch.yml")
+        self.opensearch_yml_path = self.dist.config_path
         self.security_plugin_dir = os.path.join(self.install_dir, "plugins", "opensearch-security")
 
         if not self.security_enabled and os.path.isdir(self.security_plugin_dir):
@@ -53,7 +53,7 @@ def start(self) -> None:
         if self.additional_config:
             self.__add_plugin_specific_config(self.additional_config)
 
-        self.process_handler.start(self.dist.start_cmd, self.install_dir)
+        self.process_handler.start(self.dist.start_cmd, self.install_dir, self.dist.require_sudo)
         logging.info(f"Started OpenSearch with parent PID {self.process_handler.pid}")
 
     def uninstall(self) -> None:
@@ -68,7 +68,7 @@ def get_service_response(self) -> Response:
         return requests.get(url, verify=False, auth=("admin", "admin"))
 
     def __add_plugin_specific_config(self, additional_config: dict) -> None:
-        with open(self.opensearch_yml_dir, "a") as yamlfile:
+        with open(self.opensearch_yml_path, "a") as yamlfile:
             yamlfile.write(yaml.dump(additional_config))
 
     def port(self) -> int:
diff --git a/src/test_workflow/integ_test/service_opensearch_dashboards.py b/src/test_workflow/integ_test/service_opensearch_dashboards.py
--- a/src/test_workflow/integ_test/service_opensearch_dashboards.py
+++ b/src/test_workflow/integ_test/service_opensearch_dashboards.py
@@ -23,7 +23,7 @@
 class ServiceOpenSearchDashboards(Service):
     dist: Distribution
     install_dir: str
-    opensearch_dashboards_yml_dir: str
+    opensearch_dashboards_yml_path: str
     executable_dir: str
 
     def __init__(
@@ -42,7 +42,7 @@ def __init__(
     def start(self) -> None:
         self.dist.install(self.download())
 
-        self.opensearch_dashboards_yml_dir = os.path.join(self.dist.config_dir, "opensearch_dashboards.yml")
+        self.opensearch_dashboards_yml_path = self.dist.config_path
         self.executable_dir = os.path.join(self.install_dir, "bin")
 
         if not self.security_enabled:
@@ -53,7 +53,7 @@ def start(self) -> None:
         if self.additional_config:
             self.__add_plugin_specific_config(self.additional_config)
 
-        self.process_handler.start(self.dist.start_cmd, self.executable_dir)
+        self.process_handler.start(self.dist.start_cmd, self.executable_dir, self.dist.require_sudo)
         logging.info(f"Started OpenSearch Dashboards with parent PID {self.process_handler.pid}")
 
     def uninstall(self) -> None:
@@ -70,7 +70,7 @@ def __remove_security(self) -> None:
             plugin_script = "opensearch-dashboards-plugin.bat" if current_platform() == "windows" else "bash opensearch-dashboards-plugin"
             subprocess.check_call(f"{plugin_script} remove --allow-root securityDashboards", cwd=self.executable_dir, shell=True)
 
-        with open(self.opensearch_dashboards_yml_dir, "w") as yamlfile:
+        with open(self.opensearch_dashboards_yml_path, "w") as yamlfile:
             yamlfile.close()
 
     def url(self, path: str = "") -> str:
@@ -82,7 +82,7 @@ def get_service_response(self) -> Response:
         return requests.get(url, verify=False, auth=("admin", "admin") if self.security_enabled else None)
 
     def __add_plugin_specific_config(self, additional_config: dict) -> None:
-        with open(self.opensearch_dashboards_yml_dir, "a") as yamlfile:
+        with open(self.opensearch_dashboards_yml_path, "a") as yamlfile:
             yamlfile.write(yaml.dump(additional_config))
 
     def port(self) -> int:
diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_deb.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_deb.py
--- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_deb.py
+++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_deb.py
@@ -24,12 +24,15 @@ def test_distribution_deb_vars(self) -> None:
         self.assertEqual(self.distribution_deb.filename, 'opensearch')
         self.assertEqual(self.distribution_deb.version, '1.3.0')
         self.assertEqual(self.distribution_deb.work_dir, self.work_dir)
+        self.assertEqual(self.distribution_deb.require_sudo, True)
 
     def test_install_dir(self) -> None:
         self.assertEqual(self.distribution_deb.install_dir, os.path.join(os.sep, "usr", "share", "opensearch"))
+        self.assertEqual(self.distribution_deb_dashboards.install_dir, os.path.join(os.sep, "usr", "share", "opensearch-dashboards"))
 
-    def test_config_dir(self) -> None:
-        self.assertEqual(self.distribution_deb.config_dir, os.path.join(os.sep, "etc", "opensearch"))
+    def test_config_path(self) -> None:
+        self.assertEqual(self.distribution_deb.config_path, os.path.join(os.sep, "etc", "opensearch", "opensearch.yml"))
+        self.assertEqual(self.distribution_deb_dashboards.config_path, os.path.join(os.sep, "etc", "opensearch-dashboards", "opensearch_dashboards.yml"))
 
     @patch("subprocess.check_call")
     def test_install(self, check_call_mock: Mock) -> None:
@@ -37,11 +40,11 @@ def test_install(self, check_call_mock: Mock) -> None:
         args_list = check_call_mock.call_args_list
 
         self.assertEqual(check_call_mock.call_count, 1)
-        self.assertEqual("dpkg --purge opensearch && dpkg --install opensearch.deb", args_list[0][0][0])
+        self.assertEqual(f"sudo dpkg --purge opensearch && sudo dpkg --install opensearch.deb && sudo chmod 0666 {self.distribution_deb.config_path}", args_list[0][0][0])
 
     def test_start_cmd(self) -> None:
-        self.assertEqual(self.distribution_deb.start_cmd, "systemctl start opensearch")
-        self.assertEqual(self.distribution_deb_dashboards.start_cmd, "systemctl start opensearch-dashboards")
+        self.assertEqual(self.distribution_deb.start_cmd, "sudo systemctl start opensearch")
+        self.assertEqual(self.distribution_deb_dashboards.start_cmd, "sudo systemctl start opensearch-dashboards")
 
     @patch("subprocess.check_call")
     def test_uninstall(self, check_call_mock: Mock) -> None:
@@ -49,4 +52,4 @@ def test_uninstall(self, check_call_mock: Mock) -> None:
         args_list = check_call_mock.call_args_list
 
         self.assertEqual(check_call_mock.call_count, 1)
-        self.assertEqual("dpkg --purge opensearch", args_list[0][0][0])
+        self.assertEqual("sudo dpkg --purge opensearch", args_list[0][0][0])
diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_rpm.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_rpm.py
--- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_rpm.py
+++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_rpm.py
@@ -24,12 +24,15 @@ def test_distribution_rpm_vars(self) -> None:
         self.assertEqual(self.distribution_rpm.filename, 'opensearch')
         self.assertEqual(self.distribution_rpm.version, '1.3.0')
         self.assertEqual(self.distribution_rpm.work_dir, self.work_dir)
+        self.assertEqual(self.distribution_rpm.require_sudo, True)
 
     def test_install_dir(self) -> None:
         self.assertEqual(self.distribution_rpm.install_dir, os.path.join(os.sep, "usr", "share", "opensearch"))
+        self.assertEqual(self.distribution_rpm_dashboards.install_dir, os.path.join(os.sep, "usr", "share", "opensearch-dashboards"))
 
-    def test_config_dir(self) -> None:
-        self.assertEqual(self.distribution_rpm.config_dir, os.path.join(os.sep, "etc", "opensearch"))
+    def test_config_path(self) -> None:
+        self.assertEqual(self.distribution_rpm.config_path, os.path.join(os.sep, "etc", "opensearch", "opensearch.yml"))
+        self.assertEqual(self.distribution_rpm_dashboards.config_path, os.path.join(os.sep, "etc", "opensearch-dashboards", "opensearch_dashboards.yml"))
 
     @patch("subprocess.check_call")
     def test_install(self, check_call_mock: Mock) -> None:
@@ -37,11 +40,11 @@ def test_install(self, check_call_mock: Mock) -> None:
         args_list = check_call_mock.call_args_list
 
         self.assertEqual(check_call_mock.call_count, 1)
-        self.assertEqual("yum remove -y opensearch && yum install -y opensearch.rpm", args_list[0][0][0])
+        self.assertEqual(f"sudo yum remove -y opensearch && sudo yum install -y opensearch.rpm && sudo chmod 0666 {self.distribution_rpm.config_path}", args_list[0][0][0])
 
     def test_start_cmd(self) -> None:
-        self.assertEqual(self.distribution_rpm.start_cmd, "systemctl start opensearch")
-        self.assertEqual(self.distribution_rpm_dashboards.start_cmd, "systemctl start opensearch-dashboards")
+        self.assertEqual(self.distribution_rpm.start_cmd, "sudo systemctl start opensearch")
+        self.assertEqual(self.distribution_rpm_dashboards.start_cmd, "sudo systemctl start opensearch-dashboards")
 
     @patch("subprocess.check_call")
     def test_uninstall(self, check_call_mock: Mock) -> None:
@@ -49,4 +52,4 @@ def test_uninstall(self, check_call_mock: Mock) -> None:
         args_list = check_call_mock.call_args_list
 
         self.assertEqual(check_call_mock.call_count, 1)
-        self.assertEqual("yum remove -y opensearch", args_list[0][0][0])
+        self.assertEqual("sudo yum remove -y opensearch", args_list[0][0][0])
diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_tar.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_tar.py
--- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_tar.py
+++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_tar.py
@@ -24,12 +24,15 @@ def test_distribution_tar_vars(self) -> None:
         self.assertEqual(self.distribution_tar.filename, 'opensearch')
         self.assertEqual(self.distribution_tar.version, '1.3.0')
         self.assertEqual(self.distribution_tar.work_dir, self.work_dir)
+        self.assertEqual(self.distribution_tar.require_sudo, False)
 
     def test_install_dir(self) -> None:
         self.assertEqual(self.distribution_tar.install_dir, os.path.join(self.work_dir, "opensearch-1.3.0"))
+        self.assertEqual(self.distribution_tar_dashboards.install_dir, os.path.join(self.work_dir, "opensearch-dashboards-1.3.0"))
 
-    def test_config_dir(self) -> None:
-        self.assertEqual(self.distribution_tar.config_dir, os.path.join(self.work_dir, "opensearch-1.3.0", "config"))
+    def test_config_path(self) -> None:
+        self.assertEqual(self.distribution_tar.config_path, os.path.join(self.work_dir, "opensearch-1.3.0", "config", "opensearch.yml"))
+        self.assertEqual(self.distribution_tar_dashboards.config_path, os.path.join(self.work_dir, "opensearch-dashboards-1.3.0", "config", "opensearch_dashboards.yml"))
 
     def test_install(self) -> None:
         with patch("tarfile.open") as mock_tarfile_open:
diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_zip.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_zip.py
--- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_zip.py
+++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_distribution_zip.py
@@ -18,19 +18,23 @@ def setUp(self) -> None:
 
         self.work_dir = os.path.join(os.path.dirname(__file__), "data")
         self.product = "opensearch"
+        self.product_dashboards = "opensearch-dashboards"
         self.version = "2.4.0"
         self.distribution_zip = DistributionZip(self.product, self.version, self.work_dir)
+        self.distribution_zip_dashboards = DistributionZip(self.product_dashboards, self.version, self.work_dir)
 
     def test_distribution_zip_vars(self) -> None:
         self.assertEqual(self.distribution_zip.filename, self.product)
         self.assertEqual(self.distribution_zip.version, self.version)
         self.assertEqual(self.distribution_zip.work_dir, self.work_dir)
+        self.assertEqual(self.distribution_zip.require_sudo, False)
 
     def test_install_dir(self) -> None:
         self.assertEqual(self.distribution_zip.install_dir, os.path.join(self.work_dir, f"{self.product}-{self.version}"))
 
-    def test_config_dir(self) -> None:
-        self.assertEqual(self.distribution_zip.config_dir, os.path.join(self.work_dir, f"{self.product}-{self.version}", "config"))
+    def test_config_path(self) -> None:
+        self.assertEqual(self.distribution_zip.config_path, os.path.join(self.work_dir, f"{self.product}-{self.version}", "config", "opensearch.yml"))
+        self.assertEqual(self.distribution_zip_dashboards.config_path, os.path.join(self.work_dir, f"{self.product_dashboards}-{self.version}", "config", "opensearch_dashboards.yml"))
 
     def test_install(self) -> None:
         with patch("test_workflow.integ_test.distribution_zip.ZipFile") as mock_zipfile_open:
@@ -71,8 +75,8 @@ def test_distribution_zip_vars(self) -> None:
     def test_install_dir(self) -> None:
         self.assertEqual(self.distribution_zip.install_dir, os.path.join(self.work_dir, f"{self.product}-{self.version}"))
 
-    def test_config_dir(self) -> None:
-        self.assertEqual(self.distribution_zip.config_dir, os.path.join(self.work_dir, f"{self.product}-{self.version}", "config"))
+    def test_config_path(self) -> None:
+        self.assertEqual(self.distribution_zip.config_path, os.path.join(self.work_dir, f"{self.product}-{self.version}", "config", "opensearch_dashboards.yml"))
 
     def test_install(self) -> None:
         with patch("test_workflow.integ_test.distribution_zip.ZipFile") as mock_zipfile_open:
diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch.py
--- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch.py
+++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch.py
@@ -63,7 +63,7 @@ def test_start(self, mock_tarfile_open: Mock, mock_dump: Mock, mock_file: Mock,
         # call test target function
         service.start()
 
-        mock_process.assert_called_once_with("./opensearch-tar-install.sh", os.path.join(self.work_dir, "opensearch-1.1.0"))
+        mock_process.assert_called_once_with("./opensearch-tar-install.sh", os.path.join(self.work_dir, "opensearch-1.1.0"), False)
 
         mock_dump.assert_called_once_with(self.additional_config)
 
diff --git a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch_dashboards.py b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch_dashboards.py
--- a/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch_dashboards.py
+++ b/tests/tests_test_workflow/test_integ_workflow/integ_test/test_service_opensearch_dashboards.py
@@ -72,7 +72,7 @@ def test_start(self, mock_tarfile_open: Mock, mock_dump: Mock, mock_file: Mock,
         )
         mock_file.return_value.write.assert_called_once_with(mock_dump_result)
 
-        mock_process.assert_called_once_with("./opensearch-dashboards", os.path.join(self.work_dir, "opensearch-dashboards-1.1.0", "bin"))
+        mock_process.assert_called_once_with("./opensearch-dashboards", os.path.join(self.work_dir, "opensearch-dashboards-1.1.0", "bin"), False)
         self.assertEqual(mock_pid.call_count, 1)
 
     @patch("os.path.isdir")