python-cli/mft_cli/airavata_mft_cli/bootstrap.py (149 lines of code) (raw):

# # 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 typer import requests import os import zipfile from subprocess import check_output from subprocess import STDOUT from subprocess import call from subprocess import Popen from pathlib import Path from sys import platform import shutil import time def download_and_unarchive(url, download_path, extract_dir = os.path.join(os.path.expanduser('~'), ".mft/")): response = requests.get(url, stream=True) file_size = int(response.headers['Content-Length']) with typer.progressbar(length=file_size) as progress: with open(download_path, "wb") as handle: for data in response.iter_content(chunk_size=8192 * 2): progress.update(len(data)) handle.write(data) print("Un archiving ....") with zipfile.ZipFile(download_path,"r") as zip_ref: zip_ref.extractall(extract_dir) os.remove(download_path) def restart_service(bin_path, daemon_script_name): current_dir = os.getcwd() try: os.chdir(bin_path) os.chmod(daemon_script_name, 0o744) rc = call(["./" + daemon_script_name, "stop"]) rc = call(["./" + daemon_script_name, "start"]) finally: os.chdir(current_dir) def stop_service(bin_path, daemon_script_name): current_dir = os.getcwd() try: os.chdir(bin_path) os.chmod(daemon_script_name, 0o744) rc = call(["./" + daemon_script_name, "stop"]) finally: os.chdir(current_dir) def validate_java_availability(required_version): """ Issue 96: https://github.com/apache/airavata-mft/issues/96 References: --------- https://stackoverflow.com/questions/31807882/get-java-version-number-from-python https://stackoverflow.com/questions/1332598/how-to-determine-whether-java-is-installed-on-a-system-through-python https://stackoverflow.com/questions/74206258/how-are-oracle-jdk-versions-numbered https://docs.python.org/3.8/library/subprocess.html#subprocess.check_output https://stackoverflow.com/questions/2411288/java-versioning-and-terminology-1-6-vs-6-0-openjdk-vs-sun """ if shutil.which("java"): res = check_output(['java', '-version'], stderr=STDOUT).decode('utf-8') """ res will have the value similar to the following openjdk version "17.0.5" 2022-10-18 LTS OpenJDK Runtime Environment Corretto-17.0.5.8.1 (build 17.0.5+8-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.5.8.1 (build 17.0.5+8-LTS, mixed mode, sharing) """ java_version = '' count = 0 for c in res: if c == '"' or count == 1: if (c == '.' or c == '"') and count == 1: break if count == 0: count += 1 continue java_version += c java_version = int(java_version) if java_version < required_version: print("Airavata MFT requires Java version " + required_version + " or higher") print("If you have more than one version of java please set java version "+ required_version +" or higher to the path") raise typer.Exit() else: print("Java is either not installed or path hasn't been set properly") raise typer.Exit() def start_mft(): print("Setting up MFT Services") required_java_version = 11 if platform == "linux" or platform == "linux2": consul_url = "https://releases.hashicorp.com/consul/1.7.1/consul_1.7.1_linux_amd64.zip" validate_java_availability(required_java_version) elif platform == "darwin": consul_url = "https://releases.hashicorp.com/consul/1.7.1/consul_1.7.1_darwin_amd64.zip" validate_java_availability(required_java_version) elif platform == "win32": print("Windows support is not available yet") raise typer.Exit() else: print("Un supported platform: " + platform) raise typer.Exit() mft_dir = os.path.join(os.path.expanduser('~'), ".mft") if not os.path.exists(mft_dir): os.makedirs(mft_dir) path = os.path.join(os.path.expanduser('~'), ".mft/consul") if not os.path.exists(path): print("Downloading Consul...") zip_path = os.path.join(os.path.expanduser('~'), ".mft/consul.zip") download_and_unarchive(consul_url, zip_path, os.path.join(os.path.expanduser('~'), ".mft/")) current_dir = os.getcwd() try: os.chdir(os.path.join(os.path.expanduser('~'), ".mft")) os.chmod("consul", 0o744) if os.path.exists("consul.pid"): pid = Path('consul.pid').read_text() call(["kill", "-9", pid]) consul_process = Popen(['nohup', './consul', "agent", "-dev"], stdout=open('consul.log', 'w'), stderr=open('consul.err.log', 'a'), preexec_fn=os.setpgrp) print("Consul process id: " + str(consul_process.pid)) with open("consul.pid", "w") as consul_pid: consul_pid.write(str(consul_process.pid)) finally: os.chdir(current_dir) path = os.path.join(os.path.expanduser('~'), ".mft/Standalone-Service-0.01") if not os.path.exists(path): url = "https://github.com/apache/airavata-mft/releases/download/v0.0.1/Standalone-Service-0.01-bin.zip" print("Downloading MFT Server...") zip_path = os.path.join(os.path.expanduser('~'), ".mft/Standalone-Service-0.01-bin.zip") download_and_unarchive(url, zip_path) restart_service(path + "/bin", "standalone-service-daemon.sh") print("MFT Started") def stop_mft(): print("Stopping MFT Services") path = os.path.join(os.path.expanduser('~'), ".mft/consul") if os.path.exists(path): current_dir = os.getcwd() try: os.chdir(os.path.join(os.path.expanduser('~'), ".mft")) os.chmod("consul", 0o744) if os.path.exists("consul.pid"): pid = Path('consul.pid').read_text() call(["kill", "-9", pid]) finally: os.chdir(current_dir) path = os.path.join(os.path.expanduser('~'), ".mft/Standalone-Service-0.01") if os.path.exists(path): stop_service(path + "/bin", "standalone-service-daemon.sh") print("MFT Stopped....") def update_mft(): stop_mft() mft_dir = os.path.join(os.path.expanduser('~'), ".mft") if os.path.exists(mft_dir): print("Removing .mft directory") shutil.rmtree(mft_dir) database = os.path.join(os.path.expanduser('~'), "mft_db.mv.db") if os.path.exists(database): os.remove(database) start_mft() def print_log(): log_file_path = os.path.join(os.path.expanduser('~'), ".mft", "Standalone-Service-0.01", "logs", "airavata.log") log_file = open(log_file_path,"r") lines = follow_file(log_file) for line in lines: print(line) def follow_file(file): #file.seek(0, os.SEEK_END) while True: line = file.readline() if not line: time.sleep(0.1) continue yield line