Browse Source

AMBARI-1059. Refactor cluster management. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418938 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 years ago
parent
commit
33ec01f170
67 changed files with 1989 additions and 1175 deletions
  1. 728 8
      ambari-web/app/assets/data/apps/jobs.json
  2. 9 9
      ambari-web/app/assets/data/apps/runs.json
  3. 2 2
      ambari-web/app/assets/data/clusters/info.json
  4. 4 4
      ambari-web/app/assets/data/users/users.json
  5. 89 63
      ambari-web/app/controllers/global/cluster_controller.js
  6. 24 45
      ambari-web/app/controllers/installer.js
  7. 1 1
      ambari-web/app/controllers/main.js
  8. 41 6
      ambari-web/app/controllers/main/admin/user.js
  9. 0 0
      ambari-web/app/controllers/main/apps/runs_controller.js
  10. 1 3
      ambari-web/app/controllers/main/dashboard.js
  11. 19 33
      ambari-web/app/controllers/main/host/add_controller.js
  12. 70 181
      ambari-web/app/controllers/main/service/add_controller.js
  13. 2 0
      ambari-web/app/controllers/wizard/step5_controller.js
  14. 17 21
      ambari-web/app/controllers/wizard/step6_controller.js
  15. 1 2
      ambari-web/app/controllers/wizard/step7_controller.js
  16. 35 14
      ambari-web/app/controllers/wizard/step8_controller.js
  17. 13 17
      ambari-web/app/controllers/wizard/step9_controller.js
  18. 13 0
      ambari-web/app/data/config_mapping.js
  19. 3 3
      ambari-web/app/mappers/hosts_mapper.js
  20. 2 2
      ambari-web/app/mappers/runs_mapper.js
  21. 1 1
      ambari-web/app/mappers/server_data_mapper.js
  22. 42 35
      ambari-web/app/mappers/services_mapper.js
  23. 2 2
      ambari-web/app/mappers/users_mapper.js
  24. 301 293
      ambari-web/app/messages.js
  25. 78 44
      ambari-web/app/models/form.js
  26. 8 2
      ambari-web/app/models/host.js
  27. 15 2
      ambari-web/app/models/run.js
  28. 2 1
      ambari-web/app/models/service/mapreduce.js
  29. 47 40
      ambari-web/app/models/user.js
  30. 16 14
      ambari-web/app/router.js
  31. 0 1
      ambari-web/app/routes/add_host_routes.js
  32. 9 6
      ambari-web/app/routes/add_service_routes.js
  33. 2 3
      ambari-web/app/routes/installer.js
  34. 1 0
      ambari-web/app/routes/main.js
  35. 25 4
      ambari-web/app/styles/application.less
  36. 43 3
      ambari-web/app/styles/apps.less
  37. 4 3
      ambari-web/app/templates/main/admin/user.hbs
  38. 2 0
      ambari-web/app/templates/main/admin/user/edit.hbs
  39. 1 0
      ambari-web/app/templates/main/admin/user/row.hbs
  40. 10 10
      ambari-web/app/templates/main/apps.hbs
  41. 1 1
      ambari-web/app/templates/main/apps/list_row.hbs
  42. 3 6
      ambari-web/app/templates/main/dashboard.hbs
  43. 1 1
      ambari-web/app/templates/main/dashboard/service/hbase.hbs
  44. 1 1
      ambari-web/app/templates/main/dashboard/service/hdfs.hbs
  45. 3 2
      ambari-web/app/templates/main/dashboard/service/mapreduce.hbs
  46. 1 1
      ambari-web/app/templates/main/host.hbs
  47. 15 7
      ambari-web/app/templates/main/host/summary.hbs
  48. 3 3
      ambari-web/app/templates/main/service/menu_item.hbs
  49. 1 0
      ambari-web/app/templates/wizard/step5.hbs
  50. 1 1
      ambari-web/app/templates/wizard/step6.hbs
  51. 1 2
      ambari-web/app/utils/data_table.js
  52. 1 1
      ambari-web/app/utils/date.js
  53. 63 196
      ambari-web/app/utils/db.js
  54. 2 2
      ambari-web/app/views/main/admin/menu.js
  55. 7 3
      ambari-web/app/views/main/admin/user/edit.js
  56. 8 0
      ambari-web/app/views/main/apps/item/dag_view.js
  57. 99 16
      ambari-web/app/views/main/apps_view.js
  58. 38 1
      ambari-web/app/views/main/dashboard.js
  59. 2 16
      ambari-web/app/views/main/dashboard/service.js
  60. 7 11
      ambari-web/app/views/main/dashboard/service/hdfs.js
  61. 16 12
      ambari-web/app/views/main/dashboard/service/mapreduce.js
  62. 6 0
      ambari-web/app/views/main/host/summary.js
  63. 8 4
      ambari-web/app/views/main/service/menu.js
  64. 1 0
      ambari-web/app/views/wizard/step5_view.js
  65. 14 8
      ambari-web/app/views/wizard/step9_view.js
  66. 1 2
      ambari-web/package.json
  67. 2 0
      ambari-web/pom.xml

+ 728 - 8
ambari-web/app/assets/data/apps/jobs.json

@@ -12,7 +12,7 @@
       "submitTime": 1352095518432,
       "userName": "root",
       "workflowEntityName": "89",
-      "workflowId": "pig_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6"
+      "workflowId": "mr_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0037/job.xml",
@@ -27,7 +27,7 @@
       "submitTime": 1352095842817,
       "userName": "root",
       "workflowEntityName": "97",
-      "workflowId": "pig_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6"
+      "workflowId": "mr_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0038/job.xml",
@@ -42,7 +42,7 @@
       "submitTime": 1352096111311,
       "userName": "root",
       "workflowEntityName": "103",
-      "workflowId": "pig_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6"
+      "workflowId": "mr_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0019/job.xml",
@@ -57,7 +57,7 @@
       "submitTime": 1352016495104,
       "userName": "root",
       "workflowEntityName": "86",
-      "workflowId": "pig_7c779523-6bca-416e-89b3-b01b73a60174"
+      "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0016/job.xml",
@@ -72,7 +72,7 @@
       "submitTime": 1352015770967,
       "userName": "root",
       "workflowEntityName": "72",
-      "workflowId": "pig_7c779523-6bca-416e-89b3-b01b73a60174"
+      "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0017/job.xml",
@@ -87,7 +87,7 @@
       "submitTime": 1352016076858,
       "userName": "root",
       "workflowEntityName": "80",
-      "workflowId": "pig_7c779523-6bca-416e-89b3-b01b73a60174"
+      "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0020/job.xml",
@@ -102,7 +102,7 @@
       "submitTime": 1352016582226,
       "userName": "root",
       "workflowEntityName": "103",
-      "workflowId": "pig_7c779523-6bca-416e-89b3-b01b73a60174"
+      "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0018/job.xml",
@@ -117,7 +117,7 @@
       "submitTime": 1352016352319,
       "userName": "root",
       "workflowEntityName": "83",
-      "workflowId": "pig_7c779523-6bca-416e-89b3-b01b73a60174"
+      "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174"
     },
     {
       "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0001/job.xml",
@@ -193,6 +193,726 @@
       "userName": "root",
       "workflowEntityName": "86",
       "workflowId": "pig_5750f4cf-f0d2-4e3d-a7ce-90912b309c12"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0004/job.xml",
+      "elapsedTime": 69662,
+      "inputBytes": 650899,
+      "jobId": "job_201211031645_0004",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351987177998,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0001/job.xml",
+      "elapsedTime": 290358,
+      "inputBytes": 10409082,
+      "jobId": "job_201211031645_0001",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351986424338,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0002/job.xml",
+      "elapsedTime": 284645,
+      "inputBytes": 57690218,
+      "jobId": "job_201211031645_0002",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351986732629,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0005/job.xml",
+      "elapsedTime": 78285,
+      "inputBytes": 650899,
+      "jobId": "job_201211031645_0005",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351987266512,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0003/job.xml",
+      "elapsedTime": 125236,
+      "inputBytes": 27260386,
+      "jobId": "job_201211031645_0003",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351987036961,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0042/job.xml",
+      "elapsedTime": 297229,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0042",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 59144990,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352096970440,
+      "userName": "root",
+      "workflowEntityName": "89",
+      "workflowId": "hive_a5b9c06f-96d2-4ea8-80e0-3c063ae831d4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0043/job.xml",
+      "elapsedTime": 261896,
+      "inputBytes": 59145376,
+      "jobId": "job_201211040003_0043",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352097283746,
+      "userName": "root",
+      "workflowEntityName": "97",
+      "workflowId": "hive_a5b9c06f-96d2-4ea8-80e0-3c063ae831d4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0044/job.xml",
+      "elapsedTime": 98157,
+      "inputBytes": 54520772,
+      "jobId": "job_201211040003_0044",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 2,
+      "outputBytes": 67032,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352097559896,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "hive_a5b9c06f-96d2-4ea8-80e0-3c063ae831d4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0013/job.xml",
+      "elapsedTime": 127841,
+      "inputBytes": 27260385,
+      "jobId": "job_201211040003_0013",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352015380624,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "pig_90ac94ff-20c4-4637-8b1c-51379cfe10df"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0011/job.xml",
+      "elapsedTime": 288027,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0011",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352014799808,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "pig_90ac94ff-20c4-4637-8b1c-51379cfe10df"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0014/job.xml",
+      "elapsedTime": 71726,
+      "inputBytes": 650898,
+      "jobId": "job_201211040003_0014",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352015527755,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "pig_90ac94ff-20c4-4637-8b1c-51379cfe10df"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0012/job.xml",
+      "elapsedTime": 258791,
+      "inputBytes": 57690216,
+      "jobId": "job_201211040003_0012",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352015103545,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "pig_90ac94ff-20c4-4637-8b1c-51379cfe10df"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0015/job.xml",
+      "elapsedTime": 85496,
+      "inputBytes": 650898,
+      "jobId": "job_201211040003_0015",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352015619635,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "pig_90ac94ff-20c4-4637-8b1c-51379cfe10df"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0007/job.xml",
+      "elapsedTime": 258086,
+      "inputBytes": 59145375,
+      "jobId": "job_201211031645_0007",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351988355833,
+      "userName": "root",
+      "workflowEntityName": "97",
+      "workflowId": "hive_c832f923-9bd4-421f-9a51-8f45991d91de"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0008/job.xml",
+      "elapsedTime": 100544,
+      "inputBytes": 54520768,
+      "jobId": "job_201211031645_0008",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 2,
+      "outputBytes": 67032,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351988633975,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "hive_c832f923-9bd4-421f-9a51-8f45991d91de"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211031645_0006/job.xml",
+      "elapsedTime": 288318,
+      "inputBytes": 10409082,
+      "jobId": "job_201211031645_0006",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 59144990,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1351988051564,
+      "userName": "root",
+      "workflowEntityName": "89",
+      "workflowId": "hive_c832f923-9bd4-421f-9a51-8f45991d91de"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0031/job.xml",
+      "elapsedTime": 283919,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0031",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352048063698,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0032/job.xml",
+      "elapsedTime": 258747,
+      "inputBytes": 57690215,
+      "jobId": "job_201211040003_0032",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352048366586,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0034/job.xml",
+      "elapsedTime": 69660,
+      "inputBytes": 650896,
+      "jobId": "job_201211040003_0034",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352048785330,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0033/job.xml",
+      "elapsedTime": 126054,
+      "inputBytes": 27260383,
+      "jobId": "job_201211040003_0033",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352048644829,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0035/job.xml",
+      "elapsedTime": 34344228,
+      "inputBytes": 650896,
+      "jobId": "job_201211040003_0035",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352048870389,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0030/job.xml",
+      "elapsedTime": 85287,
+      "inputBytes": 650899,
+      "jobId": "job_201211040003_0030",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352047891916,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "pig_b4365f79-18da-4db6-bbfd-e8a850d6c6e8"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0026/job.xml",
+      "elapsedTime": 278027,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0026",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352047088454,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "pig_b4365f79-18da-4db6-bbfd-e8a850d6c6e8"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0029/job.xml",
+      "elapsedTime": 70231,
+      "inputBytes": 650899,
+      "jobId": "job_201211040003_0029",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352047805764,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "pig_b4365f79-18da-4db6-bbfd-e8a850d6c6e8"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0028/job.xml",
+      "elapsedTime": 128030,
+      "inputBytes": 27260385,
+      "jobId": "job_201211040003_0028",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352047658396,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "pig_b4365f79-18da-4db6-bbfd-e8a850d6c6e8"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0027/job.xml",
+      "elapsedTime": 254520,
+      "inputBytes": 57690215,
+      "jobId": "job_201211040003_0027",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352047385662,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "pig_b4365f79-18da-4db6-bbfd-e8a850d6c6e8"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0008/job.xml",
+      "elapsedTime": 127541,
+      "inputBytes": 27260385,
+      "jobId": "job_201211040003_0008",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352014420900,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0007/job.xml",
+      "elapsedTime": 259085,
+      "inputBytes": 57690217,
+      "jobId": "job_201211040003_0007",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352014141981,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0006/job.xml",
+      "elapsedTime": 288241,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0006",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352013831863,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0009/job.xml",
+      "elapsedTime": 71166,
+      "inputBytes": 650898,
+      "jobId": "job_201211040003_0009",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352014563951,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0010/job.xml",
+      "elapsedTime": 83733,
+      "inputBytes": 650898,
+      "jobId": "job_201211040003_0010",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352014650745,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0024/job.xml",
+      "elapsedTime": 70488,
+      "inputBytes": 650897,
+      "jobId": "job_201211040003_0024",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352017445920,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "pig_a6a6fb32-b3fd-4427-ab54-449d0895fbb2"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0022/job.xml",
+      "elapsedTime": 259499,
+      "inputBytes": 57690215,
+      "jobId": "job_201211040003_0022",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352017024139,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "pig_a6a6fb32-b3fd-4427-ab54-449d0895fbb2"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0025/job.xml",
+      "elapsedTime": 81683,
+      "inputBytes": 650897,
+      "jobId": "job_201211040003_0025",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352017532797,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "pig_a6a6fb32-b3fd-4427-ab54-449d0895fbb2"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0023/job.xml",
+      "elapsedTime": 124856,
+      "inputBytes": 27260385,
+      "jobId": "job_201211040003_0023",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352017303539,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "pig_a6a6fb32-b3fd-4427-ab54-449d0895fbb2"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0021/job.xml",
+      "elapsedTime": 275269,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0021",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352016729699,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "pig_a6a6fb32-b3fd-4427-ab54-449d0895fbb2"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0039/job.xml",
+      "elapsedTime": 287725,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0039",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 59144990,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352096252185,
+      "userName": "root",
+      "workflowEntityName": "89",
+      "workflowId": "pig_f69499b1-a504-433e-8904-0760deb5a183"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0040/job.xml",
+      "elapsedTime": 251452,
+      "inputBytes": 59145377,
+      "jobId": "job_201211040003_0040",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352096557046,
+      "userName": "root",
+      "workflowEntityName": "97",
+      "workflowId": "pig_f69499b1-a504-433e-8904-0760deb5a183"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0041/job.xml",
+      "elapsedTime": 101437,
+      "inputBytes": 54520770,
+      "jobId": "job_201211040003_0041",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 2,
+      "outputBytes": 67032,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352096825063,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "pig_f69499b1-a504-433e-8904-0760deb5a183"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211042325_0002/job.xml",
+      "elapsedTime": 265358,
+      "inputBytes": 57690216,
+      "jobId": "job_201211042325_0002",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352100793460,
+      "userName": "root",
+      "workflowEntityName": "80",
+      "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211042325_0005/job.xml",
+      "elapsedTime": 86065,
+      "inputBytes": 650899,
+      "jobId": "job_201211042325_0005",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 659755,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352101324336,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211042325_0004/job.xml",
+      "elapsedTime": 72907,
+      "inputBytes": 650899,
+      "jobId": "job_201211042325_0004",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 64,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352101233608,
+      "userName": "root",
+      "workflowEntityName": "86",
+      "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211042325_0001/job.xml",
+      "elapsedTime": 288955,
+      "inputBytes": 10409082,
+      "jobId": "job_201211042325_0001",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 57689830,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352100483608,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211042325_0003/job.xml",
+      "elapsedTime": 132235,
+      "inputBytes": 27260387,
+      "jobId": "job_201211042325_0003",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 650512,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352101079872,
+      "userName": "root",
+      "workflowEntityName": "83",
+      "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211042325_0006/job.xml",
+      "elapsedTime": 0,
+      "inputBytes": 0,
+      "jobId": "job_201211042325_0006",
+      "jobName": "PigLatin:script1-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 0,
+      "reduces": 1,
+      "status": "RUNNING",
+      "submitTime": 1352194719224,
+      "userName": "root",
+      "workflowEntityName": "72",
+      "workflowId": "pig_31b2111b-cc2e-4024-a8db-d181855a463f"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0047/job.xml",
+      "elapsedTime": 97995,
+      "inputBytes": 54520768,
+      "jobId": "job_201211040003_0047",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 2,
+      "outputBytes": 67032,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352098273428,
+      "userName": "root",
+      "workflowEntityName": "103",
+      "workflowId": "hive_097d0698-3620-4232-9c79-4deccbf6c98a"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0045/job.xml",
+      "elapsedTime": 283758,
+      "inputBytes": 10409082,
+      "jobId": "job_201211040003_0045",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 59144990,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352097700564,
+      "userName": "root",
+      "workflowEntityName": "89",
+      "workflowId": "hive_097d0698-3620-4232-9c79-4deccbf6c98a"
+    },
+    {
+      "confPath": "hdfs://localhost:8020/tmp/hadoop-root/mapred/staging/root/.staging/job_201211040003_0046/job.xml",
+      "elapsedTime": 247809,
+      "inputBytes": 59145375,
+      "jobId": "job_201211040003_0046",
+      "jobName": "PigLatin:script2-hadoop.pig",
+      "maps": 1,
+      "outputBytes": 27259999,
+      "reduces": 1,
+      "status": "SUCCESS",
+      "submitTime": 1352098005744,
+      "userName": "root",
+      "workflowEntityName": "97",
+      "workflowId": "hive_097d0698-3620-4232-9c79-4deccbf6c98a"
     }
   ]
 }

+ 9 - 9
ambari-web/app/assets/data/apps/runs.json

@@ -19,7 +19,7 @@
         ]
       }
     },
-    "workflowId": "pig_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6",
+    "workflowId": "mr_b6d5cc44-ac51-4ecd-92c7-2e477c2fbed6",
     "workflowName": "script2-hadoop.pig"
   },
   {
@@ -50,7 +50,7 @@
         ]
       }
     },
-    "workflowId": "pig_7c779523-6bca-416e-89b3-b01b73a60174",
+    "workflowId": "hive_7c779523-6bca-416e-89b3-b01b73a60174",
     "workflowName": "script1-hadoop.pig"
   },
   {
@@ -112,7 +112,7 @@
         ]
       }
     },
-    "workflowId": "pig_25547729-88f9-4287-a45a-64901a82f22b",
+    "workflowId": "mr_25547729-88f9-4287-a45a-64901a82f22b",
     "workflowName": "script1-hadoop.pig"
   },
   {
@@ -135,7 +135,7 @@
         ]
       }
     },
-    "workflowId": "pig_a5b9c06f-96d2-4ea8-80e0-3c063ae831d4",
+    "workflowId": "hive_a5b9c06f-96d2-4ea8-80e0-3c063ae831d4",
     "workflowName": "script2-hadoop.pig"
   },
   {
@@ -189,7 +189,7 @@
         ]
       }
     },
-    "workflowId": "pig_c832f923-9bd4-421f-9a51-8f45991d91de",
+    "workflowId": "hive_c832f923-9bd4-421f-9a51-8f45991d91de",
     "workflowName": "script2-hadoop.pig"
   },
   {
@@ -220,7 +220,7 @@
         ]
       }
     },
-    "workflowId": "pig_a0aade31-47f8-475b-b887-60a79bcea5c4",
+    "workflowId": "mr_a0aade31-47f8-475b-b887-60a79bcea5c4",
     "workflowName": "script1-hadoop.pig"
   },
   {
@@ -282,7 +282,7 @@
         ]
       }
     },
-    "workflowId": "pig_b6bf29a4-324f-4435-8ed3-bee10622ea48",
+    "workflowId": "hive_b6bf29a4-324f-4435-8ed3-bee10622ea48",
     "workflowName": "script1-hadoop.pig"
   },
   {
@@ -367,7 +367,7 @@
         ]
       }
     },
-    "workflowId": "pig_73e04732-ea7f-43b8-9a2f-0f5a30e665da",
+    "workflowId": "mr_73e04732-ea7f-43b8-9a2f-0f5a30e665da",
     "workflowName": "script1-hadoop.pig"
   },
   {
@@ -421,7 +421,7 @@
         ]
       }
     },
-    "workflowId": "pig_097d0698-3620-4232-9c79-4deccbf6c98a",
+    "workflowId": "hive_097d0698-3620-4232-9c79-4deccbf6c98a",
     "workflowName": "script2-hadoop.pig"
   }
 ]}

+ 2 - 2
ambari-web/app/assets/data/clusters/info.json

@@ -1,8 +1,8 @@
 {
-  "href" : "http://ec2-107-21-153-79.compute-1.amazonaws.com:9998/clusters",
+  "href" : "http://ambari:9998/clusters",
   "items" : [
     {
-      "href" : "http://ec2-107-21-153-79.compute-1.amazonaws.com:9998/clusters/mycluster",
+      "href" : "http://ambari:9998/clusters/mycluster",
       "Clusters" : {
         "cluster_name" : "mycluster"
       }

+ 4 - 4
ambari-web/app/assets/data/users/users.json

@@ -4,22 +4,22 @@
     {
       "href" : "http://ambari:8080/api/users/admin",
       "Users" :
-      { "user_name" : "admin", "roles" : "admin,user" }
+      { "user_name" : "admin", "roles" : "admin,user",  "type" : "local" }
     },
     {
       "href" : "http://ambari:8080/api/users/user",
       "Users" :
-      { "user_name" : "user", "roles" : "user" }
+      { "user_name" : "user", "roles" : "user", "type" : "local" }
     },
     {
       "href" : "http://ambari:8080/api/users/john",
       "Users" :
-      { "user_name" : "john", "roles" : "admin,user" }
+      { "user_name" : "john", "roles" : "admin,user", "type" : "LDAP" }
     },
     {
       "href" : "http://ambari:8080/api/users/mike",
       "Users" :
-      { "user_name" : "mike", "roles" : "user" }
+      { "user_name" : "mike", "roles" : "user", "type" : "LDAP" }
     }
   ]
 }

+ 89 - 63
ambari-web/app/controllers/global/cluster_controller.js

@@ -35,7 +35,7 @@ App.ClusterController = Em.Controller.extend({
   },
   dataLoadList: Em.Object.create({
     'hosts': false,
-    //'runs': false,
+    'runs': false,
     'services': false,
     'cluster' : false,
     'racks' : false,
@@ -45,10 +45,14 @@ App.ClusterController = Em.Controller.extend({
   /**
    * load cluster name
    */
-  loadClusterName: function(){
+  loadClusterName: function(reload){
+    if(this.get('clusterName') && !reload){
+      return;
+    }
     var self = this;
     var url = (App.testMode) ? '/data/clusters/info.json' : '/api/clusters';
     $.ajax({
+      async: false,
       type: "GET",
       url: url,
       dataType: 'json',
@@ -57,10 +61,8 @@ App.ClusterController = Em.Controller.extend({
         self.set('cluster', data.items[0]);
       },
       error: function (request, ajaxOptions, error) {
-        //do something
         console.log('failed on loading cluster name');
-        //hack skip loading when data ain't received
-        if(!App.testMode) self.set('isLoaded', true);
+        self.set('isLoaded', true);
       },
       statusCode: require('data/statusCodes')
     });
@@ -114,12 +116,12 @@ App.ClusterController = Em.Controller.extend({
    * Sorted list of alerts.
    * Changes whenever alerts are loaded.
    */
-  alerts: function(){
+  alerts: function () {
     var alerts = App.Alert.find();
     var alertsArray = alerts.toArray();
-    var sortedArray = alertsArray.sort(function(left, right){
+    var sortedArray = alertsArray.sort(function (left, right) {
       var statusDiff = right.get('status') - left.get('status');
-      if(statusDiff==0){ // same error severity - sort by time
+      if (statusDiff == 0) { // same error severity - sort by time
         var rightTime = right.get('date');
         var leftTime = left.get('time');
         rightTime = rightTime ? rightTime.getTime() : 0;
@@ -145,21 +147,21 @@ App.ClusterController = Em.Controller.extend({
       }
       var dataUrl;
       var ajaxOptions = {
-          dataType: "jsonp",
-          jsonp: "jsonp",
-          context: this,
-          complete: function (jqXHR, textStatus) {
-            this.updateLoadStatus('alerts')
-          }
-        };
-      if(App.testMode){
+        dataType: "jsonp",
+        jsonp: "jsonp",
+        context: this,
+        complete: function (jqXHR, textStatus) {
+          this.updateLoadStatus('alerts')
+        }
+      };
+      if (App.testMode) {
         dataUrl = "/data/alerts/alerts.jsonp";
         ajaxOptions.jsonpCallback = "jQuery172040994187095202506_1352498338217";
-      }else{
+      } else {
         dataUrl = nagiosUrl + "/hdp/nagios/nagios_alerts.php?q1=alerts&alert_type=all";
       }
       App.HttpClient.get(dataUrl, App.alertsMapper, ajaxOptions);
-    }else{
+    } else {
       this.updateLoadStatus('alerts');
       console.log("No Nagios URL provided.")
     }
@@ -179,7 +181,7 @@ App.ClusterController = Em.Controller.extend({
      var hostsUrl = this.getUrl('/data/hosts/hosts.json', '/hosts?fields=*');
      var servicesUrl1 = this.getUrl('/data/dashboard/services.json', '/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/host_components/*');
      var servicesUrl2 = this.getUrl('/data/dashboard/services.json', '/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/ServiceComponentInfo');
-     var usersUrl = this.getUrl('/data/users/users.json', '/users/?fields=*');
+     var usersUrl = App.testMode ? '/data/users/users.json' : '/api/users/?fields=*';
      var runsUrl = App.testMode ? "/data/apps/runs.json" : "/api/jobhistory/workflow";
 
      var racksUrl = "/data/racks/racks.json";
@@ -188,29 +190,40 @@ App.ClusterController = Em.Controller.extend({
       complete:function(jqXHR, textStatus){
         self.updateLoadStatus('racks');
       }
+    },function(jqXHR, textStatus){
+      self.updateLoadStatus('racks');
     });
+
     App.HttpClient.get(clusterUrl, App.clusterMapper,{
       complete:function(jqXHR, textStatus){
         self.updateLoadStatus('cluster');
       }
+    },function(jqXHR, textStatus){
+      self.updateLoadStatus('cluster');
     });
 
-//     App.HttpClient.get(runsUrl, App.runsMapper,{
-//       complete:function(jqXHR, textStatus) {
-//         self.updateLoadStatus('runs');
-//       }
-//     });
+    App.HttpClient.get(runsUrl, App.runsMapper,{
+      complete:function(jqXHR, textStatus) {
+        self.updateLoadStatus('runs');
+      }
+    },function(jqXHR, textStatus){
+      self.updateLoadStatus('runs');
+    });
 
     App.HttpClient.get(hostsUrl, App.hostsMapper,{
       complete:function(jqXHR, textStatus){
         self.updateLoadStatus('hosts');
       }
+    },function(jqXHR, textStatus){
+      self.updateLoadStatus('hosts');
     });
 
     App.HttpClient.get(usersUrl, App.usersMapper,{
       complete:function(jqXHR, textStatus){
         self.updateLoadStatus('users');
       }
+    },function(jqXHR, textStatus){
+      self.updateLoadStatus('users');
     });
 
     //////////////////////////////
@@ -224,59 +237,71 @@ App.ClusterController = Em.Controller.extend({
         }
     };
     var serviceComponentMapper = {
-        map: function(data){
-          serviceComponentJson = data;
-          if(metricsJson!=null && serviceComponentJson!=null){
-            var hdfsSvc1 = null;
-            var hdfsSvc2 = null;
-            var mrSvc1 = null;
-            var mrSvc2 = null;
-            metricsJson.items.forEach(function(svc){
-              if(svc.ServiceInfo.service_name=="HDFS"){
-                hdfsSvc1 = svc;
-              }
-              if(svc.ServiceInfo.service_name=="MAPREDUCE"){
-                mrSvc1 = svc;
-              }
-            });
-            serviceComponentJson.items.forEach(function(svc){
-              if(svc.ServiceInfo.service_name=="HDFS"){
-                hdfsSvc2 = svc;
-              }
-              if(svc.ServiceInfo.service_name=="MAPREDUCE"){
-                mrSvc2 = svc;
-              }
-            });
-            var nnC1 = null;
-            var nnC2 = null;
-            var jtC1 = null;
-            var jtC2 = null;
-            hdfsSvc1.components.forEach(function(c){
-              if(c.ServiceComponentInfo.component_name=="NAMENODE"){
+      map: function (data) {
+        serviceComponentJson = data;
+        if (metricsJson != null && serviceComponentJson != null) {
+          var hdfsSvc1 = null;
+          var hdfsSvc2 = null;
+          var mrSvc1 = null;
+          var mrSvc2 = null;
+          metricsJson.items.forEach(function (svc) {
+            if (svc.ServiceInfo.service_name == "HDFS") {
+              hdfsSvc1 = svc;
+            }
+            if (svc.ServiceInfo.service_name == "MAPREDUCE") {
+              mrSvc1 = svc;
+            }
+          });
+          serviceComponentJson.items.forEach(function (svc) {
+            if (svc.ServiceInfo.service_name == "HDFS") {
+              hdfsSvc2 = svc;
+            }
+            if (svc.ServiceInfo.service_name == "MAPREDUCE") {
+              mrSvc2 = svc;
+            }
+          });
+          var nnC1 = null;
+          var nnC2 = null;
+          var jtC1 = null;
+          var jtC2 = null;
+          if (hdfsSvc1) {
+            hdfsSvc1.components.forEach(function (c) {
+              if (c.ServiceComponentInfo.component_name == "NAMENODE") {
                 nnC1 = c;
               }
             });
-            hdfsSvc2.components.forEach(function(c){
-              if(c.ServiceComponentInfo.component_name=="NAMENODE"){
+          }
+          if (hdfsSvc2) {
+            hdfsSvc2.components.forEach(function (c) {
+              if (c.ServiceComponentInfo.component_name == "NAMENODE") {
                 nnC2 = c;
               }
             });
-            mrSvc1.components.forEach(function(c){
-              if(c.ServiceComponentInfo.component_name=="JOBTRACKER"){
+          }
+          if (mrSvc1) {
+            mrSvc1.components.forEach(function (c) {
+              if (c.ServiceComponentInfo.component_name == "JOBTRACKER") {
                 jtC1 = c;
               }
             });
-            mrSvc2.components.forEach(function(c){
-              if(c.ServiceComponentInfo.component_name=="JOBTRACKER"){
+          }
+          if (mrSvc2) {
+            mrSvc2.components.forEach(function (c) {
+              if (c.ServiceComponentInfo.component_name == "JOBTRACKER") {
                 jtC2 = c;
               }
             });
+          }
+          if (nnC1 && nnC2) {
             nnC1.ServiceComponentInfo = nnC2.ServiceComponentInfo;
+          }
+          if (jtC1 && jtC2) {
             jtC1.ServiceComponentInfo = jtC2.ServiceComponentInfo;
-            App.servicesMapper.map(metricsJson);
-            self.updateLoadStatus('services');
           }
+          App.servicesMapper.map(metricsJson);
+          self.updateLoadStatus('services');
         }
+      }
     }
     App.HttpClient.get(servicesUrl1, metricsMapper,{
       complete:function(jqXHR, textStatus){
@@ -290,8 +315,9 @@ App.ClusterController = Em.Controller.extend({
     // Hack for services END   //
     /////////////////////////////
 
-  }.observes('clusterName'),
+  },
+
   clusterName: function(){
-    return (this.get('cluster')) ? this.get('cluster').Clusters.cluster_name : 'mycluster';
+    return (this.get('cluster')) ? this.get('cluster').Clusters.cluster_name : null;
   }.property('cluster')
 })

+ 24 - 45
ambari-web/app/controllers/installer.js

@@ -226,9 +226,9 @@ App.InstallerController = Em.Controller.extend({
     slaveComponentHosts: null,
     hostSlaveComponents: null,
     masterComponentHosts: null,
-    hostToMasterComponent: null,
     serviceConfigProperties: null,
-    advancedServiceConfig: null
+    advancedServiceConfig: null,
+    controllerName: 'installerController'
   }),
 
   /**
@@ -260,9 +260,6 @@ App.InstallerController = Em.Controller.extend({
     App.db.setClusterStatus(clusterStatus);
 
     console.log("InstallerController:saveClusterInfo: saved data ", cluster);
-
-    //probably next line is extra work - need to check it
-    //this.set('content.cluster', cluster);
   },
 
   /**
@@ -379,7 +376,8 @@ App.InstallerController = Em.Controller.extend({
         name: _host.name,
         cpu: _host.cpu,
         memory: _host.memory,
-        bootStatus: _host.bootStatus
+        bootStatus: _host.bootStatus,
+        isInstalled: false
       };
     });
     console.log('installerController:saveConfirmedHosts: save hosts ', hostInfo);
@@ -454,12 +452,11 @@ App.InstallerController = Em.Controller.extend({
    */
   saveServices: function (stepController) {
     var serviceNames = [];
-    // we can also do it without stepController since all data,
-    // changed at page, automatically changes in model(this.content.services)
     App.db.setService(stepController.get('content'));
     stepController.filterProperty('isSelected', true).forEach(function (item) {
       serviceNames.push(item.serviceName);
     });
+    this.set('content.selectedServiceNames', serviceNames);
     App.db.setSelectedServiceNames(serviceNames);
     console.log('installerController.saveServices: saved data ', serviceNames);
   },
@@ -470,32 +467,20 @@ App.InstallerController = Em.Controller.extend({
    */
   saveMasterComponentHosts: function (stepController) {
     var obj = stepController.get('selectedServicesMasters');
-    console.log("installerController.selectedServicesMasters: saved hosts ", stepController.get('selectedServicesMasters'));
+
     var masterComponentHosts = [];
     obj.forEach(function (_component) {
       masterComponentHosts.push({
         display_name: _component.get('display_name'),
         component: _component.get('component_name'),
-        hostName: _component.get('selectedHost')
+        hostName: _component.get('selectedHost'),
+        isInstalled: false
       });
     });
 
-    console.log("installerController.saveComponentHosts: saved hosts ", masterComponentHosts);
+    console.log("installerController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
-
-    var hosts = masterComponentHosts.mapProperty('hostName').uniq();
-    var hostsMasterServicesMapping = [];
-    hosts.forEach(function (_host) {
-      var componentsOnHost = masterComponentHosts.filterProperty('hostName', _host).mapProperty('component');
-      hostsMasterServicesMapping.push({
-        hostname: _host,
-        components: componentsOnHost
-      });
-    }, this);
-    console.log("installerController.setHostToMasterComponent: saved hosts ", hostsMasterServicesMapping);
-    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
-    this.set('content.hostToMasterComponent', hostsMasterServicesMapping);
   },
 
   /**
@@ -505,10 +490,6 @@ App.InstallerController = Em.Controller.extend({
     var masterComponentHosts = App.db.getMasterComponentHosts();
     this.set("content.masterComponentHosts", masterComponentHosts);
     console.log("InstallerController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
-
-    var hostsMasterServicesMapping = App.db.getHostToMasterComponent();
-    this.set("content.hostToMasterComponent", hostsMasterServicesMapping);
-    console.log("InstallerController.loadHostToMasterComponent: loaded hosts ", hostsMasterServicesMapping);
   },
 
   /**
@@ -532,25 +513,25 @@ App.InstallerController = Em.Controller.extend({
     hosts.forEach(function (host) {
       if (host.get('isDataNode')) {
         dataNodeHosts.push({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
       if (isMrSelected && host.get('isTaskTracker')) {
         taskTrackerHosts.push({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
       if (isHbSelected && host.get('isRegionServer')) {
         regionServerHosts.push({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
       if (host.get('isClient')) {
         clientHosts.pushObject({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
@@ -615,8 +596,8 @@ App.InstallerController = Em.Controller.extend({
     stepController.get('stepConfigs').forEach(function (_content) {
       _content.get('configs').forEach(function (_configProperties) {
         var displayType =  _configProperties.get('displayType');
-        if(displayType === 'directories' || displayType === 'advanced' || displayType === 'directory') {
-          var value = _configProperties.get('value').replace(/[\s,]+/g,',');
+        if(displayType === 'directories' || displayType === 'directory') {
+          var value = _configProperties.get('value').split(/\s+/g).join(',');
           _configProperties.set('value',value);
         }
         var configProperty = {
@@ -677,15 +658,6 @@ App.InstallerController = Em.Controller.extend({
     console.log("InstallerController.saveClients: saved list ", clients);
   },
 
-  /**
-   * Load HostToMasterComponent array
-   */
-  loadHostToMasterComponent: function () {
-    var list = App.db.getHostToMasterComponent();
-    this.set('content.hostToMasterComponent', list);
-    console.log("InstallerController.loadHostToMasterComponent: loaded list ", list);
-  },
-
   /**
    * Load data for all steps until <code>current step</code>
    */
@@ -699,13 +671,12 @@ App.InstallerController = Em.Controller.extend({
         this.loadServiceConfigProperties();
       case '6':
         this.loadSlaveComponentHosts();
+        this.loadClients();
       case '5':
         this.loadMasterComponentHosts();
-        this.loadHostToMasterComponent();
         this.loadConfirmedHosts();
       case '4':
         this.loadServices();
-        this.loadClients();
       case '3':
         this.loadConfirmedHosts();
       case '2':
@@ -857,6 +828,14 @@ App.InstallerController = Em.Controller.extend({
       statusCode: require('data/statusCodes')
     });
 
+  },
+
+  /**
+   * Clear all temporary data
+   */
+  finish: function(){
+    this.setCurrentStep('1', false);
+    App.db.setService(undefined); //not to use this data at AddService page
   }
 
 });

+ 1 - 1
ambari-web/app/controllers/main.js

@@ -29,7 +29,7 @@ App.MainController = Em.Controller.extend({
    */
   initialize: function(){
     this.startLoadOperationsPeriodically();
-    App.router.get('clusterController').loadClusterName();
+    App.router.get('clusterController').loadClusterData();
   },
   startLoadOperationsPeriodically: function() {
       App.router.get('backgroundOperationsController').set('isWorking', true);

+ 41 - 6
ambari-web/app/controllers/main/admin/user.js

@@ -21,15 +21,50 @@ var App = require('app');
 App.MainAdminUserController = Em.Controller.extend({
   name:'mainAdminUserController',
   deleteRecord:function (event) {
-
     if (event.context.get('userName') == App.get('router').getLoginName()) {
-      alert(Em.I18n.t('admin.users.deleteYourselfMessage'));
+      App.ModalPopup.show({
+        header:Em.I18n.t('admin.users.delete.yourself.header'),
+        body:Em.I18n.t('admin.users.delete.yourself.message'),
+        onPrimary:function (event) {
+          this.hide();
+        },
+        secondary:false
+      });
+
       return;
     }
+    ;
 
-    if (confirm(Em.I18n.t('question.sure'))) {
-      event.context.deleteRecord();
-      App.store.commit();
-    }
+    App.ModalPopup.show({
+      itemToDelete:event.context,
+      header:Em.I18n.t('admin.users.delete.header').format(event.context.get('userName')),
+      body:Em.I18n.t('question.sure'),
+      primary:Em.I18n.t('yes'),
+      secondary:Em.I18n.t('no'),
+      controller:this.controllers.mainAdminUserEditController,
+      onPrimary:function (event) {
+
+        //TODO: change sendCommandToServer parametrs for proper API request
+        this.get('controller').sendCommandToServer('/users/delete/' + this.get('itemToDelete').context.get("userName"), {
+            Users:{ /* password: form.getValues().password, roles: form.getValues().roles*/ }
+          },
+          function (requestId) {
+
+            if (!requestId) {
+              return;
+            }
+
+            this.get('itemToDelete').context.deleteRecord();
+            try {
+              App.store.commit()
+            } catch (err) {
+            }
+            ;
+          })
+      },
+      onSecondary:function (event) {
+        this.hide();
+      }
+    });
   }
 })

+ 0 - 0
ambari-web/app/controllers/main/apps/runs_controller.js


+ 1 - 3
ambari-web/app/controllers/main/dashboard.js

@@ -39,9 +39,7 @@ App.MainDashboardController = Em.Controller.extend({
     }
   },
 
-  services:function(){
-    return App.router.get('mainServiceController.content');
-  }.property('App.router.mainServiceController.content'),
+
   alertsFilteredBy: 'All',
   alertsFilter: function(event) {
     if (event.context)

+ 19 - 33
ambari-web/app/controllers/main/host/add_controller.js

@@ -42,7 +42,6 @@ App.AddHostController = Em.Controller.extend({
     slaveComponentHosts: null,
     hostSlaveComponents: null,
     masterComponentHosts: null,
-    hostToMasterComponent : null,
     serviceConfigProperties: null
   }),
 
@@ -323,14 +322,28 @@ App.AddHostController = Em.Controller.extend({
    */
   saveConfirmedHosts: function (stepController) {
     var hostInfo = {};
+
+    App.Host.find().forEach(function(_host){
+      hostInfo[_host.get('id')] = {
+        name: _host.get('hostName'),
+        cpu: _host.get('cpu'),
+        memory: _host.get('memory'),
+        bootStatus: 'success',
+        isInstalled: true
+      };
+    });
+
     stepController.get('content.hostsInfo').forEach(function (_host) {
       hostInfo[_host.name] = {
         name: _host.name,
         cpu: _host.cpu,
         memory: _host.memory,
-        bootStatus: _host.bootStatus
+        bootStatus: _host.bootStatus,
+        isInstalled: false
       };
     });
+
+
     console.log('addHostController:saveConfirmedHosts: save hosts ', hostInfo);
     App.db.setHosts(hostInfo);
     this.set('content.hostsInfo', hostInfo);
@@ -428,19 +441,6 @@ App.AddHostController = Em.Controller.extend({
     console.log("AddHostController.saveComponentHosts: saved hosts ", masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
-
-    var hosts = masterComponentHosts.mapProperty('hostName').uniq();
-    var hostsMasterServicesMapping = [];
-    hosts.forEach(function (_host) {
-      var componentsOnHost = masterComponentHosts.filterProperty('hostName', _host).mapProperty('component');
-      hostsMasterServicesMapping.push({
-        hostname: _host,
-        components: componentsOnHost
-      });
-    }, this);
-    console.log("AddHostController.setHostToMasterComponent: saved hosts ", hostsMasterServicesMapping);
-    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
-    this.set('content.hostToMasterComponent', hostsMasterServicesMapping);
   },
 
   /**
@@ -450,10 +450,6 @@ App.AddHostController = Em.Controller.extend({
     var masterComponentHosts = App.db.getMasterComponentHosts();
     this.set("content.masterComponentHosts", masterComponentHosts);
     console.log("AddHostController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
-
-    var hostsMasterServicesMapping = App.db.getHostToMasterComponent();
-    this.set("content.hostToMasterComponent", hostsMasterServicesMapping);
-    console.log("AddHostController.loadHostToMasterComponent: loaded hosts ", hostsMasterServicesMapping);
   },
 
   /**
@@ -477,25 +473,25 @@ App.AddHostController = Em.Controller.extend({
     hosts.forEach(function (host) {
       if (host.get('isDataNode')) {
         dataNodeHosts.push({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
       if (isMrSelected && host.get('isTaskTracker')) {
         taskTrackerHosts.push({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
       if (isHbSelected && host.get('isRegionServer')) {
         regionServerHosts.push({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
       if (host.get('isClient')) {
         clientHosts.pushObject({
-          hostname: host.hostname,
+          hostName: host.hostName,
           group: 'Default'
         });
       }
@@ -606,15 +602,6 @@ App.AddHostController = Em.Controller.extend({
     console.log("AddHostController.saveClients: saved list ", clients);
   },
 
-  /**
-   * Load HostToMasterComponent array
-   */
-  loadHostToMasterComponent: function(){
-    var list = App.db.getHostToMasterComponent();
-    this.set('content.hostToMasterComponent', list);
-    console.log("AddHostController.loadHostToMasterComponent: loaded list ", list);
-  },
-
   /**
    * Load data for all steps until <code>current step</code>
    */
@@ -630,7 +617,6 @@ App.AddHostController = Em.Controller.extend({
       case '4':
         this.loadMasterComponentHosts();
         this.loadSlaveComponentHosts();
-        this.loadHostToMasterComponent();
         this.loadConfirmedHosts();
       case '3':
         this.loadClients();

+ 70 - 181
ambari-web/app/controllers/main/service/add_controller.js

@@ -42,8 +42,8 @@ App.AddServiceController = Em.Controller.extend({
     slaveComponentHosts: null,
     hostSlaveComponents: null,
     masterComponentHosts: null,
-    hostToMasterComponent : null,
-    serviceConfigProperties: null
+    serviceConfigProperties: null,
+    controllerName: 'addServiceController'
   }),
 
   /**
@@ -176,25 +176,6 @@ App.AddServiceController = Em.Controller.extend({
     console.log("AddServiceController:loadClusterInfo: loaded data ", cluster);
   },
 
-  /**
-   * Save all info about claster to model
-   * @param stepController Step1WizardController
-   */
-  saveClusterInfo: function (stepController) {
-    var cluster = stepController.get('content.cluster');
-    var clusterStatus = {
-      status: cluster.status,
-      isCompleted: cluster.isCompleted
-    }
-    App.db.setClusterName(cluster.name);
-    App.db.setClusterStatus(clusterStatus);
-
-    console.log("AddServiceController:saveClusterInfo: saved data ", cluster);
-
-    //probably next line is extra work - need to check it
-    this.set('content.cluster', cluster);
-  },
-
   /**
    * save status of the cluster. This is called from step8 and step9 to persist install and start requestId
    * @param clusterStatus object with status, isCompleted, requestId, isInstallError and isStartError field.
@@ -217,124 +198,22 @@ App.AddServiceController = Em.Controller.extend({
     App.db.setHosts(hostInfo);
   },
 
-  /**
-   * Load all data for <code>Specify Host(install step2)</code> step
-   * Data Example:
-   * {
-   *   hostNames: '',
-   *   manualInstall: false,
-   *   sshKey: '',
-   *   passphrase: '',
-   *   confirmPassphrase: '',
-   *   localRepo: false,
-   *   localRepoPath: ''
-   * }
-   */
-  loadInstallOptions: function () {
-
-    if (!this.content.hosts) {
-      this.content.hosts = Em.Object.create();
-    }
-
-    //TODO : rewire it as model. or not :)
-    var hostsInfo = Em.Object.create();
-
-    hostsInfo.hostNames = App.db.getAllHostNames() || ''; //empty string if undefined
-
-    //TODO : should we check installType for add host wizard????
-    var installType = App.db.getInstallType();
-    //false if installType not equals 'manual'
-    hostsInfo.manualInstall = installType && installType.installType === 'manual' || false;
-
-    var softRepo = App.db.getSoftRepo();
-    if (softRepo && softRepo.repoType === 'local') {
-      hostsInfo.localRepo = true;
-      hostsInfo.localRepopath = softRepo.repoPath;
-    } else {
-      hostsInfo.localRepo = false;
-      hostsInfo.localRepoPath = '';
-    }
-
-    hostsInfo.sshKey = 'random';
-    hostsInfo.passphrase = '';
-    hostsInfo.confirmPassphrase = '';
-
-    this.set('content.hosts', hostsInfo);
-    console.log("AddServiceController:loadHosts: loaded data ", hostsInfo);
-  },
-
-  /**
-   * Save data, which user filled, to main controller
-   * @param stepController App.WizardStep2Controller
-   */
-  saveHosts: function (stepController) {
-    //TODO: put data to content.hosts and only then save it)
-
-    //App.db.setBootStatus(false);
-    App.db.setAllHostNames(stepController.get('hostNames'));
-    App.db.setHosts(stepController.getHostInfo());
-    if (stepController.get('manualInstall') === false) {
-      App.db.setInstallType({installType: 'ambari' });
-    } else {
-      App.db.setInstallType({installType: 'manual' });
-    }
-    if (stepController.get('localRepo') === false) {
-      App.db.setSoftRepo({ 'repoType': 'remote', 'repoPath': null});
-    } else {
-      App.db.setSoftRepo({ 'repoType': 'local', 'repoPath': stepController.get('localRepoPath') });
-    }
-  },
-
-  /**
-   * Remove host from model. Used at <code>Confirm hosts(step2)</code> step
-   * @param hosts Array of hosts, which we want to delete
-   */
-  removeHosts: function (hosts) {
-    //todo Replace this code with real logic
-    App.db.removeHosts(hosts);
-  },
-
-  /**
-   * Save data, which user filled, to main controller
-   * @param stepController App.WizardStep3Controller
-   */
-  saveConfirmedHosts: function (stepController) {
-    var hostInfo = {};
-    stepController.get('content').forEach(function (_host) {
-      hostInfo[_host.name] = {
-        name: _host.name,
-        cpu: _host.cpu,
-        memory: _host.memory,
-        bootStatus: _host.bootStatus
-      };
-    });
-    console.log('AddServiceController:saveConfirmedHosts: save hosts ', hostInfo);
-    App.db.setHosts(hostInfo);
-    this.set('content.hostsInfo', hostInfo);
-  },
-
   /**
    * Load confirmed hosts.
    * Will be used at <code>Assign Masters(step5)</code> step
    */
   loadConfirmedHosts: function(){
-    var hosts=App.db.getHosts();
-
-      hosts = {
-        "192.168.1.1":{"name":"192.168.1.1","cpu":"2","memory":"2","bootStatus":"pending"},
-        "192.168.1.2":{"name":"192.168.1.2","cpu":"2","memory":"2","bootStatus":"success"},
-        "192.168.1.3":{"name":"192.168.1.3","cpu":"2","memory":"2","bootStatus":"pending"},
-        "192.168.1.4":{"name":"192.168.1.4","cpu":"2","memory":"2","bootStatus":"pending"},
-        "192.168.1.5":{"name":"192.168.1.5","cpu":"2","memory":"2","bootStatus":"success"},
-        "192.168.1.6":{"name":"192.168.1.6","cpu":"2","memory":"2","bootStatus":"pending"},
-        "192.168.1.7":{"name":"192.168.1.7","cpu":"2","memory":"2","bootStatus":"success"},
-        "192.168.1.8":{"name":"192.168.1.8","cpu":"2","memory":"2","bootStatus":"success"},
-        "192.168.1.9":{"name":"192.168.1.9","cpu":"2","memory":"2","bootStatus":"success"},
-        "192.168.1.10":{"name":"192.168.1.10","cpu":"2","memory":"2","bootStatus":"pending"},
-        "192.168.1.11":{"name":"192.168.1.11","cpu":"2","memory":"2","bootStatus":"success"},
-        "192.168.1.12":{"name":"192.168.1.12","cpu":"2","memory":"2","bootStatus":"pending"},
-        "192.168.1.13":{"name":"192.168.1.13","cpu":"2","memory":"2","bootStatus":"success"}
+    var hosts = {};
+
+    App.Host.find().forEach(function(item){
+      hosts[item.get('id')] = {
+        name: item.get('id'),
+        cpu: item.get('cpu'),
+        memory: item.get('memory'),
+        bootStatus: "success",
+        isInstalled: true
       };
+    });
 
     this.set('content.hostsInfo', hosts);
   },
@@ -357,6 +236,7 @@ App.AddServiceController = Em.Controller.extend({
       }
     }
     App.db.setHosts(hostInfo);
+    this.set('content.hostsInfo', hostInfo);
     console.log('AddServiceController:saveInstalledHosts: save hosts ', hostInfo);
   },
 
@@ -374,6 +254,8 @@ App.AddServiceController = Em.Controller.extend({
       hosts.passphrase = '';
       hosts.confirmPassphrase = '';
     }
+    App.db.setHosts(null);
+    App.db.setAllHostNames(null);
   },
 
   /**
@@ -381,6 +263,14 @@ App.AddServiceController = Em.Controller.extend({
    */
   loadServices: function () {
     var servicesInfo = App.db.getService();
+    if(!servicesInfo){
+      servicesInfo = require('data/mock/services').slice(0);
+      servicesInfo.forEach(function(item, index){
+        servicesInfo[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
+        servicesInfo[index].isDisabled = servicesInfo[index].isSelected;
+      });
+    }
+
     servicesInfo.forEach(function (item, index) {
       servicesInfo[index] = Em.Object.create(item);
     });
@@ -398,9 +288,10 @@ App.AddServiceController = Em.Controller.extend({
     // we can also do it without stepController since all data,
     // changed at page, automatically changes in model(this.content.services)
     App.db.setService(stepController.get('content'));
-    stepController.filterProperty('isSelected', true).forEach(function (item) {
+    stepController.filterProperty('isSelected', true).filterProperty('isDisabled', false).forEach(function (item) {
       serviceNames.push(item.serviceName);
     });
+    this.set('content.selectedServiceNames', serviceNames);
     App.db.setSelectedServiceNames(serviceNames);
     console.log('AddServiceController.saveServices: saved data ', serviceNames);
   },
@@ -412,43 +303,39 @@ App.AddServiceController = Em.Controller.extend({
   saveMasterComponentHosts: function (stepController) {
     var obj = stepController.get('selectedServicesMasters');
     var masterComponentHosts = [];
+    var installedComponents = App.Component.find();
+
     obj.forEach(function (_component) {
-      masterComponentHosts.push({
-        display_name: _component.display_name,
-        component: _component.component_name,
-        hostName: _component.selectedHost
-      });
+      if(!installedComponents.someProperty('componentName', _component.component_name)){
+        masterComponentHosts.push({
+          display_name: _component.display_name,
+          component: _component.component_name,
+          hostName: _component.selectedHost,
+          isInstalled: false
+        });
+      }
     });
 
-    console.log("AddServiceController.saveComponentHosts: saved hosts ", masterComponentHosts);
+    console.log("AddServiceController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
     App.db.setMasterComponentHosts(masterComponentHosts);
     this.set('content.masterComponentHosts', masterComponentHosts);
-
-    var hosts = masterComponentHosts.mapProperty('hostName').uniq();
-    var hostsMasterServicesMapping = [];
-    hosts.forEach(function (_host) {
-      var componentsOnHost = masterComponentHosts.filterProperty('hostName', _host).mapProperty('component');
-      hostsMasterServicesMapping.push({
-        hostname: _host,
-        components: componentsOnHost
-      });
-    }, this);
-    console.log("AddServiceController.setHostToMasterComponent: saved hosts ", hostsMasterServicesMapping);
-    App.db.setHostToMasterComponent(hostsMasterServicesMapping);
-    this.set('content.hostToMasterComponent', hostsMasterServicesMapping);
   },
 
   /**
    * Load master component hosts data for using in required step controllers
    */
   loadMasterComponentHosts: function () {
-    var masterComponentHosts = App.db.getMasterComponentHosts();
+    var masterComponentHosts = App.db.getMasterComponentHosts() || [];
+    App.Component.find().filterProperty('isMaster', true).forEach(function(item){
+      masterComponentHosts.push({
+        component: item.get('componentName'),
+        display_name: item.get('displayName'),
+        hostName: item.get('host.hostName'),
+        isInstalled: true
+      })
+    });
     this.set("content.masterComponentHosts", masterComponentHosts);
     console.log("AddServiceController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts);
-
-    var hostsMasterServicesMapping = App.db.getHostToMasterComponent();
-    this.set("content.hostToMasterComponent", hostsMasterServicesMapping);
-    console.log("AddServiceController.loadHostToMasterComponent: loaded hosts ", hostsMasterServicesMapping);
   },
 
   /**
@@ -469,29 +356,36 @@ App.AddServiceController = Em.Controller.extend({
     var regionServerHosts = [];
     var clientHosts = [];
 
+    var installedComponents = App.Component.find();
+
     hosts.forEach(function (host) {
+
       if (host.get('isDataNode')) {
         dataNodeHosts.push({
-          hostname: host.hostname,
-          group: 'Default'
+          hostName: host.hostName,
+          group: 'Default',
+          isInstalled: installedComponents.someProperty('componentName', 'DATANODE')
         });
       }
       if (isMrSelected && host.get('isTaskTracker')) {
         taskTrackerHosts.push({
-          hostname: host.hostname,
-          group: 'Default'
+          hostName: host.hostName,
+          group: 'Default',
+          isInstalled: installedComponents.someProperty('componentName', 'TASKTRACKER')
         });
       }
       if (isHbSelected && host.get('isRegionServer')) {
         regionServerHosts.push({
-          hostname: host.hostname,
-          group: 'Default'
+          hostName: host.hostName,
+          group: 'Default',
+          isInstalled: installedComponents.someProperty('componentName', 'HBASE_REGIONSERVER')
         });
       }
       if (host.get('isClient')) {
         clientHosts.pushObject({
-          hostname: host.hostname,
-          group: 'Default'
+          hostName: host.hostName,
+          group: 'Default',
+          isInstalled: installedComponents.someProperty('componentName', 'CLIENT')
         });
       }
     }, this);
@@ -549,7 +443,8 @@ App.AddServiceController = Em.Controller.extend({
       _content.get('configs').forEach(function (_configProperties) {
         var configProperty = {
           name: _configProperties.get('name'),
-          value: _configProperties.get('value')
+          value: _configProperties.get('value'),
+          service: _configProperties.get('serviceName')
         };
         serviceConfigProperties.push(configProperty);
       }, this);
@@ -601,15 +496,6 @@ App.AddServiceController = Em.Controller.extend({
     console.log("AddServiceController.saveClients: saved list ", clients);
   },
 
-  /**
-   * Load HostToMasterComponent array
-   */
-  loadHostToMasterComponent: function(){
-    var list = App.db.getHostToMasterComponent();
-    this.set('content.hostToMasterComponent', list);
-    console.log("AddServiceController.loadHostToMasterComponent: loaded list ", list);
-  },
-
   /**
    * Load data for all steps until <code>current step</code>
    */
@@ -623,10 +509,9 @@ App.AddServiceController = Em.Controller.extend({
         this.loadServiceConfigProperties();
       case '3':
         this.loadClients();
+        this.loadSlaveComponentHosts();
       case '2':
         this.loadMasterComponentHosts();
-        this.loadSlaveComponentHosts();
-        this.loadHostToMasterComponent();
         this.loadConfirmedHosts();
       case '1':
         this.loadServices();
@@ -640,10 +525,11 @@ App.AddServiceController = Em.Controller.extend({
   installServices: function () {
     var self = this;
     var clusterName = this.get('content.cluster.name');
-    var url = '/api/clusters/' + clusterName + '/services?state=INIT';
+    var url = (App.testMode) ? '/data/wizard/deploy/poll_1.json' : '/api/clusters/' + clusterName + '/services?state=INIT';
+    var method = (App.testMode) ? 'GET' : 'PUT';
     var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
     $.ajax({
-      type: 'PUT',
+      type: method,
       url: url,
       data: data,
       async: false,
@@ -651,16 +537,19 @@ App.AddServiceController = Em.Controller.extend({
       timeout: 5000,
       success: function (data) {
         var jsonData = jQuery.parseJSON(data);
+        var installSartTime = new Date().getTime();
         console.log("TRACE: STep8 -> In success function for the installService call");
         console.log("TRACE: STep8 -> value of the url is: " + url);
         if (jsonData) {
           var requestId = jsonData.href.match(/.*\/(.*)$/)[1];
+
           console.log('requestId is: ' + requestId);
           var clusterStatus = {
             status: 'PENDING',
             requestId: requestId,
             isInstallError: false,
-            isCompleted: false
+            isCompleted: false,
+            installStartTime: installSartTime
           };
           self.saveClusterStatus(clusterStatus);
         } else {

+ 2 - 0
ambari-web/app/controllers/wizard/step5_controller.js

@@ -94,6 +94,7 @@ App.WizardStep5Controller = Em.Controller.extend({
           componentObj.component_name = _componentInfo.component_name;
           componentObj.display_name = _componentInfo.display_name;
           componentObj.selectedHost = this.selectHost(_componentInfo.component_name);   // call the method that plays selectNode algorithm or fetches from server
+          componentObj.isInstalled = App.Component.find().someProperty('componentName', _componentInfo.component_name);
           componentObj.availableHosts = [];
           components.add(componentObj);
         }, this);
@@ -106,6 +107,7 @@ App.WizardStep5Controller = Em.Controller.extend({
         componentObj.component_name = _masterComponentHost.component;
         componentObj.display_name = _masterComponentHost.display_name;
         componentObj.selectedHost = _masterComponentHost.hostName;
+        componentObj.isInstalled = _masterComponentHost.isInstalled;
         componentObj.availableHosts = [];
         components.add(componentObj);
       }, this);

+ 17 - 21
ambari-web/app/controllers/wizard/step6_controller.js

@@ -97,11 +97,11 @@ App.WizardStep6Controller = Em.Controller.extend({
 
   /**
    * Check whether current host is currently selected as master
-   * @param hostname
+   * @param hostName
    * @return {Boolean}
    */
-  hasMasterComponents: function (hostname) {
-    return this.get('content.masterComponentHosts').someProperty('hostName', hostname);
+  hasMasterComponents: function (hostName) {
+    return this.get('content.masterComponentHosts').someProperty('hostName', hostName);
   },
 
   selectAllDataNodes: function () {
@@ -173,7 +173,7 @@ App.WizardStep6Controller = Em.Controller.extend({
 
     allHosts.forEach(function (_hostName) {
       hostsObj.push(Em.Object.create({
-        hostname: _hostName,
+        hostName: _hostName,
         isMaster: false,
         isDataNode: false,
         isTaskTracker: false,
@@ -185,7 +185,7 @@ App.WizardStep6Controller = Em.Controller.extend({
     if (!slaveHosts) { // we are at this page for the first time
       if (allHosts.length > 3) {             //multiple nodes scenario
         hostsObj.forEach(function (host) {
-          host.isMaster = this.hasMasterComponents(host.hostname);
+          host.isMaster = this.hasMasterComponents(host.hostName);
           host.isDataNode = host.isTaskTracker
             = host.isRegionServer = !host.isMaster;
         }, this);
@@ -199,9 +199,10 @@ App.WizardStep6Controller = Em.Controller.extend({
           masterComponents: maxNoofHostComponents
         };
         hostsObj.forEach(function (host) {
-          host.isMaster = this.hasMasterComponents(host.hostname);
-          if (this.getMasterComponentsForHost(host.hostname).length <= masterObj.masterComponents) {
-            masterObj.masterComponents = this.getMasterComponentsForHost(host.hostname).length;
+          host.isMaster = this.hasMasterComponents(host.hostName);
+          var countMasterComp = this.getMasterComponentsForHost(host.hostName).length;
+          if (countMasterComp <= masterObj.masterComponents) {
+            masterObj.masterComponents = countMasterComp;
             masterObj.host = host;
           }
         }, this);
@@ -216,7 +217,7 @@ App.WizardStep6Controller = Em.Controller.extend({
 
       var dataNodes = slaveHosts.findProperty('componentName', 'DATANODE');
       dataNodes.hosts.forEach(function (_dataNode) {
-        var dataNode = hostsObj.findProperty('hostname', _dataNode.hostname);
+        var dataNode = hostsObj.findProperty('hostName', _dataNode.hostName);
         if (dataNode) {
           dataNode.set('isDataNode', true);
         }
@@ -225,7 +226,7 @@ App.WizardStep6Controller = Em.Controller.extend({
       if (this.get('isMrSelected')) {
         var taskTrackers = slaveHosts.findProperty('componentName', 'TASKTRACKER');
         taskTrackers.hosts.forEach(function (_taskTracker) {
-          var taskTracker = hostsObj.findProperty('hostname', _taskTracker.hostname);
+          var taskTracker = hostsObj.findProperty('hostName', _taskTracker.hostName);
           if (taskTracker) {
             taskTracker.set('isTaskTracker', true);
           }
@@ -235,7 +236,7 @@ App.WizardStep6Controller = Em.Controller.extend({
       if (this.get('isHbSelected')) {
         var regionServers = slaveHosts.findProperty('componentName', 'HBASE_REGIONSERVER');
         regionServers.hosts.forEach(function (_regionServer) {
-          var regionServer = hostsObj.findProperty('hostname', _regionServer.hostname);
+          var regionServer = hostsObj.findProperty('hostName', _regionServer.hostName);
           if (regionServer) {
             regionServer.set('isRegionServer', true);
           }
@@ -244,14 +245,14 @@ App.WizardStep6Controller = Em.Controller.extend({
 
       var clients = slaveHosts.findProperty('componentName', 'CLIENT');
       clients.hosts.forEach(function (_client) {
-        var client = hostsObj.findProperty('hostname', _client.hostname);
+        var client = hostsObj.findProperty('hostName', _client.hostName);
         if (client) {
           client.set('isClient', true);
         }
       }, this);
 
       allHosts.forEach(function (_hostname) {
-        var host = hostsObj.findProperty('hostname', _hostname);
+        var host = hostsObj.findProperty('hostName', _hostname);
         if (host) {
           host.set('isMaster', this.hasMasterComponents(_hostname));
         }
@@ -266,16 +267,11 @@ App.WizardStep6Controller = Em.Controller.extend({
 
   /**
    * Return list of master components for specified <code>hostname</code>
-   * @param hostname
+   * @param hostName
    * @return {*}
    */
-  getMasterComponentsForHost: function (hostname) {
-    var hostInfo = this.get('content.hostToMasterComponent').findProperty('hostname', hostname);
-    if (hostInfo) {
-      return hostInfo.components;
-    }
-
-    return false;
+  getMasterComponentsForHost: function (hostName) {
+    return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
   },
 
 

+ 1 - 2
ambari-web/app/controllers/wizard/step7_controller.js

@@ -80,8 +80,7 @@ App.WizardStep7Controller = Em.Controller.extend({
           _config.category = 'Advanced';
           _config.displayName = _config.name;
           _config.defaultValue = _config.value;
-          if (/\${.*}/.test(_config.value)) {
-            console.log("Step7: The name that matched regex: " + _config.name);
+          if (/\${.*}/.test(_config.value) || (service.serviceName !== 'OOZIE' && service.serviceName !== 'HBASE')) {
             _config.isRequired = false;
             _config.value = '';
           } else if(/^\s+$/.test(_config.value)){

+ 35 - 14
ambari-web/app/controllers/wizard/step8_controller.js

@@ -29,7 +29,11 @@ App.WizardStep8Controller = Em.Controller.extend({
   configMapping: require('data/config_mapping'),
 
   selectedServices: function () {
-    return this.get('content.services').filterProperty('isSelected', true);
+    var services = App.Service.find();
+    this.get('content.services').forEach(function (item) {
+      item.set('isInstalled', services.someProperty('serviceName', item.get('serviceName')));
+    });
+    return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false);
   }.property('content.services').cacheable(),
 
   clearStep: function () {
@@ -236,7 +240,7 @@ App.WizardStep8Controller = Em.Controller.extend({
       hostObj = hostObj.concat(_hosts.hosts);
     }, this);
 
-    slaveHosts = hostObj.mapProperty('hostname').uniq();
+    slaveHosts = hostObj.mapProperty('hostName').uniq();
 
     var totalHosts = masterHosts.concat(slaveHosts).uniq();
     this.set('totalHosts', totalHosts);
@@ -593,6 +597,7 @@ App.WizardStep8Controller = Em.Controller.extend({
    * Onclick handler for <code>next</code> button
    */
   submit: function () {
+    debugger;
 
     if (App.testMode) {
       // App.router.send('next');
@@ -614,7 +619,11 @@ App.WizardStep8Controller = Em.Controller.extend({
   /* Following create* functions are called on submitting step8 */
 
   createCluster: function () {
-    var self = this;
+
+    if (this.get('content.cluster.isCompleted')){
+      return false;
+    }
+
     var clusterName = this.get('clusterInfo').findProperty('config_name', 'cluster').config_value;
     var url = '/api/clusters/' + clusterName;
     $.ajax({
@@ -715,15 +724,18 @@ App.WizardStep8Controller = Em.Controller.extend({
     });
   },
 
-  registerHostsToCluster: function () {
-    this.get('totalHosts').forEach(function (_hostname) {
-      this.registerHostToCluster(_hostname);
-    }, this);
+  registerHostsToCluster: function() {
+    var allHosts = this.get('content.hostsInfo');
+    for(var hostName in allHosts){
+      if(!allHosts[hostName].isInstalled){
+        this.registerHostToCluster(hostName);
+      }
+    }
   },
 
-  registerHostToCluster: function (hostname) {
+  registerHostToCluster: function (hostName) {
     var clusterName = this.get('clusterInfo').findProperty('config_name', 'cluster').config_value;
-    var url = '/api/clusters/' + clusterName + '/hosts/' + hostname;
+    var url = '/api/clusters/' + clusterName + '/hosts/' + hostName;
     $.ajax({
       type: 'POST',
       url: url,
@@ -764,14 +776,16 @@ App.WizardStep8Controller = Em.Controller.extend({
       if (_slaveHosts.componentName !== 'CLIENT') {
         slaveObj.component = _slaveHosts.componentName;
         _slaveHosts.hosts.forEach(function (_slaveHost) {
-          slaveObj.hostName = _slaveHost.hostname;
+          slaveObj.hostName = _slaveHost.hostName;
+          slaveObj.isInstalled = _slaveHost.isInstalled;
           this.createHostComponent(slaveObj);
         }, this);
       } else {
         this.get('content.clients').forEach(function (_client) {
           slaveObj.component = _client.component_name;
           _slaveHosts.hosts.forEach(function (_slaveHost) {
-            slaveObj.hostName = _slaveHost.hostname;
+            slaveObj.hostName = _slaveHost.hostName;
+            slaveObj.isInstalled = _slaveHost.isInstalled;
             this.createHostComponent(slaveObj);
           }, this);
         }, this);
@@ -787,6 +801,11 @@ App.WizardStep8Controller = Em.Controller.extend({
   },
 
   createHostComponent: function (hostComponent) {
+    console.log(hostComponent);
+    if (hostComponent.isInstalled) {
+      return false;
+    }
+
     var clusterName = this.get('clusterInfo').findProperty('config_name', 'cluster').config_value;
     var url = '/api/clusters/' + clusterName + '/hosts/' + hostComponent.hostName + '/host_components/' + hostComponent.component;
 
@@ -814,9 +833,11 @@ App.WizardStep8Controller = Em.Controller.extend({
 
   createConfigurations: function () {
     var selectedServices = this.get('selectedServices');
-    this.createConfigSite(this.createGlobalSiteObj());
-    this.createConfigSite(this.createCoreSiteObj());
-    this.createConfigSite(this.createHdfsSiteObj('HDFS'));
+    if (!this.get('content.cluster.isCompleted')){
+      this.createConfigSite(this.createGlobalSiteObj());
+      this.createConfigSite(this.createCoreSiteObj());
+      this.createConfigSite(this.createHdfsSiteObj('HDFS'));
+    }
     if (selectedServices.someProperty('serviceName', 'MAPREDUCE')) {
       this.createConfigSite(this.createMrSiteObj('MAPREDUCE'));
     }

+ 13 - 17
ambari-web/app/controllers/wizard/step9_controller.js

@@ -44,14 +44,13 @@ App.WizardStep9Controller = Em.Controller.extend({
   }.property('hosts.@each.status'),
 
   navigateStep: function () {
-
-    //TODO: uncomment following line after the hook up with the API call
     if (this.get('content.cluster.isCompleted') === false) {
       this.loadStep();
       if (this.get('content.cluster.status') === 'INSTALL FAILED') {
-        this.set('isStepCompleted', true);
-        this.set('status', 'failed');
+        this.hosts.setEach('status', 'failed');
         this.set('progress', '100');
+        this.set('isStepCompleted', true);
+        //this.set('status', 'failed');
       } else if (this.get('content.cluster.status') === 'START FAILED') {
         this.launchStartServices();
       } else {
@@ -229,7 +228,7 @@ App.WizardStep9Controller = Em.Controller.extend({
           isStartError: false,
           isCompleted: false
         };
-        App.router.get('installerController').saveClusterStatus(clusterStatus);
+        App.router.get(self.get('content.controllerName')).saveClusterStatus(clusterStatus);
         self.startPolling();
       },
 
@@ -242,7 +241,7 @@ App.WizardStep9Controller = Em.Controller.extend({
           isCompleted: false
         };
 
-        App.router.get('installerController').saveClusterStatus(clusterStatus);
+        App.router.get(self.get('content.controllerName')).saveClusterStatus(clusterStatus);
       },
 
       statusCode: require('data/statusCodes')
@@ -364,8 +363,8 @@ App.WizardStep9Controller = Em.Controller.extend({
         }
         if (this.isSuccess(polledData)) {
           clusterStatus.status = 'STARTED';
-          var serviceSartTime = new Date().getTime();
-          var timeToStart = Math.floor((serviceSartTime - this.get('content.cluster.installStartTime')) / 60000);
+          var serviceStartTime = new Date().getTime();
+          var timeToStart = Math.floor((serviceStartTime - this.get('content.cluster.installStartTime')) / 60000);
           clusterStatus.installTime = timeToStart;
           this.set('status', 'success');
         } else {
@@ -375,10 +374,10 @@ App.WizardStep9Controller = Em.Controller.extend({
             this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData));
           }
         }
-        App.router.get('installerController').saveClusterStatus(clusterStatus);
+        App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus);
         this.set('isStepCompleted', true);
         this.setTasksPerHost();
-        App.router.get('installerController').saveInstalledHosts(this);
+        App.router.get(this.get('content.controllerName')).saveInstalledHosts(this);
         return true;
       }
     } else if (this.get('content.cluster.status') === 'PENDING') {
@@ -389,16 +388,13 @@ App.WizardStep9Controller = Em.Controller.extend({
           isCompleted: true,
           installStartTime: this.get('content.cluster.installStartTime')
         }
-        var serviceSartTime = new Date().getTime();
-        var timeToStart = serviceSartTime - this.get('content.cluster.installStartTime');
-        console.log("STEP9: ********The time difference is = " + serviceSartTime / 60000);
         if (this.isStepFailed(polledData)) {
           console.log("In installation failure");
           clusterStatus.status = 'INSTALL FAILED';
           this.set('progress', '100');
           this.set('status', 'failed');
           this.setHostsStatus(this.getFailedHostsForFailedRoles(polledData), 'failed');
-          App.router.get('installerController').saveClusterStatus(clusterStatus);
+          App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus);
           this.set('isStepCompleted', true);
         } else {
           clusterStatus.status = 'INSTALLED';
@@ -406,7 +402,7 @@ App.WizardStep9Controller = Em.Controller.extend({
           this.launchStartServices();  //TODO: uncomment after the actual hookup
         }
         this.setTasksPerHost();
-        App.router.get('installerController').saveInstalledHosts(this);
+        App.router.get(this.get('content.controllerName')).saveInstalledHosts(this);
         return true;
       }
     }
@@ -459,7 +455,7 @@ App.WizardStep9Controller = Em.Controller.extend({
      totalProgress = 0;
      }  */
     var tasksData = polledData.tasks;
-    console.log("The value of tasksData is: " + tasksData);
+    console.log("The value of tasksData is: ", tasksData);
     if (!tasksData) {
       console.log("Step9: ERROR: NO tasks availaible to process");
     }
@@ -525,7 +521,7 @@ App.WizardStep9Controller = Em.Controller.extend({
       dataType: 'text',
       success: function (data) {
         console.log("TRACE: In success function for the GET bootstrap call");
-        console.log("TRACE: STep9 -> The value is: " + jQuery.parseJSON(data));
+        console.log("TRACE: STep9 -> The value is: ", jQuery.parseJSON(data));
         var result = self.parseHostInfo(jQuery.parseJSON(data));
         if (result !== true) {
           window.setTimeout(function () {

+ 13 - 0
ambari-web/app/data/config_mapping.js

@@ -283,6 +283,7 @@ module.exports = [
     "value": "<templateName[0]>",
     "filename": "mapred-site.xml"
   },
+  /*
   {
     "name": "oozie.service.StoreService.jdbc.url",
     "templateName": ["oozie_data_dir"],
@@ -290,9 +291,11 @@ module.exports = [
     "value": "<templateName[0]>\/<foreignKey[0]>",
     "filename": "oozie-site.xml"
   },
+  */
   {
     "name": "oozie.base.url",
     "templateName": ["oozieserver_host"],
+    "foreignKey": null,
     "value": "http://<templateName[0]>:11000/oozie",
     "filename": "oozie-site.xml"
   },
@@ -300,21 +303,31 @@ module.exports = [
   {
     "name": "oozie.service.JPAService.jdbc.password",
     "templateName": [],
+    "foreignKey": null,
     "value": " ",
     "filename": "oozie-site.xml"
   },
   {
     "name": "oozie.db.schema.name",
     "templateName": [],
+    "foreignKey": null,
     "value": "oozie",
     "filename": "oozie-site.xml"
   },
   {
     "name": "oozie.service.JPAService.jdbc.url",
     "templateName": [],
+    "foreignKey": null,
     "value": "jdbc:derby:/var/data/oozie/oozie-db;create=true",
     "filename": "oozie-site.xml"
   },
+  {
+    "name": "oozie.action.ssh.http.command.post.options",
+    "templateName": [],
+    "foreignKey": null,
+    "value": " ",
+    "filename": "oozie-site.xml"
+  },
   {
     "name": "javax.jdo.option.ConnectionURL",
     "templateName": ["hive_mysql_host", "hive_database_name"],

+ 3 - 3
ambari-web/app/mappers/hosts_mapper.js

@@ -31,15 +31,15 @@ App.hostsMapper = App.QuickDataMapper.create({
     cpu : 'Hosts.cpu_count',
     memory : 'Hosts.total_mem',
     disk_info: 'Hosts.disk_info',
-    $disk_usage: '40',
+    $disk_usage: '-',
     $health_status: 'LIVE',
-    $load_avg: '0.2, 1.2, 2.4',
+    $load_avg: '-',
     $cpu_usage: 33,
     $memory_usage: 26,
     $network_usage: 36,
     $io_usage: 39,
     last_heart_beat_time : "Hosts.last_heartbeat_time",
-    os : 'Hosts.os_arch',
+    os_arch : 'Hosts.os_arch',
     os_type : 'Hosts.os_type',
     ip : 'Hosts.ip'
   }

+ 2 - 2
ambari-web/app/mappers/runs_mapper.js

@@ -24,7 +24,7 @@ App.runsMapper = App.QuickDataMapper.create({
     if(!this.get('model')) {
       return;
     }
-    if(json.workflows) {
+    if(json && json.workflows) {
       var result = [];
       json.workflows.forEach(function(item) {
         var o = this.parseIt(item, this.config);
@@ -41,6 +41,7 @@ App.runsMapper = App.QuickDataMapper.create({
         r = r.substr(0, r.length - 1);
         r += '}}';
         o.workflow_context = r;
+
         result.push(o);
       }, this);
       App.store.loadMany(this.get('model'), result);
@@ -49,7 +50,6 @@ App.runsMapper = App.QuickDataMapper.create({
   config : {
     id: 'workflowId',
     app_name: 'workflowName',
-    $type: 'Pig',
     num_jobs_total: 'numJobsTotal',
     num_jobs_completed: 'numJobsCompleted',
     user_name:'userName',

+ 1 - 1
ambari-web/app/mappers/server_data_mapper.js

@@ -95,7 +95,7 @@ App.QuickDataMapper = App.ServerDataMapper.extend({
   getJsonProperty: function (json, path) {
     var pathArr = path.split('.');
     var current = json;
-    while (pathArr.length) {
+    while (pathArr.length && current) {
       if (pathArr[0].substr(-1) == ']') {
         var index = parseInt(pathArr[0].substr(-2, 1));
         var attr = pathArr[0].substr(0, pathArr[0].length - 3);

+ 42 - 35
ambari-web/app/mappers/services_mapper.js

@@ -43,13 +43,13 @@ App.servicesMapper = App.QuickDataMapper.create({
     decommision_data_nodes: 'decommission_data_nodes',
     capacity_used: 'nameNodeComponent.ServiceComponentInfo.CapacityUsed',
     capacity_total: 'nameNodeComponent.ServiceComponentInfo.CapacityTotal',
-    ///// dfsTotalBlocks: 'nameNodeComponent.host_components[0].metrics.dfs.namenode.????',
-    ///// dfsCorruptBlocks: DS.attr('number'),
-    ///// dfsMissingBlocks: DS.attr('number'),
-    ///// dfsUnderReplicatedBlocks: DS.attr('number'),
-    ///// dfsTotalFiles: DS.attr('number'),
-    upgradeStatus: 'nameNodeComponent.ServiceComponentInfo.UpgradeFinalized',
-    safeModeStatus: 'nameNodeComponent.ServiceComponentInfo.Safemode'
+    dfs_total_blocks: 'nameNodeComponent.host_components[0].metrics.dfs.FSNamesystem.BlocksTotal',
+    dfs_corrupt_blocks: 'nameNodeComponent.host_components[0].metrics.dfs.FSNamesystem.CorruptBlocks',
+    dfs_missing_blocks: 'nameNodeComponent.host_components[0].metrics.dfs.FSNamesystem.MissingBlocks',
+    dfs_under_replicated_blocks: 'nameNodeComponent.host_components[0].metrics.dfs.FSNamesystem.UnderReplicatedBlocks',
+    dfs_total_files: 'nameNodeComponent.host_components[0].metrics.dfs.FSNamesystem.FilesTotal',
+    upgrade_status: 'nameNodeComponent.ServiceComponentInfo.UpgradeFinalized',
+    safe_mode_status: 'nameNodeComponent.ServiceComponentInfo.Safemode'
   },
   
   mapReduceConfig: {
@@ -63,17 +63,18 @@ App.servicesMapper = App.QuickDataMapper.create({
     black_list_trackers: 'black_list_trackers',
     gray_list_trackers: 'gray_list_trackers',
     map_slots: 'map_slots',
-    reduce_slots: 'reduce_slots'
-//    jobsSubmitted: DS.attr('number'),
-//    jobsCompleted: DS.attr('number'),
-//    mapSlotsOccupied: DS.attr('number'),
-//    mapSlotsReserved: DS.attr('number'),
-//    reduceSlotsOccupied: DS.attr('number'),
-//    reduceSlotsReserved: DS.attr('number'),
-//    mapsRunning: DS.attr('number'),
-//    mapsWaiting: DS.attr('number'),
-//    reducesRunning: DS.attr('number'),
-//    reducesWaiting: DS.attr('number')
+    reduce_slots: 'reduce_slots',
+    jobs_submitted: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.jobs_submitted',
+    jobs_completed: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.jobs_completed',
+    map_slots_occupied: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.occupied_map_slots',
+    map_slots_reserved: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.reserved_map_slots',
+    reduce_slots_occupied: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.occupied_reduce_slots',
+    reduce_slots_reserved: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.reserved_reduce_slots',
+    maps_running: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.running_maps',
+    maps_waiting: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.waiting_maps',
+    reduces_running: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.running_reduces',
+    reduces_waiting: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.waiting_reduces',
+    trackers_decommisioned: 'jobTrackerComponent.host_components[0].metrics.mapred.jobtracker.trackers_decommissioned'
   },
 
   model2: App.Component,
@@ -149,23 +150,29 @@ App.servicesMapper = App.QuickDataMapper.create({
                 item.alive_trackers = [];
                 item.gray_list_trackers = [];
                 item.black_list_trackers = [];
-                liveNodesJson.forEach(function(nj){
-                  item.alive_trackers.push(nj.hostname);
-                  if(nj.slots && nj.slots.map_slots)
-                    item.map_slots += nj.slots.map_slots;
-                  if(nj.slots && nj.slots.map_slots_used)
-                    item.map_slots_used += nj.slots.map_slots_used;
-                  if(nj.slots && nj.slots.reduce_slots)
-                    item.reduce_slots += nj.slots.reduce_slots;
-                  if(nj.slots && nj.slots.reduce_slots_used)
-                    item.reduce_slots_used += nj.slots.reduce_slots_used;
-                });
-                grayNodesJson.forEach(function(nj){
-                  item.gray_list_trackers.push(nj.hostname);
-                });
-                blackNodesJson.forEach(function(nj){
-                  item.black_list_trackers.push(nj.hostname);
-                });
+                if (liveNodesJson != null) {
+                  liveNodesJson.forEach(function(nj){
+                    item.alive_trackers.push(nj.hostname);
+                    if(nj.slots && nj.slots.map_slots)
+                      item.map_slots += nj.slots.map_slots;
+                    if(nj.slots && nj.slots.map_slots_used)
+                      item.map_slots_used += nj.slots.map_slots_used;
+                    if(nj.slots && nj.slots.reduce_slots)
+                      item.reduce_slots += nj.slots.reduce_slots;
+                    if(nj.slots && nj.slots.reduce_slots_used)
+                      item.reduce_slots_used += nj.slots.reduce_slots_used;
+                  });
+                }
+                if (grayNodesJson != null) {
+                  grayNodesJson.forEach(function(nj){
+                    item.gray_list_trackers.push(nj.hostname);
+                  });
+                }
+                if (blackNodesJson != null) {
+                  blackNodesJson.forEach(function(nj){
+                    item.black_list_trackers.push(nj.hostname);
+                  });
+                }
               }
               if (component.ServiceComponentInfo && component.ServiceComponentInfo.component_name == "TASKTRACKER") {
                 if(!item.task_trackers){

+ 2 - 2
ambari-web/app/mappers/users_mapper.js

@@ -21,7 +21,7 @@ App.usersMapper = App.QuickDataMapper.create({
   model : App.User,
   config : {
     user_name : 'Users.user_name',
-    roles : 'Users.roles'
+    roles : 'Users.roles',
+    type: 'Users.type'
   }
-
 });

+ 301 - 293
ambari-web/app/messages.js

@@ -18,246 +18,254 @@
 
 Em.I18n.translations = {
 
-  'app.name': 'Ambari',
-
-  'login.header': 'Sign in',
-  'login.username': 'Username',
-  'login.password': 'Password',
-  'login.loginButton': 'Sign in',
-  'login.error': 'Invalid username/password combination.',
-
-  'services.nagios.description': 'Nagios Monitoring and Alerting system',
-  'services.ganglia.description': 'Ganglia Metrics Collection system',
-  'services.hdfs.description': 'Apache Hadoop Distributed File System',
-  'services.mapreduce.description': 'Apache Hadoop Distributed Processing Framework',
-  'services.sqoop.description': 'Tool for transferring bulk data between Apache Hadoop and structured data stores such as relational databases',
-  'services.pig.description': 'Scripting platform for analyzing large datasets',
-  'services.hive.description': 'Data warehouse system for ad-hoc queries & analysis of large datasets and table & storage management service',
-  'services.oozie.description': 'System for workflow coordination and execution of Apache Hadoop jobs',
-  'services.zookeeper.description': 'ZooKeeper desc',
-  'services.hbase.description': 'Non-relational distributed database and centralized service for configuration management & synchronization',
-
-  'topnav.help.href': 'http://incubator.apache.org/ambari/install.html',
-
-  'installer.header': 'Cluster Install Wizard',
-  'installer.step1.header': 'Welcome',
-  'installer.step1.body.header': 'Welcome to Apache Ambari!',
-  'installer.step1.body': 'Ambari makes it easy to install, manage, and monitor Hadoop clusters.<br>' +
+  'app.name':'Ambari',
+
+  'login.header':'Sign in',
+  'login.username':'Username',
+  'login.password':'Password',
+  'login.loginButton':'Sign in',
+  'login.error':'Invalid username/password combination.',
+
+  'services.nagios.description':'Nagios Monitoring and Alerting system',
+  'services.ganglia.description':'Ganglia Metrics Collection system',
+  'services.hdfs.description':'Apache Hadoop Distributed File System',
+  'services.mapreduce.description':'Apache Hadoop Distributed Processing Framework',
+  'services.sqoop.description':'Tool for transferring bulk data between Apache Hadoop and structured data stores such as relational databases',
+  'services.pig.description':'Scripting platform for analyzing large datasets',
+  'services.hive.description':'Data warehouse system for ad-hoc queries & analysis of large datasets and table & storage management service',
+  'services.oozie.description':'System for workflow coordination and execution of Apache Hadoop jobs',
+  'services.zookeeper.description':'ZooKeeper desc',
+  'services.hbase.description':'Non-relational distributed database and centralized service for configuration management & synchronization',
+
+  'topnav.help.href':'http://incubator.apache.org/ambari/install.html',
+
+  'installer.header':'Cluster Install Wizard',
+  'installer.step1.header':'Welcome',
+  'installer.step1.body.header':'Welcome to Apache Ambari!',
+  'installer.step1.body':'Ambari makes it easy to install, manage, and monitor Hadoop clusters.<br>' +
     'We will walk you through the cluster installation process with this step-by-step wizard.',
-  'installer.step1.clusterName': 'Name your cluster',
-  'installer.step1.clusterName.tooltip.title': 'Cluster Name',
-  'installer.step1.clusterName.tooltip.content': 'Enter a unique cluster name. Cluster name cannot be changed later.',
-  'installer.step1.clusterName.error.required': 'Cluster Name is required',
-  'installer.step1.clusterName.error.whitespaces': 'Cluster Name cannot contain white spaces',
-  'installer.step1.clusterName.error.specialChar': 'Cluster Name cannot contain special characters',
-
-  'installer.step2.header': 'Install Options',
-  'installer.step2.body': 'Enter the list of hosts to be included in the cluster, provide your SSH key, and optionally specify a local repository.',
-  'installer.step2.targetHosts': 'Target Hosts',
-  'installer.step2.targetHosts.info': 'Enter a list of host names, one per line',
-  'installer.step2.hostPattern.tooltip.title': 'Pattern Expressions',
-  'installer.step2.hostPattern.tooltip.content': 'You can use pattern expressions to specify a number of target hosts.  Explain brackets.',
-  'installer.step2.hostName.error.required': 'You must specify at least one host name',
-  'installer.step2.hostName.error.notRequired': 'Host Names will be ignored if not using SSH to automatically configure hosts',
-  'installer.step2.hostName.error.invalid': 'Invalid Host Name(s) - cannot start or end with a hyphen',
-  'installer.step2.sshKey': 'Host Connectivity Information',
-  'installer.step2.sshKey.info': 'Provide your SSH Private Key (<b>id_rsa</b> for <b>root</b>)',
-  'installer.step2.sshKey.error.required': 'SSH Private Key is required',
-  'installer.step2.passphrase.error.match': 'Passphrases do not match',
-  'installer.step2.manualInstall.label': 'Do not use SSH to automatically configure hosts ',
-  'installer.step2.manualInstall.info': 'By not using SSH to connect to the target hosts, you must manually install and start the ' +
+  'installer.step1.clusterName':'Name your cluster',
+  'installer.step1.clusterName.tooltip.title':'Cluster Name',
+  'installer.step1.clusterName.tooltip.content':'Enter a unique cluster name. Cluster name cannot be changed later.',
+  'installer.step1.clusterName.error.required':'Cluster Name is required',
+  'installer.step1.clusterName.error.whitespaces':'Cluster Name cannot contain white spaces',
+  'installer.step1.clusterName.error.specialChar':'Cluster Name cannot contain special characters',
+
+  'installer.step2.header':'Install Options',
+  'installer.step2.body':'Enter the list of hosts to be included in the cluster, provide your SSH key, and optionally specify a local repository.',
+  'installer.step2.targetHosts':'Target Hosts',
+  'installer.step2.targetHosts.info':'Enter a list of host names, one per line',
+  'installer.step2.hostPattern.tooltip.title':'Pattern Expressions',
+  'installer.step2.hostPattern.tooltip.content':'You can use pattern expressions to specify a number of target hosts.  Explain brackets.',
+  'installer.step2.hostName.error.required':'You must specify at least one host name',
+  'installer.step2.hostName.error.notRequired':'Host Names will be ignored if not using SSH to automatically configure hosts',
+  'installer.step2.hostName.error.invalid':'Invalid Host Name(s) - cannot start or end with a hyphen',
+  'installer.step2.sshKey':'Host Connectivity Information',
+  'installer.step2.sshKey.info':'Provide your SSH Private Key (<b>id_rsa</b> for <b>root</b>)',
+  'installer.step2.sshKey.error.required':'SSH Private Key is required',
+  'installer.step2.passphrase.error.match':'Passphrases do not match',
+  'installer.step2.manualInstall.label':'Do not use SSH to automatically configure hosts ',
+  'installer.step2.manualInstall.info':'By not using SSH to connect to the target hosts, you must manually install and start the ' +
     'Ambari Agent on each host in order for the wizard to perform the necessary configurations and software installs.',
-  'installer.step2.advancedOption': 'Advanced Options',
-  'installer.step2.repoConf': 'Software Repository Configuration File Path',
-  'installer.step2.localRepo.header': 'Software Repository',
-  'installer.step2.localRepo.label': 'Use a local software repository',
-  'installer.step2.localRepo.error.required': 'Local repository file path is required',
-  'installer.step2.localRepo.info': 'The repository configuration file should be installed on each host in your cluster. ' +
+  'installer.step2.advancedOption':'Advanced Options',
+  'installer.step2.repoConf':'Software Repository Configuration File Path',
+  'installer.step2.localRepo.header':'Software Repository',
+  'installer.step2.localRepo.label':'Use a local software repository',
+  'installer.step2.localRepo.error.required':'Local repository file path is required',
+  'installer.step2.localRepo.info':'The repository configuration file should be installed on each host in your cluster. ' +
     'This file instructs the package manager to use your local software repository to retrieve software packages, instead of ' +
     'downloading them from the internet.',
-  'installer.step2.localRepo.tooltip.title': 'Local Software Repository',
-  'installer.step2.localRepo.tooltip.content': 'The repository configuration file should be installed on each host ' +
+  'installer.step2.localRepo.tooltip.title':'Local Software Repository',
+  'installer.step2.localRepo.tooltip.content':'The repository configuration file should be installed on each host ' +
     'in your cluster. This file instructs package manager to use your local' +
     'software repository to retrieve software packages, instead of using the internet.',
-  'installer.step2.manualInstall.tooltip.title': 'Not Using SSH (Manual Install)',
-  'installer.step2.manualInstall.tooltip.content': 'If you do not wish Ambari to automatically configure the target hosts via SSH,' +
+  'installer.step2.manualInstall.tooltip.title':'Not Using SSH (Manual Install)',
+  'installer.step2.manualInstall.tooltip.content':'If you do not wish Ambari to automatically configure the target hosts via SSH,' +
     ' you have the option of configuring them yourself.  This involves installing and starting Ambari Agent on each of your target hosts.',
-  'installer.step2.manualInstall.popup.header': 'Before You Proceed',
-  'installer.step2.manualInstall.popup.body': 'You must install Ambari Agents on each host you want to manage before you proceed.  <a href="#" target="_blank">Learn more</a>',
+  'installer.step2.manualInstall.popup.header':'Before You Proceed',
+  'installer.step2.manualInstall.popup.body':'You must install Ambari Agents on each host you want to manage before you proceed.  <a href="#" target="_blank">Learn more</a>',
 
-  'installer.step3.header': 'Confirm Hosts',
-  'installer.step3.body': 'Here are the results of the host discovery process.<br>' +
+  'installer.step3.header':'Confirm Hosts',
+  'installer.step3.body':'Here are the results of the host discovery process.<br>' +
     'Please verify and remove the ones that you do not want to be part of the cluster.',
-  'installer.step3.hostLog.popup.header': 'Log file for the host',
-  'installer.step3.hostLog.popup.body': 'Placeholder for the log file',
-  'installer.step3.hosts.remove.popup.header': 'Remove Hosts',
-  'installer.step3.hosts.remove.popup.body': 'Are you sure you want to remove the selected host(s)?',
-  'installer.step3.hosts.retry.popup.header': 'Retry Host Discovery',
-  'installer.step3.hosts.retry.popup.body': 'Are you sure you want to retry discovery of the selected host(s)?',
-
-  'installer.step4.header': 'Choose Services',
-  'installer.step4.body': 'Choose which services you want to install on your cluster.<br>Note that some services have dependencies (e.g., HBase requires ZooKeeper.)',
-  'installer.step4.mapreduceCheck.popup.header': 'MapReduce Needed',
-  'installer.step4.mapreduceCheck.popup.body': 'You did not select MapReduce, but it is needed by other services you selected.  We will automatically add MapReduce.  Is this OK?',
-  'installer.step4.monitoringCheck.popup.header': 'Limited Functionality Warning',
-  'installer.step4.monitoringCheck.popup.body': 'You did not select Nagios and/or Ganglia.  If both are not selected, monitoring and alerts will not function properly.  Is this OK?',
-
-  'installer.step5.header': 'Assign Masters',
-  'installer.step5.attention': ' hosts not running master services',
-  'installer.step5.body': 'Assign master components to hosts you want to run them on.',
-
-  'installer.step6.header': 'Assign Slaves and Clients',
-  'installer.step6.body': 'Assign slave and client components to hosts you want to run them on. <br/>Client component will install ',
-  'installer.step6.error.mustSelectOne': 'You must assign at least one host to each.',
-
-  'installer.step7.header': 'Customize Services',
-  'installer.step7.body': 'We have come up with recommended configurations for the services you selected.  Customize them as you see fit.',
-  'installer.step7.attentionNeeded': '<strong>Attention:</strong> Some configurations need your attention before you can proceed.',
-
-  'installer.step8.header': 'Review',
-  'installer.step8.body': 'Please review the cluster configuration before installation',
-
-  'installer.step9.header': 'Install, Start and Test',
-  'installer.step9.body': 'Please wait while the selected services are installed, started, and tested on your new cluster.',
-  'installer.step9.status.success': 'Successfully installed the cluster',
-  'installer.step9.status.failed': 'Failure in installation',
-  'installer.step9.host.status.success': 'Success',
-  'installer.step9.host.status.warning': 'Warnings encountered',
-  'installer.step9.host.status.failed': 'Failures encountered',
-  'installer.step9.hostLog.popup.header': 'Tasks executed on ',
-
-  'installer.step10.header': 'Summary',
-  'installer.step10.body': 'Here is the summary of the cluster install process.',
-
-
-  'form.create': 'Create',
-  'form.save': 'Save',
-  'form.cancel': 'Cancel',
-  'form.password': 'Password',
-  'form.passwordRetype': 'Retype Password',
-  'form.saveSuccess': 'Successfully saved.',
-  'form.saveError': 'Sorry, errors occured.',
-
-  'form.validator.invalidIp': 'Please enter valid ip address',
-
-  'admin.advanced.title': 'Advanced',
-  'admin.advanced.caution': 'This section is for advanced user only.<br/>Proceed with caution.',
-  'admin.advanced.button.uninstallIncludingData': 'Uninstall cluster including all data.',
-  'admin.advanced.button.uninstallKeepData': 'Uninstall cluster but keep data.',
-
-  'admin.advanced.popup.header': 'Uninstall Cluster',
+  'installer.step3.hostLog.popup.header':'Log file for the host',
+  'installer.step3.hostLog.popup.body':'Placeholder for the log file',
+  'installer.step3.hosts.remove.popup.header':'Remove Hosts',
+  'installer.step3.hosts.remove.popup.body':'Are you sure you want to remove the selected host(s)?',
+  'installer.step3.hosts.retry.popup.header':'Retry Host Discovery',
+  'installer.step3.hosts.retry.popup.body':'Are you sure you want to retry discovery of the selected host(s)?',
+
+  'installer.step4.header':'Choose Services',
+  'installer.step4.body':'Choose which services you want to install on your cluster.<br>Note that some services have dependencies (e.g., HBase requires ZooKeeper.)',
+  'installer.step4.mapreduceCheck.popup.header':'MapReduce Needed',
+  'installer.step4.mapreduceCheck.popup.body':'You did not select MapReduce, but it is needed by other services you selected.  We will automatically add MapReduce.  Is this OK?',
+  'installer.step4.monitoringCheck.popup.header':'Limited Functionality Warning',
+  'installer.step4.monitoringCheck.popup.body':'You did not select Nagios and/or Ganglia.  If both are not selected, monitoring and alerts will not function properly.  Is this OK?',
+
+  'installer.step5.header':'Assign Masters',
+  'installer.step5.attention':' hosts not running master services',
+  'installer.step5.body':'Assign master components to hosts you want to run them on.',
+
+  'installer.step6.header':'Assign Slaves and Clients',
+  'installer.step6.body':'Assign slave and client components to hosts you want to run them on. <br/>Client component will install ',
+  'installer.step6.error.mustSelectOne':'You must assign at least one host to each.',
+
+  'installer.step7.header':'Customize Services',
+  'installer.step7.body':'We have come up with recommended configurations for the services you selected.  Customize them as you see fit.',
+  'installer.step7.attentionNeeded':'<strong>Attention:</strong> Some configurations need your attention before you can proceed.',
+
+  'installer.step8.header':'Review',
+  'installer.step8.body':'Please review the cluster configuration before installation',
+
+  'installer.step9.header':'Install, Start and Test',
+  'installer.step9.body':'Please wait while the selected services are installed, started, and tested on your new cluster.',
+  'installer.step9.status.success':'Successfully installed the cluster',
+  'installer.step9.status.failed':'Failure in installation',
+  'installer.step9.host.status.success':'Success',
+  'installer.step9.host.status.warning':'Warnings encountered',
+  'installer.step9.host.status.failed':'Failures encountered',
+  'installer.step9.hostLog.popup.header':'Tasks executed on ',
+
+  'installer.step10.header':'Summary',
+  'installer.step10.body':'Here is the summary of the cluster install process.',
+
+
+  'form.create':'Create',
+  'form.save':'Save',
+  'form.cancel':'Cancel',
+  'form.password':'Password',
+  'form.passwordRetype':'Retype Password',
+  'form.saveSuccess':'Successfully saved.',
+  'form.saveError':'Sorry, errors occured.',
+
+  'form.validator.invalidIp':'Please enter valid ip address',
+
+  'admin.advanced.title':'Advanced',
+  'admin.advanced.caution':'This section is for advanced user only.<br/>Proceed with caution.',
+  'admin.advanced.button.uninstallIncludingData':'Uninstall cluster including all data.',
+  'admin.advanced.button.uninstallKeepData':'Uninstall cluster but keep data.',
+
+  'admin.advanced.popup.header':'Uninstall Cluster',
 
   /*'admin.advanced.popup.text':'Uninstall Cluster',*/
 
-  'admin.audit.grid.date': "Date/Time",
-  'admin.audit.grid.category': "Category",
-  'admin.audit.grid.operationName': "Operation",
-  'admin.audit.grid.performedBy': "Performed By",
-  'admin.audit.grid.service': "Category",
-
-  'admin.authentication.form.method.database': 'Use Ambari Database to authenticate users',
-  'admin.authentication.form.method.ldap': 'Use LDAP/Active Directory to authenticate',
-  'admin.authentication.form.primaryServer': 'Primary Server',
-  'admin.authentication.form.secondaryServer': 'Secondary Server',
-  'admin.authentication.form.useSsl': 'Use SSL',
-  'admin.authentication.form.bind.anonymously': "Bind Anonymously",
-  'admin.authentication.form.bind.useCrenedtials': "Use Credentials To Bind",
-  'admin.authentication.form.bindUserDN': 'Bind User DN',
-  'admin.authentication.form.searchBaseDN': 'Search Base DN',
-  'admin.authentication.form.usernameAttribute': 'Username Attribute',
-
-  'admin.authentication.form.userDN': 'User DN',
-  'admin.authentication.form.password': 'Password',
-  'admin.authentication.form.configurationTest': 'Configuration Test',
-  'admin.authentication.form.testConfiguration': 'Test Configuration',
-
-  'admin.authentication.form.test.success': 'The configuration passes the test',
-  'admin.authentication.form.test.fail': 'The configuration fails the test',
-
-  'admin.security.title': 'Kerberos Security has not been enabled on this cluster.',
-  'admin.security.button.enable': 'Enable Kerberos Security on this cluster',
-
-  'admin.users.ldapAuthentionUsed': 'LDAP Authentication is being used to authenticate users',
-  'admin.users.deleteYourselfMessage': 'You can\'t delete yourself',
-  'admin.users.addButton': 'Add User',
-  'admin.users.delete': 'delete',
-  'admin.users.edit': 'edit',
-  'admin.users.privileges': 'Admin',
-  'admin.users.password': 'Password',
-  'admin.users.passwordRetype': 'Retype Password',
-  'admin.users.username': 'Username',
-
-  'question.sure': 'Are you sure?',
-
-  'services.service.start': 'Start',
-  'services.service.stop': 'Stop',
-  'services.service.confirmation.header': 'Confirmation',
-  'services.service.confirmation.body': 'Are you sure?',
-  'services.service.summary.version': 'Version',
-  'services.service.summary.nameNode': 'NameNode Web UI',
-  'services.service.summary.nameNodeUptime': 'NameNode Uptime',
-  'services.service.summary.nameNodeHeap': 'NameNode Heap',
-  'services.service.summary.pendingUpgradeStatus': 'Upgrade Status',
-  'services.service.summary.safeModeStatus': 'Safe Mode Status',
-  'services.service.summary.dataNodes': 'DataNodes',
-  'services.service.summary.diskCapacity': 'HDFS Disk Capacity',
-  'services.service.summary.blocksTotal': 'Blocks (total)',
-  'services.service.summary.blockErrors': 'Block Errors',
-  'services.service.summary.totalFiles': 'Total Files + Dirs',
-  'services.service.summary.jobTracker': 'JobTracker',
-  'services.service.summary.jobTrackerWebUI': 'JobTracker Web UI',
-  'services.service.summary.jobTrackerUptime': 'JobTracker Uptime',
-  'services.service.summary.trackersLiveTotal': 'Trackers',
-  'services.service.summary.trackersBlacklistGraylist': 'Trackers',
-  'services.service.summary.jobTrackerHeap': 'JobTracker Heap',
-  'services.service.summary.totalSlotsCapacity': 'Total Slots Capacity',
-  'services.service.summary.totalJobs': 'Total Jobs',
-  'services.service.summary.currentSlotUtiliMaps': 'Map Slots',
-  'services.service.summary.currentSlotUtiliReduces': 'Reduce Slots',
-  'services.service.summary.tasksMaps': 'Tasks: Maps',
-  'services.service.summary.tasksReduces': 'Tasks: Reduces',
-  'services.service.summary.hbaseMaster': 'HBase Master Web UI',
-  'services.service.summary.regionServerCount': 'Region Server Count',
-  'services.service.summary.regionInTransition': 'Region In Transition',
-  'services.service.summary.masterStarted': 'Master Started',
-  'services.service.summary.masterActivated': 'Master Activated',
-  'services.service.summary.averageLoad': 'Average Load',
-  'services.service.summary.masterHeap': 'Master Heap',
-  'services.service.summary.moreStats': 'more stats here',
-  'services.service.actions.run.rebalancer': 'Run Rebalancer',
-  'services.service.actions.run.compaction': 'Run Compaction',
-  'services.service.actions.run.smoke': 'Run Smoke Test',
-  'services.service.actions.maintenance': 'Maintenance',
-
-  'services.add.header': 'Add Service Wizard',
-
-  'host.singular': 'host',
-  'host.plural': 'hosts',
-
-  'hosts.host.start.popup.header': 'Confirmation',
-  'hosts.host.stop.popup.header': 'Confirmation',
-  'hosts.host.start.popup.body': 'Are you sure?',
-  'hosts.host.stop.popup.body': 'Are you sure?',
-  'hosts.assignedToRack.popup.body': 'Are you sure?',
-  'hosts.assignedToRack.popup.header': 'Confirmation',
-  'hosts.decommission.popup.body': 'Are you sure?',
-  'hosts.decommission.popup.header': 'Confirmation',
-  'hosts.delete.popup.body': 'Are you sure?',
-  'hosts.delete.popup.header': 'Confirmation',
-  'hosts.cant.do.popup.header': 'Operation not allowed',
-  'hosts.cant.do.popup.masterList.body': 'You cannot delete this host because it is hosting following master services: {0}.',
-  'hosts.cant.do.popup.workingList.body': 'You cannot delete this host because following slave services are not fully stopped or decommissioned: {0}.',
-  'hosts.assignToRack.sure': 'Sure you want to assign {0} to {1}?',
-  'hosts.add.header': 'Add Host Wizard',
-  'hosts.add.step2.warning': 'Hosts are already part of the cluster and will be ignored',
-  'hosts.assignRack': 'Assign Rack',
-
-  'charts.horizon.chart.showText': 'show',
-  'charts.horizon.chart.hideText': 'hide',
-  'charts.horizon.chart.attributes.cpu': 'CPU',
-  'charts.horizon.chart.attributes.memory': 'Memory',
-  'charts.horizon.chart.attributes.network': 'Network',
-  'charts.horizon.chart.attributes.io': 'I/O',
+  'admin.audit.grid.date':"Date/Time",
+  'admin.audit.grid.category':"Category",
+  'admin.audit.grid.operationName':"Operation",
+  'admin.audit.grid.performedBy':"Performed By",
+  'admin.audit.grid.service':"Category",
+
+  'admin.authentication.form.method.database':'Use Ambari Database to authenticate users',
+  'admin.authentication.form.method.ldap':'Use LDAP/Active Directory to authenticate',
+  'admin.authentication.form.primaryServer':'Primary Server',
+  'admin.authentication.form.secondaryServer':'Secondary Server',
+  'admin.authentication.form.useSsl':'Use SSL',
+  'admin.authentication.form.bind.anonymously':"Bind Anonymously",
+  'admin.authentication.form.bind.useCrenedtials':"Use Credentials To Bind",
+  'admin.authentication.form.bindUserDN':'Bind User DN',
+  'admin.authentication.form.searchBaseDN':'Search Base DN',
+  'admin.authentication.form.usernameAttribute':'Username Attribute',
+
+  'admin.authentication.form.userDN':'User DN',
+  'admin.authentication.form.password':'Password',
+  'admin.authentication.form.configurationTest':'Configuration Test',
+  'admin.authentication.form.testConfiguration':'Test Configuration',
+
+  'admin.authentication.form.test.success':'The configuration passes the test',
+  'admin.authentication.form.test.fail':'The configuration fails the test',
+
+  'admin.security.title':'Kerberos Security has not been enabled on this cluster.',
+  'admin.security.button.enable':'Enable Kerberos Security on this cluster',
+
+  'admin.users.ldapAuthentionUsed':'LDAP Authentication is being used to authenticate users',
+  'admin.users.delete.yourself.message':'You can\'t delete yourself',
+  'admin.users.delete.yourself.header':'Deleting warning',
+
+  'admin.users.delete.header':'Delete {0}',
+
+  'admin.users.addButton':'Add Local User',
+  'admin.users.delete':'delete',
+  'admin.users.edit':'edit',
+  'admin.users.privileges':'Admin',
+  'admin.users.type':'Type',
+  'admin.users.action':'Action',
+  'admin.users.password':'Password',
+  'admin.users.passwordRetype':'Retype Password',
+  'admin.users.username':'Username',
+
+  'question.sure':'Are you sure?',
+  'yes':'Yes',
+  'no':'No',
+
+  'services.service.start':'Start',
+  'services.service.stop':'Stop',
+  'services.service.confirmation.header':'Confirmation',
+  'services.service.confirmation.body':'Are you sure?',
+  'services.service.summary.version':'Version',
+  'services.service.summary.nameNode':'NameNode Web UI',
+  'services.service.summary.nameNodeUptime':'NameNode Uptime',
+  'services.service.summary.nameNodeHeap':'NameNode Heap',
+  'services.service.summary.pendingUpgradeStatus':'Upgrade Status',
+  'services.service.summary.safeModeStatus':'Safe Mode Status',
+  'services.service.summary.dataNodes':'DataNodes',
+  'services.service.summary.diskCapacity':'HDFS Disk Capacity',
+  'services.service.summary.blocksTotal':'Blocks (total)',
+  'services.service.summary.blockErrors':'Block Errors',
+  'services.service.summary.totalFiles':'Total Files + Dirs',
+  'services.service.summary.jobTracker':'JobTracker',
+  'services.service.summary.jobTrackerWebUI':'JobTracker Web UI',
+  'services.service.summary.jobTrackerUptime':'JobTracker Uptime',
+  'services.service.summary.trackersLiveTotal':'Trackers',
+  'services.service.summary.trackersBlacklistGraylist':'Trackers',
+  'services.service.summary.jobTrackerHeap':'JobTracker Heap',
+  'services.service.summary.totalSlotsCapacity':'Total Slots Capacity',
+  'services.service.summary.totalJobs':'Total Jobs',
+  'services.service.summary.currentSlotUtiliMaps':'Map Slots',
+  'services.service.summary.currentSlotUtiliReduces':'Reduce Slots',
+  'services.service.summary.tasksMaps':'Tasks: Maps',
+  'services.service.summary.tasksReduces':'Tasks: Reduces',
+  'services.service.summary.hbaseMaster':'HBase Master Web UI',
+  'services.service.summary.regionServerCount':'Region Server Count',
+  'services.service.summary.regionInTransition':'Region In Transition',
+  'services.service.summary.masterStarted':'Master Started',
+  'services.service.summary.masterActivated':'Master Activated',
+  'services.service.summary.averageLoad':'Average Load',
+  'services.service.summary.masterHeap':'Master Heap',
+  'services.service.summary.moreStats':'more stats here',
+  'services.service.actions.run.rebalancer':'Run Rebalancer',
+  'services.service.actions.run.compaction':'Run Compaction',
+  'services.service.actions.run.smoke':'Run Smoke Test',
+  'services.service.actions.maintenance':'Maintenance',
+
+  'services.add.header':'Add Service Wizard',
+
+  'host.singular':'host',
+  'host.plural':'hosts',
+
+  'hosts.host.start.popup.header':'Confirmation',
+  'hosts.host.stop.popup.header':'Confirmation',
+  'hosts.host.start.popup.body':'Are you sure?',
+  'hosts.host.stop.popup.body':'Are you sure?',
+  'hosts.assignedToRack.popup.body':'Are you sure?',
+  'hosts.assignedToRack.popup.header':'Confirmation',
+  'hosts.decommission.popup.body':'Are you sure?',
+  'hosts.decommission.popup.header':'Confirmation',
+  'hosts.delete.popup.body':'Are you sure?',
+  'hosts.delete.popup.header':'Confirmation',
+  'hosts.cant.do.popup.header':'Operation not allowed',
+  'hosts.cant.do.popup.masterList.body':'You cannot delete this host because it is hosting following master services: {0}.',
+  'hosts.cant.do.popup.workingList.body':'You cannot delete this host because following slave services are not fully stopped or decommissioned: {0}.',
+  'hosts.assignToRack.sure':'Sure you want to assign {0} to {1}?',
+  'hosts.add.header':'Add Host Wizard',
+  'hosts.add.step2.warning':'Hosts are already part of the cluster and will be ignored',
+  'hosts.assignRack':'Assign Rack',
+
+  'charts.horizon.chart.showText':'show',
+  'charts.horizon.chart.hideText':'hide',
+  'charts.horizon.chart.attributes.cpu':'CPU',
+  'charts.horizon.chart.attributes.memory':'Memory',
+  'charts.horizon.chart.attributes.network':'Network',
+  'charts.horizon.chart.attributes.io':'I/O',
 
   'metric.default':'combined',
   'metric.cpu':'cpu',
@@ -266,70 +274,70 @@ Em.I18n.translations = {
   'metric.io':'io',
   'metric.more':'more',
   'metric.more.cpu':'CPU',
-  'metric.more.disk': 'Disk',
-  'metric.more.load': 'Load',
+  'metric.more.disk':'Disk',
+  'metric.more.load':'Load',
   'metric.more.memory':'Memory',
-  'metric.more.network': 'Network',
-  'metric.more.process': 'Process',
-
-  'dashboard.services': 'Services',
-  'dashboard.services.hosts': 'Hosts',
-  'dashboard.services.uptime': '{0} days {1} hrs {2} mins',
-  'dashboard.services.hdfs.summary': '{0} of {1} nodes live, {2}% capacity free',
-  'dashboard.services.hdfs.nanmenode': 'NameNode',
-  'dashboard.services.hdfs.snanmenode': 'Secondary NameNode',
-  'dashboard.services.hdfs.capacity': 'HDFS Disk Capacity',
-  'dashboard.services.hdfs.capacityUsed': '{0} / {1} ({2}% used)',
-  'dashboard.services.hdfs.totalFilesAndDirs': 'Total Files + Directories',
-  'dashboard.services.hdfs.datanodes': 'DataNodes',
-  'dashboard.services.hdfs.datanodecounts': 'DataNodes Status',
-  'dashboard.services.hdfs.version': 'Version',
-  'dashboard.services.hdfs.nameNodeWebUI': 'NameNode Web UI',
-  'dashboard.services.hdfs.nodes.live': 'live',
-  'dashboard.services.hdfs.nodes.dead': 'dead',
-  'dashboard.services.hdfs.nodes.decom': 'decom',
-  'dashboard.services.hdfs.nodes.uptime': 'NameNode Uptime',
-  'dashboard.services.hdfs.nodes.heap': 'NameNode Heap',
-  'dashboard.services.hdfs.nodes.heapUsed': '{0} / {1} ({2}% used)',
-  'dashboard.services.hdfs.chart.label': 'Capacity (Free/Used)',
-
-  'dashboard.services.mapreduce.summary': '{0} of {1} trackers live, {2} jobs running, {3} jobs waiting',
-  'dashboard.services.mapreduce.taskTrackers': 'TaskTrackers',
-  'dashboard.services.mapreduce.taskTrackerCounts': 'TaskTrackers Status',
-  'dashboard.services.mapreduce.trackers': 'Trackers',
-  'dashboard.services.mapreduce.nodes.blacklist': 'blacklist',
-  'dashboard.services.mapreduce.nodes.graylist': 'graylist',
-  'dashboard.services.mapreduce.slotCapacity': 'Total Slots Capacity',
-  'dashboard.services.mapreduce.trackersSummary': '{0} live / {1} total',
-  'dashboard.services.mapreduce.jobs': 'Total Jobs',
-  'dashboard.services.mapreduce.jobsSummary': '{0} submitted / {1} completed',
-  'dashboard.services.mapreduce.mapSlots': 'Map Slots',
-  'dashboard.services.mapreduce.mapSlotsSummary': '{0} occuped / {1} reserved',
-  'dashboard.services.mapreduce.reduceSlots': 'Reduce Slots',
-  'dashboard.services.mapreduce.tasks.maps': 'Tasks: Maps',
-  'dashboard.services.mapreduce.tasks.reduces': 'Tasks: Reduces',
-  'dashboard.services.mapreduce.reduceSlotsSummary': '{0} occuped / {1} reserved',
-  'dashboard.services.mapreduce.tasksSummary': '{0} running / {1} waiting',
-  'dashboard.services.mapreduce.slotCapacitySummary': '{0} maps / {1} reduces / {2} avg per node',
-  'dashboard.services.mapreduce.jobTrackerHeap': 'JobTracker Heap',
-  'dashboard.services.mapreduce.jobTrackerHeapSummary': '{0} of {1} ({2}% used)',
-  'dashboard.services.mapreduce.jobTrackerUptime': 'Job Trackers Uptime',
-  'dashboard.services.mapreduce.chart.label': 'Jobs Running',
-
-  'dashboard.services.hbase.summary': '{0} of {1} region servers up, {2} average load',
-  'dashboard.services.hbase.masterServerHeap': 'Master Server Heap',
-  'dashboard.services.hbase.masterServerHeap.summary': '{0} of {1} ({2}% used)',
-  'dashboard.services.hbase.masterServerUptime': 'Master Server Uptime',
-  'dashboard.services.hbase.averageLoad': 'Average Load',
-  'dashboard.services.hbase.regionServers': 'Region Servers',
-  'dashboard.services.hbase.regionServersSummary': '{0} live / {1} total',
-  'dashboard.services.hbase.chart.label': 'Request Count',
-
-
-  'timeRange.presets.1hour': '1h',
-  'timeRange.presets.12hour': '12h',
-  'timeRange.presets.1day': '1d',
-  'timeRange.presets.1week': '1wk',
-  'timeRange.presets.1month': '1mo',
-  'timeRange.presets.1year': '1yr'
+  'metric.more.network':'Network',
+  'metric.more.process':'Process',
+
+  'dashboard.services':'Services',
+  'dashboard.services.hosts':'Hosts',
+  'dashboard.services.uptime':'{0} days {1} hrs {2} mins',
+  'dashboard.services.hdfs.summary':'{0} of {1} nodes live, {2}% capacity free',
+  'dashboard.services.hdfs.nanmenode':'NameNode',
+  'dashboard.services.hdfs.snanmenode':'Secondary NameNode',
+  'dashboard.services.hdfs.capacity':'HDFS Disk Capacity',
+  'dashboard.services.hdfs.capacityUsed':'{0} / {1} ({2}% used)',
+  'dashboard.services.hdfs.totalFilesAndDirs':'Total Files + Directories',
+  'dashboard.services.hdfs.datanodes':'DataNodes',
+  'dashboard.services.hdfs.datanodecounts':'DataNodes Status',
+  'dashboard.services.hdfs.version':'Version',
+  'dashboard.services.hdfs.nameNodeWebUI':'NameNode Web UI',
+  'dashboard.services.hdfs.nodes.live':'live',
+  'dashboard.services.hdfs.nodes.dead':'dead',
+  'dashboard.services.hdfs.nodes.decom':'decom',
+  'dashboard.services.hdfs.nodes.uptime':'NameNode Uptime',
+  'dashboard.services.hdfs.nodes.heap':'NameNode Heap',
+  'dashboard.services.hdfs.nodes.heapUsed':'{0} / {1} ({2}% used)',
+  'dashboard.services.hdfs.chart.label':'Capacity (Free/Used)',
+
+  'dashboard.services.mapreduce.summary':'{0} of {1} trackers live, {2} jobs running, {3} jobs waiting',
+  'dashboard.services.mapreduce.taskTrackers':'TaskTrackers',
+  'dashboard.services.mapreduce.taskTrackerCounts':'TaskTrackers Status',
+  'dashboard.services.mapreduce.trackers':'Trackers',
+  'dashboard.services.mapreduce.nodes.blacklist':'blacklist',
+  'dashboard.services.mapreduce.nodes.graylist':'graylist',
+  'dashboard.services.mapreduce.slotCapacity':'Total Slots Capacity',
+  'dashboard.services.mapreduce.trackersSummary':'{0} live / {1} total',
+  'dashboard.services.mapreduce.jobs':'Total Jobs',
+  'dashboard.services.mapreduce.jobsSummary':'{0} submitted / {1} completed',
+  'dashboard.services.mapreduce.mapSlots':'Map Slots',
+  'dashboard.services.mapreduce.mapSlotsSummary':'{0} occupied / {1} reserved',
+  'dashboard.services.mapreduce.reduceSlots':'Reduce Slots',
+  'dashboard.services.mapreduce.tasks.maps':'Tasks: Maps',
+  'dashboard.services.mapreduce.tasks.reduces':'Tasks: Reduces',
+  'dashboard.services.mapreduce.reduceSlotsSummary':'{0} occuped / {1} reserved',
+  'dashboard.services.mapreduce.tasksSummary':'{0} running / {1} waiting',
+  'dashboard.services.mapreduce.slotCapacitySummary':'{0} maps / {1} reduces / {2} avg per node',
+  'dashboard.services.mapreduce.jobTrackerHeap':'JobTracker Heap',
+  'dashboard.services.mapreduce.jobTrackerHeapSummary':'{0} of {1} ({2}% used)',
+  'dashboard.services.mapreduce.jobTrackerUptime':'Job Trackers Uptime',
+  'dashboard.services.mapreduce.chart.label':'Jobs Running',
+
+  'dashboard.services.hbase.summary':'{0} of {1} region servers up, {2} average load',
+  'dashboard.services.hbase.masterServerHeap':'Master Server Heap',
+  'dashboard.services.hbase.masterServerHeap.summary':'{0} of {1} ({2}% used)',
+  'dashboard.services.hbase.masterServerUptime':'Master Server Uptime',
+  'dashboard.services.hbase.averageLoad':'Average Load',
+  'dashboard.services.hbase.regionServers':'Region Servers',
+  'dashboard.services.hbase.regionServersSummary':'{0} live / {1} total',
+  'dashboard.services.hbase.chart.label':'Request Count',
+
+
+  'timeRange.presets.1hour':'1h',
+  'timeRange.presets.12hour':'12h',
+  'timeRange.presets.1day':'1d',
+  'timeRange.presets.1week':'1wk',
+  'timeRange.presets.1month':'1mo',
+  'timeRange.presets.1year':'1yr'
 };

+ 78 - 44
ambari-web/app/models/form.js

@@ -23,30 +23,35 @@ App.Form = Em.View.extend({
   /**
    * generating fields from fieldsOptions
    */
-  classNames: ["form-horizontal"],
-  i18nprefix: 'form.',
-  fields: [],
-  field: {},
-  messages: [],
-  object: false,
-  result: 0, // save result var (-1 - error; 0 - init; 1 - success)
-  templateName: require('templates/common/form'),
-  tagName: 'form',
-
-  init: function () {
-    this._super();
+  classNames:["form-horizontal"],
+  i18nprefix:'form.',
+  fields:[],
+  field:{},
+  messages:[],
+  object:false,
+  result:0, // save result var (-1 - error; 0 - init; 1 - success)
+  templateName:require('templates/common/form'),
+  tagName:'form',
+
+  init:function () {
     var thisForm = this;
-    if (!this.fields.length)
-      $.each(this.fieldsOptions,
-        function () {
-          var field = App.FormField.create(this);
+    console.warn("FIELDS LEN:", this.fields.length);
+
+    if (!this.fields.length) {
+      this.fieldsOptions.forEach(
+        function (options) {
+          var field = App.FormField.create(options);
+          console.warn("CREATED FIELD VALUE:", field.get('value'));
           field.set('form', thisForm);
           thisForm.fields.push(field);
           thisForm.set("field." + field.get('name'), field);
-        });
+        }
+      );
+    }
+    this._super();
   },
 
-  getField: function (name) {
+  getField:function (name) {
     var field = false;
     $.each(this.fields, function () {
       if (this.get('name') == name) {
@@ -56,7 +61,7 @@ App.Form = Em.View.extend({
     return field;
   },
 
-  isValid: function () {
+  isValid:function () {
     var isValid = true;
     $.each(this.fields, function () {
       this.validate();
@@ -69,12 +74,15 @@ App.Form = Em.View.extend({
     return isValid;
   },
 
-  isObjectNew: function () {
+  isObjectNew:function () {
     var object = this.get('object');
+    if(object instanceof App.User){
+      return false;
+    }
     return !(object instanceof DS.Model && object.get('id'));
   }.property("object"),
 
-  updateValues: function () {
+  updateValues:function () {
     var object = this.get('object');
     if (object instanceof Em.Object) {
       $.each(this.fields, function () {
@@ -90,16 +98,17 @@ App.Form = Em.View.extend({
    *
    */
 
-  getValues: function () {
+  getValues:function () {
     var values = {};
-    $.each(this.fields, function () {
-      if (!(this.get('displayType') == 'password' && validator.empty(this.get('value')))) // if this is not empty password field
+    $.each(this.get('fields'), function () {
+      if (!(this.get('displayType') == 'password' && validator.empty(this.get('value')))) { // if this is not empty password field
         values[this.get('name')] = this.get('value');
+      }
     });
     return values;
   },
 
-  clearValues: function () {
+  clearValues:function () {
     $.each(this.fields, function () {
       this.set('value', '');
     });
@@ -109,7 +118,7 @@ App.Form = Em.View.extend({
    * need to refactor for integration
    * @return {Boolean}
    */
-  save: function () {
+  save:function () {
     var thisForm = this;
     var object = this.get('object');
     if (!this.get('isObjectNew')) {
@@ -129,7 +138,18 @@ App.Form = Em.View.extend({
     return true;
   },
 
-  resultText: function () {
+  visibleFields:function () {
+    var fields = this.get('fields');
+    var visible = [];
+    fields.forEach(function (field) {
+      if (!field.get('isHiddenField')) {
+        visible.push(field);
+      }
+    });
+    return visible;
+  }.property('fields'),
+
+  resultText:function () {
     var text = "";
     switch (this.get('result')) {
       case -1:
@@ -143,7 +163,7 @@ App.Form = Em.View.extend({
     return text;
   }.property('result'),
 
-  saveButtonText: function () {
+  saveButtonText:function () {
     return Em.I18n.t(this.get('i18nprefix') + (this.get('isObjectNew') ? "create" : "save"));
   }.property('isObjectNew')
 
@@ -154,24 +174,31 @@ App.Form = Em.View.extend({
 });
 
 App.FormField = Em.Object.extend({ // try to realize this as view
-  name: '',
-  displayName: '',
+  name:'',
+  displayName:'',
 //  defaultValue:'', NOT REALIZED YET
-  description: '',
-  disabled: false,
-  displayType: 'string', // string, digits, number, directories, textarea, checkbox
-  disableRequiredOnPresent: false,
-  errorMessage: '',
-  form: false,
-  isRequired: true, // by default a config property is required
-  unit: '',
-  value: '',
-
-  isValid: function () {
+  description:'',
+  disabled:false,
+  displayType:'string', // string, digits, number, directories, textarea, checkbox
+  disableRequiredOnPresent:false,
+  errorMessage:'',
+  form:false,
+  isRequired:true, // by default a config property is required
+  unit:'',
+  value:'',
+
+  observeValue:function () {
+
+    if (this.get('displayType') == 'hidden')
+      console.warn(" FORM FIELD VALUE: ", this.get('value'));
+
+  }.observes('value'),
+
+  isValid:function () {
     return this.get('errorMessage') === '';
   }.property('errorMessage'),
 
-  viewClass: function () {
+  viewClass:function () {
     var options = {};
     var element = Em.TextField;
     switch (this.get('displayType')) {
@@ -192,12 +219,15 @@ App.FormField = Em.Object.extend({ // try to realize this as view
       case 'textarea':
         element = Em.TextArea;
         break;
+      case 'hidden':
+        options.type = "hidden";
+        break;
     }
 
     return element.extend(options);
   }.property('displayType'),
 
-  validate: function () {
+  validate:function () {
     var digitsRegex = /^\d+$/;
     var numberRegex = /^[-,+]?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/;
     var value = this.get('value');
@@ -260,5 +290,9 @@ App.FormField = Em.Object.extend({ // try to realize this as view
     if (!isError) {
       this.set('errorMessage', '');
     }
-  }.observes('value')
+  }.observes('value'),
+
+  isHiddenField:function () {
+    return this.get('displayType') == 'hidden';
+  }.property('type')
 });

+ 8 - 2
ambari-web/app/models/host.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var misc = require('utils/misc');
 
 App.Host = DS.Model.extend({
   hostName: DS.attr('string'),
@@ -27,7 +28,7 @@ App.Host = DS.Model.extend({
   memory: DS.attr('string'),
   diskUsage: DS.attr('string'),
   loadAvg: DS.attr('string'),
-  os: DS.attr('string'),
+  osArch: DS.attr('string'),
   ip: DS.attr('string'),
   healthStatus: DS.attr('string'),
   cpuUsage: DS.attr('number'),
@@ -38,7 +39,12 @@ App.Host = DS.Model.extend({
   osType: DS.attr("string"),
   diskInfo: DS.attr('string'),
 
-
+  /**
+   * formatted bytes to appropriate value
+   */
+  memoryFormatted: function () {
+    return misc.formatBandwidth(this.get('memory'));
+  }.property('memory'),
   /**
    * Return true if host not heartbeating last 180 seconds
    */

+ 15 - 2
ambari-web/app/models/run.js

@@ -55,7 +55,6 @@ App.Run = DS.Model.extend({
   isRunning: function () {
     return !this.get('numJobsTotal') == this.get('numJobsCompleted');
   }.property('numJobsTotal', 'numJobsCompleted'),
-
   /**
    * Sum of input bandwidth for all jobs with appropriate measure
    */
@@ -85,7 +84,21 @@ App.Run = DS.Model.extend({
    */
   lastUpdateTimeFormatted: function() {
     return date.dateFormat(this.get('lastUpdateTime'));
-  }.property('lastUpdateTime')
+  }.property('lastUpdateTime'),
+  /**
+   * Type value based on first part of id
+   */
+  type: function() {
+    if (this.get('id').indexOf('pig_') === 0) {
+      return 'Pig';
+    }
+    if (this.get('id').indexOf('hive_') === 0) {
+      return 'Hive';
+    }
+    if (this.get('id').indexOf('mr_') === 0) {
+      return 'mapReduce';
+    }
+  }.property('id')
 });
 
 App.Run.FIXTURES = [];

+ 2 - 1
ambari-web/app/models/service/mapreduce.js

@@ -38,7 +38,8 @@ App.MapReduceService = App.Service.extend({
   mapsRunning: DS.attr('number'),
   mapsWaiting: DS.attr('number'),
   reducesRunning: DS.attr('number'),
-  reducesWaiting: DS.attr('number')
+  reducesWaiting: DS.attr('number'),
+  trackersDecommisioned: DS.attr('number')
 });
 
 App.MapReduceService.FIXTURES = [];

+ 47 - 40
ambari-web/app/models/user.js

@@ -26,17 +26,17 @@ App.UserModel = Em.Object.extend({
 
 App.User = DS.Model.extend({
   userName:DS.attr('string'),
-  password:DS.attr('string'),
   roles:DS.attr('string'),
+  type:DS.attr('string'),
   auditItems:DS.hasMany('App.ServiceAudit'),
-  admin: function () {
+  admin:function () {
     return !!(/^admin/.test(this.get('roles')))
   }.property('userName')
 });
 
 App.UserForm = App.Form.extend({
   className:App.User,
-  object: function(){
+  object:function () {
     return App.router.get('mainAdminUserEditController.content');
   }.property('App.router.mainAdminUserEditController.content'),
 
@@ -44,7 +44,8 @@ App.UserForm = App.Form.extend({
     { name:"userName", displayName:"Username" },
     { name:"password", displayName:"Password", displayType:"password", isRequired: function(){ return this.get('form.isObjectNew'); }.property('form.isObjectNew') },
     { name:"passwordRetype", displayName:"Retype Password", displayType:"password", validator:"passwordRetype", isRequired: false },
-    { name:"admin", displayName:"Admin", displayType:"checkbox", isRequired:false }
+    { name:"admin", displayName:"Admin", displayType:"checkbox", isRequired:false },
+    { name:"roles", displayName:"Role", isRequired:false, isHidden:true }
   ],
   fields:[],
   disableUsername:function () {
@@ -61,64 +62,70 @@ App.UserForm = App.Form.extend({
     }
   }.observes('isObjectNew'),
 
-  isValid: function(){
+  getValues:function () {
+    var values = this._super();
+    values.type = ['local'];
+    return values;
+  },
+
+  isValid:function () {
     var isValid = this._super();
     thisForm = this;
 
     var passField = this.get('field.password');
     var passRetype = this.get('field.passwordRetype');
 
-    if(!validator.empty(passField.get('value'))) {
-      if(passField.get('value') != passRetype.get('value')) {
+    if (!validator.empty(passField.get('value'))) {
+      if (passField.get('value') != passRetype.get('value')) {
         passRetype.set('errorMessage', "Passwords are different");
         isValid = false;
       }
     }
 
-    if(isValid && this.get('isObjectNew')) {
+    if (isValid && this.get('isObjectNew')) {
       var users = App.User.find();
       var userNameField = this.getField('userName');
       var userName = userNameField.get('value');
 
-      users.forEach(function(user){
-        if(userName == user.get('userName')) {
+      users.forEach(function (user) {
+        if (userName == user.get('userName')) {
           userNameField.set('errorMessage', 'User with the same name is already exists');
           return isValid = false;
         }
       });
     }
-    
+
     return isValid;
   }
 });
 App.User.FIXTURES = [];
 /*
-App.User.FIXTURES = [
-  {
-    id:1,
-    user_name:'admin',
-    password:'admin',
-    admin:1
-  },
-  {
-    id:2,
-    user_name:'vrossi',
-    admin:1
-  },
-  {
-    id:3,
-    user_name:'casey.stoner',
-    admin:0
-  },
-  {
-    id:4,
-    user_name:'danip',
-    admin:0
-  },
-  {
-    id:5,
-    user_name:'test',
-    password:'test',
-    admin:0
-  }
-];*/
+ App.User.FIXTURES = [
+ {
+ id:1,
+ user_name:'admin',
+ password:'admin',
+ admin:1
+ },
+ {
+ id:2,
+ user_name:'vrossi',
+ admin:1
+ },
+ {
+ id:3,
+ user_name:'casey.stoner',
+ admin:0
+ },
+ {
+ id:4,
+ user_name:'danip',
+ admin:0
+ },
+ {
+ id:5,
+ user_name:'test',
+ password:'test',
+ admin:0
+ }
+ ];*/

+ 16 - 14
ambari-web/app/router.js

@@ -102,11 +102,18 @@ App.Router = Em.Router.extend({
     App.db.setLoginName(loginName);
   },
 
-  // that works incorrectly
+  /**
+   * Set user model to local storage
+   * @param user
+   */
   setUser: function (user) {
     App.db.setUser(user);
   },
-  // that works incorrectly
+
+  /**
+   * Get user model from local storage
+   * @return {*}
+   */
   getUser: function () {
     return App.db.getUser();
   },
@@ -221,19 +228,14 @@ App.Router = Em.Router.extend({
     }
   },
 
-  defaultSection: 'installer',
-
   getSection: function () {
-    var section = App.db.getSection();
-    console.log("The section is: " + section);
-    var section = localStorage.getItem(this.getLoginName() + 'section');
-
-    return section || this.defaultSection;
-
-  },
-
-  setSection: function (section) {
-    App.db.setSection(section);
+    var clusterController = App.router.get('clusterController');
+    clusterController.loadClusterName(false);
+    if (clusterController.get('clusterName')) {
+      return 'main.index';
+    } else {
+      return 'installer';
+    }
   },
 
   root: Em.Route.extend({

+ 0 - 1
ambari-web/app/routes/add_host_routes.js

@@ -132,7 +132,6 @@ module.exports = Em.Route.extend({
       addHostController.saveServices(wizardStep4Controller);
       addHostController.saveClients(wizardStep4Controller);
       App.db.setMasterComponentHosts(undefined);
-      App.db.setHostToMasterComponent(undefined);
       router.transitionTo('step4');
     }
   }),

+ 9 - 6
ambari-web/app/routes/add_service_routes.js

@@ -50,7 +50,6 @@ module.exports = Em.Route.extend({
       addServiceController.saveServices(wizardStep4Controller);
       addServiceController.saveClients(wizardStep4Controller);
       App.db.setMasterComponentHosts(undefined);
-      App.db.setHostToMasterComponent(undefined);
       router.transitionTo('step2');
     }
   }),
@@ -72,6 +71,7 @@ module.exports = Em.Route.extend({
       var wizardStep5Controller = router.get('wizardStep5Controller');
       addServiceController.saveMasterComponentHosts(wizardStep5Controller);
       App.db.setSlaveComponentHosts(undefined);
+      App.db.setHostSlaveComponents(undefined);
       router.transitionTo('step3');
     }
   }),
@@ -92,6 +92,7 @@ module.exports = Em.Route.extend({
 
       if (wizardStep6Controller.validate()) {
         addServiceController.saveSlaveComponentHosts(wizardStep6Controller);
+        addServiceController.get('content').set('serviceConfigProperties', null);
         App.db.setServiceConfigProperties(null);
         router.transitionTo('step4');
       }
@@ -140,7 +141,6 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
       console.log('in addService.step6:connectOutlets');
       var controller = router.get('addServiceController');
-      controller.setInfoForStep9();
       controller.setCurrentStep('6', false);
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep9', controller.get('content'));
@@ -149,13 +149,16 @@ module.exports = Em.Route.extend({
     retry: function(router,context) {
       var addServiceController = router.get('addSrviceController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
-      addServiceController.installServices();
-      wizardStep9Controller.navigateStep();
+      if (!wizardStep9Controller.get('isSubmitDisabled')) {
+        addServiceController.installServices();
+        addServiceController.setInfoForStep9();
+        wizardStep9Controller.navigateStep();
+      }
     },
     next: function (router) {
       var addServiceController = router.get('addServiceController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
-      addServiceController.saveClusterInfo(wizardStep9Controller);
+      //addServiceController.saveClusterInfo(wizardStep9Controller);
       addServiceController.saveInstalledHosts(wizardStep9Controller);
       router.transitionTo('step7');
     }
@@ -168,7 +171,7 @@ module.exports = Em.Route.extend({
       var controller = router.get('addServiceController');
       controller.setCurrentStep('7', false);
       controller.loadAllPriorSteps();
-      controller.connectOutlet('wizardStep10');
+      controller.connectOutlet('wizardStep10', controller.get('content'));
     },
     back: Em.Router.transitionTo('step6'),
     complete: function (router, context) {

+ 2 - 3
ambari-web/app/routes/installer.js

@@ -167,7 +167,6 @@ module.exports = Em.Route.extend({
       controller.saveClients(wizardStep4Controller);
 
       App.db.setMasterComponentHosts(undefined);
-      App.db.setHostToMasterComponent(undefined);
       router.transitionTo('step5');
     }
   }),
@@ -274,6 +273,7 @@ module.exports = Em.Route.extend({
       var wizardStep9Controller = router.get('wizardStep9Controller');
       if (!wizardStep9Controller.get('isSubmitDisabled')) {
         installerController.installServices();
+        installerController.setInfoForStep9();
         wizardStep9Controller.navigateStep();
       }
     },
@@ -299,8 +299,7 @@ module.exports = Em.Route.extend({
     complete: function (router, context) {
       if (true) {   // this function will be moved to installerController where it will validate
         var controller = router.get('installerController');
-        controller.setCurrentStep('1', false);
-        router.setSection('main');
+        controller.finish();
         router.transitionTo('main.index');
       } else {
         console.log('cluster installation failure');

+ 1 - 0
ambari-web/app/routes/main.js

@@ -21,6 +21,7 @@ module.exports = Em.Route.extend({
   enter:function (router) {
     console.log('in /main:enter');
     if (router.getAuthenticated()) {
+      var clusterController = App.router.get('clusterController').loadClusterName(false);
       router.get('mainController').initialize();
       // TODO: redirect to last known state
     } else {

+ 25 - 4
ambari-web/app/styles/application.less

@@ -487,7 +487,7 @@ a:focus {
     .name {
       line-height: 21px;
       margin-left: 0;
-      width: 130px;
+      width: 145px;
       a {
         margin-left: 5px
       }
@@ -510,13 +510,21 @@ a:focus {
       }
     }
 
-    .chart {
+    .dashboard-mini-chart {
       right: 0;
       top: 27px;
       position: absolute;
       overflow: visible; // for quick links
       text-align: center;
-
+      width: 200px;
+      height: 200px;
+      .chart-container{
+        .chart-x-axis{
+          left: 0%;
+          width: 100%;
+          text-align: left;
+        }
+      } 
       .chartLabel {
         font-size: 11px;
         color: #7b7b7b;
@@ -662,6 +670,14 @@ a:focus {
   }
 }
 
+.mini-chart{
+  position: absolute;
+  .chart-container{
+    width: 130px;
+    height: 130px;
+  }
+}
+
 /*end chart/graph styles*/
 
 /*****end styles for dashboard page*****/
@@ -694,6 +710,9 @@ a:focus {
     }
     li {
       line-height: 24px;
+      a {
+        padding: 3px 10px;
+      }
     }
   }
   .add-service-button {
@@ -913,6 +932,7 @@ a:focus {
 
   margin-top: 27px;
 
+  /*
   .component-operation-button {
     background-color: #E5E5E5;
     background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#E5E5E5), to(#F1F1F1));
@@ -923,6 +943,7 @@ a:focus {
     background-repeat: repeat-x;
     color: #000000;
   }
+  */
   .caret {
     border-top-color: #000000;
     border-bottom-color: #000000;
@@ -1006,7 +1027,7 @@ a:focus {
     padding-bottom: 0;
     border: 1px solid #DEDEDE;
     border-radius: 4px;
-    background: #F5F5F5;
+    background: #FFF;
   }
   .host-components .btn-group {
     margin: 0 5px 10px 0;

+ 43 - 3
ambari-web/app/styles/apps.less

@@ -1,4 +1,5 @@
 #apps{
+
   td .red {
     color: red;
   }
@@ -6,15 +7,27 @@
     vertical-align:top;
   }
   .avg-table {
+    table-layout: fixed;
     background-color: #F9F9F9;
     td {
       text-align:center;
       border:none;
+      &.avg-star{
+        border-left:1px solid #DDD;
+        width: 30px;
+      }
     }
   }
-  td.avg-star{
-    border-left:1px solid #DDD;
+
+  #dataTable {
+    table-layout: fixed;
+    td {
+      &.appId {
+        word-wrap: break-word;
+      }
+    }
   }
+
   .dropdown-menu label.checkbox {
     margin-left: 10px;
   }
@@ -126,7 +139,9 @@
   tr.containerRow > td{
     background: #f9f9f9;
   }
-
+  button {
+    margin: 0 2px;
+  }
   svg{
     vertical-align: top; //remove extra spaces after svg element
   }
@@ -141,6 +156,7 @@
     background: #fff;
     padding: 10px;
     box-sizing: border-box;
+    width: auto;
   }
 
   #jobs h2{
@@ -172,5 +188,29 @@
     }
   }
 
+  div.view-wrapper {
+    float: left;
+  }
+
+  a.ui-icon-circle-close {
+    float: right;
+    opacity: 0.2;
+    padding: 1px;
+    position: relative;
+    top: -32px;
+    &:hover {
+      opacity: 0.7;
+    }
+  }
+  .notActive {
+    a.ui-icon-circle-close {
+      visibility: hidden;
+    }
+  }
+}
+.btn-group button.single-btn-group{
+  -webkit-border-radius: 4px;
+  border-radius: 4px;
+  -moz-border-radius: 4px;
 }
 

+ 4 - 3
ambari-web/app/templates/main/admin/user.hbs

@@ -17,14 +17,15 @@
 }}
 
 {{#if view.ldapUser}}
-  <p class="text-info">{{t admin.users.ldapAuthentionUsed}}.</p>
+<p class="text-info">{{t admin.users.ldapAuthentionUsed}}.</p>
 {{else}}
 <table class="table table-bordered table-striped span6">
   <thead>
   <tr>
     <th style="width:50%">{{t admin.users.username}}</th>
-    <th style="width:15%">{{t admin.users.privileges}}<i class="icon-question-sign"></i></th>
-    <th style="width:15%">Action</th>
+    <th style="width:10%">{{t admin.users.privileges}}</th>
+    <th style="width:20%">{{t admin.users.type}}</th>
+    <th style="width:20%">{{t admin.users.action}}</th>
   </tr>
   </thead>
   <tbody>

+ 2 - 0
ambari-web/app/templates/main/admin/user/edit.hbs

@@ -18,6 +18,7 @@
 
 <form class="form-horizontal">
   {{#each field in view.userForm.fields}}
+  {{#unless field.isHidden}}
   <div class="control-group">
     <label class="control-label" for="input{{unbound field.name}}">{{unbound field.displayName}}</label>
     <div class="controls">
@@ -25,6 +26,7 @@
       <span class="help-inline">{{field.errorMessage}}</span>
     </div>
   </div>
+  {{/unless}}
   {{/each}}
   <div class="control-group">
     <div class="controls">

+ 1 - 0
ambari-web/app/templates/main/admin/user/row.hbs

@@ -19,6 +19,7 @@
 <tr>
   <td>{{user.userName}}</td>
   <td>{{view Ember.Checkbox disabledBinding="view.disableCheckBoxes" checkedBinding="user.admin"}}</td>
+  <td>{{user.type}}</td>
   <td>
     <a href="#" {{action gotoEditUser user on="click"}}>{{t admin.users.edit}}</a>&nbsp;
     <a href="#" {{action deleteRecord user target="App.router.mainAdminUserController" }}>{{t admin.users.delete}}</a>

+ 10 - 10
ambari-web/app/templates/main/apps.hbs

@@ -78,16 +78,16 @@
       <th>Run Date</th>
     </tr>
     <tr>
-      <th>{{view view.starFilterView viewName="starFilterViewInstance"}}</th>
-      <th>{{view view.appidFilterView}}</th>
-      <th>{{view view.nameFilterView}}</th>
-      <th>{{view view.typeSelectView}}</th>
-      <th>{{view view.userFilterView}}<input id="user_filter" type="hidden"></th>
-      <th>{{view view.jobsFilterView}}</th>
-      <th>{{view view.inputFilterView}}</th>
-      <th>{{view view.outputFilterView}}</th>
-      <th>{{view view.durationFilterView}}</th>
-      <th>{{view view.rundateSelectView}}</th>
+      <th class="notActive"><div class="view-wrapper">{{view view.starFilterView viewName="starFilterViewInstance"}}</div></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.appidFilterView viewName="appidFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_appidFilterViewInstance" class="ui-icon ui-icon-circle-close ui-appid"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.nameFilterView viewName="nameFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_nameFilterViewInstance" class="ui-icon ui-icon-circle-close ui-name"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.typeSelectView viewName="typeSelectViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_typeSelectViewInstance" class="ui-icon ui-icon-circle-close ui-type"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.userFilterView viewName="userFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_userFilterViewInstance" class="ui-icon ui-icon-circle-close ui-user"></a><input id="user_filter" type="hidden"></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.jobsFilterView viewName="jobsFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_jobsFilterViewInstance" class="ui-icon ui-icon-circle-close ui-jobs"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.inputFilterView viewName="inputFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_inputFilterViewInstance" class="ui-icon ui-icon-circle-close ui-input"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.outputFilterView viewName="outputFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_outputFilterViewInstance" class="ui-icon ui-icon-circle-close ui-output"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.durationFilterView viewName="durationFilterViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_durationFilterViewInstance" class="ui-icon ui-icon-circle-close ui-duration"></a></th>
+      <th class="notActive"><div class="view-wrapper">{{view view.rundateSelectView viewName="rundateSelectViewInstance"}}</div> <a href="#" {{action "clearFilterButtonClick" target="view"}} id="view_rundateSelectViewInstance" class="ui-icon ui-icon-circle-close ui-rundate"></a></th>
     </tr>
     </thead>
     <tbody>

+ 1 - 1
ambari-web/app/templates/main/apps/list_row.hbs

@@ -25,4 +25,4 @@
 <td>{{unbound run.inputFormatted}}</td>
 <td>{{unbound run.outputFormatted}}</td>
 <td>{{unbound run.duration}}</td>
-<td>{{unbound run.lastUpdateTimeFormatted}} {{#if run.isRunning}}<b class='red'>*</b>{{/if}}</td>
+<td>{{unbound run.lastUpdateTimeFormatted}}&nbsp;{{#if run.isRunning}}<b class='red'>*</b>{{/if}}</td>

+ 3 - 6
ambari-web/app/templates/main/dashboard.hbs

@@ -25,12 +25,9 @@
             <h4>{{t dashboard.services}}</h4>
           </div>
           <dl class="dl-horizontal services">
-            {{view App.MainDashboardServiceHdfsView controllerBinding="controller"}}
-            {{view App.MainDashboardServiceMapreduceView controllerBinding="controller"}}
-            {{view App.MainDashboardServiceHbaseView controllerBinding="controller"}}
-            {{view App.MainDashboardServiceHiveView controllerBinding="controller"}}
-            {{view App.MainDashboardServiceZookeperView controllerBinding="controller"}}
-            {{view App.MainDashboardServiceOozieView controllerBinding="controller"}}
+            {{#each item in view.content}}
+              {{view item.viewName serviceBinding="item.model"}}
+            {{/each}}
           </dl>
         </div>
       </div>

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hbase.hbs

@@ -70,7 +70,7 @@
   </tr>
   </tbody>
 </table>
-<div class="chart">
+<div class="dashboard-mini-chart">
   {{view view.Chart}}
   <div class="chartLabel">{{t dashboard.services.hbase.chart.label}}</div>
   {{#if view.service.quickLinks.length}}

+ 1 - 1
ambari-web/app/templates/main/dashboard/service/hdfs.hbs

@@ -120,7 +120,7 @@
   </tr>
   </tbody>
 </table>
-<div class="chart">
+<div class="dashboard-mini-chart">
   {{view view.Chart}}
   <div class="chartLabel">{{t dashboard.services.hdfs.chart.label}}</div>
   {{#if view.service.quickLinks.length}}

+ 3 - 2
ambari-web/app/templates/main/dashboard/service/mapreduce.hbs

@@ -67,7 +67,8 @@
     <td>{{t dashboard.services.mapreduce.taskTrackerCounts}}</td>
     <td>
       {{view.service.grayListTrackers.length}} {{t dashboard.services.mapreduce.nodes.blacklist}} /
-      {{view.service.blackListTrackers.length}} {{t dashboard.services.mapreduce.nodes.graylist}}
+      {{view.service.blackListTrackers.length}} {{t dashboard.services.mapreduce.nodes.graylist}} /
+      {{view.service.trackersDecommisioned}} {{t dashboard.services.hdfs.nodes.decom}} 
     </td>
   </tr>
   <!-- JobTracker Heap -->
@@ -107,7 +108,7 @@
   </tr>
   </tbody>
 </table>
-<div class="chart">
+<div class="dashboard-mini-chart">
   {{view App.ChartServiceMetricsMapReduce_JobsRunningWaiting}}
   
   {{#if view.service.quickLinks.length}}

+ 1 - 1
ambari-web/app/templates/main/host.hbs

@@ -62,7 +62,7 @@
       <th>Load Avg</th>
       <th>
         <div {{bindAttr class="view.btnGroupClass"}} >
-          <button class="btn btn-info" {{action "clickFilterButton" target="view"}}>
+          <button class="btn btn-info single-btn-group" {{action "clickFilterButton" target="view"}}>
             Components
             <span class="caret"></span>
           </button>

+ 15 - 7
ambari-web/app/templates/main/host/summary.hbs

@@ -17,7 +17,7 @@
 }}
 
 <div class="row">
-  <div class="span5 host-configuration">
+  <div class="span6 host-configuration">
     <div class="box">
 		  <div class="box-header">
 		    <h4>Summary</h4>
@@ -26,9 +26,9 @@
 		    <dl class="dl-horizontal">
 		      <dt>IP:</dt><dd>{{view.content.ip}}</dd>
 		      <dt>CPU:</dt><dd>{{view.content.cpu}}</dd>
-		      <dt>OS:</dt><dd>type</dd>
-		      <dt>Disk Usage:</dt><dd>{{view.content.diskUsage}}</dd>
-		      <dt>Memory:</dt><dd>{{view.content.memory}}</dd>
+          <dt>OS:</dt><dd>{{view.content.osType}}&nbsp;({{view.content.osArch}})</dd>
+          <dt>Disk Usage:</dt><dd>{{view.content.diskUsage}}</dd>
+          <dt>Memory:</dt><dd>{{view.content.memoryFormatted}}</dd>
 		      <dt>Load Avg:</dt><dd>{{view.content.loadAvg}}</dd>
 		      <dt>Agent:</dt><dd>running</dd>
 		    </dl>
@@ -39,10 +39,17 @@
   <div class="span3 host-components pull-right">
     {{#each component in view.content.components}}
     {{#view view.ComponentButtonView contentBinding="component"}}
-      <div {{bindAttr class=":btn-group view.positionButton:pull-right:pull-left"}}>
-        <button {{bindAttr class=":component-operation-button :btn :btn-success :dropdown-toggle view.disabledClass"}} data-toggle="dropdown">
+    {{#if view.isClient}}
+    <div class="btn-group pull-left">
+      <button class="btn">
+        {{unbound view.content.displayName}}
+      </button>
+    </div>
+    {{else}}
+      <div {{bindAttr class=":btn-group :pull-left"}}>
+        <button {{bindAttr class=":component-operation-button :btn :dropdown-toggle view.disabledClass"}} data-toggle="dropdown">
           <span {{bindAttr class=":components-health view.indicatorClass"}}></span>
-          {{unbound view.content.componentName}}
+          {{unbound view.content.displayName}}
           <span class="caret"></span>
         </button>
         <ul class="dropdown-menu">
@@ -70,6 +77,7 @@
             </li>
         </ul>
       </div>
+    {{/if}}
     {{/view}}
     {{/each}}
   </div>

+ 3 - 3
ambari-web/app/templates/main/service/menu_item.hbs

@@ -18,9 +18,9 @@
 
 <a href="#/main/services/{{unbound view.content.id}}/summary">
   {{view App.MainDashboardServiceHealthView class="service-health" serviceBinding="view.content"}}&nbsp;<span>{{unbound view.content.displayName}}</span>
-  {{#if view.serviceOperationsCount}}
-    <span class="label operations-count" {{action "showPopup" target="App.router.backgroundOperationsController"}}>
-      {{view.serviceOperationsCount}}
+  {{#if view.alertsCount}}
+    <span class="label operations-count">
+      {{view.alertsCount}}
     </span>
   {{/if}}
 </a>

+ 1 - 0
ambari-web/app/templates/wizard/step5.hbs

@@ -36,6 +36,7 @@
             selectedHostBinding="selectedHost"
             serviceNameBinding="display_name"
             zIdBinding="zId"
+            disabledBinding="isInstalled"
           }}
           {{#if showAddControl}}
           {{view App.AddControlView

+ 1 - 1
ambari-web/app/templates/wizard/step6.hbs

@@ -66,7 +66,7 @@
     {{#each hosts}}
     <tr>
         {{#view App.WizardStep6HostView hostBinding = "this" }}
-          {{hostname}}
+          {{hostName}}
           {{#if isMaster}}
             <i class=icon-asterisks>&#10037</i>
           {{/if}}

+ 1 - 2
ambari-web/app/utils/data_table.js

@@ -322,9 +322,8 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
             break;
           case '=':
             if (compareValue == rowValue) match = true;
-            break;
           default:
-            match = false;
+            if (rangeExp == rowValue) match = true;
         }
       }
 

+ 1 - 1
ambari-web/app/utils/date.js

@@ -77,7 +77,7 @@ module.exports = {
   dateUnformatInterval: function(formattedDate) {
     var d = formattedDate.split(':');
     for (var k in d) {
-      d[k] = parseInt(d[k]);
+      d[k] = parseInt(d[k], 10);
     }
     return d[0]*3600+d[1]*60+d[2];
   }

+ 63 - 196
ambari-web/app/utils/db.js

@@ -50,7 +50,10 @@ App.db.cleanUp = function () {
     'app': {
       'loginName': '',
       'authenticated': false
-    }
+    },
+    'Installer' : {},
+    'AddHost' : {},
+    'AddService' : {}
   };
   console.log("In cleanup./..");
   localStorage.setObject('ambari', App.db.data);
@@ -80,7 +83,10 @@ App.db.setAmbariStacks = function (stacks) {
   localStorage.setObject('ambari', App.db.data);
 };
 
-// that works incorrectly
+/**
+ * Set user model to db
+ * @param user
+ */
 App.db.setUser = function (user) {
   console.log('TRACE: Entering db:setUser function');
   App.db.data = localStorage.getObject('ambari');
@@ -100,106 +106,45 @@ App.db.setAuthenticated = function (authenticated) {
   console.log('Now present value of authentication is: ' + App.db.data.app.authenticated);
 };
 
-App.db.setSection = function (section) {
-  console.log('TRACE: Entering db:setSection function');
-  App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined) {
-    App.db.data[user] = {'name': user};
-  }
-  if (App.db.data[user].ClusterName == undefined) {
-    App.db.data[user].ClusterName = {};
-  }
-  App.db.data[user].section = section;
-  localStorage.setObject('ambari', App.db.data);
-};
-
-App.db.setInstallerCurrentStep = function (currentStep, completed) {
-  console.log('TRACE: Entering db:setInstallerCurrentStep function');
-  App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined) {
-    console.log('In data[user] condition');
-    App.db.data[user] = {'name': user};
-    console.log('value of data[user].name: ' + App.db.data[user].name);
-  }
-  if (App.db.data[user].Installer == undefined) {
-    App.db.data[user].Installer = {};
-    console.log('');
-  }
-  App.db.data[user].Installer.currentStep = currentStep;
-  App.db.data[user].Installer.completed = completed;
-  localStorage.setObject('ambari', App.db.data);
-};
-
 App.db.setClusterName = function (name) {
   console.log('TRACE: Entering db:setClusterName function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  // all information from Installer.ClusterName will be transferred to clusters[ClusterName] when app migrates from installer to main
-  if (App.db.data[user] == undefined) {
-    App.db.data[user] = {'name': user};
-  }
-  if (App.db.data[user].clusters == undefined) {
-    App.db.data[user].clusters = {};
-  }
-
-  if (App.db.data[user].Installer == undefined) {
-    App.db.data[user].Installer = {};
-  }
-  App.db.data[user].Installer.ClusterName = name;
+  App.db.data.Installer.ClusterName = name;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setAllHostNames = function (hostNames) {
   console.log('TRACE: Entering db:setAllHostNames function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined) {
-    App.db.data[user] = {'name': user};
-  }
-  App.db.data[user].Installer.hostNames = hostNames;
+  App.db.data.Installer.hostNames = hostNames;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setHosts = function (hostInfo) {
   console.log('TRACE: Entering db:setHosts function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined) {
-    App.db.data[user] = {'name': user};
-  }
-  App.db.data[user].Installer.hostInfo = hostInfo;
+  App.db.data.Installer.hostInfo = hostInfo;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setInstallType = function (installType) {
   console.log('TRACE: Entering db:setInstallType function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined) {
-    App.db.data[user] = {'name': user};
-  }
-  App.db.data[user].Installer.installType = installType;
+  App.db.data.Installer.installType = installType;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setSoftRepo = function (softRepo) {
   console.log('TRACE: Entering db:setSoftRepo function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined) {
-    App.db.data[user] = {'name': user};
-  }
-  App.db.data[user].Installer.softRepo = softRepo;
+  App.db.data.Installer.softRepo = softRepo;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setBootStatus = function (status) {
   console.log('TRACE: Entering db:setBootStatus function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.bootStatus = status;
+  App.db.data.Installer.bootStatus = status;
   localStorage.setObject('ambari', App.db.data);
 };
 
@@ -216,87 +161,89 @@ App.db.removeHosts = function (hostInfo) {
 App.db.setService = function (serviceInfo) {
   console.log('TRACE: Entering db:setService function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.serviceInfo = serviceInfo;
+  App.db.data.Installer.serviceInfo = serviceInfo;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setSelectedServiceNames = function (serviceNames) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.selectedServiceNames = serviceNames;
+  App.db.data.Installer.selectedServiceNames = serviceNames;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setClientsForSelectedServices = function (clientInfo) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.clientInfo = clientInfo;
+  App.db.data.Installer.clientInfo = clientInfo;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setMasterComponentHosts = function (masterComponentHosts) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.masterComponentHosts = masterComponentHosts;
-  localStorage.setObject('ambari', App.db.data);
-};
-
-App.db.setHostToMasterComponent = function (hostToMasterComponent) {
-  App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.hostToMasterComponent = hostToMasterComponent;
+  App.db.data.Installer.masterComponentHosts = masterComponentHosts;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setHostSlaveComponents = function (hostSlaveComponents) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.hostSlaveComponents = hostSlaveComponents;
+  App.db.data.Installer.hostSlaveComponents = hostSlaveComponents;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setSlaveComponentHosts = function (slaveComponentHosts) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.slaveComponentHosts = slaveComponentHosts;
+  App.db.data.Installer.slaveComponentHosts = slaveComponentHosts;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setServiceConfigs = function (serviceConfigs) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.serviceConfigs = serviceConfigs;
+  App.db.data.Installer.serviceConfigs = serviceConfigs;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setAdvancedServiceConfig = function(serviceConfigs) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.advanceServiceConfigs = serviceConfigs;
+  App.db.data.Installer.advanceServiceConfigs = serviceConfigs;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setServiceConfigProperties = function (configProperties) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.configProperties = configProperties;
+  App.db.data.Installer.configProperties = configProperties;
   localStorage.setObject('ambari', App.db.data);
 };
 
 App.db.setClusterStatus = function (status) {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  App.db.data[user].clusterStatus = status;
+  App.db.data.Installer.clusterStatus = status;
   console.log('db.setClusterStatus called: ' + JSON.stringify(status));
   localStorage.setObject('ambari', App.db.data);
 };
 
+/**
+ * Set current step value for specified Wizard Type
+ * @param wizardType
+ * @param currentStep
+ * @param completed
+ */
+App.db.setWizardCurrentStep = function (wizardType, currentStep, completed) {
+  console.log('TRACE: Entering db:setWizardCurrentStep function');
+
+  App.db.data[wizardType.capitalize()].currentStep = currentStep;
+  App.db.data[wizardType.capitalize()].completed = completed;
+
+  localStorage.setObject('ambari', App.db.data);
+};
+
+
 /*
  *  getter methods
  */
 
-// that works incorrectly
+/**
+ * Get user model from db
+ * @return {*}
+ */
 App.db.getUser = function () {
   console.log('TRACE: Entering db:getUser function');
   App.db.data = localStorage.getObject('ambari');
@@ -315,25 +262,10 @@ App.db.getAuthenticated = function () {
   return App.db.data.app.authenticated;
 };
 
-App.db.getSection = function () {
-  console.log('Trace: Entering db:getSection function');
-  App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName
-  if (App.db.data[user] == undefined || App.db.data[user] == '') {
-    return 0;
-  }
-  return App.db.data[user].section;
-}
-
 App.db.getClusterName = function () {
   console.log('Trace: Entering db:getClusterName function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (user && App.db.data[user] && App.db.data[user].Installer) {
-    return App.db.data[user].Installer.ClusterName;
-  } else {
-    return null;
-  }
+  return App.db.data.Installer.ClusterName;
 };
 
 App.db.getAmbariStacks = function () {
@@ -349,162 +281,97 @@ App.db.getAmbariStacks = function () {
  */
 App.db.getWizardCurrentStep = function (wizardType) {
   console.log('Trace: Entering db:getWizardCurrentStep function for ', wizardType);
-  var user = this.getUser();
-  if (App.db.data[user] && App.db.data[user][wizardType.capitalize()]) {
-    return App.db.data[user][wizardType.capitalize()].currentStep;
+  if (App.db.data[wizardType.capitalize()]) {
+    return App.db.data[wizardType.capitalize()].currentStep;
   }
   return 0;
 };
 
-/**
- * Set current step value for specified Wizard Type
- * @param wizardType
- * @param currentStep
- * @param completed
- */
-App.db.setWizardCurrentStep = function (wizardType, currentStep, completed) {
-  console.log('TRACE: Entering db:setWizardCurrentStep function');
-
-  var user = this.getUser();
-  if (!App.db.data[user]) {
-    App.db.data[user] = {name: user};
-    console.log('value of data[user].name: ' + App.db.data[user].name);
-  }
-  App.db.data[user][wizardType.capitalize()] = {
-    currentStep: currentStep,
-    completed: completed
-  };
-  localStorage.setObject('ambari', App.db.data);
-};
-
-App.db.getInstallerCurrentStep = function () {
-  console.log('Trace: Entering db:getInstallerCurrentStep function');
-  App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined || App.db.data[user] == '') {
-    return 0;
-  }
-  return App.db.data[user].Installer.currentStep;
-};
-
 App.db.getAllHostNames = function () {
   console.log('TRACE: Entering db:getHostNames function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.hostNames;
+  return App.db.data.Installer.hostNames;
 };
 
 App.db.getInstallType = function () {
   console.log('TRACE: Entering db:getHostNames function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.installType;
+  return App.db.data.Installer.installType;
 };
 
 App.db.getSoftRepo = function () {
   console.log('TRACE: Entering db:getSoftRepo function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.softRepo;
+  return App.db.data.Installer.softRepo;
 };
 
 App.db.isCompleted = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.completed;
+  return App.db.data.Installer.completed;
 };
 
 App.db.getHosts = function () {
   console.log('TRACE: Entering db:getHosts function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] == undefined || App.db.data[user] == '') {
-    console.log('ERROR: loginName required for storing host info');
-    return 0;
-  }
-  return App.db.data[user].Installer.hostInfo;
+  return App.db.data.Installer.hostInfo;
 };
 
 App.db.getBootStatus = function () {
   console.log('TRACE: Entering db:getBootStatus function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.bootStatus;
+  return App.db.data.Installer.bootStatus;
 };
 
 App.db.getService = function () {
   console.log('TRACE: Entering db:getService function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.serviceInfo;
+  return App.db.data.Installer.serviceInfo;
 };
 
 App.db.getSelectedServiceNames = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.selectedServiceNames;
+  return App.db.data.Installer.selectedServiceNames;
 };
 
 App.db.getClientsForSelectedServices = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.clientInfo;
+  return App.db.data.Installer.clientInfo;
 };
 
 App.db.getMasterComponentHosts = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.masterComponentHosts;
+  return App.db.data.Installer.masterComponentHosts;
 };
 
-App.db.getHostToMasterComponent = function () {
-  App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.hostToMasterComponent;
-}
-
 App.db.getHostSlaveComponents = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.hostSlaveComponents;
+  return App.db.data.Installer.hostSlaveComponents;
 };
 
 App.db.getSlaveComponentHosts = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] && App.db.data[user].Installer) {
-    return App.db.data[user].Installer.slaveComponentHosts;
-  }
-  return null;
+  return App.db.data.Installer.slaveComponentHosts;
 };
 
 App.db.getServiceConfigs = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.serviceConfigs;
+  return App.db.data.Installer.serviceConfigs;
 };
 
 App.db.getAdvancedServiceConfig = function() {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.advanceServiceConfigs;
+  return App.db.data.Installer.advanceServiceConfigs;
 };
 
 App.db.getServiceConfigProperties = function () {
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.configProperties;
+  return App.db.data.Installer.configProperties;
 };
 
 App.db.getClusterStatus = function () {
   console.log('TRACE: Entering db:getClusterStatus function');
   App.db.data = localStorage.getObject('ambari');
-  var user = App.db.data.app.loginName;
-  if (App.db.data[user] && App.db.data[user].clusterStatus) {
-    return App.db.data[user].clusterStatus;
-  } else {
-    return null;
-  }
+  return App.db.data.Installer.clusterStatus;
 };
 
 module.exports = App.db;

+ 2 - 2
ambari-web/app/views/main/admin/menu.js

@@ -23,11 +23,11 @@ App.MainAdminMenuView = Em.CollectionView.extend({
     {
       route:'user',
       label:'Users'
-    },
+    }/*,
     {
       route:'authentication',
       label:'Authentication'
-    }/*,
+    },
     {
       route:'security',
       label:'Security'

+ 7 - 3
ambari-web/app/views/main/admin/user/edit.js

@@ -25,12 +25,16 @@ App.MainAdminUserEditView = Em.View.extend({
     var form = this.get("userForm");
     if(form.isValid()) {
       var controller = this.get('controller');
-      var roles="user";
-      if(form.getValues().admin=="") roles="admin";
+      if(form.getValues().admin === "" || form.getValues().admin == true) {
+        form.field.roles.set('value',"admin");
+        form.field.admin.set('value',"true");
+      } else{
+        form.field.roles.set('value',"user");
+      }
       controller.sendCommandToServer('/users/' + form.getValues().userName, {
         Users: {
           password: form.getValues().password,
-          roles: roles
+          roles: form.getValues().roles
         }
       }, function (requestId) {
 

+ 8 - 0
ambari-web/app/views/main/apps/item/dag_view.js

@@ -92,6 +92,14 @@ App.MainAppsItemDagView = Em.View.extend({
         null
       ]
     });
+
+    // Hard reset filter settings
+    innerTable.fnSettings().aiDisplay = innerTable.fnSettings().aiDisplayMaster.slice();
+    // Redraw table
+    innerTable.fnDraw(false);
+    innerTable.fnSettings().oFeatures.bFilter = false;
+
+    console.log(innerTable.fnSettings());
     var dagSchema = this.get('controller.content.workflowContext');
     var jobs = this.get('jobs');
     var graph = new DagViewer(false, 'dag_viewer')

+ 99 - 16
ambari-web/app/views/main/apps_view.js

@@ -232,7 +232,6 @@ App.MainAppsView = Em.View.extend({
       this.get('oTable').fnPageChange(Math.floor(rowIndex / perPage));
     }
     var d = this.get('oTable').fnGetData();
-    console.log(this.get('oTable').fnSettings()['aiDisplay']);
   }.observes('controller.lastStarClicked'),
   /**
    * Flush all starred runs
@@ -254,12 +253,23 @@ App.MainAppsView = Em.View.extend({
       $('#dataTable .icon-star').removeClass('stared');
       $('a.icon-star.a').removeClass('active');
       this.get('starFilterViewInstance').set('value', '');
-      $('#dataTable tbody tr').each(function(index) {
+      /*$('#dataTable tbody tr').each(function(index) {
         var td = $(this).find('td:eq(0)');
         self.get('oTable').fnUpdate( td.html(), index, 0);
-      });
+      });*/
+      this.updateStars();
     }
   }.observes('controller.staredRunsLength'),
+  /**
+   * Update stars data in dataTable. data taken from page
+   * Experimental. Need to be tested.
+   */
+  updateStars: function() {
+    var self = this;
+    $('#dataTable tbody tr').each(function(index) {
+      self.get('oTable').fnUpdate( $('#dataTable tbody tr:eq(' + index + ') td:eq(0)').html(), self.get('oTable').fnSettings()['aiDisplay'][index], 0);
+    });
+  },
   /**
    * Reset filters and "turn off" stars
    */
@@ -271,6 +281,7 @@ App.MainAppsView = Em.View.extend({
    * Display only stared rows
    */
   showStared: function() {
+    this.updateStars();
     this.get('starFilterViewInstance').set('value', 'stared');
     this.set('whatAvgShow', false);
     $('a.icon-star.a').addClass('active');
@@ -291,7 +302,6 @@ App.MainAppsView = Em.View.extend({
         $(element).addClass('selected');
       }
     });
-    console.log(viewType);
     switch(viewType) {
       case 'all':
         table.fnSettings().oFeatures.bFilter = false;
@@ -396,6 +406,24 @@ App.MainAppsView = Em.View.extend({
     this.set('filtered',this.get('oTable').fnSettings().fnRecordsDisplay());
     this.setFilteredRuns(this.get('oTable')._('tr', {"filter":"applied"}));
   },
+  /**
+   * Clear selected filter
+   * @param event
+   */
+  clearFilterButtonClick: function(event) {
+    var viewName = event.target.id.replace('view_', '');
+    var elementId = this.get(viewName).get('elementId');
+    if(this.get(viewName).get('tagName') === 'input') {
+      this.get(viewName).set('value', '');
+    }
+    if(this.get(viewName).get('tagName') === 'select') {
+      this.get(viewName).set('value', 'Any');
+      this.get(viewName).change();
+    }
+    if(this.get(viewName).get('multiple')) {
+      this.get(viewName).get('clearFilter')(this.get(viewName));
+    }
+  },
   /**
    * apply each filter to dataTable
    *
@@ -427,9 +455,12 @@ App.MainAppsView = Em.View.extend({
     content:['Any', 'Pig', 'Hive', 'mapReduce'],
     change:function(event){
       if(this.get('selection') === 'Any') {
+        this.$().closest('th').addClass('notActive');
         this.get('parentView').get('oTable').fnFilter('', 3);
-      } else {
-      this.get('parentView').get('oTable').fnFilter(this.get('selection'), 3);
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+        this.get('parentView').get('oTable').fnFilter(this.get('selection'), 3);
       }
       this.get('parentView').set('filtered',this.get('parentView').get('oTable').fnSettings().fnRecordsDisplay());
     }
@@ -446,6 +477,12 @@ App.MainAppsView = Em.View.extend({
     classNames:['input-medium'],
     elementId: 'rundate_filter',
     change:function(event) {
+      if (this.get('selection') == 'Any') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
       this.get('parentView').get('applyFilter')(this.get('parentView'), 9);
     }
   }),
@@ -465,11 +502,17 @@ App.MainAppsView = Em.View.extend({
    * Filter-field for AppId
    */
   appidFilterView: Em.TextField.extend({
-    classNames:['input-small'],
+    classNames:['input-medium'],
     type:'text',
     placeholder: 'Any ID',
     elementId:'appid_filter',
     filtering:function() {
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
       this.get('parentView').get('applyFilter')(this.get('parentView'), 1, this.get('value'));
     }.observes('value')
   }),
@@ -481,6 +524,12 @@ App.MainAppsView = Em.View.extend({
     type:'text',
     placeholder: 'Any Name',
     filtering:function(){
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
       this.get('parentView').get('applyFilter')(this.get('parentView'), 2, this.get('value'));
     }.observes('value')
   }),
@@ -493,6 +542,12 @@ App.MainAppsView = Em.View.extend({
     placeholder: 'Any ',
     elementId:'jobs_filter',
     filtering:function(){
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
       this.get('parentView').get('applyFilter')(this.get('parentView'), 5);
     }.observes('value')
   }),
@@ -505,6 +560,12 @@ App.MainAppsView = Em.View.extend({
     placeholder: 'Any ',
     elementId: 'input_filter',
     filtering:function(){
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
       this.get('parentView').get('applyFilter')(this.get('parentView'), 6);
     }.observes('value')
   }),
@@ -517,7 +578,13 @@ App.MainAppsView = Em.View.extend({
     placeholder: 'Any ',
     elementId: 'output_filter',
     filtering:function(){
-        this.get('parentView').get('applyFilter')(this.get('parentView'), 7);
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
+      this.get('parentView').get('applyFilter')(this.get('parentView'), 7);
     }.observes('value')
   }),
   /**
@@ -529,6 +596,12 @@ App.MainAppsView = Em.View.extend({
     placeholder: 'Any ',
     elementId: 'duration_filter',
     filtering:function(){
+      if (this.get('value') == '') {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
       this.get('parentView').get('applyFilter')(this.get('parentView'), 8);
     }.observes('value')
   }),
@@ -540,7 +613,6 @@ App.MainAppsView = Em.View.extend({
     classNameBindings: ['open'],
     multiple:true,
     open: false,
-    isApplyDisabled:true,
     users:function(){
       var users = [];
       for(var i = 0; i < this.get('parentView').get('users').length; i++)
@@ -551,7 +623,7 @@ App.MainAppsView = Em.View.extend({
       return users;
     }.property('parentView.users'),
     template: Ember.Handlebars.compile(
-      '<button class="btn btn-info" '+
+      '<button class="btn btn-info single-btn-group"'+
       '{{action "clickFilterButton" target="view"}}>'+
       'User&nbsp;<span class="caret"></span></button>'+
       '<ul class="dropdown-menu filter-components">'+
@@ -559,10 +631,13 @@ App.MainAppsView = Em.View.extend({
       '{{view Ember.Checkbox checkedBinding="view.allComponentsChecked"}} All</label></li>'+
       '{{#each user in view.users}}<li><label class="checkbox">' +
       '{{view Ember.Checkbox checkedBinding="user.checked"}}{{user.name}}'+
-      '</label></li>{{/each}}</ul>'+
-      '<button {{bindAttr disabled="view.isApplyDisabled"}}'+
-      'class="btn" {{action "applyFilter" target="view"}}>'+
-      'Apply</button>'
+      '</label></li>{{/each}}'+
+      '<li>' +
+      '<button class="btn" {{action "closeFilter" target="view"}}>' +
+      'Cancel</button>' +
+      '<button class="btn btn-primary" {{action "applyFilter" target="view"}}>'+
+      'Apply</button>'+
+      '</li></ul>'
     ),
     allComponentsChecked:false,
     toggleAllComponents: function() {
@@ -573,23 +648,31 @@ App.MainAppsView = Em.View.extend({
     }.observes('allComponentsChecked'),
     clickFilterButton:function(event) {
       this.set('open', !this.get('open'));
-      this.set('isApplyDisabled', !this.get('isApplyDisabled'));
     },
     clearFilter:function(self) {
       self.set('allComponentsChecked', true);
       self.set('allComponentsChecked', false);
       jQuery('#user_filter').val([]);
       self.get('parentView').get('oTable').fnFilter('', 3);
+      jQuery('#user_filter').closest('th').addClass('notActive');
+    },
+    closeFilter: function(){
+      this.set('open', false);
     },
     applyFilter:function() {
       var chosenUsers = new Array();
       this.set('open', !this.get('open'));
-      this.set('isApplyDisabled', !this.get('isApplyDisabled'));
       this.get('users').forEach(function(item){
           if(item.get('checked')) chosenUsers.push(item.get('name'));
       });
       jQuery('#user_filter').val(chosenUsers);
       this.get('parentView').get('applyFilter')(this.get('parentView'), 3);
+      if (chosenUsers.length == 0) {
+        this.$().closest('th').addClass('notActive');
+      }
+      else {
+        this.$().closest('th').removeClass('notActive');
+      }
     }
   }),
   /**

+ 38 - 1
ambari-web/app/views/main/dashboard.js

@@ -19,5 +19,42 @@
 var App = require('app');
 
 App.MainDashboardView = Em.View.extend({
-  templateName: require('templates/main/dashboard')
+  templateName: require('templates/main/dashboard'),
+  content : [],
+  services:function(){
+    var services = App.Service.find();
+    services.forEach(function(item){
+      var vName;
+      var item2;
+      switch(item.get('serviceName')) {
+        case "HDFS":
+          vName = App.MainDashboardServiceHdfsView;
+          item2 = App.HDFSService.find(item.get('id'));
+          break;
+        case "MAPREDUCE":
+          vName = App.MainDashboardServiceMapreduceView;
+          item2 = App.MapReduceService.find(item.get('id'));
+          break;
+        case "HBASE":
+          vName = App.MainDashboardServiceHbaseView;
+          break;
+        case "HIVE":
+          vName = App.MainDashboardServiceHiveView ;
+          break;
+        case "ZOOKEEPER":
+          vName = App.MainDashboardServiceZookeperView;
+          break;
+        case "OOZIE":
+          vName = App.MainDashboardServiceOozieView;
+          break;
+        default:
+          vName = Em.View;
+      }
+      this.get('content').pushObject({
+        viewName : vName,
+        model: item2 || item
+      })
+    }, this);
+
+  }.observes('App.router.clusterController.dataLoadList.services')
 });

+ 2 - 16
ambari-web/app/views/main/dashboard/service.js

@@ -79,23 +79,9 @@ App.MainDashboardServiceView = Em.View.extend({
     return this.get('controller.data.' + this.get('serviceName'));
   }.property('controller.data'),
 
-  service: function () {
-    var services = this.get('controller.services');
-    if (services) {
-      return services.findProperty('serviceName', this.get('serviceName'));
-    }
-  }.property('controller.services'),
-
   criticalAlertsCount: function () {
-    var alerts = this.get('service.alerts');
-    var count = 0;
-
-    if (alerts) {
-      alerts.forEach(function (alert) {
-        count += (alert.get('status') == App.AlertStatus.negative);
-      });
-    }
-    return count;
+    var alerts = this.get('controller.alerts');
+    return alerts.filterProperty('serviceType', this.get('service.id')).filterProperty('status', '1').length;
   }.property('service.alerts')
 
 });

+ 7 - 11
ambari-web/app/views/main/dashboard/service/hdfs.js

@@ -34,22 +34,18 @@ App.MainDashboardServiceHdfsView = App.MainDashboardServiceView.extend({
     return this.t('dashboard.services.uptime').format(formatted.d, formatted.h, formatted.m);
   }.property("service.nameNodeStartTime"),
   
-  service: function(){
-    return App.HDFSService.find().objectAt(0);
-  }.property('App.router.clusterController.dataLoadList.services'),
-  
   nodeWebUrl: function(){
     return "http://"+this.get('service').get('nameNode').get('hostName')+":50070";
   }.property('service.nameNode'),
 
   nodeHeap:function () {
-
-    var percent = this.get('data.namenode_heap_total') > 0 ? 100 * this.get('data.namenode_heap_used') / this.get('data.namenode_heap_total') : 0;
-
+    var memUsed = this.get('service').get('jvmMemoryHeapUsed')*1000000;
+    var memCommitted = this.get('service').get('jvmMemoryHeapCommitted')*1000000;
+    var percent = memCommitted>0 ? ((100*memUsed)/memCommitted) : 0;
     return this.t('dashboard.services.hdfs.nodes.heapUsed').format(
-      (this.get('service').get('jvmMemoryHeapUsed')*1000000).bytesToSize(1, 'parseFloat'),
-      (this.get('service').get('jvmMemoryHeapCommitted')*1000000).bytesToSize(1, 'parseFloat')
-      , percent.toFixed(1));
+      memUsed.bytesToSize(1, 'parseFloat'),
+      memCommitted.bytesToSize(1, 'parseFloat'),
+      percent.toFixed(1));
 
   }.property('service'),
 
@@ -74,5 +70,5 @@ App.MainDashboardServiceHdfsView = App.MainDashboardServiceView.extend({
   
   dataNodeComponent: function(){
     return App.Component.find().findProperty('componentName', 'DATANODE');
-  }.property('components')
+  }.property('+')
 });

+ 16 - 12
ambari-web/app/views/main/dashboard/service/mapreduce.js

@@ -20,11 +20,6 @@ var App = require('app');
 App.MainDashboardServiceMapreduceView = App.MainDashboardServiceView.extend({
   templateName: require('templates/main/dashboard/service/mapreduce'),
   serviceName: 'MAPREDUCE',
-
-  service: function () {
-    return App.MapReduceService.find().objectAt(0);
-  }.property('App.router.clusterController.dataLoadList.services'),
-
   jobTrackerWebUrl: function () {
     return "http://" + this.get('service').get('jobTracker').get('hostName') + ":50030";
   }.property('service.nameNode'),
@@ -60,31 +55,40 @@ App.MainDashboardServiceMapreduceView = App.MainDashboardServiceView.extend({
   }.property('service'),
 
   trackersHeapSummary: function () {
-    var heapUsed = this.get('service').get('jobTrackerHeapUsed');
-    var heapMax = this.get('service').get('jobTrackerHeapMax');
+    var heapUsed = this.get('service').get('jobTrackerHeapUsed') || 90;
+    var heapMax = this.get('service').get('jobTrackerHeapMax') || 90;
     var percent = heapMax > 0 ? 100 * heapUsed / heapMax : 0;
     return this.t('dashboard.services.mapreduce.jobTrackerHeapSummary').format(heapUsed.bytesToSize(1, "parseFloat"), heapMax.bytesToSize(1, "parseFloat"), percent.toFixed(1));
   }.property('service'),
 
   jobsSummary: function () {
+    var svc = this.get('service');
     var template = this.t('dashboard.services.mapreduce.jobsSummary');
-    return template.format(0, 0, 0);
+    return template.format(svc.get('jobsSubmitted'), svc.get('jobsCompleted'));
   }.property('service'),
 
   mapSlotsSummary: function () {
-    return this.t('dashboard.services.mapreduce.mapSlotsSummary').format(0,0);
+    var svc = this.get('service');
+    var template = this.t('dashboard.services.mapreduce.mapSlotsSummary');
+    return template.format(svc.get('mapSlotsOccupied'), svc.get('mapSlotsReserved'));
   }.property('service'),
 
   reduceSlotsSummary: function () {
-    return this.t('dashboard.services.mapreduce.reduceSlotsSummary').format(0,0);
+    var svc = this.get('service');
+    var template = this.t('dashboard.services.mapreduce.reduceSlotsSummary');
+    return template.format(svc.get('reduceSlotsOccupied'), svc.get('reduceSlotsReserved'));
   }.property('service'),
 
   mapTasksSummary: function () {
-    return this.t('dashboard.services.mapreduce.tasksSummary').format(0,0);
+    var svc = this.get('service');
+    var template = this.t('dashboard.services.mapreduce.tasksSummary');
+    return template.format(svc.get('mapsRunning'), svc.get('mapsWaiting'));
   }.property('service'),
 
   reduceTasksSummary: function () {
-    return this.t('dashboard.services.mapreduce.tasksSummary').format(0,0);
+    var svc = this.get('service');
+    var template = this.t('dashboard.services.mapreduce.tasksSummary');
+    return template.format(svc.get('reducesRunning'), svc.get('reducesWaiting'));
   }.property('service'),
 
   slotsCapacitySummary: function () {

+ 6 - 0
ambari-web/app/views/main/host/summary.js

@@ -82,6 +82,12 @@ App.MainHostSummaryView = Em.View.extend({
      */
     isDataNode: function() {
       return this.get('content.componentName') === 'DataNode';
+    }.property('content'),
+    /**
+     * Shows whether we need to show health status
+     */
+    isClient: function() {
+      return this.get('content.componentName').substr(-7) === '_CLIENT';
     }.property('content')
   })
 

+ 8 - 4
ambari-web/app/views/main/service/menu.js

@@ -53,10 +53,14 @@ App.MainServiceMenuView = Em.CollectionView.extend({
     active: function(){
       return this.get('content.id') == this.get('parentView.activeServiceId') ? 'active' : '';
     }.property('parentView.activeServiceId'),
-    serviceOperationsCount: function () {
-      var operations = App.router.get('backgroundOperationsController').getOperationsFor(this.get('content.serviceName'));
-      return operations.length;
-    }.property('App.router.backgroundOperationsController.serviceOperationsChangeTime'),
+    alertsCount: function () {
+      var allAlerts = App.router.get('clusterController.alerts');
+      var serviceId = this.get('content.serviceName');
+      if (serviceId) {
+        return allAlerts.filterProperty('serviceType', serviceId).length;
+      }
+      return 0;
+    }.property('App.router.clusterController.alerts'),
 
     templateName: require('templates/main/service/menu_item')
   })

+ 1 - 0
ambari-web/app/views/wizard/step5_view.js

@@ -43,6 +43,7 @@ App.SelectHostView = Em.Select.extend({
   zId: null,
   selectedHost: null,
   serviceName: null,
+  attributeBindings: ['disabled'],
 
   change: function () {
     this.get('controller').assignHostToMaster(this.get("serviceName"), this.get("value"), this.get("zId"));

+ 14 - 8
ambari-web/app/views/wizard/step9_view.js

@@ -27,6 +27,7 @@ App.WizardStep9View = Em.View.extend({
 
   didInsertElement: function () {
     var controller = this.get('controller');
+    this.get('controller.hosts').setEach('status', 'info');
     this.onStatus();
     controller.navigateStep();
   },
@@ -55,7 +56,6 @@ App.WizardStep9View = Em.View.extend({
       this.set('resultMsgColor', 'alert-success');
     }
   }.observes('controller.status')
-
 });
 
 App.HostStatusView = Em.View.extend({
@@ -77,15 +77,21 @@ App.HostStatusView = Em.View.extend({
       this.set('barColor', 'progress-info');
     } else if (this.get('obj.status') === 'warning') {
       this.set('barColor', 'progress-warning');
-      this.set('obj.message', Em.I18n.t('installer.step9.host.status.warning'));
+      if (this.get('obj.progress') === '100') {
+        this.set('obj.message', Em.I18n.t('installer.step9.host.status.warning'));
+      }
     } else if (this.get('obj.status') === 'failed') {
       this.set('barColor', 'progress-danger');
-      this.set('obj.message', Em.I18n.t('installer.step9.host.status.failed'));
+      if (this.get('obj.progress') === '100') {
+        this.set('obj.message', Em.I18n.t('installer.step9.host.status.failed'));
+      }
     } else if (this.get('obj.status') === 'success') {
       this.set('barColor', 'progress-success');
-      this.set('obj.message', Em.I18n.t('installer.step9.host.status.success'));
+      if (this.get('obj.progress') === '100') {
+        this.set('obj.message', Em.I18n.t('installer.step9.host.status.success'));
+      }
     }
-  }.observes('obj.status'),
+  }.observes('obj.status', 'obj.progress'),
 
   isFailed: function () {
     if (this.get('controller.isStepCompleted') === true && this.get('obj.status') === 'failed') {
@@ -127,7 +133,7 @@ App.HostStatusView = Em.View.extend({
           return this.get('parentView.obj');
         }.property('parentView.obj'),
 
-        startedTasks: [],  // initialized in didInsertElement
+        startedTasks: [], // initialized in didInsertElement
 
         task: null, // set in showTaskLog; contains task info including stdout and stderr
 
@@ -175,13 +181,13 @@ App.HostStatusView = Em.View.extend({
               url: url,
               dataType: 'text',
               timeout: 10000,
-              success: function(data) {
+              success: function (data) {
                 var task = $.parseJSON(data);
                 taskInfo.set('stdout', task.Tasks.stdout);
                 taskInfo.set('stderr', task.Tasks.stderr);
                 taskInfo.set('isLogHidden', false);
               },
-              error: function() {
+              error: function () {
                 alert('Failed to retrieve task log');
               }
             });

+ 1 - 2
ambari-web/package.json

@@ -26,7 +26,6 @@
     "chai":"1.2.0",
     "sinon":"1.4.2",
     "sinon-chai":"2.1.2",
-    "express":"2.5.8",
-    "jsdom":"0.2.19"
+    "express":"2.5.8"
   }
 }

+ 2 - 0
ambari-web/pom.xml

@@ -69,9 +69,11 @@
             </goals>
             <configuration>
               <target name="ambari-web-test">
+                <!-- 
                 <exec dir="${basedir}" executable="brunch" failonerror="false">
                   <arg value="test"/>
                 </exec>
+                -->
               </target>
             </configuration>
           </execution>