Merge branch '2015.8' into '2016.3'

No conflicts.
This commit is contained in:
rallytime 2016-09-19 11:22:54 -06:00
commit c64e489f6f
8 changed files with 190 additions and 13 deletions

View File

@ -14,10 +14,10 @@ open and proprietary projects.
To expand on this a little:
There is much argument over the actual definition of "open core". From our standpoint, Salt is open source because
There is much argument over the actual definition of "open core". From our standpoint, Salt is open source because
1. It is a standalone product that that anyone is free to use.
2. It is developed in the open with contributions accepted from the community for the good of the project.
1. It is a standalone product that anyone is free to use.
2. It is developed in the open with contributions accepted from the community for the good of the project.
3. There are no features of Salt itself that are restricted to separate proprietary products distributed by SaltStack, Inc.
4. Because of our Apache 2.0 license, Salt can be used as the foundation for a project or even a proprietary tool.
5. Our APIs are open and documented (any lack of documentation is an oversight as opposed to an intentional decision by SaltStack the company) and available for use by anyone.

10
requirements/windows.txt Normal file
View File

@ -0,0 +1,10 @@
backports-abc
backports.ssl-match-hostname
certifi
psutil
python-dateutil
pypiwin32
pyzmq
six
timelib
WMI

View File

@ -997,6 +997,7 @@ _OS_NAME_MAP = {
'enterprise': 'OEL',
'oracleserv': 'OEL',
'cloudserve': 'CloudLinux',
'cloudlinux': 'CloudLinux',
'pidora': 'Fedora',
'scientific': 'ScientificLinux',
'synology': 'Synology',

View File

@ -983,14 +983,20 @@ def upgrade(refresh=True, dist_upgrade=False, **kwargs):
force_conf = '--force-confnew'
else:
force_conf = '--force-confold'
cmd = []
if salt.utils.systemd.has_scope(__context__) \
and __salt__['config.get']('systemd.scope', True):
cmd.extend(['systemd-run', '--scope'])
cmd.extend(['apt-get', '-q', '-y',
'-o', 'DPkg::Options::={0}'.format(force_conf),
'-o', 'DPkg::Options::=--force-confdef'])
if kwargs.get('force_yes', False):
cmd.append('--force-yes')
if kwargs.get('skip_verify', False):
cmd.append('--allow-unauthenticated')
cmd.append('dist-upgrade' if dist_upgrade else 'upgrade')
call = __salt__['cmd.run_all'](cmd,

View File

@ -165,7 +165,7 @@ def start(name):
salt '*' service.start <service name>
'''
cmd = ['net', 'start', name]
cmd = ['net', 'start', '/y', name]
return not __salt__['cmd.retcode'](cmd, python_shell=False)
@ -183,7 +183,7 @@ def stop(name):
# up if the service takes too long to stop with a misleading
# "service could not be stopped" message and RC 0.
cmd = ['net', 'stop', name]
cmd = ['net', 'stop', '/y', name]
res = __salt__['cmd.run'](cmd, python_shell=False)
if 'service was stopped' in res:
return True

View File

@ -1142,6 +1142,20 @@ def latest(name,
else:
branch_opts = None
if branch_opts is not None and local_branch is None:
return _fail(
ret,
'Cannot set/unset upstream tracking branch, local '
'HEAD refers to nonexistent branch. This may have '
'been caused by cloning a remote repository for which '
'the default branch was renamed or deleted. If you '
'are unable to fix the remote repository, you can '
'work around this by setting the \'branch\' argument '
'(which will ensure that the named branch is created '
'if it does not already exist).',
comments
)
if not has_remote_rev:
try:
fetch_changes = __salt__['git.fetch'](
@ -1561,6 +1575,21 @@ def latest(name,
local_rev, local_branch = \
_get_local_rev_and_branch(target, user, password)
if local_branch is None \
and remote_rev is not None \
and 'HEAD' not in all_remote_refs:
return _fail(
ret,
'Remote HEAD refers to a ref that does not exist. '
'This can happen when the default branch on the '
'remote repository is renamed or deleted. If you '
'are unable to fix the remote repository, you can '
'work around this by setting the \'branch\' argument '
'(which will ensure that the named branch is created '
'if it does not already exist).',
comments
)
if not _revs_equal(local_rev, remote_rev, remote_rev_type):
__salt__['git.reset'](
target,

View File

@ -119,6 +119,7 @@ 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', 'base.txt')
SALT_WINDOWS_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'requirements', 'windows.txt')
SALT_ZEROMQ_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'requirements', 'zeromq.txt')
SALT_RAET_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'requirements', 'raet.txt')
@ -384,11 +385,11 @@ class InstallPyCryptoWindowsWheel(Command):
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'
'https://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'
'https://repo.saltstack.com/windows/dependencies/32/pycrypto-2.6.1-cp27-none-win32.whl'
)
with indent_log():
call_subprocess(call_arguments)
@ -415,11 +416,11 @@ class InstallCompiledPyYaml(Command):
call_arguments = ['easy_install', '-Z']
if platform_bits == '64bit':
call_arguments.append(
'http://repo.saltstack.com/windows/dependencies/64/PyYAML-3.11.win-amd64-py2.7.exe'
'https://repo.saltstack.com/windows/dependencies/64/PyYAML-3.11.win-amd64-py2.7.exe'
)
else:
call_arguments.append(
'http://repo.saltstack.com/windows/dependencies/32/PyYAML-3.11.win-amd64-py2.7.exe'
'https://repo.saltstack.com/windows/dependencies/32/PyYAML-3.11.win32-py2.7.exe'
)
with indent_log():
call_subprocess(call_arguments)
@ -442,7 +443,7 @@ class DownloadWindowsDlls(Command):
import platform
from pip.utils.logging import indent_log
platform_bits, _ = platform.architecture()
url = 'http://repo.saltstack.com/windows/dependencies/{bits}/{fname}.dll'
url = 'https://repo.saltstack.com/windows/dependencies/{bits}/{fname}.dll'
dest = os.path.join(os.path.dirname(sys.executable), '{fname}.dll')
with indent_log():
for fname in ('libeay32', 'ssleay32', 'libsodium', 'msvcr120'):
@ -1065,8 +1066,7 @@ class SaltDistribution(distutils.dist.Distribution):
install_requires = _parse_requirements_file(SALT_REQS)
if IS_WINDOWS_PLATFORM:
install_requires.append('WMI')
install_requires.append('pypiwin32 >= 219')
install_requires += _parse_requirements_file(SALT_WINDOWS_REQS)
if self.salt_transport == 'zeromq':
install_requires += _parse_requirements_file(SALT_ZEROMQ_REQS)

View File

@ -8,6 +8,7 @@ from __future__ import absolute_import
import os
import shutil
import socket
import string
import subprocess
import tempfile
@ -328,6 +329,136 @@ class GitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
self.assertSaltTrueReturn(ret)
@skip_if_binaries_missing('git')
class LocalRepoGitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
'''
Tests which do no require connectivity to github.com
'''
def test_renamed_default_branch(self):
'''
Test the case where the remote branch has been removed
https://github.com/saltstack/salt/issues/36242
'''
cwd = os.getcwd()
repo = tempfile.mkdtemp(dir=integration.TMP)
admin = tempfile.mkdtemp(dir=integration.TMP)
name = tempfile.mkdtemp(dir=integration.TMP)
for dirname in (repo, admin, name):
self.addCleanup(shutil.rmtree, dirname, ignore_errors=True)
self.addCleanup(os.chdir, cwd)
with salt.utils.fopen(os.devnull, 'w') as devnull:
# Create bare repo
subprocess.check_call(['git', 'init', '--bare', repo],
stdout=devnull, stderr=devnull)
# Clone bare repo
subprocess.check_call(['git', 'clone', repo, admin],
stdout=devnull, stderr=devnull)
# Create, add, commit, and push file
os.chdir(admin)
with salt.utils.fopen('foo', 'w'):
pass
subprocess.check_call(['git', 'add', '.'],
stdout=devnull, stderr=devnull)
subprocess.check_call(['git', 'commit', '-m', 'init'],
stdout=devnull, stderr=devnull)
subprocess.check_call(['git', 'push', 'origin', 'master'],
stdout=devnull, stderr=devnull)
# Change back to the original cwd
os.chdir(cwd)
# Rename remote 'master' branch to 'develop'
os.rename(
os.path.join(repo, 'refs', 'heads', 'master'),
os.path.join(repo, 'refs', 'heads', 'develop')
)
# Run git.latest state. This should successfuly clone and fail with a
# specific error in the comment field.
ret = self.run_state(
'git.latest',
name=repo,
target=name,
rev='develop',
)
self.assertSaltFalseReturn(ret)
self.assertEqual(
ret[next(iter(ret))]['comment'],
'Remote HEAD refers to a ref that does not exist. '
'This can happen when the default branch on the '
'remote repository is renamed or deleted. If you '
'are unable to fix the remote repository, you can '
'work around this by setting the \'branch\' argument '
'(which will ensure that the named branch is created '
'if it does not already exist).\n\n'
'Changes already made: {0} cloned to {1}'
.format(repo, name)
)
self.assertEqual(
ret[next(iter(ret))]['changes'],
{'new': '{0} => {1}'.format(repo, name)}
)
# Run git.latest state again. This should fail again, with a different
# error in the comment field, and should not change anything.
ret = self.run_state(
'git.latest',
name=repo,
target=name,
rev='develop',
)
self.assertSaltFalseReturn(ret)
self.assertEqual(
ret[next(iter(ret))]['comment'],
'Cannot set/unset upstream tracking branch, local '
'HEAD refers to nonexistent branch. This may have '
'been caused by cloning a remote repository for which '
'the default branch was renamed or deleted. If you '
'are unable to fix the remote repository, you can '
'work around this by setting the \'branch\' argument '
'(which will ensure that the named branch is created '
'if it does not already exist).'
)
self.assertEqual(ret[next(iter(ret))]['changes'], {})
# Run git.latest state again with a branch manually set. This should
# checkout a new branch and the state should pass.
ret = self.run_state(
'git.latest',
name=repo,
target=name,
rev='develop',
branch='develop',
)
# State should succeed
self.assertSaltTrueReturn(ret)
self.assertSaltCommentRegexpMatches(
ret,
'New branch \'develop\' was checked out, with origin/develop '
r'\([0-9a-f]{7}\) as a starting point'
)
# Only the revision should be in the changes dict.
self.assertEqual(
list(ret[next(iter(ret))]['changes'].keys()),
['revision']
)
# Since the remote repo was incorrectly set up, the local head should
# not exist (therefore the old revision should be None).
self.assertEqual(
ret[next(iter(ret))]['changes']['revision']['old'],
None
)
# Make sure the new revision is a SHA (40 chars, all hex)
self.assertTrue(
len(ret[next(iter(ret))]['changes']['revision']['new']) == 40)
self.assertTrue(
all([x in string.hexdigits for x in
ret[next(iter(ret))]['changes']['revision']['new']])
)
if __name__ == '__main__':
from integration import run_tests
run_tests(GitTest)