Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id CF9E9200CA4 for ; Tue, 23 May 2017 11:53:02 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id CE881160BEF; Tue, 23 May 2017 09:53:02 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 91744160BE5 for ; Tue, 23 May 2017 11:53:01 +0200 (CEST) Received: (qmail 90447 invoked by uid 500); 23 May 2017 09:53:00 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 89410 invoked by uid 99); 23 May 2017 09:53:00 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 May 2017 09:53:00 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 0F699E00B3; Tue, 23 May 2017 09:53:00 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: adoroszlai@apache.org To: commits@ambari.apache.org Date: Tue, 23 May 2017 09:53:40 -0000 Message-Id: <15645eb06a3e41ad95a548e15e8305f7@git.apache.org> In-Reply-To: <645a5a0143ef494fb15ab90178b232ad@git.apache.org> References: <645a5a0143ef494fb15ab90178b232ad@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [42/50] [abbrv] ambari git commit: AMBARI-21069. Minimize config changes during ambari upgrade. Add script to compare stack configs (dlysnichenko) archived-at: Tue, 23 May 2017 09:53:03 -0000 AMBARI-21069. Minimize config changes during ambari upgrade. Add script to compare stack configs (dlysnichenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5ea441aa Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5ea441aa Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5ea441aa Branch: refs/heads/ambari-rest-api-explorer Commit: 5ea441aa7b4080a7a1eb07a4a1e01a2aa8d0d92e Parents: cdc18ec Author: Lisnichenko Dmitro Authored: Mon May 22 18:48:32 2017 +0300 Committer: Lisnichenko Dmitro Committed: Mon May 22 18:48:32 2017 +0300 ---------------------------------------------------------------------- .../config-utils/diff_stack_properties.py | 154 +++++++++++++++++++ 1 file changed, 154 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/5ea441aa/dev-support/config-utils/diff_stack_properties.py ---------------------------------------------------------------------- diff --git a/dev-support/config-utils/diff_stack_properties.py b/dev-support/config-utils/diff_stack_properties.py new file mode 100644 index 0000000..beef608 --- /dev/null +++ b/dev-support/config-utils/diff_stack_properties.py @@ -0,0 +1,154 @@ +#!/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. +""" + +import sys +import os + +import xml.etree.ElementTree as ET + +COMMON = "common-services" +STACKS = "stacks" +CONFIG_DIR = "configuration" +SERVICES_DIR = "services" + +SYMLINKS_TXT = "symlinks.txt" +VERSIONS_TXT = "versions.txt" + + +def main(): + """ Parse arguments from user, check that all required args are passed in and start work.""" + + if len(sys.argv) != 3: + print "usage: diff_stack_properties.py [first_stack_dir] [second_stack_dir]" + sys.exit(-1) + + args = sys.argv[1:] + + if not os.path.exists(args[0]) or not os.path.exists(args[1]): + print "usage: diff_stack_properties.py [first_stack_dir] [second_stack_dir]" + sys.exit(-1) + + args = sys.argv[1:] + + do_work(args) + + +def do_work(args): + """ + Compare stack dirs. + :param args: + """ + new_stacks = args[0] + old_stacks = args[1] + + compare_common(new_stacks, old_stacks) + + compare_stacks(new_stacks, old_stacks) + + +def compare_stacks(new_stacks, old_stacks): + print "#############[{}]#############".format(STACKS) + for stack in [stack for stack in os.listdir(os.path.join(new_stacks, STACKS)) if + os.path.isdir(os.path.join(new_stacks, STACKS, stack))]: + for version in os.listdir(os.path.join(new_stacks, STACKS, stack)): + if os.path.exists(os.path.join(new_stacks, STACKS, stack, version, CONFIG_DIR)): + diff = compare_config_dirs(os.path.join(new_stacks, STACKS, stack, version, CONFIG_DIR), + os.path.join(old_stacks, STACKS, stack, version, CONFIG_DIR)) + if diff != "": + print "#############{}.{}#############".format(stack, version) + print diff + if os.path.exists(os.path.join(new_stacks, STACKS, stack, version, SERVICES_DIR)): + print "#############{}.{}#############".format(stack, version) + for service_name in os.listdir(os.path.join(new_stacks, STACKS, stack, version, SERVICES_DIR)): + new_configs_dir = os.path.join(new_stacks, STACKS, stack, version, SERVICES_DIR, service_name, CONFIG_DIR) + old_configs_dir = os.path.join(old_stacks, STACKS, stack, version, SERVICES_DIR, service_name, CONFIG_DIR) + diff = compare_config_dirs(new_configs_dir, old_configs_dir) + if diff != "": + print "=========={}==========".format(service_name) + print diff + + +def compare_common(new_stacks, old_stacks): + print "#############[{}]#############".format(COMMON) + for service_name in os.listdir(os.path.join(new_stacks, COMMON)): + for version in os.listdir(os.path.join(new_stacks, COMMON, service_name)): + new_configs_dir = os.path.join(new_stacks, COMMON, service_name, version, CONFIG_DIR) + old_configs_dir = os.path.join(old_stacks, COMMON, service_name, version, CONFIG_DIR) + diff = compare_config_dirs(new_configs_dir, old_configs_dir) + if diff != "": + print "=========={}.{}==========".format(service_name, version) + print diff + + +def compare_config_dirs(new_configs_dir, old_configs_dir): + result = "" + if os.path.exists(old_configs_dir) and os.path.exists(new_configs_dir): + for file_name in os.listdir(new_configs_dir): + old_file_name = os.path.join(old_configs_dir, file_name) + if os.path.exists(old_file_name): + result += compare_config_files(os.path.join(new_configs_dir, file_name), + os.path.join(old_configs_dir, file_name), + file_name) + else: + result += "new file {}\n".format(file_name) + else: + if os.path.exists(old_configs_dir) or os.path.exists(new_configs_dir): + if not os.path.exists(new_configs_dir): + result += "deleted configuration dir {}\n".format(new_configs_dir) + if not os.path.exists(old_configs_dir): + result += "new configuration dir {} with files {} \n".format(new_configs_dir, os.listdir(new_configs_dir)) + return result + + +def compare_config_files(new_configs, old_configs, file_name): + result = "" + if os.path.exists(old_configs): + old_configs_tree = ET.ElementTree(file=old_configs) + new_configs_tree = ET.ElementTree(file=new_configs) + for new_property in new_configs_tree.findall("property"): + name = new_property.find("name").text + if new_property.find("value") is not None: + value = new_property.find("value").text + if new_property.find("on-ambari-upgrade") is not None: + on_amb_upgrade = new_property.find("on-ambari-upgrade").get("add") + else: + on_amb_upgrade = None + + deleted = None + old_deleted = None + if new_property.find("deleted") is not None: + deleted = new_property.find("deleted").text + old_property = old_configs_tree.find("property[name='{}']".format(name)) + + if on_amb_upgrade == "true" and old_property is None: + result += "add {}\n".format(name) + else: + if old_property is not None and old_property.find("deleted") is not None: + old_deleted = old_property.find("deleted").text + if deleted == "true" and old_deleted != "true": + result += "deleted {}\n".format(name) + if result != "": + result = "------{}------\n".format(file_name) + result + else: + result += "{} not exists\n".format(old_configs, ) + return result + + +if __name__ == "__main__": + main()