mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #26324 from s0undt3ch/2015.5
Salt is now pip install'able in windows
This commit is contained in:
commit
c0811d3302
2 changed files with 318 additions and 29 deletions
|
@ -212,6 +212,48 @@ and 103 characters on BSD-based systems.
|
|||
</topics/installation/osx>` instructions.
|
||||
|
||||
|
||||
Changing Default Paths
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Instead of updating your configuration files to point to the new root directory
|
||||
and having to pass the new configuration directory path to all of Salt's CLI
|
||||
tools, you can explicitly tweak the default system paths that Salt expects:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
GENERATE_SALT_SYSPATHS=1 pip --global-option='--salt-root-dir=/path/to/your/virtualenv/' \
|
||||
install -e ./salt # the path to the salt git clone from above
|
||||
|
||||
|
||||
You can now call all of Salt's CLI tools without explicitly passing the configuration directory.
|
||||
|
||||
Additional Options
|
||||
..................
|
||||
|
||||
In case you want to distribute your virtualenv, you probably don't want to
|
||||
include Salt's clone ``.git/`` directory, and, without it, Salt won't report
|
||||
the accurate version. You can tell ``setup.py`` to generate the hardcoded
|
||||
version information which is distributable:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
GENERATE_SALT_SYSPATHS=1 WRITE_SALT_VERSION=1 pip --global-option='--salt-root-dir=/path/to/your/virtualenv/' \
|
||||
install -e ./salt # the path to the salt git clone from above
|
||||
|
||||
|
||||
Instead of passing those two environmental variables, you can just pass a
|
||||
single one which will trigger the other two:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
MIMIC_SALT_INSTALL=1 pip --global-option='--salt-root-dir=/path/to/your/virtualenv/' \
|
||||
install -e ./salt # the path to the salt git clone from above
|
||||
|
||||
|
||||
This last one will grant you an edditable salt installation with hardcoded
|
||||
system paths and version information.
|
||||
|
||||
|
||||
Installing Salt from the Python Package Index
|
||||
---------------------------------------------
|
||||
|
||||
|
|
305
setup.py
305
setup.py
|
@ -5,7 +5,7 @@ The setup script for salt
|
|||
'''
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
# pylint: disable=file-perms
|
||||
# pylint: disable=C0111,E1101,E1103,F0401,W0611,W0201,W0232,R0201,R0902,R0903
|
||||
|
||||
# For Python 2.5. A no-op on 2.6 and above.
|
||||
|
@ -18,7 +18,7 @@ import time
|
|||
try:
|
||||
from urllib2 import urlopen
|
||||
except ImportError:
|
||||
from urllib.request import urlopen
|
||||
from urllib.request import urlopen # pylint: disable=no-name-in-module
|
||||
from datetime import datetime
|
||||
# pylint: disable=E0611
|
||||
import distutils.dist
|
||||
|
@ -71,6 +71,7 @@ WITH_SETUPTOOLS = False
|
|||
if 'USE_SETUPTOOLS' in os.environ or 'setuptools' in sys.modules:
|
||||
try:
|
||||
from setuptools import setup
|
||||
from setuptools.command.develop import develop
|
||||
from setuptools.command.install import install
|
||||
from setuptools.command.sdist import sdist
|
||||
from setuptools.command.egg_info import egg_info
|
||||
|
@ -103,6 +104,7 @@ except ImportError:
|
|||
|
||||
SALT_VERSION = os.path.join(os.path.abspath(SETUP_DIRNAME), 'salt', 'version.py')
|
||||
SALT_VERSION_HARDCODED = os.path.join(os.path.abspath(SETUP_DIRNAME), 'salt', '_version.py')
|
||||
SALT_SYSPATHS_HARDCODED = os.path.join(os.path.abspath(SETUP_DIRNAME), 'salt', '_syspaths.py')
|
||||
SALT_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), '_requirements.txt')
|
||||
SALT_ZEROMQ_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'zeromq-requirements.txt')
|
||||
SALT_RAET_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'raet-requirements.txt')
|
||||
|
@ -125,8 +127,16 @@ def _parse_requirements_file(requirements_file):
|
|||
line = line.strip()
|
||||
if not line or line.startswith(('#', '-r')):
|
||||
continue
|
||||
if IS_WINDOWS_PLATFORM and 'libcloud' in line:
|
||||
continue
|
||||
if IS_WINDOWS_PLATFORM:
|
||||
if 'libcloud' in line:
|
||||
continue
|
||||
if 'pycrypto' in line.lower():
|
||||
# On windows we install PyCrypto using python wheels
|
||||
continue
|
||||
if 'm2crypto' in line.lower() and __saltstack_version__.info < (2015, 8): # pylint: disable=undefined-variable
|
||||
# In Windows, we're installing M2CryptoWin{32,64} which comes
|
||||
# compiled
|
||||
continue
|
||||
parsed_requirements.append(line)
|
||||
return parsed_requirements
|
||||
# <---- Helper Functions ---------------------------------------------------------------------------------------------
|
||||
|
@ -164,6 +174,40 @@ class WriteSaltVersion(Command):
|
|||
# pylint: enable=E0602
|
||||
|
||||
|
||||
class GenerateSaltSyspaths(Command):
|
||||
|
||||
description = 'Generate salt\'s hardcoded syspaths file'
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
# Write the syspaths file
|
||||
if getattr(self.distribution, 'salt_syspaths_hardcoded_path', None) is None:
|
||||
print('This command is not meant to be called on it\'s own')
|
||||
exit(1)
|
||||
|
||||
# Write the system paths file
|
||||
open(self.distribution.salt_syspaths_hardcoded_path, 'w').write(
|
||||
INSTALL_SYSPATHS_TEMPLATE.format(
|
||||
date=datetime.utcnow(),
|
||||
root_dir=self.distribution.salt_root_dir,
|
||||
config_dir=self.distribution.salt_config_dir,
|
||||
cache_dir=self.distribution.salt_cache_dir,
|
||||
sock_dir=self.distribution.salt_sock_dir,
|
||||
srv_root_dir=self.distribution.salt_srv_root_dir,
|
||||
base_file_roots_dir=self.distribution.salt_base_file_roots_dir,
|
||||
base_pillar_roots_dir=self.distribution.salt_base_pillar_roots_dir,
|
||||
base_master_roots_dir=self.distribution.salt_base_master_roots_dir,
|
||||
logs_dir=self.distribution.salt_logs_dir,
|
||||
pidfile_dir=self.distribution.salt_pidfile_dir,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class WriteSaltSshPackagingFile(Command):
|
||||
|
||||
description = 'Write salt\'s ssh packaging file'
|
||||
|
@ -190,6 +234,198 @@ class WriteSaltSshPackagingFile(Command):
|
|||
# pylint: enable=E0602
|
||||
|
||||
|
||||
if WITH_SETUPTOOLS:
|
||||
class Develop(develop):
|
||||
user_options = develop.user_options + [
|
||||
('write-salt-version', None,
|
||||
'Generate Salt\'s _version.py file which allows proper version '
|
||||
'reporting. This defaults to False on develop/editable setups. '
|
||||
'If WRITE_SALT_VERSION is found in the environment this flag is '
|
||||
'switched to True.'),
|
||||
('generate-salt-syspaths', None,
|
||||
'Generate Salt\'s _syspaths.py file which allows tweaking some '
|
||||
'common paths that salt uses. This defaults to False on '
|
||||
'develop/editable setups. If GENERATE_SALT_SYSPATHS is found in '
|
||||
'the environment this flag is switched to True.'),
|
||||
('mimic-salt-install', None,
|
||||
'Mimmic the install command when running the develop command. '
|
||||
'This will generate salt\'s _version.py and _syspaths.py files. '
|
||||
'Generate Salt\'s _syspaths.py file which allows tweaking some '
|
||||
'This defaults to False on develop/editable setups. '
|
||||
'If MIMIC_INSTALL is found in the environment this flag is '
|
||||
'switched to True.')
|
||||
]
|
||||
boolean_options = develop.boolean_options + [
|
||||
'write-salt-version',
|
||||
'generate-salt-syspaths',
|
||||
'mimic-salt-install'
|
||||
]
|
||||
|
||||
def initialize_options(self):
|
||||
develop.initialize_options(self)
|
||||
self.write_salt_version = False
|
||||
self.generate_salt_syspaths = False
|
||||
self.mimic_salt_install = False
|
||||
|
||||
def finalize_options(self):
|
||||
develop.finalize_options(self)
|
||||
if 'WRITE_SALT_VERSION' in os.environ:
|
||||
self.write_salt_version = True
|
||||
if 'GENERATE_SALT_SYSPATHS' in os.environ:
|
||||
self.generate_salt_syspaths = True
|
||||
if 'MIMIC_SALT_INSTALL' in os.environ:
|
||||
self.mimic_salt_install = True
|
||||
|
||||
if self.mimic_salt_install:
|
||||
self.write_salt_version = True
|
||||
self.generate_salt_syspaths = True
|
||||
|
||||
def run(self):
|
||||
if IS_WINDOWS_PLATFORM:
|
||||
if __saltstack_version__.info < (2015, 8): # pylint: disable=undefined-variable
|
||||
# Install M2Crypto first
|
||||
self.distribution.salt_installing_m2crypto_windows = True
|
||||
self.run_command('install-m2crypto-windows')
|
||||
self.distribution.salt_installing_m2crypto_windows = None
|
||||
|
||||
# Install PyCrypto
|
||||
self.distribution.salt_installing_pycrypto_windows = True
|
||||
self.run_command('install-pycrypto-windows')
|
||||
self.distribution.salt_installing_pycrypto_windows = None
|
||||
|
||||
# Download the required DLLs
|
||||
self.distribution.salt_download_windows_dlls = True
|
||||
self.run_command('download-windows-dlls')
|
||||
self.distribution.salt_download_windows_dlls = None
|
||||
|
||||
if self.write_salt_version is True:
|
||||
self.distribution.running_salt_install = True
|
||||
self.distribution.salt_version_hardcoded_path = SALT_VERSION_HARDCODED
|
||||
self.run_command('write-salt-version')
|
||||
|
||||
if self.generate_salt_syspaths:
|
||||
self.distribution.salt_syspaths_hardcoded_path = SALT_SYSPATHS_HARDCODED
|
||||
self.run_command('generate-salt-syspaths')
|
||||
|
||||
# Resume normal execution
|
||||
develop.run(self)
|
||||
|
||||
|
||||
class InstallM2CryptoWindows(Command):
|
||||
|
||||
description = 'Install M2CryptoWindows'
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
if getattr(self.distribution, 'salt_installing_m2crypto_windows', None) is None:
|
||||
print('This command is not meant to be called on it\'s own')
|
||||
exit(1)
|
||||
import platform
|
||||
from pip.utils import call_subprocess
|
||||
from pip.utils.logging import indent_log
|
||||
platform_bits, _ = platform.architecture()
|
||||
with indent_log():
|
||||
call_subprocess(
|
||||
['pip', 'install', '--egg', 'M2CryptoWin{0}'.format(platform_bits[:2])]
|
||||
)
|
||||
|
||||
|
||||
class InstallPyCryptoWindowsWheel(Command):
|
||||
|
||||
description = 'Install PyCrypto on Windows'
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
if getattr(self.distribution, 'salt_installing_pycrypto_windows', None) is None:
|
||||
print('This command is not meant to be called on it\'s own')
|
||||
exit(1)
|
||||
import platform
|
||||
from pip.utils import call_subprocess
|
||||
from pip.utils.logging import indent_log
|
||||
platform_bits, _ = platform.architecture()
|
||||
call_arguments = ['pip', 'install', 'wheel']
|
||||
if platform_bits == '64bit':
|
||||
call_arguments.append(
|
||||
'http://repo.saltstack.com/windows/dependencies/64/pycrypto-2.6.1-cp27-none-win_amd64.whl'
|
||||
)
|
||||
else:
|
||||
call_arguments.append(
|
||||
'http://repo.saltstack.com/windows/dependencies/32/pycrypto-2.6.1-cp27-none-win32.whl'
|
||||
)
|
||||
with indent_log():
|
||||
call_subprocess(call_arguments)
|
||||
|
||||
|
||||
class DownloadWindowsDlls(Command):
|
||||
|
||||
description = 'Download required DLL\'s for windows'
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
if getattr(self.distribution, 'salt_download_windows_dlls', None) is None:
|
||||
print('This command is not meant to be called on it\'s own')
|
||||
exit(1)
|
||||
import platform
|
||||
from pip.utils.logging import indent_log
|
||||
platform_bits, _ = platform.architecture()
|
||||
url = 'https://repo.saltstack.com/windows/dependencies/{bits}/{fname}32.dll'
|
||||
dest = os.path.join(os.path.dirname(sys.executable), '{fname}32.dll')
|
||||
with indent_log():
|
||||
for fname in ('libeay', 'ssleay'):
|
||||
furl = url.format(bits=platform_bits[:2], fname=fname)
|
||||
fdest = dest.format(fname=fname)
|
||||
if not os.path.exists(fdest):
|
||||
log.info('Downloading {0}32.dll to {1} from {2}'.format(fname, fdest, furl))
|
||||
try:
|
||||
import requests
|
||||
from contextlib import closing
|
||||
with closing(requests.get(furl, stream=True)) as req:
|
||||
if req.status_code == 200:
|
||||
with open(fdest, 'w') as wfh:
|
||||
for chunk in req.iter_content(chunk_size=4096):
|
||||
if chunk: # filter out keep-alive new chunks
|
||||
wfh.write(chunk)
|
||||
wfh.flush()
|
||||
else:
|
||||
log.error(
|
||||
'Failed to download {0}32.dll to {1} from {2}'.format(
|
||||
fname, fdest, furl
|
||||
)
|
||||
)
|
||||
except ImportError:
|
||||
req = urlopen(furl)
|
||||
|
||||
if req.getcode() == 200:
|
||||
with open(fdest, 'w') as wfh:
|
||||
while True:
|
||||
for chunk in req.read(4096):
|
||||
if not chunk:
|
||||
break
|
||||
wfh.write(chunk)
|
||||
wfh.flush()
|
||||
else:
|
||||
log.error(
|
||||
'Failed to download {0}32.dll to {1} from {2}'.format(
|
||||
fname, fdest, furl
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class Sdist(sdist):
|
||||
|
||||
def make_release_tree(self, base_dir, files):
|
||||
|
@ -397,24 +633,10 @@ class Build(build):
|
|||
self.run_command('write-salt-version')
|
||||
|
||||
# Write the system paths file
|
||||
system_paths_file_path = os.path.join(
|
||||
self.distribution.salt_syspaths_hardcoded_path = os.path.join(
|
||||
self.build_lib, 'salt', '_syspaths.py'
|
||||
)
|
||||
open(system_paths_file_path, 'w').write(
|
||||
INSTALL_SYSPATHS_TEMPLATE.format(
|
||||
date=datetime.utcnow(),
|
||||
root_dir=self.distribution.salt_root_dir,
|
||||
config_dir=self.distribution.salt_config_dir,
|
||||
cache_dir=self.distribution.salt_cache_dir,
|
||||
sock_dir=self.distribution.salt_sock_dir,
|
||||
srv_root_dir=self.distribution.salt_srv_root_dir,
|
||||
base_file_roots_dir=self.distribution.salt_base_file_roots_dir,
|
||||
base_pillar_roots_dir=self.distribution.salt_base_pillar_roots_dir,
|
||||
base_master_roots_dir=self.distribution.salt_base_master_roots_dir,
|
||||
logs_dir=self.distribution.salt_logs_dir,
|
||||
pidfile_dir=self.distribution.salt_pidfile_dir,
|
||||
)
|
||||
)
|
||||
self.run_command('generate-salt-syspaths')
|
||||
|
||||
|
||||
class Install(install):
|
||||
|
@ -507,6 +729,20 @@ class Install(install):
|
|||
self.distribution.salt_version_hardcoded_path = os.path.join(
|
||||
self.build_lib, 'salt', '_version.py'
|
||||
)
|
||||
if IS_WINDOWS_PLATFORM:
|
||||
if __saltstack_version__.info < (2015, 8): # pylint: disable=undefined-variable
|
||||
# Install M2Crypto first
|
||||
self.distribution.salt_installing_m2crypto_windows = True
|
||||
self.run_command('install-m2crypto-windows')
|
||||
self.distribution.salt_installing_m2crypto_windows = None
|
||||
# Install PyCrypto
|
||||
self.distribution.salt_installing_pycrypto_windows = True
|
||||
self.run_command('install-pycrypto-windows')
|
||||
self.distribution.salt_installing_pycrypto_windows = None
|
||||
# Download the required DLLs
|
||||
self.distribution.salt_download_windows_dlls = True
|
||||
self.run_command('download-windows-dlls')
|
||||
self.distribution.salt_download_windows_dlls = None
|
||||
# Run install.run
|
||||
install.run(self)
|
||||
|
||||
|
@ -605,7 +841,6 @@ class SaltDistribution(distutils.dist.Distribution):
|
|||
self.salt_logs_dir = None
|
||||
self.salt_pidfile_dir = None
|
||||
|
||||
|
||||
self.name = 'salt-ssh' if PACKAGED_FOR_SALT_SSH else 'salt'
|
||||
self.salt_version = __version__ # pylint: disable=undefined-variable
|
||||
self.description = 'Portable, distributed, remote execution and configuration management system'
|
||||
|
@ -618,10 +853,19 @@ class SaltDistribution(distutils.dist.Distribution):
|
|||
'sdist': Sdist,
|
||||
'install': Install,
|
||||
'write-salt-version': WriteSaltVersion,
|
||||
'generate-salt-syspaths': GenerateSaltSyspaths,
|
||||
'write-salt-ssh-packaging-file': WriteSaltSshPackaingFile})
|
||||
if not IS_WINDOWS_PLATFORM:
|
||||
self.cmdclass.update({'sdist': CloudSdist,
|
||||
'install_lib': InstallLib})
|
||||
if IS_WINDOWS_PLATFORM:
|
||||
self.cmdclass.update({'install-pycrypto-windows': InstallPyCryptoWindowsWheel,
|
||||
'download-windows-dlls': DownloadWindowsDlls})
|
||||
if __saltstack_version__.info < (2015, 8): # pylint: disable=undefined-variable
|
||||
self.cmdclass.update({'install-m2crypto-windows': InstallM2CryptoWindows})
|
||||
|
||||
if WITH_SETUPTOOLS:
|
||||
self.cmdclass.update({'develop': Develop})
|
||||
|
||||
self.license = 'Apache Software License 2.0'
|
||||
self.packages = self.discover_packages()
|
||||
|
@ -739,6 +983,7 @@ class SaltDistribution(distutils.dist.Distribution):
|
|||
|
||||
if IS_WINDOWS_PLATFORM:
|
||||
install_requires.append('WMI')
|
||||
install_requires.append('pypiwin32 >= 219')
|
||||
|
||||
if self.salt_transport == 'zeromq':
|
||||
install_requires += _parse_requirements_file(SALT_ZEROMQ_REQS)
|
||||
|
@ -916,14 +1161,6 @@ class SaltDistribution(distutils.dist.Distribution):
|
|||
def parse_command_line(self):
|
||||
args = distutils.dist.Distribution.parse_command_line(self)
|
||||
|
||||
# Setup our property functions after class initialization and
|
||||
# after parsing the command line since most are set to None
|
||||
for funcname in dir(self):
|
||||
if not funcname.startswith('_property_'):
|
||||
continue
|
||||
property_name = funcname.split('_property_', 1)[-1]
|
||||
setattr(self, property_name, getattr(self, funcname))
|
||||
|
||||
if not self.ssh_packaging and PACKAGED_FOR_SALT_SSH:
|
||||
self.ssh_packaging = 1
|
||||
|
||||
|
@ -941,6 +1178,16 @@ class SaltDistribution(distutils.dist.Distribution):
|
|||
)
|
||||
)
|
||||
|
||||
# Setup our property functions after class initialization and
|
||||
# after parsing the command line since most are set to None
|
||||
# ATTENTION: This should be the last step before returning the args or
|
||||
# some of the requirements won't be correctly set
|
||||
for funcname in dir(self):
|
||||
if not funcname.startswith('_property_'):
|
||||
continue
|
||||
property_name = funcname.split('_property_', 1)[-1]
|
||||
setattr(self, property_name, getattr(self, funcname))
|
||||
|
||||
return args
|
||||
# <---- Overridden Methods ---------------------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue