ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vbrodets...@apache.org
Subject ambari git commit: AMBARI-13274. Define a new API to refresh HDP.repo files using the provided repo baseurl.(vbrodetskyi)
Date Thu, 08 Oct 2015 15:41:35 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 664bde1c6 -> b434f1891


AMBARI-13274. Define a new API to refresh HDP.repo files using the provided repo baseurl.(vbrodetskyi)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b434f189
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b434f189
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b434f189

Branch: refs/heads/trunk
Commit: b434f18915954a725c1f8cd81b71907c2a9f5174
Parents: 664bde1
Author: Vitaly Brodetskyi <vbrodetskyi@hortonworks.com>
Authored: Thu Oct 8 18:41:07 2015 +0300
Committer: Vitaly Brodetskyi <vbrodetskyi@hortonworks.com>
Committed: Thu Oct 8 18:41:07 2015 +0300

----------------------------------------------------------------------
 .../controller/AmbariActionExecutionHelper.java | 78 ++++++++++++-----
 .../system_action_definitions.xml               | 10 +++
 .../custom_actions/scripts/update_repo.py       | 71 ++++++++++++++++
 .../python/custom_actions/TestUpdateRepo.py     | 89 ++++++++++++++++++++
 4 files changed, 227 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b434f189/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
index 1c110fc..a379a75 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariActionExecutionHelper.java
@@ -18,18 +18,10 @@
 
 package org.apache.ambari.server.controller;
 
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMPONENT_CATEGORY;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.Role;
@@ -43,6 +35,10 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 import org.apache.ambari.server.customactions.ActionDefinition;
+import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
+import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
@@ -55,8 +51,17 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMPONENT_CATEGORY;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
 
 /**
  * Helper class containing logic to process custom action execution requests
@@ -77,6 +82,8 @@ public class AmbariActionExecutionHelper {
   private MaintenanceStateHelper maintenanceStateHelper;
   @Inject
   private Configuration configs;
+  @Inject
+  private ClusterVersionDAO clusterVersionDAO;
 
   /**
    * Validates the request to execute an action.
@@ -195,13 +202,14 @@ public class AmbariActionExecutionHelper {
       }
     }
 
-    if (TargetHostType.SPECIFIC.equals(actionDef.getTargetType())
-      || (targetService.isEmpty() && targetComponent.isEmpty())) {
-      if (resourceFilter == null || resourceFilter.getHostNames().size() == 0) {
-        throw new AmbariException("Action " + actionRequest.getActionName() + " requires
explicit target host(s)" +
-          " that is not provided.");
-      }
-    }
+    // decided to hide this part of code, to have ability, by default execute custom action
on all hosts(according to targetType in definition)
+    //if (TargetHostType.SPECIFIC.equals(actionDef.getTargetType())
+    //  || (targetService.isEmpty() && targetComponent.isEmpty())) {
+    //  if (resourceFilter == null || resourceFilter.getHostNames().size() == 0) {
+    //    throw new AmbariException("Action " + actionRequest.getActionName() + " requires
explicit target host(s)" +
+    //      " that is not provided.");
+    //  }
+    //}
   }
 
 
@@ -380,6 +388,8 @@ public class AmbariActionExecutionHelper {
       execCmd.setComponentName(componentName == null || componentName.isEmpty() ?
         resourceFilter.getComponentName() : componentName);
 
+      addRepoInfoToHostLevelParams(cluster, execCmd.getHostLevelParams(), hostName);
+
       Map<String, String> roleParams = execCmd.getRoleParams();
       if (roleParams == null) {
         roleParams = new TreeMap<String, String>();
@@ -412,4 +422,30 @@ public class AmbariActionExecutionHelper {
       }
     }
   }
+
+  private void addRepoInfoToHostLevelParams(Cluster cluster, Map<String, String> hostLevelParams,
String hostName) throws AmbariException {
+    if (cluster != null) {
+      JsonObject rootJsonObject = new JsonObject();
+      JsonArray repositories = new JsonArray();
+      ClusterVersionEntity clusterVersionEntity = clusterVersionDAO.findByClusterAndStateCurrent(cluster.getClusterName());
+      if (clusterVersionEntity != null && clusterVersionEntity.getRepositoryVersion()
!= null) {
+        String hostOsFamily = clusters.getHost(hostName).getOsFamily();
+        for (OperatingSystemEntity operatingSystemEntity : clusterVersionEntity.getRepositoryVersion().getOperatingSystems())
{
+          // ostype in OperatingSystemEntity it's os family. That should be fixed in OperatingSystemEntity.
+          if (operatingSystemEntity.getOsType().equals(hostOsFamily)) {
+            for (RepositoryEntity repositoryEntity : operatingSystemEntity.getRepositories())
{
+              JsonObject repositoryInfo = new JsonObject();
+              repositoryInfo.addProperty("base_url", repositoryEntity.getBaseUrl());
+              repositoryInfo.addProperty("repo_name", repositoryEntity.getName());
+              repositoryInfo.addProperty("repo_id", repositoryEntity.getRepositoryId());
+
+              repositories.add(repositoryInfo);
+            }
+            rootJsonObject.add("repositories", repositories);
+          }
+        }
+      }
+      hostLevelParams.put("repo_info", rootJsonObject.toString());
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b434f189/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
b/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
index 777ced7..e725d68 100644
--- a/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
+++ b/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
@@ -30,6 +30,16 @@
     <targetType>ANY</targetType>
   </actionDefinition>
   <actionDefinition>
+    <actionName>update_repo</actionName>
+    <actionType>SYSTEM</actionType>
+    <inputs/>
+    <targetService/>
+    <targetComponent/>
+    <defaultTimeout>60</defaultTimeout>
+    <description>Update repo files on hosts</description>
+    <targetType>ALL</targetType>
+  </actionDefinition>
+  <actionDefinition>
     <actionName>validate_configs</actionName>
     <actionType>SYSTEM</actionType>
     <inputs/>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b434f189/ambari-server/src/main/resources/custom_actions/scripts/update_repo.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/update_repo.py b/ambari-server/src/main/resources/custom_actions/scripts/update_repo.py
new file mode 100644
index 0000000..9f2107d
--- /dev/null
+++ b/ambari-server/src/main/resources/custom_actions/scripts/update_repo.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Ambari Agent
+
+"""
+from resource_management import *
+from resource_management import Script, Repository, format
+from ambari_commons.os_check import OSCheck
+import ambari_simplejson as json
+from resource_management.core.logger import Logger
+
+
+
+class UpdateRepo(Script):
+
+  UBUNTU_REPO_COMPONENTS_POSTFIX = ["main"]
+
+  def actionexecute(self, env):
+    config = Script.get_config()
+    structured_output = {}
+
+
+    try:
+      repo_info_json = config['hostLevelParams']['repo_info']
+      repo_info_dict = json.loads(repo_info_json)
+
+      for item in repo_info_dict["repositories"]:
+        base_url = item["base_url"]
+        repo_name = item["repo_name"]
+        repo_id = item["repo_id"]
+
+        repo_rhel_suse = config['configurations']['cluster-env']['repo_suse_rhel_template']
+        repo_ubuntu = config['configurations']['cluster-env']['repo_ubuntu_template']
+
+        template = repo_rhel_suse if OSCheck.is_suse_family() or OSCheck.is_redhat_family()
else repo_ubuntu
+        ubuntu_components = [repo_name] + self.UBUNTU_REPO_COMPONENTS_POSTFIX
+
+        Repository(repo_id,
+                 action = "create",
+                 base_url = base_url,
+                 mirror_list = None,
+                 repo_file_name = repo_name,
+                 repo_template = template,
+                 components = ubuntu_components, # ubuntu specific
+        )
+        structured_output["repo_update"] = {"exit_code" : 0, "message": format("Repository
files successfully updated!")}
+    except Exception, exception:
+      Logger.logger.exception("ERROR: There was an unexpected error while updating repositories")
+      raise Fail("Failed to update repo files!")
+
+    self.put_structured_out(structured_output)
+
+
+if __name__ == "__main__":
+  UpdateRepo().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/b434f189/ambari-server/src/test/python/custom_actions/TestUpdateRepo.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/custom_actions/TestUpdateRepo.py b/ambari-server/src/test/python/custom_actions/TestUpdateRepo.py
new file mode 100644
index 0000000..f3ee5ba
--- /dev/null
+++ b/ambari-server/src/test/python/custom_actions/TestUpdateRepo.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Ambari Agent
+
+"""
+import os, sys
+
+from mock.mock import patch
+from mock.mock import MagicMock
+from unittest import TestCase
+
+from resource_management import *
+from resource_management import Script
+
+from ambari_commons.os_check import OSCheck
+from update_repo import UpdateRepo
+
+class TestUpdateRepo(TestCase):
+
+
+  @patch.object(OSCheck, "is_suse_family")
+  @patch.object(OSCheck, "is_ubuntu_family")
+  @patch.object(OSCheck, "is_redhat_family")
+  @patch.object(Script, 'get_config')
+  @patch("resource_management.libraries.providers.repository.File")
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  @patch.object(System, "os_family", new='redhat')
+  def testUpdateRepo(self, structured_out_mock, file_mock, mock_config, is_redhat_mock, is_ubuntu_mock,
is_suse_mock):
+    ###### valid case
+    is_suse_mock.return_value = False
+    is_ubuntu_mock.return_value = False
+    is_redhat_mock.return_value = True
+    updateRepo = UpdateRepo()
+
+    mock_config.return_value = { "configurations": {
+                                        "cluster-env": {
+                                                "repo_suse_rhel_template": "REPO_SUSE_RHEL_TEST_TEMPLATE",
+                                                "repo_ubuntu_template": "REPO_UBUNTU_TEMPLATE"
+                                        }
+                                 },
+                                 "hostLevelParams": {
+                                   "repo_info": '{"repositories":[{"base_url":"TEST_BASE_URL","repo_name":"TEST_REPO_NAME","repo_id":"TEST_REPO_ID"}]}'
+                                 }
+                               }
+
+    with Environment('/') as env:
+      updateRepo.actionexecute(None)
+
+    self.assertTrue(file_mock.called)
+    self.assertEquals(file_mock.call_args[0][0], "/etc/yum.repos.d/TEST_REPO_NAME.repo")
+    self.assertEquals(structured_out_mock.call_args[0][0], {'repo_update': {'message': 'Repository
files successfully updated!', 'exit_code': 0}})
+
+    ###### invalid repo info
+    file_mock.reset_mock()
+    failed = False
+    mock_config.return_value = { "configurations": {
+                                        "cluster-env": {
+                                                "repo_suse_rhel_template": "REPO_SUSE_RHEL_TEST_TEMPLATE",
+                                                "repo_ubuntu_template": "REPO_UBUNTU_TEMPLATE"
+                                        }
+                                 },
+                                 "hostLevelParams": {
+                                   "repo_info": '{}'
+                                 }
+                               }
+    try:
+      with Environment('/') as env:
+        updateRepo.actionexecute(None)
+    except Exception, exception:
+      failed = True
+
+    self.assertFalse(file_mock.called)
+    self.assertTrue(failed)
\ No newline at end of file


Mime
View raw message