* [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS @ 2020-04-06 20:59 Nate DeSimone 2020-04-06 21:19 ` [edk2-devel] " Bjorge, Erik C 2020-04-08 19:59 ` Ashley E Desimone 0 siblings, 2 replies; 5+ messages in thread From: Nate DeSimone @ 2020-04-06 20:59 UTC (permalink / raw) To: devel Cc: Ashley DeSimone, Puja Pandya, Erik Bjorge, Prince Agyeman, Bret Barkelew, Philippe Mathieu-Daude Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Ashley DeSimone <ashley.e.desimone@intel.com> Cc: Puja Pandya <puja.pandya@intel.com> Cc: Erik Bjorge <erik.c.bjorge@intel.com> Cc: Prince Agyeman <prince.agyeman@intel.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Philippe Mathieu-Daude <philmd@redhat.com> --- build-scripts/build_linux_installer.py | 2 + build-scripts/set_version_and_build_wheels.py | 10 +-- edkrepo/config/config_factory.py | 6 +- edkrepo_installer/linux-scripts/install.py | 65 +++++++++++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/build-scripts/build_linux_installer.py b/build-scripts/build_linux_installer.py index 0130552..11dd8d7 100755 --- a/build-scripts/build_linux_installer.py +++ b/build-scripts/build_linux_installer.py @@ -10,6 +10,7 @@ from argparse import ArgumentParser import fnmatch, os, shutil, subprocess, sys import set_version_and_build_wheels as build_edkrepo +import traceback def main(): parser = ArgumentParser() @@ -31,6 +32,7 @@ def main(): try: build_edkrepo.main() except: + traceback.print_exc() print('Failed to build edkrepo wheel') return 1 diff --git a/build-scripts/set_version_and_build_wheels.py b/build-scripts/set_version_and_build_wheels.py index 42e58cc..7df0c84 100755 --- a/build-scripts/set_version_and_build_wheels.py +++ b/build-scripts/set_version_and_build_wheels.py @@ -3,7 +3,7 @@ ## @file # set_version_and_build_wheels.py # -# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -214,7 +214,7 @@ def build_wheels(extension_pkgs): def copy_wheels_and_set_xml(package_version, extension_pkgs): dir_path = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), "dist") dest_path = os.path.join(dir_path, "self_extract") - if ostype == LINUX: + if ostype != WIN: dest_path = os.path.join(dest_path, 'wheels') if not os.path.isdir(dest_path): os.makedirs(dest_path) @@ -241,9 +241,9 @@ def create_final_copy_script(version): f.write("pushd ..\\dist\n") f.write("ren \"setup.exe\" \"EdkRepoSetup-{}.exe\"\n".format(version)) f.write("popd\n") - elif ostype == LINUX: + else: with open('final_copy.py', 'w') as f: - f.write('#!/usr/bin/python3\n') + f.write('#!/usr/bin/env python3\n') f.write('import os, shutil, sys\n') f.write('dist_name = "edkrepo-{{}}".format("{}")\n'.format(version)) f.write('installer_dir = "../dist/self_extract"\n') @@ -257,7 +257,7 @@ def _copy_file(source, destination): check_call("cp -f {} {}".format(source, destination), shell=True) def make_version_cfg_file(version): - if ostype == LINUX: + if ostype != WIN: cfg_src = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), 'edkrepo_installer', 'linux-scripts') install_cfg = configparser.ConfigParser(allow_no_value=True) install_cfg.read(os.path.join(cfg_src, 'install.cfg')) diff --git a/edkrepo/config/config_factory.py b/edkrepo/config/config_factory.py index e3a437f..b86e0b8 100644 --- a/edkrepo/config/config_factory.py +++ b/edkrepo/config/config_factory.py @@ -3,7 +3,7 @@ ## @file # config_factory.py # -# Copyright (c) 2017- 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -30,9 +30,7 @@ def get_edkrepo_global_data_directory(): common_appdata = create_unicode_buffer(MAX_PATH) SHGetFolderPath(None, CSIDL_COMMON_APPDATA, None, SHGFP_TYPE_CURRENT, common_appdata) global_data_dir = os.path.join(common_appdata.value, "edkrepo") - elif sys.platform == "darwin": - raise OSError("macOS support is in progress") - elif sys.platform.startswith("linux") or os.name == "posix": + elif sys.platform == "darwin" or sys.platform.startswith("linux") or os.name == "posix": global_data_dir = os.path.expanduser("~/.edkrepo") if not os.path.isdir(global_data_dir): if not os.path.exists(os.path.dirname(global_data_dir)): diff --git a/edkrepo_installer/linux-scripts/install.py b/edkrepo_installer/linux-scripts/install.py index 52f0c52..099954d 100755 --- a/edkrepo_installer/linux-scripts/install.py +++ b/edkrepo_installer/linux-scripts/install.py @@ -23,6 +23,21 @@ import sys import traceback import xml.etree.ElementTree as et +# +# Environment detection +# +MAC = "mac" +LINUX = "linux" +if sys.platform == "darwin": + ostype = MAC +elif sys.platform.startswith("linux"): + ostype = LINUX +elif os.name == "posix": + print("Warning: Unrecognized UNIX OS... treating as Linux") + ostype = LINUX +else: + raise EnvironmentError("Unsupported OS") + tool_sign_on = 'Installer for edkrepo version {}\nCopyright(c) Intel Corporation, 2020' # Data here should be maintained in a configuration file @@ -31,6 +46,7 @@ directories_with_executables = ['git_automation'] cfg_src_dir = os.path.abspath('config') whl_src_dir = os.path.abspath('wheels') def_python = 'python3' +nfs_home_directory_data = re.compile(r"NFSHomeDirectory:\s*(\S+)") # ZSH Configuration options prompt_regex = re.compile(r"#\s+[Aa][Dd][Dd]\s+[Ee][Dd][Kk][Rr][Ee][Pp][Oo]\s+&\s+[Gg][Ii][Tt]\s+[Tt][Oo]\s+[Tt][Hh][Ee]\s+[Pp][Rr][Oo][Mm][Pp][Tt]") @@ -63,7 +79,8 @@ def init_logger(verbose): def get_args(): parser = ArgumentParser() - parser.add_argument('-l', '--local', action='store_true', default=False, help='Install edkrepo to the user directory instead of system wide') + if ostype != MAC: + parser.add_argument('-l', '--local', action='store_true', default=False, help='Install edkrepo to the user directory instead of system wide') parser.add_argument('-p', '--py', action='store', default=None, help='Specify the python command to use when installing') parser.add_argument('-u', '--user', action='store', default=None, help='Specify user account to install edkrepo support on') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enables verbose output') @@ -218,6 +235,18 @@ def _check_version(current, expected): return 1 return 0 +def get_user_home_directory(username): + if ostype == MAC: + res = default_run(['dscl', '.', '-read', '/Users/{}'.format(username), 'NFSHomeDirectory']) + data = nfs_home_directory_data.match(res.stdout.strip()) + if data: + return data.group(1) + else: + raise ValueError("home directory not found") + else: + res = default_run(['getent', 'passwd', username]) + return res.stdout.strip().split(':')[5] + def get_site_packages_directory(): res = default_run([def_python, '-c', 'import site; print(site.getsitepackages()[0])']) return res.stdout.strip() @@ -424,6 +453,9 @@ def do_install(): # Initialize information based on command line input username = args.user + install_to_local = False + if ostype != MAC and args.local: + install_to_local = True try: cfg = configparser.ConfigParser(allow_no_value=True) @@ -449,7 +481,7 @@ def do_install(): # Determine the user running sudo log.info('\nCollecting system information:') - if not args.local: + if not install_to_local and ostype != MAC: try: res = default_run(['id', '-u']) except: @@ -466,11 +498,21 @@ def do_install(): log.info('- Unable to determine current user. Run installer using the --user flag and specify the correct user name.') return 1 try: - res = default_run(['getent', 'passwd', username]) - user_home_dir = res.stdout.strip().split(':')[5] + user_home_dir = get_user_home_directory(username) except: log.info('- Unable to determine users home directory') return 1 + if ostype == MAC: + try: + res = default_run(['id', '-u']) + except: + log.info('- Failed to determine user ID') + return 1 + if res.stdout.strip() == '0': + log.info('- Installer must NOT be run as root') + return 1 + if os.path.commonprefix([user_home_dir, sys.executable]) != user_home_dir: + install_to_local = True default_cfg_dir = os.path.join(user_home_dir, cfg_dir) get_add_prompt_customization(args, user_home_dir) log.info('+ System information collected') @@ -625,7 +667,7 @@ def do_install(): install_whl = wheels_to_install[whl_name]['install'] if install_whl: install_cmd = [def_python, '-m', 'pip', 'install'] - if args.local: + if install_to_local: install_cmd.append('--user') install_cmd.append(os.path.join(whl_src_dir, whl)) try: @@ -639,23 +681,32 @@ def do_install(): set_execute_permissions() log.info('+ Marked scripts as executable') + #If pyenv is being used, regenerate the pyenv shims + if shutil.which('pyenv') is not None: + try: + res = default_run(['pyenv', 'rehash']) + log.info('+ Generated pyenv shims') + except: + log.info('- Failed to generate pyenv shim') #Install the command completion script if shutil.which('edkrepo') is not None: - if args.local: + if install_to_local or ostype == MAC: command_completion_script = os.path.join(default_cfg_dir, 'edkrepo_completions.sh') else: command_completion_script = os.path.join('/', 'etc', 'profile.d', 'edkrepo_completions.sh') try: res = default_run(['edkrepo', 'generate-command-completion-script', command_completion_script]) - if args.local: + if install_to_local or ostype == MAC: shutil.chown(command_completion_script, user=username) os.chmod(command_completion_script, 0o644) add_command_completions_to_shell(command_completion_script, args, username, user_home_dir) + log.info('+ Configured edkrepo command completion') except: log.info('- Failed to configure edkrepo command completion') if args.verbose: traceback.print_exc() + log.log(logging.PRINT, '\nInstallation complete\n') return 0 -- 2.25.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS 2020-04-06 20:59 [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Nate DeSimone @ 2020-04-06 21:19 ` Bjorge, Erik C 2020-04-06 21:42 ` Nate DeSimone 2020-04-08 19:59 ` Ashley E Desimone 1 sibling, 1 reply; 5+ messages in thread From: Bjorge, Erik C @ 2020-04-06 21:19 UTC (permalink / raw) To: devel@edk2.groups.io, Desimone, Nathaniel L Cc: Desimone, Ashley E, Pandya, Puja, Agyeman, Prince, Bret Barkelew, Philippe Mathieu-Daude Nate, To simplify some of the installer code should we just switch to local (user) installs in for Linux and Mac? I would like to move to this for Linux anyway. I can also submit a patch for this at some other time. The rest of the code looks good. Thanks, -Erik -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nate DeSimone Sent: Monday, April 6, 2020 1:59 PM To: devel@edk2.groups.io Cc: Desimone, Ashley E <ashley.e.desimone@intel.com>; Pandya, Puja <puja.pandya@intel.com>; Bjorge, Erik C <erik.c.bjorge@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Philippe Mathieu-Daude <philmd@redhat.com> Subject: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Ashley DeSimone <ashley.e.desimone@intel.com> Cc: Puja Pandya <puja.pandya@intel.com> Cc: Erik Bjorge <erik.c.bjorge@intel.com> Cc: Prince Agyeman <prince.agyeman@intel.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Philippe Mathieu-Daude <philmd@redhat.com> --- build-scripts/build_linux_installer.py | 2 + build-scripts/set_version_and_build_wheels.py | 10 +-- edkrepo/config/config_factory.py | 6 +- edkrepo_installer/linux-scripts/install.py | 65 +++++++++++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/build-scripts/build_linux_installer.py b/build-scripts/build_linux_installer.py index 0130552..11dd8d7 100755 --- a/build-scripts/build_linux_installer.py +++ b/build-scripts/build_linux_installer.py @@ -10,6 +10,7 @@ from argparse import ArgumentParser import fnmatch, os, shutil, subprocess, sys import set_version_and_build_wheels as build_edkrepo +import traceback def main(): parser = ArgumentParser() @@ -31,6 +32,7 @@ def main(): try: build_edkrepo.main() except: + traceback.print_exc() print('Failed to build edkrepo wheel') return 1 diff --git a/build-scripts/set_version_and_build_wheels.py b/build-scripts/set_version_and_build_wheels.py index 42e58cc..7df0c84 100755 --- a/build-scripts/set_version_and_build_wheels.py +++ b/build-scripts/set_version_and_build_wheels.py @@ -3,7 +3,7 @@ ## @file # set_version_and_build_wheels.py # -# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -214,7 +214,7 @@ def build_wheels(extension_pkgs): def copy_wheels_and_set_xml(package_version, extension_pkgs): dir_path = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), "dist") dest_path = os.path.join(dir_path, "self_extract") - if ostype == LINUX: + if ostype != WIN: dest_path = os.path.join(dest_path, 'wheels') if not os.path.isdir(dest_path): os.makedirs(dest_path) @@ -241,9 +241,9 @@ def create_final_copy_script(version): f.write("pushd ..\\dist\n") f.write("ren \"setup.exe\" \"EdkRepoSetup-{}.exe\"\n".format(version)) f.write("popd\n") - elif ostype == LINUX: + else: with open('final_copy.py', 'w') as f: - f.write('#!/usr/bin/python3\n') + f.write('#!/usr/bin/env python3\n') f.write('import os, shutil, sys\n') f.write('dist_name = "edkrepo-{{}}".format("{}")\n'.format(version)) f.write('installer_dir = "../dist/self_extract"\n') @@ -257,7 +257,7 @@ def _copy_file(source, destination): check_call("cp -f {} {}".format(source, destination), shell=True) def make_version_cfg_file(version): - if ostype == LINUX: + if ostype != WIN: cfg_src = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), 'edkrepo_installer', 'linux-scripts') install_cfg = configparser.ConfigParser(allow_no_value=True) install_cfg.read(os.path.join(cfg_src, 'install.cfg')) diff --git a/edkrepo/config/config_factory.py b/edkrepo/config/config_factory.py index e3a437f..b86e0b8 100644 --- a/edkrepo/config/config_factory.py +++ b/edkrepo/config/config_factory.py @@ -3,7 +3,7 @@ ## @file # config_factory.py # -# Copyright (c) 2017- 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -30,9 +30,7 @@ def get_edkrepo_global_data_directory(): common_appdata = create_unicode_buffer(MAX_PATH) SHGetFolderPath(None, CSIDL_COMMON_APPDATA, None, SHGFP_TYPE_CURRENT, common_appdata) global_data_dir = os.path.join(common_appdata.value, "edkrepo") - elif sys.platform == "darwin": - raise OSError("macOS support is in progress") - elif sys.platform.startswith("linux") or os.name == "posix": + elif sys.platform == "darwin" or sys.platform.startswith("linux") or os.name == "posix": global_data_dir = os.path.expanduser("~/.edkrepo") if not os.path.isdir(global_data_dir): if not os.path.exists(os.path.dirname(global_data_dir)): diff --git a/edkrepo_installer/linux-scripts/install.py b/edkrepo_installer/linux-scripts/install.py index 52f0c52..099954d 100755 --- a/edkrepo_installer/linux-scripts/install.py +++ b/edkrepo_installer/linux-scripts/install.py @@ -23,6 +23,21 @@ import sys import traceback import xml.etree.ElementTree as et +# +# Environment detection +# +MAC = "mac" +LINUX = "linux" +if sys.platform == "darwin": + ostype = MAC +elif sys.platform.startswith("linux"): + ostype = LINUX +elif os.name == "posix": + print("Warning: Unrecognized UNIX OS... treating as Linux") + ostype = LINUX +else: + raise EnvironmentError("Unsupported OS") + tool_sign_on = 'Installer for edkrepo version {}\nCopyright(c) Intel Corporation, 2020' # Data here should be maintained in a configuration file @@ -31,6 +46,7 @@ directories_with_executables = ['git_automation'] cfg_src_dir = os.path.abspath('config') whl_src_dir = os.path.abspath('wheels') def_python = 'python3' +nfs_home_directory_data = re.compile(r"NFSHomeDirectory:\s*(\S+)") # ZSH Configuration options prompt_regex = re.compile(r"#\s+[Aa][Dd][Dd]\s+[Ee][Dd][Kk][Rr][Ee][Pp][Oo]\s+&\s+[Gg][Ii][Tt]\s+[Tt][Oo]\s+[Tt][Hh][Ee]\s+[Pp][Rr][Oo][Mm][Pp][Tt]") @@ -63,7 +79,8 @@ def init_logger(verbose): def get_args(): parser = ArgumentParser() - parser.add_argument('-l', '--local', action='store_true', default=False, help='Install edkrepo to the user directory instead of system wide') + if ostype != MAC: + parser.add_argument('-l', '--local', action='store_true', + default=False, help='Install edkrepo to the user directory instead of + system wide') parser.add_argument('-p', '--py', action='store', default=None, help='Specify the python command to use when installing') parser.add_argument('-u', '--user', action='store', default=None, help='Specify user account to install edkrepo support on') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enables verbose output') @@ -218,6 +235,18 @@ def _check_version(current, expected): return 1 return 0 +def get_user_home_directory(username): + if ostype == MAC: + res = default_run(['dscl', '.', '-read', '/Users/{}'.format(username), 'NFSHomeDirectory']) + data = nfs_home_directory_data.match(res.stdout.strip()) + if data: + return data.group(1) + else: + raise ValueError("home directory not found") + else: + res = default_run(['getent', 'passwd', username]) + return res.stdout.strip().split(':')[5] + def get_site_packages_directory(): res = default_run([def_python, '-c', 'import site; print(site.getsitepackages()[0])']) return res.stdout.strip() @@ -424,6 +453,9 @@ def do_install(): # Initialize information based on command line input username = args.user + install_to_local = False + if ostype != MAC and args.local: + install_to_local = True try: cfg = configparser.ConfigParser(allow_no_value=True) @@ -449,7 +481,7 @@ def do_install(): # Determine the user running sudo log.info('\nCollecting system information:') - if not args.local: + if not install_to_local and ostype != MAC: try: res = default_run(['id', '-u']) except: @@ -466,11 +498,21 @@ def do_install(): log.info('- Unable to determine current user. Run installer using the --user flag and specify the correct user name.') return 1 try: - res = default_run(['getent', 'passwd', username]) - user_home_dir = res.stdout.strip().split(':')[5] + user_home_dir = get_user_home_directory(username) except: log.info('- Unable to determine users home directory') return 1 + if ostype == MAC: + try: + res = default_run(['id', '-u']) + except: + log.info('- Failed to determine user ID') + return 1 + if res.stdout.strip() == '0': + log.info('- Installer must NOT be run as root') + return 1 + if os.path.commonprefix([user_home_dir, sys.executable]) != user_home_dir: + install_to_local = True default_cfg_dir = os.path.join(user_home_dir, cfg_dir) get_add_prompt_customization(args, user_home_dir) log.info('+ System information collected') @@ -625,7 +667,7 @@ def do_install(): install_whl = wheels_to_install[whl_name]['install'] if install_whl: install_cmd = [def_python, '-m', 'pip', 'install'] - if args.local: + if install_to_local: install_cmd.append('--user') install_cmd.append(os.path.join(whl_src_dir, whl)) try: @@ -639,23 +681,32 @@ def do_install(): set_execute_permissions() log.info('+ Marked scripts as executable') + #If pyenv is being used, regenerate the pyenv shims + if shutil.which('pyenv') is not None: + try: + res = default_run(['pyenv', 'rehash']) + log.info('+ Generated pyenv shims') + except: + log.info('- Failed to generate pyenv shim') #Install the command completion script if shutil.which('edkrepo') is not None: - if args.local: + if install_to_local or ostype == MAC: command_completion_script = os.path.join(default_cfg_dir, 'edkrepo_completions.sh') else: command_completion_script = os.path.join('/', 'etc', 'profile.d', 'edkrepo_completions.sh') try: res = default_run(['edkrepo', 'generate-command-completion-script', command_completion_script]) - if args.local: + if install_to_local or ostype == MAC: shutil.chown(command_completion_script, user=username) os.chmod(command_completion_script, 0o644) add_command_completions_to_shell(command_completion_script, args, username, user_home_dir) + log.info('+ Configured edkrepo command completion') except: log.info('- Failed to configure edkrepo command completion') if args.verbose: traceback.print_exc() + log.log(logging.PRINT, '\nInstallation complete\n') return 0 -- 2.25.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS 2020-04-06 21:19 ` [edk2-devel] " Bjorge, Erik C @ 2020-04-06 21:42 ` Nate DeSimone 2020-04-06 21:50 ` Bjorge, Erik C 0 siblings, 1 reply; 5+ messages in thread From: Nate DeSimone @ 2020-04-06 21:42 UTC (permalink / raw) To: Bjorge, Erik C, devel@edk2.groups.io Cc: Desimone, Ashley E, Pandya, Puja, Agyeman, Prince, Bret Barkelew, Philippe Mathieu-Daude Hi Erik, I'm not planning on this being the only patch on this topic anyway. I still need to update documentation and stuff like that. You are welcome to take a look at what it would take to switch to user-based installs. For macOS, the only method I support is using pyenv. Thanks, Nate On 4/6/20, 2:19 PM, "Bjorge, Erik C" <erik.c.bjorge@intel.com> wrote: Nate, To simplify some of the installer code should we just switch to local (user) installs in for Linux and Mac? I would like to move to this for Linux anyway. I can also submit a patch for this at some other time. The rest of the code looks good. Thanks, -Erik -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nate DeSimone Sent: Monday, April 6, 2020 1:59 PM To: devel@edk2.groups.io Cc: Desimone, Ashley E <ashley.e.desimone@intel.com>; Pandya, Puja <puja.pandya@intel.com>; Bjorge, Erik C <erik.c.bjorge@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Philippe Mathieu-Daude <philmd@redhat.com> Subject: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Ashley DeSimone <ashley.e.desimone@intel.com> Cc: Puja Pandya <puja.pandya@intel.com> Cc: Erik Bjorge <erik.c.bjorge@intel.com> Cc: Prince Agyeman <prince.agyeman@intel.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Philippe Mathieu-Daude <philmd@redhat.com> --- build-scripts/build_linux_installer.py | 2 + build-scripts/set_version_and_build_wheels.py | 10 +-- edkrepo/config/config_factory.py | 6 +- edkrepo_installer/linux-scripts/install.py | 65 +++++++++++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/build-scripts/build_linux_installer.py b/build-scripts/build_linux_installer.py index 0130552..11dd8d7 100755 --- a/build-scripts/build_linux_installer.py +++ b/build-scripts/build_linux_installer.py @@ -10,6 +10,7 @@ from argparse import ArgumentParser import fnmatch, os, shutil, subprocess, sys import set_version_and_build_wheels as build_edkrepo +import traceback def main(): parser = ArgumentParser() @@ -31,6 +32,7 @@ def main(): try: build_edkrepo.main() except: + traceback.print_exc() print('Failed to build edkrepo wheel') return 1 diff --git a/build-scripts/set_version_and_build_wheels.py b/build-scripts/set_version_and_build_wheels.py index 42e58cc..7df0c84 100755 --- a/build-scripts/set_version_and_build_wheels.py +++ b/build-scripts/set_version_and_build_wheels.py @@ -3,7 +3,7 @@ ## @file # set_version_and_build_wheels.py # -# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -214,7 +214,7 @@ def build_wheels(extension_pkgs): def copy_wheels_and_set_xml(package_version, extension_pkgs): dir_path = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), "dist") dest_path = os.path.join(dir_path, "self_extract") - if ostype == LINUX: + if ostype != WIN: dest_path = os.path.join(dest_path, 'wheels') if not os.path.isdir(dest_path): os.makedirs(dest_path) @@ -241,9 +241,9 @@ def create_final_copy_script(version): f.write("pushd ..\\dist\n") f.write("ren \"setup.exe\" \"EdkRepoSetup-{}.exe\"\n".format(version)) f.write("popd\n") - elif ostype == LINUX: + else: with open('final_copy.py', 'w') as f: - f.write('#!/usr/bin/python3\n') + f.write('#!/usr/bin/env python3\n') f.write('import os, shutil, sys\n') f.write('dist_name = "edkrepo-{{}}".format("{}")\n'.format(version)) f.write('installer_dir = "../dist/self_extract"\n') @@ -257,7 +257,7 @@ def _copy_file(source, destination): check_call("cp -f {} {}".format(source, destination), shell=True) def make_version_cfg_file(version): - if ostype == LINUX: + if ostype != WIN: cfg_src = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), 'edkrepo_installer', 'linux-scripts') install_cfg = configparser.ConfigParser(allow_no_value=True) install_cfg.read(os.path.join(cfg_src, 'install.cfg')) diff --git a/edkrepo/config/config_factory.py b/edkrepo/config/config_factory.py index e3a437f..b86e0b8 100644 --- a/edkrepo/config/config_factory.py +++ b/edkrepo/config/config_factory.py @@ -3,7 +3,7 @@ ## @file # config_factory.py # -# Copyright (c) 2017- 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -30,9 +30,7 @@ def get_edkrepo_global_data_directory(): common_appdata = create_unicode_buffer(MAX_PATH) SHGetFolderPath(None, CSIDL_COMMON_APPDATA, None, SHGFP_TYPE_CURRENT, common_appdata) global_data_dir = os.path.join(common_appdata.value, "edkrepo") - elif sys.platform == "darwin": - raise OSError("macOS support is in progress") - elif sys.platform.startswith("linux") or os.name == "posix": + elif sys.platform == "darwin" or sys.platform.startswith("linux") or os.name == "posix": global_data_dir = os.path.expanduser("~/.edkrepo") if not os.path.isdir(global_data_dir): if not os.path.exists(os.path.dirname(global_data_dir)): diff --git a/edkrepo_installer/linux-scripts/install.py b/edkrepo_installer/linux-scripts/install.py index 52f0c52..099954d 100755 --- a/edkrepo_installer/linux-scripts/install.py +++ b/edkrepo_installer/linux-scripts/install.py @@ -23,6 +23,21 @@ import sys import traceback import xml.etree.ElementTree as et +# +# Environment detection +# +MAC = "mac" +LINUX = "linux" +if sys.platform == "darwin": + ostype = MAC +elif sys.platform.startswith("linux"): + ostype = LINUX +elif os.name == "posix": + print("Warning: Unrecognized UNIX OS... treating as Linux") + ostype = LINUX +else: + raise EnvironmentError("Unsupported OS") + tool_sign_on = 'Installer for edkrepo version {}\nCopyright(c) Intel Corporation, 2020' # Data here should be maintained in a configuration file @@ -31,6 +46,7 @@ directories_with_executables = ['git_automation'] cfg_src_dir = os.path.abspath('config') whl_src_dir = os.path.abspath('wheels') def_python = 'python3' +nfs_home_directory_data = re.compile(r"NFSHomeDirectory:\s*(\S+)") # ZSH Configuration options prompt_regex = re.compile(r"#\s+[Aa][Dd][Dd]\s+[Ee][Dd][Kk][Rr][Ee][Pp][Oo]\s+&\s+[Gg][Ii][Tt]\s+[Tt][Oo]\s+[Tt][Hh][Ee]\s+[Pp][Rr][Oo][Mm][Pp][Tt]") @@ -63,7 +79,8 @@ def init_logger(verbose): def get_args(): parser = ArgumentParser() - parser.add_argument('-l', '--local', action='store_true', default=False, help='Install edkrepo to the user directory instead of system wide') + if ostype != MAC: + parser.add_argument('-l', '--local', action='store_true', + default=False, help='Install edkrepo to the user directory instead of + system wide') parser.add_argument('-p', '--py', action='store', default=None, help='Specify the python command to use when installing') parser.add_argument('-u', '--user', action='store', default=None, help='Specify user account to install edkrepo support on') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enables verbose output') @@ -218,6 +235,18 @@ def _check_version(current, expected): return 1 return 0 +def get_user_home_directory(username): + if ostype == MAC: + res = default_run(['dscl', '.', '-read', '/Users/{}'.format(username), 'NFSHomeDirectory']) + data = nfs_home_directory_data.match(res.stdout.strip()) + if data: + return data.group(1) + else: + raise ValueError("home directory not found") + else: + res = default_run(['getent', 'passwd', username]) + return res.stdout.strip().split(':')[5] + def get_site_packages_directory(): res = default_run([def_python, '-c', 'import site; print(site.getsitepackages()[0])']) return res.stdout.strip() @@ -424,6 +453,9 @@ def do_install(): # Initialize information based on command line input username = args.user + install_to_local = False + if ostype != MAC and args.local: + install_to_local = True try: cfg = configparser.ConfigParser(allow_no_value=True) @@ -449,7 +481,7 @@ def do_install(): # Determine the user running sudo log.info('\nCollecting system information:') - if not args.local: + if not install_to_local and ostype != MAC: try: res = default_run(['id', '-u']) except: @@ -466,11 +498,21 @@ def do_install(): log.info('- Unable to determine current user. Run installer using the --user flag and specify the correct user name.') return 1 try: - res = default_run(['getent', 'passwd', username]) - user_home_dir = res.stdout.strip().split(':')[5] + user_home_dir = get_user_home_directory(username) except: log.info('- Unable to determine users home directory') return 1 + if ostype == MAC: + try: + res = default_run(['id', '-u']) + except: + log.info('- Failed to determine user ID') + return 1 + if res.stdout.strip() == '0': + log.info('- Installer must NOT be run as root') + return 1 + if os.path.commonprefix([user_home_dir, sys.executable]) != user_home_dir: + install_to_local = True default_cfg_dir = os.path.join(user_home_dir, cfg_dir) get_add_prompt_customization(args, user_home_dir) log.info('+ System information collected') @@ -625,7 +667,7 @@ def do_install(): install_whl = wheels_to_install[whl_name]['install'] if install_whl: install_cmd = [def_python, '-m', 'pip', 'install'] - if args.local: + if install_to_local: install_cmd.append('--user') install_cmd.append(os.path.join(whl_src_dir, whl)) try: @@ -639,23 +681,32 @@ def do_install(): set_execute_permissions() log.info('+ Marked scripts as executable') + #If pyenv is being used, regenerate the pyenv shims + if shutil.which('pyenv') is not None: + try: + res = default_run(['pyenv', 'rehash']) + log.info('+ Generated pyenv shims') + except: + log.info('- Failed to generate pyenv shim') #Install the command completion script if shutil.which('edkrepo') is not None: - if args.local: + if install_to_local or ostype == MAC: command_completion_script = os.path.join(default_cfg_dir, 'edkrepo_completions.sh') else: command_completion_script = os.path.join('/', 'etc', 'profile.d', 'edkrepo_completions.sh') try: res = default_run(['edkrepo', 'generate-command-completion-script', command_completion_script]) - if args.local: + if install_to_local or ostype == MAC: shutil.chown(command_completion_script, user=username) os.chmod(command_completion_script, 0o644) add_command_completions_to_shell(command_completion_script, args, username, user_home_dir) + log.info('+ Configured edkrepo command completion') except: log.info('- Failed to configure edkrepo command completion') if args.verbose: traceback.print_exc() + log.log(logging.PRINT, '\nInstallation complete\n') return 0 -- 2.25.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS 2020-04-06 21:42 ` Nate DeSimone @ 2020-04-06 21:50 ` Bjorge, Erik C 0 siblings, 0 replies; 5+ messages in thread From: Bjorge, Erik C @ 2020-04-06 21:50 UTC (permalink / raw) To: Desimone, Nathaniel L, devel@edk2.groups.io Cc: Desimone, Ashley E, Pandya, Puja, Agyeman, Prince, Bret Barkelew, Philippe Mathieu-Daude I will take a look at removing system wide installs on Linux and we can keep these change focused on Mac support. Thanks, -Erik Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com> -----Original Message----- From: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com> Sent: Monday, April 6, 2020 2:43 PM To: Bjorge, Erik C <erik.c.bjorge@intel.com>; devel@edk2.groups.io Cc: Desimone, Ashley E <ashley.e.desimone@intel.com>; Pandya, Puja <puja.pandya@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Philippe Mathieu-Daude <philmd@redhat.com> Subject: Re: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Hi Erik, I'm not planning on this being the only patch on this topic anyway. I still need to update documentation and stuff like that. You are welcome to take a look at what it would take to switch to user-based installs. For macOS, the only method I support is using pyenv. Thanks, Nate On 4/6/20, 2:19 PM, "Bjorge, Erik C" <erik.c.bjorge@intel.com> wrote: Nate, To simplify some of the installer code should we just switch to local (user) installs in for Linux and Mac? I would like to move to this for Linux anyway. I can also submit a patch for this at some other time. The rest of the code looks good. Thanks, -Erik -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nate DeSimone Sent: Monday, April 6, 2020 1:59 PM To: devel@edk2.groups.io Cc: Desimone, Ashley E <ashley.e.desimone@intel.com>; Pandya, Puja <puja.pandya@intel.com>; Bjorge, Erik C <erik.c.bjorge@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Philippe Mathieu-Daude <philmd@redhat.com> Subject: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Ashley DeSimone <ashley.e.desimone@intel.com> Cc: Puja Pandya <puja.pandya@intel.com> Cc: Erik Bjorge <erik.c.bjorge@intel.com> Cc: Prince Agyeman <prince.agyeman@intel.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Philippe Mathieu-Daude <philmd@redhat.com> --- build-scripts/build_linux_installer.py | 2 + build-scripts/set_version_and_build_wheels.py | 10 +-- edkrepo/config/config_factory.py | 6 +- edkrepo_installer/linux-scripts/install.py | 65 +++++++++++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/build-scripts/build_linux_installer.py b/build-scripts/build_linux_installer.py index 0130552..11dd8d7 100755 --- a/build-scripts/build_linux_installer.py +++ b/build-scripts/build_linux_installer.py @@ -10,6 +10,7 @@ from argparse import ArgumentParser import fnmatch, os, shutil, subprocess, sys import set_version_and_build_wheels as build_edkrepo +import traceback def main(): parser = ArgumentParser() @@ -31,6 +32,7 @@ def main(): try: build_edkrepo.main() except: + traceback.print_exc() print('Failed to build edkrepo wheel') return 1 diff --git a/build-scripts/set_version_and_build_wheels.py b/build-scripts/set_version_and_build_wheels.py index 42e58cc..7df0c84 100755 --- a/build-scripts/set_version_and_build_wheels.py +++ b/build-scripts/set_version_and_build_wheels.py @@ -3,7 +3,7 @@ ## @file # set_version_and_build_wheels.py # -# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -214,7 +214,7 @@ def build_wheels(extension_pkgs): def copy_wheels_and_set_xml(package_version, extension_pkgs): dir_path = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), "dist") dest_path = os.path.join(dir_path, "self_extract") - if ostype == LINUX: + if ostype != WIN: dest_path = os.path.join(dest_path, 'wheels') if not os.path.isdir(dest_path): os.makedirs(dest_path) @@ -241,9 +241,9 @@ def create_final_copy_script(version): f.write("pushd ..\\dist\n") f.write("ren \"setup.exe\" \"EdkRepoSetup-{}.exe\"\n".format(version)) f.write("popd\n") - elif ostype == LINUX: + else: with open('final_copy.py', 'w') as f: - f.write('#!/usr/bin/python3\n') + f.write('#!/usr/bin/env python3\n') f.write('import os, shutil, sys\n') f.write('dist_name = "edkrepo-{{}}".format("{}")\n'.format(version)) f.write('installer_dir = "../dist/self_extract"\n') @@ -257,7 +257,7 @@ def _copy_file(source, destination): check_call("cp -f {} {}".format(source, destination), shell=True) def make_version_cfg_file(version): - if ostype == LINUX: + if ostype != WIN: cfg_src = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), 'edkrepo_installer', 'linux-scripts') install_cfg = configparser.ConfigParser(allow_no_value=True) install_cfg.read(os.path.join(cfg_src, 'install.cfg')) diff --git a/edkrepo/config/config_factory.py b/edkrepo/config/config_factory.py index e3a437f..b86e0b8 100644 --- a/edkrepo/config/config_factory.py +++ b/edkrepo/config/config_factory.py @@ -3,7 +3,7 @@ ## @file # config_factory.py # -# Copyright (c) 2017- 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -30,9 +30,7 @@ def get_edkrepo_global_data_directory(): common_appdata = create_unicode_buffer(MAX_PATH) SHGetFolderPath(None, CSIDL_COMMON_APPDATA, None, SHGFP_TYPE_CURRENT, common_appdata) global_data_dir = os.path.join(common_appdata.value, "edkrepo") - elif sys.platform == "darwin": - raise OSError("macOS support is in progress") - elif sys.platform.startswith("linux") or os.name == "posix": + elif sys.platform == "darwin" or sys.platform.startswith("linux") or os.name == "posix": global_data_dir = os.path.expanduser("~/.edkrepo") if not os.path.isdir(global_data_dir): if not os.path.exists(os.path.dirname(global_data_dir)): diff --git a/edkrepo_installer/linux-scripts/install.py b/edkrepo_installer/linux-scripts/install.py index 52f0c52..099954d 100755 --- a/edkrepo_installer/linux-scripts/install.py +++ b/edkrepo_installer/linux-scripts/install.py @@ -23,6 +23,21 @@ import sys import traceback import xml.etree.ElementTree as et +# +# Environment detection +# +MAC = "mac" +LINUX = "linux" +if sys.platform == "darwin": + ostype = MAC +elif sys.platform.startswith("linux"): + ostype = LINUX +elif os.name == "posix": + print("Warning: Unrecognized UNIX OS... treating as Linux") + ostype = LINUX +else: + raise EnvironmentError("Unsupported OS") + tool_sign_on = 'Installer for edkrepo version {}\nCopyright(c) Intel Corporation, 2020' # Data here should be maintained in a configuration file @@ -31,6 +46,7 @@ directories_with_executables = ['git_automation'] cfg_src_dir = os.path.abspath('config') whl_src_dir = os.path.abspath('wheels') def_python = 'python3' +nfs_home_directory_data = re.compile(r"NFSHomeDirectory:\s*(\S+)") # ZSH Configuration options prompt_regex = re.compile(r"#\s+[Aa][Dd][Dd]\s+[Ee][Dd][Kk][Rr][Ee][Pp][Oo]\s+&\s+[Gg][Ii][Tt]\s+[Tt][Oo]\s+[Tt][Hh][Ee]\s+[Pp][Rr][Oo][Mm][Pp][Tt]") @@ -63,7 +79,8 @@ def init_logger(verbose): def get_args(): parser = ArgumentParser() - parser.add_argument('-l', '--local', action='store_true', default=False, help='Install edkrepo to the user directory instead of system wide') + if ostype != MAC: + parser.add_argument('-l', '--local', action='store_true', + default=False, help='Install edkrepo to the user directory instead of + system wide') parser.add_argument('-p', '--py', action='store', default=None, help='Specify the python command to use when installing') parser.add_argument('-u', '--user', action='store', default=None, help='Specify user account to install edkrepo support on') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enables verbose output') @@ -218,6 +235,18 @@ def _check_version(current, expected): return 1 return 0 +def get_user_home_directory(username): + if ostype == MAC: + res = default_run(['dscl', '.', '-read', '/Users/{}'.format(username), 'NFSHomeDirectory']) + data = nfs_home_directory_data.match(res.stdout.strip()) + if data: + return data.group(1) + else: + raise ValueError("home directory not found") + else: + res = default_run(['getent', 'passwd', username]) + return res.stdout.strip().split(':')[5] + def get_site_packages_directory(): res = default_run([def_python, '-c', 'import site; print(site.getsitepackages()[0])']) return res.stdout.strip() @@ -424,6 +453,9 @@ def do_install(): # Initialize information based on command line input username = args.user + install_to_local = False + if ostype != MAC and args.local: + install_to_local = True try: cfg = configparser.ConfigParser(allow_no_value=True) @@ -449,7 +481,7 @@ def do_install(): # Determine the user running sudo log.info('\nCollecting system information:') - if not args.local: + if not install_to_local and ostype != MAC: try: res = default_run(['id', '-u']) except: @@ -466,11 +498,21 @@ def do_install(): log.info('- Unable to determine current user. Run installer using the --user flag and specify the correct user name.') return 1 try: - res = default_run(['getent', 'passwd', username]) - user_home_dir = res.stdout.strip().split(':')[5] + user_home_dir = get_user_home_directory(username) except: log.info('- Unable to determine users home directory') return 1 + if ostype == MAC: + try: + res = default_run(['id', '-u']) + except: + log.info('- Failed to determine user ID') + return 1 + if res.stdout.strip() == '0': + log.info('- Installer must NOT be run as root') + return 1 + if os.path.commonprefix([user_home_dir, sys.executable]) != user_home_dir: + install_to_local = True default_cfg_dir = os.path.join(user_home_dir, cfg_dir) get_add_prompt_customization(args, user_home_dir) log.info('+ System information collected') @@ -625,7 +667,7 @@ def do_install(): install_whl = wheels_to_install[whl_name]['install'] if install_whl: install_cmd = [def_python, '-m', 'pip', 'install'] - if args.local: + if install_to_local: install_cmd.append('--user') install_cmd.append(os.path.join(whl_src_dir, whl)) try: @@ -639,23 +681,32 @@ def do_install(): set_execute_permissions() log.info('+ Marked scripts as executable') + #If pyenv is being used, regenerate the pyenv shims + if shutil.which('pyenv') is not None: + try: + res = default_run(['pyenv', 'rehash']) + log.info('+ Generated pyenv shims') + except: + log.info('- Failed to generate pyenv shim') #Install the command completion script if shutil.which('edkrepo') is not None: - if args.local: + if install_to_local or ostype == MAC: command_completion_script = os.path.join(default_cfg_dir, 'edkrepo_completions.sh') else: command_completion_script = os.path.join('/', 'etc', 'profile.d', 'edkrepo_completions.sh') try: res = default_run(['edkrepo', 'generate-command-completion-script', command_completion_script]) - if args.local: + if install_to_local or ostype == MAC: shutil.chown(command_completion_script, user=username) os.chmod(command_completion_script, 0o644) add_command_completions_to_shell(command_completion_script, args, username, user_home_dir) + log.info('+ Configured edkrepo command completion') except: log.info('- Failed to configure edkrepo command completion') if args.verbose: traceback.print_exc() + log.log(logging.PRINT, '\nInstallation complete\n') return 0 -- 2.25.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS 2020-04-06 20:59 [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Nate DeSimone 2020-04-06 21:19 ` [edk2-devel] " Bjorge, Erik C @ 2020-04-08 19:59 ` Ashley E Desimone 1 sibling, 0 replies; 5+ messages in thread From: Ashley E Desimone @ 2020-04-08 19:59 UTC (permalink / raw) To: devel@edk2.groups.io, Desimone, Nathaniel L Cc: Pandya, Puja, Bjorge, Erik C, Agyeman, Prince, Bret Barkelew, Philippe Mathieu-Daude Reviewed-by: Ashley DeSimone <ashley.e.desimone@intel.com> -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nate DeSimone Sent: Monday, April 6, 2020 1:59 PM To: devel@edk2.groups.io Cc: Desimone, Ashley E <ashley.e.desimone@intel.com>; Pandya, Puja <puja.pandya@intel.com>; Bjorge, Erik C <erik.c.bjorge@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Philippe Mathieu-Daude <philmd@redhat.com> Subject: [edk2-devel] [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Ashley DeSimone <ashley.e.desimone@intel.com> Cc: Puja Pandya <puja.pandya@intel.com> Cc: Erik Bjorge <erik.c.bjorge@intel.com> Cc: Prince Agyeman <prince.agyeman@intel.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Philippe Mathieu-Daude <philmd@redhat.com> --- build-scripts/build_linux_installer.py | 2 + build-scripts/set_version_and_build_wheels.py | 10 +-- edkrepo/config/config_factory.py | 6 +- edkrepo_installer/linux-scripts/install.py | 65 +++++++++++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/build-scripts/build_linux_installer.py b/build-scripts/build_linux_installer.py index 0130552..11dd8d7 100755 --- a/build-scripts/build_linux_installer.py +++ b/build-scripts/build_linux_installer.py @@ -10,6 +10,7 @@ from argparse import ArgumentParser import fnmatch, os, shutil, subprocess, sys import set_version_and_build_wheels as build_edkrepo +import traceback def main(): parser = ArgumentParser() @@ -31,6 +32,7 @@ def main(): try: build_edkrepo.main() except: + traceback.print_exc() print('Failed to build edkrepo wheel') return 1 diff --git a/build-scripts/set_version_and_build_wheels.py b/build-scripts/set_version_and_build_wheels.py index 42e58cc..7df0c84 100755 --- a/build-scripts/set_version_and_build_wheels.py +++ b/build-scripts/set_version_and_build_wheels.py @@ -3,7 +3,7 @@ ## @file # set_version_and_build_wheels.py # -# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -214,7 +214,7 @@ def build_wheels(extension_pkgs): def copy_wheels_and_set_xml(package_version, extension_pkgs): dir_path = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), "dist") dest_path = os.path.join(dir_path, "self_extract") - if ostype == LINUX: + if ostype != WIN: dest_path = os.path.join(dest_path, 'wheels') if not os.path.isdir(dest_path): os.makedirs(dest_path) @@ -241,9 +241,9 @@ def create_final_copy_script(version): f.write("pushd ..\\dist\n") f.write("ren \"setup.exe\" \"EdkRepoSetup-{}.exe\"\n".format(version)) f.write("popd\n") - elif ostype == LINUX: + else: with open('final_copy.py', 'w') as f: - f.write('#!/usr/bin/python3\n') + f.write('#!/usr/bin/env python3\n') f.write('import os, shutil, sys\n') f.write('dist_name = "edkrepo-{{}}".format("{}")\n'.format(version)) f.write('installer_dir = "../dist/self_extract"\n') @@ -257,7 +257,7 @@ def _copy_file(source, destination): check_call("cp -f {} {}".format(source, destination), shell=True) def make_version_cfg_file(version): - if ostype == LINUX: + if ostype != WIN: cfg_src = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), 'edkrepo_installer', 'linux-scripts') install_cfg = configparser.ConfigParser(allow_no_value=True) install_cfg.read(os.path.join(cfg_src, 'install.cfg')) diff --git a/edkrepo/config/config_factory.py b/edkrepo/config/config_factory.py index e3a437f..b86e0b8 100644 --- a/edkrepo/config/config_factory.py +++ b/edkrepo/config/config_factory.py @@ -3,7 +3,7 @@ ## @file # config_factory.py # -# Copyright (c) 2017- 2019, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2020, Intel Corporation. All rights +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -30,9 +30,7 @@ def get_edkrepo_global_data_directory(): common_appdata = create_unicode_buffer(MAX_PATH) SHGetFolderPath(None, CSIDL_COMMON_APPDATA, None, SHGFP_TYPE_CURRENT, common_appdata) global_data_dir = os.path.join(common_appdata.value, "edkrepo") - elif sys.platform == "darwin": - raise OSError("macOS support is in progress") - elif sys.platform.startswith("linux") or os.name == "posix": + elif sys.platform == "darwin" or sys.platform.startswith("linux") or os.name == "posix": global_data_dir = os.path.expanduser("~/.edkrepo") if not os.path.isdir(global_data_dir): if not os.path.exists(os.path.dirname(global_data_dir)): diff --git a/edkrepo_installer/linux-scripts/install.py b/edkrepo_installer/linux-scripts/install.py index 52f0c52..099954d 100755 --- a/edkrepo_installer/linux-scripts/install.py +++ b/edkrepo_installer/linux-scripts/install.py @@ -23,6 +23,21 @@ import sys import traceback import xml.etree.ElementTree as et +# +# Environment detection +# +MAC = "mac" +LINUX = "linux" +if sys.platform == "darwin": + ostype = MAC +elif sys.platform.startswith("linux"): + ostype = LINUX +elif os.name == "posix": + print("Warning: Unrecognized UNIX OS... treating as Linux") + ostype = LINUX +else: + raise EnvironmentError("Unsupported OS") + tool_sign_on = 'Installer for edkrepo version {}\nCopyright(c) Intel Corporation, 2020' # Data here should be maintained in a configuration file @@ -31,6 +46,7 @@ directories_with_executables = ['git_automation'] cfg_src_dir = os.path.abspath('config') whl_src_dir = os.path.abspath('wheels') def_python = 'python3' +nfs_home_directory_data = re.compile(r"NFSHomeDirectory:\s*(\S+)") # ZSH Configuration options prompt_regex = re.compile(r"#\s+[Aa][Dd][Dd]\s+[Ee][Dd][Kk][Rr][Ee][Pp][Oo]\s+&\s+[Gg][Ii][Tt]\s+[Tt][Oo]\s+[Tt][Hh][Ee]\s+[Pp][Rr][Oo][Mm][Pp][Tt]") @@ -63,7 +79,8 @@ def init_logger(verbose): def get_args(): parser = ArgumentParser() - parser.add_argument('-l', '--local', action='store_true', default=False, help='Install edkrepo to the user directory instead of system wide') + if ostype != MAC: + parser.add_argument('-l', '--local', action='store_true', + default=False, help='Install edkrepo to the user directory instead of + system wide') parser.add_argument('-p', '--py', action='store', default=None, help='Specify the python command to use when installing') parser.add_argument('-u', '--user', action='store', default=None, help='Specify user account to install edkrepo support on') parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enables verbose output') @@ -218,6 +235,18 @@ def _check_version(current, expected): return 1 return 0 +def get_user_home_directory(username): + if ostype == MAC: + res = default_run(['dscl', '.', '-read', '/Users/{}'.format(username), 'NFSHomeDirectory']) + data = nfs_home_directory_data.match(res.stdout.strip()) + if data: + return data.group(1) + else: + raise ValueError("home directory not found") + else: + res = default_run(['getent', 'passwd', username]) + return res.stdout.strip().split(':')[5] + def get_site_packages_directory(): res = default_run([def_python, '-c', 'import site; print(site.getsitepackages()[0])']) return res.stdout.strip() @@ -424,6 +453,9 @@ def do_install(): # Initialize information based on command line input username = args.user + install_to_local = False + if ostype != MAC and args.local: + install_to_local = True try: cfg = configparser.ConfigParser(allow_no_value=True) @@ -449,7 +481,7 @@ def do_install(): # Determine the user running sudo log.info('\nCollecting system information:') - if not args.local: + if not install_to_local and ostype != MAC: try: res = default_run(['id', '-u']) except: @@ -466,11 +498,21 @@ def do_install(): log.info('- Unable to determine current user. Run installer using the --user flag and specify the correct user name.') return 1 try: - res = default_run(['getent', 'passwd', username]) - user_home_dir = res.stdout.strip().split(':')[5] + user_home_dir = get_user_home_directory(username) except: log.info('- Unable to determine users home directory') return 1 + if ostype == MAC: + try: + res = default_run(['id', '-u']) + except: + log.info('- Failed to determine user ID') + return 1 + if res.stdout.strip() == '0': + log.info('- Installer must NOT be run as root') + return 1 + if os.path.commonprefix([user_home_dir, sys.executable]) != user_home_dir: + install_to_local = True default_cfg_dir = os.path.join(user_home_dir, cfg_dir) get_add_prompt_customization(args, user_home_dir) log.info('+ System information collected') @@ -625,7 +667,7 @@ def do_install(): install_whl = wheels_to_install[whl_name]['install'] if install_whl: install_cmd = [def_python, '-m', 'pip', 'install'] - if args.local: + if install_to_local: install_cmd.append('--user') install_cmd.append(os.path.join(whl_src_dir, whl)) try: @@ -639,23 +681,32 @@ def do_install(): set_execute_permissions() log.info('+ Marked scripts as executable') + #If pyenv is being used, regenerate the pyenv shims + if shutil.which('pyenv') is not None: + try: + res = default_run(['pyenv', 'rehash']) + log.info('+ Generated pyenv shims') + except: + log.info('- Failed to generate pyenv shim') #Install the command completion script if shutil.which('edkrepo') is not None: - if args.local: + if install_to_local or ostype == MAC: command_completion_script = os.path.join(default_cfg_dir, 'edkrepo_completions.sh') else: command_completion_script = os.path.join('/', 'etc', 'profile.d', 'edkrepo_completions.sh') try: res = default_run(['edkrepo', 'generate-command-completion-script', command_completion_script]) - if args.local: + if install_to_local or ostype == MAC: shutil.chown(command_completion_script, user=username) os.chmod(command_completion_script, 0o644) add_command_completions_to_shell(command_completion_script, args, username, user_home_dir) + log.info('+ Configured edkrepo command completion') except: log.info('- Failed to configure edkrepo command completion') if args.verbose: traceback.print_exc() + log.log(logging.PRINT, '\nInstallation complete\n') return 0 -- 2.25.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-04-08 19:59 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-04-06 20:59 [edk2-staging/EdkRepo] [PATCH] EdkRepo: Add Support for macOS Nate DeSimone 2020-04-06 21:19 ` [edk2-devel] " Bjorge, Erik C 2020-04-06 21:42 ` Nate DeSimone 2020-04-06 21:50 ` Bjorge, Erik C 2020-04-08 19:59 ` Ashley E Desimone
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox