Repository: Azure/WALinuxAgent
Pull request #1420 (2018-12-11 16:43:03)

Added --debug flag to agent
<!-- DO NOT DELETE THIS TEMPLATE -->

Added --debug flag to bypass the check for orphan processes; this makes debugging the agent a little easier.

<!--
Please add an informative description that covers that changes made by the pull request. 
This checklist is used to make sure that common issues in a pull request are addressed.
This will expedite the process of getting your pull request merged and avoid extra work on your part to fix issues discovered during the review process.
-->

---

### PR information
- [ ] The title of the PR is clear and informative.
- [ ] There are a small number of commits, each of which has an informative message. This means that previously merged commits do not appear in the history of the PR. For information on cleaning up the commits in your pull request, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md).
- [ ] Except for special cases involving multiple contributors, the PR is started from a fork of the main repository, not a branch.
- [ ] If applicable, the PR references the bug/issue that it fixes in the description.
- [ ] New Unit tests were added for the changes made and Travis.CI is passing.

### Quality of Code and Contribution Guidelines
- [ ] I have read the [contribution guidelines](https://github.com/Azure/WALinuxAgent/blob/master/.github/CONTRIBUTING.md).


Patch:
diff --git a/__main__.py b/__main__.py
new file mode 100644
index 00000000..087b4080
--- /dev/null
+++ b/__main__.py
@@ -0,0 +1,20 @@
+# Copyright 2018 Microsoft Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Requires Python 2.6+ and Openssl 1.0+
+#
+
+import azurelinuxagent.agent as agent
+
+agent.main()
diff --git a/azurelinuxagent/agent.py b/azurelinuxagent/agent.py
index b38724bc..6e5c92d1 100644
--- a/azurelinuxagent/agent.py
+++ b/azurelinuxagent/agent.py
@@ -127,14 +127,14 @@ class Agent(object):
         print("Start {0} service".format(AGENT_NAME))
         self.osutil.start_agent_service()
 
-    def run_exthandlers(self):
+    def run_exthandlers(self, debug=False):
         """
         Run the update and extension handler
         """
         logger.set_prefix("ExtHandler")
         from azurelinuxagent.ga.update import get_update_handler
         update_handler = get_update_handler()
-        update_handler.run()
+        update_handler.run(debug)
 
     def show_configuration(self):
         configuration = conf.get_configuration()
@@ -148,7 +148,7 @@ def main(args=[]):
     """
     if len(args) <= 0:
         args = sys.argv[1:]
-    command, force, verbose, conf_file_path = parse_args(args)
+    command, force, verbose, debug, conf_file_path = parse_args(args)
     if command == "version":
         version()
     elif command == "help":
@@ -169,7 +169,7 @@ def main(args=[]):
             elif command == "daemon":
                 agent.daemon()
             elif command == "run-exthandlers":
-                agent.run_exthandlers()
+                agent.run_exthandlers(debug)
             elif command == "show-configuration":
                 agent.show_configuration()
         except Exception:
@@ -184,6 +184,7 @@ def parse_args(sys_args):
     cmd = "help"
     force = False
     verbose = False
+    debug = False
     conf_file_path = None
     for a in sys_args:
         m = re.match("^(?:[-/]*)configuration-path:([\w/\.\-_]+)", a)
@@ -211,6 +212,8 @@ def parse_args(sys_args):
             cmd = "version"
         elif re.match("^([-/]*)verbose", a):
             verbose = True
+        elif re.match("^([-/]*)debug", a):
+            debug = True
         elif re.match("^([-/]*)force", a):
             force = True
         elif re.match("^([-/]*)show-configuration", a):
@@ -220,7 +223,9 @@ def parse_args(sys_args):
         else:
             cmd = "help"
             break
-    return cmd, force, verbose, conf_file_path
+
+    return cmd, force, verbose, debug, conf_file_path
+
 
 def version():
     """
diff --git a/azurelinuxagent/ga/update.py b/azurelinuxagent/ga/update.py
index d3c39c17..bb66614c 100644
--- a/azurelinuxagent/ga/update.py
+++ b/azurelinuxagent/ga/update.py
@@ -245,7 +245,7 @@ class UpdateHandler(object):
         self.child_process = None
         return
 
-    def run(self):
+    def run(self, debug=False):
         """
         This is the main loop which watches for agent and extension updates.
         """
@@ -280,7 +280,7 @@ class UpdateHandler(object):
                 else GOAL_STATE_INTERVAL_DISABLED
 
             while self.running:
-                if self._is_orphaned:
+                if not debug and self._is_orphaned:
                     logger.info("Agent {0} is an orphan -- exiting",
                                 CURRENT_AGENT)
                     break
diff --git a/setup.py b/setup.py
index c24180d2..301df01d 100755
--- a/setup.py
+++ b/setup.py
@@ -221,6 +221,11 @@ requires = []
 if float(sys.version[:3]) >= 3.7:
     requires = ['distro']
 
+modules = []
+
+if "bdist_egg" in sys.argv:
+    modules.append("__main__")
+
 setuptools.setup(
     name=AGENT_NAME,
     version=AGENT_VERSION,
@@ -231,6 +236,7 @@ setuptools.setup(
     url='https://github.com/Azure/WALinuxAgent',
     license='Apache License Version 2.0',
     packages=find_packages(exclude=["tests*"]),
+    py_modules=modules,
     install_requires=requires,
     cmdclass={
         'install': install


Test patch:
diff --git a/tests/test_agent.py b/tests/test_agent.py
index c6135529..7d8eee2d 100644
--- a/tests/test_agent.py
+++ b/tests/test_agent.py
@@ -75,13 +75,13 @@ class TestAgent(AgentTestCase):
 
     def test_accepts_configuration_path(self):
         conf_path = os.path.join(data_dir, "test_waagent.conf")
-        c, f, v, cfp = parse_args(["-configuration-path:" + conf_path])
+        c, f, v, d, cfp = parse_args(["-configuration-path:" + conf_path])
         self.assertEqual(cfp, conf_path)
 
     @patch("os.path.exists", return_value=True)
     def test_checks_configuration_path(self, mock_exists):
         conf_path = "/foo/bar-baz/something.conf"
-        c, f, v, cfp = parse_args(["-configuration-path:"+conf_path])
+        c, f, v, d, cfp = parse_args(["-configuration-path:"+conf_path])
         self.assertEqual(cfp, conf_path)
         self.assertEqual(mock_exists.call_count, 1)
 
@@ -90,13 +90,13 @@ class TestAgent(AgentTestCase):
     @patch("sys.exit", side_effect=Exception)
     def test_rejects_missing_configuration_path(self, mock_exit, mock_exists, mock_stderr):
         try:
-            c, f, v, cfp = parse_args(["-configuration-path:/foo/bar.conf"])
+            c, f, v, d, cfp = parse_args(["-configuration-path:/foo/bar.conf"])
             self.assertTrue(False)
         except Exception:
             self.assertEqual(mock_exit.call_count, 1)
 
     def test_configuration_path_defaults_to_none(self):
-        c, f, v, cfp = parse_args([])
+        c, f, v, d, cfp = parse_args([])
         self.assertEqual(cfp, None)
 
     def test_agent_accepts_configuration_path(self):