Jelajahi Sumber

AMBARI-3792. Unable to connect to: https://server:8441/agent/v1/heartbeat/agent_hostname due to No JSON object could be decoded" when ping_port is not set (Dmytro Sen via dlysnichenko)

Lisnichenko Dmitro 11 tahun lalu
induk
melakukan
015130d441

+ 7 - 3
ambari-agent/src/main/python/ambari_agent/PuppetExecutor.py

@@ -26,7 +26,7 @@ import threading
 from threading import Thread
 from threading import Thread
 
 
 from shell import shellRunner
 from shell import shellRunner
-from manifestGenerator import generateManifest
+import manifestGenerator
 from RepoInstaller import RepoInstaller
 from RepoInstaller import RepoInstaller
 from Grep import Grep
 from Grep import Grep
 import shell
 import shell
@@ -170,8 +170,12 @@ class PuppetExecutor:
     if command.has_key("taskId"):
     if command.has_key("taskId"):
       taskId = command['taskId']
       taskId = command['taskId']
     siteppFileName = os.path.join(self.tmpDir, "site-" + str(taskId) + ".pp")
     siteppFileName = os.path.join(self.tmpDir, "site-" + str(taskId) + ".pp")
-    generateManifest(command, siteppFileName, self.modulesdir, self.config)
-    result = self.run_manifest(command, siteppFileName, tmpoutfile, tmperrfile)
+    errMsg = manifestGenerator.generateManifest(command, siteppFileName,
+                                                self.modulesdir, self.config)
+    if not errMsg:
+      result = self.run_manifest(command, siteppFileName, tmpoutfile, tmperrfile)
+    else:
+      result = {'stdout': '', 'stderr': errMsg, 'exitcode': 1}
     return result
     return result
 
 
   def runPuppetFile(self, puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
   def runPuppetFile(self, puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):

+ 50 - 40
ambari-agent/src/main/python/ambari_agent/manifestGenerator.py

@@ -73,49 +73,59 @@ def generateManifest(parsedJson, fileName, modulesdir, ambariconfig):
   roles = [{'role' : parsedJson['role'],
   roles = [{'role' : parsedJson['role'],
             'cmd' : parsedJson['roleCommand'],
             'cmd' : parsedJson['roleCommand'],
             'roleParams' : roleParams}]
             'roleParams' : roleParams}]
-  #writing manifest
-  manifest = open(fileName, 'w')
-  #Change mode to make site.pp files readable to owner and group only
-  os.chmod(fileName, 0660)
+  errMsg = ''
+  try:
+    #writing manifest
+    manifest = open(fileName, 'w')
+    #Change mode to make site.pp files readable to owner and group only
+    os.chmod(fileName, 0660)
 
 
-  #Check for Ambari Config and make sure you pick the right imports file
-    
-  #writing imports from external static file
-  writeImports(outputFile=manifest, modulesdir=modulesdir, importsList=AmbariConfig.imports)
+    #Check for Ambari Config and make sure you pick the right imports file
 
 
-  #writing hostname
-  writeHostnames(manifest)
+    #writing imports from external static file
+    writeImports(outputFile=manifest, modulesdir=modulesdir, importsList=AmbariConfig.imports)
 
 
-  #writing nodes
-  writeNodes(manifest, clusterHostInfo)
-  
-  #writing params from map
-  writeParams(manifest, params, modulesdir)
-
-  nonGlobalConfigurations = {}
-  flatConfigurations = {}
-
-  if configurations: 
-    for configKey in configurations.iterkeys():
-      if configKey in nonGlobalConfigurationsKeys:
-        nonGlobalConfigurations[configKey] = configurations[configKey]
-      else:
-        flatConfigurations[configKey] = configurations[configKey]
-      
-  #writing config maps
-  if (nonGlobalConfigurations):
-    writeNonGlobalConfigurations(manifest, nonGlobalConfigurations)
-  if (flatConfigurations):
-    writeFlatConfigurations(manifest, flatConfigurations)
-
-  #writing host attributes
-  #writeHostAttributes(manifest, hostAttributes)
-
-  #writing task definitions 
-  writeTasks(manifest, roles, ambariconfig, clusterHostInfo, hostname)
-     
-  manifest.close()
-    
+    #writing hostname
+    writeHostnames(manifest)
+
+    #writing nodes
+    writeNodes(manifest, clusterHostInfo)
+
+    #writing params from map
+    writeParams(manifest, params, modulesdir)
+
+    nonGlobalConfigurations = {}
+    flatConfigurations = {}
+
+    if configurations:
+      for configKey in configurations.iterkeys():
+        if configKey in nonGlobalConfigurationsKeys:
+          nonGlobalConfigurations[configKey] = configurations[configKey]
+        else:
+          flatConfigurations[configKey] = configurations[configKey]
+
+    #writing config maps
+    if (nonGlobalConfigurations):
+      writeNonGlobalConfigurations(manifest, nonGlobalConfigurations)
+    if (flatConfigurations):
+      writeFlatConfigurations(manifest, flatConfigurations)
+
+    #writing host attributes
+    #writeHostAttributes(manifest, hostAttributes)
+
+    #writing task definitions
+    writeTasks(manifest, roles, ambariconfig, clusterHostInfo, hostname)
+
+
+  except TypeError:
+    errMsg = 'Manifest can\'t be generated from the JSON \n' + \
+                    json.dumps(parsedJson, sort_keys=True, indent=4)
+
+    logger.error(errMsg)
+  finally:
+    manifest.close()
+
+  return errMsg
 
 
 def writeHostnames(outputFile):
 def writeHostnames(outputFile):
   fqdn = hostname.hostname()
   fqdn = hostname.hostname()

+ 17 - 1
ambari-agent/src/test/python/TestManifestGenerator.py

@@ -78,6 +78,10 @@ class TestManifestGenerator(TestCase):
 
 
     print file(tmpFileName).read()
     print file(tmpFileName).read()
 
 
+    def raiseTypeError():
+      raise TypeError()
+    writeNodesMock.side_effect = raiseTypeError
+    manifestGenerator.generateManifest(self.parsedJson, tmpFileName, '../../main/puppet/modules', self.config.getConfig())
     pass
     pass
 
 
   def testEscape(self):
   def testEscape(self):
@@ -98,6 +102,18 @@ class TestManifestGenerator(TestCase):
     tmpFile.close()
     tmpFile.close()
     os.remove(tmpFileName)
     os.remove(tmpFileName)
 
 
+  def test_writeNodes_failed(self):
+    tmpFileName = tempfile.mkstemp(dir=self.dir, text=True)[1]
+    tmpFile = file(tmpFileName, 'r+')
+
+    clusterHostInfo = self.parsedJson['clusterHostInfo']
+    clusterHostInfo.update({u'ZOOKEEPER':[None]})
+    clusterHostInfo['zookeeper_hosts'] = ["h1.hortonworks.com", "h2.hortonworks.com"]
+    self.assertRaises(TypeError, manifestGenerator.writeNodes, tmpFile, clusterHostInfo)
+    tmpFile.seek(0)
+    print tmpFile.read()
+    tmpFile.close()
+    os.remove(tmpFileName)
 
 
   def test_writeHostAttributes(self):
   def test_writeHostAttributes(self):
     tmpFileName = tempfile.mkstemp(dir=self.dir, text=True)[1]
     tmpFileName = tempfile.mkstemp(dir=self.dir, text=True)[1]
@@ -123,4 +139,4 @@ class TestManifestGenerator(TestCase):
     tmpFile.seek(0)
     tmpFile.seek(0)
     print tmpFile.read()
     print tmpFile.read()
     tmpFile.close()
     tmpFile.close()
-    os.remove(tmpFileName)
+    os.remove(tmpFileName)

+ 13 - 5
ambari-agent/src/test/python/TestPuppetExecutor.py

@@ -31,6 +31,7 @@ from AmbariConfig import AmbariConfig
 from mock.mock import patch, MagicMock, call
 from mock.mock import patch, MagicMock, call
 from threading import Thread
 from threading import Thread
 from shell import shellRunner
 from shell import shellRunner
+import manifestGenerator
 
 
 class TestPuppetExecutor(TestCase):
 class TestPuppetExecutor(TestCase):
 
 
@@ -55,11 +56,11 @@ class TestPuppetExecutor(TestCase):
     
     
     cmdrun_mock.return_value = {'exitCode': 0, 'output': 'OK', 'error': ''}
     cmdrun_mock.return_value = {'exitCode': 0, 'output': 'OK', 'error': ''}
     self.assertEquals(puppetInstance.isJavaAvailable(command), True)
     self.assertEquals(puppetInstance.isJavaAvailable(command), True)
-    
-    
+
+  @patch.object(manifestGenerator, 'generateManifest')
   @patch.object(PuppetExecutor, 'isJavaAvailable')
   @patch.object(PuppetExecutor, 'isJavaAvailable')
   @patch.object(PuppetExecutor, 'runPuppetFile')
   @patch.object(PuppetExecutor, 'runPuppetFile')
-  def test_run_command(self, runPuppetFileMock, isJavaAvailableMock):
+  def test_run_command(self, runPuppetFileMock, isJavaAvailableMock, generateManifestMock):
     tmpdir = tempfile.gettempdir()
     tmpdir = tempfile.gettempdir()
     puppetInstance = PuppetExecutor("/tmp", "/x", "/y", tmpdir, AmbariConfig().getConfig())
     puppetInstance = PuppetExecutor("/tmp", "/x", "/y", tmpdir, AmbariConfig().getConfig())
     jsonFile = open('../../main/python/ambari_agent/test.json', 'r')
     jsonFile = open('../../main/python/ambari_agent/test.json', 'r')
@@ -69,6 +70,7 @@ class TestPuppetExecutor(TestCase):
     def side_effect1(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
     def side_effect1(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
         result["exitcode"] = 0
         result["exitcode"] = 0
     runPuppetFileMock.side_effect = side_effect1
     runPuppetFileMock.side_effect = side_effect1
+    generateManifestMock.return_value = ''
     puppetInstance.reposInstalled = False
     puppetInstance.reposInstalled = False
     isJavaAvailableMock.return_value = True
     isJavaAvailableMock.return_value = True
     res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
     res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
@@ -83,8 +85,13 @@ class TestPuppetExecutor(TestCase):
     res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
     res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
     self.assertEquals(res["exitcode"], 999)
     self.assertEquals(res["exitcode"], 999)
     self.assertFalse(puppetInstance.reposInstalled)
     self.assertFalse(puppetInstance.reposInstalled)
-    os.unlink(tmpdir + os.sep + 'site-' + str(parsedJson["taskId"]) + '.pp')
-    
+
+    generateManifestMock.return_value = 'error during manifest generation'
+    res = puppetInstance.runCommand(parsedJson, tmpdir + '/out.txt', tmpdir + '/err.txt')
+    self.assertTrue(generateManifestMock.called)
+    self.assertEquals(res["exitcode"], 1)
+    generateManifestMock.return_value = ''
+
     def side_effect2(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
     def side_effect2(puppetFile, result, puppetEnv, tmpoutfile, tmperrfile):
         result["exitcode"] = 0
         result["exitcode"] = 0
     runPuppetFileMock.side_effect = side_effect2
     runPuppetFileMock.side_effect = side_effect2
@@ -105,6 +112,7 @@ class TestPuppetExecutor(TestCase):
     self.assertEquals(res["exitcode"], 1)
     self.assertEquals(res["exitcode"], 1)
     self.assertEquals(res["stderr"], "Cannot access JDK! Make sure java64_home is specified in global config")
     self.assertEquals(res["stderr"], "Cannot access JDK! Make sure java64_home is specified in global config")
 
 
+
   @patch.object(PuppetExecutor, 'isJavaAvailable')
   @patch.object(PuppetExecutor, 'isJavaAvailable')
   @patch.object(RepoInstaller, 'generate_repo_manifests')
   @patch.object(RepoInstaller, 'generate_repo_manifests')
   @patch.object(PuppetExecutor, 'runPuppetFile')
   @patch.object(PuppetExecutor, 'runPuppetFile')

+ 3 - 1
ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java

@@ -60,6 +60,7 @@ public class StageUtils {
       new HashMap<String, String>();
       new HashMap<String, String>();
 
 
   private volatile static Gson gson;
   private volatile static Gson gson;
+  private static final String DEFAULT_PING_PORT = "8670";
 
 
   public static void setGson(Gson gson) {
   public static void setGson(Gson gson) {
     if (gson==null) {
     if (gson==null) {
@@ -233,7 +234,8 @@ public class StageUtils {
     List<String> allHostPingPorts = new ArrayList<String>();
     List<String> allHostPingPorts = new ArrayList<String>();
     for (Host host : allHosts.values()) {
     for (Host host : allHosts.values()) {
       allHostNames.add(host.getHostName());
       allHostNames.add(host.getHostName());
-      allHostPingPorts.add(host.getCurrentPingPort() == null ? null : host.getCurrentPingPort().toString());
+      allHostPingPorts.add(host.getCurrentPingPort() == null ?
+        DEFAULT_PING_PORT : host.getCurrentPingPort().toString());
     }
     }
     info.put("all_hosts", allHostNames);
     info.put("all_hosts", allHostNames);
     info.put("all_ping_ports", allHostPingPorts);
     info.put("all_ping_ports", allHostPingPorts);

+ 8 - 4
ambari-server/src/test/java/org/apache/ambari/server/utils/TestStageUtils.java

@@ -194,10 +194,10 @@ public class TestStageUtils {
     fsm.getHost("h2").setOsType("centos5");
     fsm.getHost("h2").setOsType("centos5");
     fsm.getHost("h3").setOsType("centos5");
     fsm.getHost("h3").setOsType("centos5");
     fsm.getHost("h4").setOsType("centos5");
     fsm.getHost("h4").setOsType("centos5");
-    fsm.getHost("h1").setCurrentPingPort(1024);
-    fsm.getHost("h2").setCurrentPingPort(1024);
-    fsm.getHost("h3").setCurrentPingPort(1024);
-    fsm.getHost("h4").setCurrentPingPort(1024);
+    fsm.getHost("h1").setCurrentPingPort(8670);
+    fsm.getHost("h2").setCurrentPingPort(null);
+    fsm.getHost("h3").setCurrentPingPort(null);
+    fsm.getHost("h4").setCurrentPingPort(8670);
     fsm.getHost("h1").persist();
     fsm.getHost("h1").persist();
     fsm.getHost("h2").persist();
     fsm.getHost("h2").persist();
     fsm.getHost("h3").persist();
     fsm.getHost("h3").persist();
@@ -220,6 +220,10 @@ public class TestStageUtils {
     assertEquals(4, info.get("all_hosts").size());
     assertEquals(4, info.get("all_hosts").size());
     assertEquals(4, info.get("all_ping_ports").size());
     assertEquals(4, info.get("all_ping_ports").size());
     assertEquals("h1", info.get("hbase_master_hosts").get(0));
     assertEquals("h1", info.get("hbase_master_hosts").get(0));
+    assertEquals("8670", info.get("all_ping_ports").get(0));
+    assertEquals("8670", info.get("all_ping_ports").get(1));
+    assertEquals("8670", info.get("all_ping_ports").get(2));
+    assertEquals("8670", info.get("all_ping_ports").get(3));
 
 
     assertFalse(info.get("ambari_db_rca_url").get(0).contains(Configuration.HOSTNAME_MACRO));
     assertFalse(info.get("ambari_db_rca_url").get(0).contains(Configuration.HOSTNAME_MACRO));
     String address = InetAddress.getLocalHost().getCanonicalHostName();
     String address = InetAddress.getLocalHost().getCanonicalHostName();