You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ph...@apache.org on 2019/04/11 16:18:44 UTC

[nifi-minifi-cpp] branch master updated: MINIFICPP-672 - Bootstrap agent through Python

This is an automated email from the ASF dual-hosted git repository.

phrocker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git


The following commit(s) were added to refs/heads/master by this push:
     new 6b40502  MINIFICPP-672 - Bootstrap agent through Python
6b40502 is described below

commit 6b40502cbc819f9979b6767a2a872deb1823560b
Author: Arpad Boda <ab...@hortonworks.com>
AuthorDate: Tue Mar 12 14:53:14 2019 +0100

    MINIFICPP-672 - Bootstrap agent through Python
    
    This closes #527.
    
    Signed-off-by: Marc Parisi <ph...@apache.org>
---
 bootstrap.py | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)

diff --git a/bootstrap.py b/bootstrap.py
new file mode 100755
index 0000000..cfe76e8
--- /dev/null
+++ b/bootstrap.py
@@ -0,0 +1,237 @@
+#!/usr/bin/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.
+
+from __future__ import print_function
+
+MINIFI_SUBFOLDER = '/nifi/nifi-minifi-cpp/'
+APACHE_CLOSER_REPO_JSON_URL = 'https://www.apache.org/dyn/closer.cgi?as_json=1&path=/nifi/nifi-minifi-cpp'
+APACHE_MIRROR_LIST = "http://www.apache.org/mirrors/"
+
+import argparse
+import sys
+
+if sys.version_info[0] < 3:
+  from urllib2 import urlopen
+  input = raw_input
+else:
+  from urllib.request import urlopen
+
+import json
+import os.path
+import platform
+import tarfile
+
+
+from distutils.util import strtobool
+from ftplib import FTP
+
+def install_package(package_name):
+  try:
+    import pip
+    if hasattr(pip, 'main'):
+      pipcode = pip.main(['install', package])
+    else:
+      pipcode = pip._internal.main(['install', package])
+    return pipcode == 0
+  except:
+    return False
+
+
+distro_available = False
+
+try:
+  import distro
+
+  distro_available = True
+except:
+  distro_available = install_package("distro")
+
+
+def get_distro():
+  if is_mac():
+    return ["osx", "", "darwin"]
+  try:
+    if distro_available:
+      return distro.linux_distribution(full_distribution_name=False)
+    else:
+      return platform.linux_distribution()
+  except:
+    return ["N/A", "N/A", "N/A"]
+
+
+def is_mac():
+  return platform.system() == "Darwin"
+
+
+def mapped_distro():
+  distro_info = get_distro()
+  distro = distro_info[0].lower()
+  release = distro_info[2].lower()
+  if any(d in distro for d in ["rhel", "red hat", "centos"]):
+    return "rhel", release
+  else:
+    return distro, release
+
+
+def find_closest_mirror():
+  try:
+    url = urlopen(APACHE_CLOSER_REPO_JSON_URL)
+    data = json.loads(url.read().decode())
+
+    return data['ftp'][0]
+
+  except Exception as e:
+    print ("Failed to find closest mirror, please specify one!")
+    return ""
+
+
+def get_release_and_binaries_from_ftp(host, apache_dir, version = None):
+  ftp = FTP(host)
+  ftp.login()
+  ftp.cwd(apache_dir + MINIFI_SUBFOLDER)
+  # list files with ftplib
+  file_list = list(filter(lambda x: any(char.isdigit() for char in x),
+                          ftp.nlst("")))  # to filter "." and ".." - relese names contain number
+  file_list.sort(reverse=True)
+  if not version:
+    latest_release = file_list[0]
+  else:
+    if version not in file_list:
+      print("The specified version (" + version + ") doesn't exist. Please use one of the following: " + ", ".join(file_list))
+      exit(-1)
+    latest_release = version
+
+  ftp.cwd("./" + latest_release)
+  binaries = list(filter(lambda x: any(char.isdigit() for char in x), ftp.nlst("")))
+
+  ftp.quit()
+
+  return latest_release, binaries
+
+
+def download_binary_from_ftp(host, apache_dir, release, binary):
+  successful_download = False
+
+  try:
+    ftp = FTP(host)
+    ftp.login()
+    ftp.cwd(apache_dir + MINIFI_SUBFOLDER + release)
+
+    print ("Downloading: ftp://" + host + "/" + MINIFI_SUBFOLDER + release + "/" + binary)
+
+    with open(os.path.join(os.getcwd(), binary), "wb") as targetfile:
+      ftp.retrbinary("RETR " + binary, targetfile.write)
+    successful_download = True
+  except:
+    print("Failed to download binary")
+  finally:
+    ftp.quit()
+
+  return successful_download
+
+
+def main(args):
+  print(get_distro())
+  binaries = []
+
+  try:
+    local_repo = args.mirror if args.mirror else find_closest_mirror()
+
+    print(local_repo)
+
+    host, dir = local_repo.replace('ftp://', '').split('/', 1)
+    latest_release, binaries = get_release_and_binaries_from_ftp(host, dir, args.version if args.version else None)
+
+  except:
+    print("Failed to get binaries from Apache mirror")
+    return -1
+
+  matching_binaries = []
+
+  for binary in binaries:
+    distro, release = mapped_distro()
+    if release and release in binary:
+      matching_binaries.append(binary)
+    elif distro and distro in binary:
+      matching_binaries.append(binary)
+
+  if not matching_binaries:
+    print("No compatible binary found, MiNiFi needs to be compiled locally")
+    return 1
+
+  invalid_input = True
+  download = None
+  selected_binary = None
+
+  if len(matching_binaries) == 1:
+    print("A binary in Apache repo seems to match your system: " + matching_binaries[0])
+    while invalid_input:
+      try:
+        download = strtobool(input("Would you like to download? [y/n]"))
+        invalid_input = False
+        if download:
+          selected_binary = matching_binaries[0]
+      except:
+        pass
+
+  else:
+    print("The following binaries in Apache repo seem to match your system: ")
+    for i, item in enumerate(matching_binaries):
+      print(str(i + 1) + " - " + item)
+    print()
+    while invalid_input:
+      try:
+        user_input = input("Please select one to download (1 to " + str(
+          len(matching_binaries)) + ") or \"s\" to skip and compile locally\n")
+        user_input.lower()
+        if user_input == "s":
+          invalid_input = False
+          download = False
+          break
+        idx = int(user_input) - 1
+        if (idx < 0):
+          continue
+        selected_binary = matching_binaries[idx]
+        download = True
+        invalid_input = False
+      except:
+        pass
+
+  if not download:
+    return 1
+
+  if not download_binary_from_ftp(host, dir, latest_release, selected_binary):
+    return -1
+
+  try:
+    with tarfile.open(os.path.join(os.getcwd(), selected_binary), "r:gz") as tar:
+      tar.extractall()
+  except:
+    print("Failed to extract tar file")
+    return -1
+
+  print("Successfully downloaded and extracted MiNiFi")
+  return 0
+
+
+if __name__ == '__main__':
+  parser = argparse.ArgumentParser(description="Download latest MiNiFi release")
+  parser.add_argument("-m", "--mirror", dest="mirror", help="user-specified apache mirror")
+  parser.add_argument("-v", "--version", dest="version", help="user-specified version to be downloaded")
+  args = parser.parse_args()
+  main(args)