Thcipriani has uploaded a new change for review.
https://gerrit.wikimedia.org/r/224374
Change subject: Add service deploy via scap
......................................................................
Add service deploy via scap
Preliminary rough concept for deploying services via git from scap.
The command would looks something like: `deploy <rev>` run from
/srv/deployment/restbase/deploy (or other service directory: like
git-deploy now) and would require a `.scaprc` file at the root of the
repository being deployed with the following information:
[global]
git_server: tin.eqiad.wmnet
git_repo: restbase/deploy
git_deploy_dir: /srv/deployment
dsh_targets: restbase-installation
[wmflabs]
git_server: staging-test-tin.staging.eqiad.wmflabs
Change-Id: I542bb9acc0f65360452fb4f0b0c92dec4894e5d8
---
A bin/deploy
A bin/deploy-local
M scap/__init__.py
M scap/config.py
M scap/main.py
M scap/tasks.py
M scap/utils.py
7 files changed, 157 insertions(+), 3 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/tools/scap
refs/changes/74/224374/1
diff --git a/bin/deploy b/bin/deploy
new file mode 100755
index 0000000..e048d76
--- /dev/null
+++ b/bin/deploy
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Sync MW source and config to cluster.
+#
+# Copyright © 2014 Wikimedia Foundation and contributors
+
+import os
+import sys
+
+# Add scap package to search path
+script = os.path.realpath(sys.argv[0])
+scap_src = os.path.dirname(os.path.dirname(script))
+sys.path.append(scap_src)
+
+import scap
+scap.Deploy.run()
diff --git a/bin/deploy-local b/bin/deploy-local
new file mode 100755
index 0000000..09e0ac1
--- /dev/null
+++ b/bin/deploy-local
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Sync MW source and config to cluster.
+#
+# Copyright © 2014 Wikimedia Foundation and contributors
+
+import os
+import sys
+
+# Add scap package to search path
+script = os.path.realpath(sys.argv[0])
+scap_src = os.path.dirname(os.path.dirname(script))
+sys.path.append(scap_src)
+
+import scap
+scap.DeployLocal.run()
diff --git a/scap/__init__.py b/scap/__init__.py
index 84af164..98607eb 100644
--- a/scap/__init__.py
+++ b/scap/__init__.py
@@ -21,6 +21,8 @@
SyncFile,
SyncWikiversions,
UpdateL10n,
+ DeployLocal,
+ Deploy,
)
__all__ = (
@@ -38,6 +40,8 @@
'SyncFile',
'SyncWikiversions',
'UpdateL10n',
+ 'DeployLocal',
+ 'Deploy',
)
any((
@@ -54,4 +58,7 @@
SyncDocroot,
SyncFile,
SyncWikiversions,
- UpdateL10n)) # Ignore unused import warning
+ UpdateL10n,
+ DeployLocal,
+ Deploy
+ )) # Ignore unused import warning
diff --git a/scap/config.py b/scap/config.py
index b4a4348..ba32e8d 100644
--- a/scap/config.py
+++ b/scap/config.py
@@ -30,6 +30,10 @@
'apache_pid_file': '/var/run/apache2/apache2.pid',
'pybal_interface': 'lo:LVS',
'dsh_targets': 'mediawiki-installation',
+ 'git_deploy_dir': '/srv/deployments',
+ 'git_repo_user': 'mwdeploy',
+ 'git_server': 'tin.eqiad.wmnet',
+ 'git_scheme': 'http',
}
@@ -68,11 +72,18 @@
parser.readfp(cfg_file)
else:
- parser.read([
+ cfg_paths = [
os.path.join(os.path.dirname(__file__), '..', 'scap.cfg'),
'/srv/scap/scap.cfg',
'/etc/scap.cfg',
- ])
+ ]
+
+ local_cfg = os.path.join(os.getcwd(), ".scaprc")
+
+ if os.access(local_cfg, os.R_OK):
+ cfg_paths += [local_cfg]
+
+ parser.read(cfg_paths)
fqdn = socket.getfqdn().split('.')
sections = ['global']
diff --git a/scap/main.py b/scap/main.py
index 70402b0..f938387 100644
--- a/scap/main.py
+++ b/scap/main.py
@@ -559,3 +559,67 @@
self.get_stats().increment('deploy.restart')
return exit_code
+
+
+class DeployLocal(cli.Application):
+ """Fetch new restbase code from gerrit"""
+
+ def main(self, *extra_args):
+ repo = self.config['git_repo']
+ repo_user = self.config['git_repo_user']
+ server = self.config['git_server']
+ rev = self.config['git_rev']
+
+ location =
os.path.normpath("{0}/{1}".format(self.config['git_deploy_dir'], repo))
+
+ if self.config['git_scheme'] == 'git' or self.config['git_scheme'] ==
'http':
+ scheme = 'http'
+
+ url = os.path.normpath('{0}/{1}'.format(server, repo))
+ url = "{0}://{1}".format(scheme, url)
+
+ # Fetch
+ tasks.git_fetch(location, url, repo_user)
+
+ # Checkout
+ tasks.git_co(location, rev, repo_user)
+
+
+class Deploy(cli.Application):
+
+ @cli.argument('rev', help='Revision to deploy')
+ def main(self, *extra_args):
+
+ in_deploy_dir = os.path.commonprefix([
+ os.getcwd(),
+ self.config['git_deploy_dir']
+ ]) == self.config['git_deploy_dir']
+
+ if not in_deploy_dir:
+ raise IOError(1,
+ 'Your path is not a part of the git deploy path',
+ self.config['git_deploy_dir'])
+
+ repo = self.config['git_repo']
+ targets = utils.read_dsh_hosts_file(self.config['dsh_targets'])
+ with utils.lock(self.config['lock_file']):
+ with log.Timer('deploy_' + repo):
+ deploy_rev = ssh.Job(targets, user=self.config['ssh_user'])
+ deploy_rev.command([
+ self.get_script_path('deploy-local'),
+ '-D git_repo:{}'.format(repo),
+ '-D git_repo_user:{}'.format(self.config['git_repo_user']),
+ '-D git_server:{}'.format(self.config['git_server']),
+ '-D git_rev:{}'.format(self.arguments.rev)
+ ])
+ deploy_rev.progress('deploy_' + repo)
+ succeeded, failed = deploy_rev.run()
+ if failed:
+ self.get_logger().warning(
+ '%d targets had deploy errors', failed)
+ self.soft_errors = True
+
+ if self.soft_errors:
+ return 1
+ else:
+ return 0
diff --git a/scap/tasks.py b/scap/tasks.py
index 2fa6cea..9dde01e 100644
--- a/scap/tasks.py
+++ b/scap/tasks.py
@@ -533,3 +533,27 @@
restart.command('sudo -u mwdeploy -n -- %s' %
os.path.join(cfg['bin_dir'], 'scap-hhvm-restart'))
return restart.progress('restart_hhvm').run(batch_size=batch_size)
+
+
+def git_fetch(location, repo, user="mwdeploy"):
+ """Fetch a git repo to a location as a user
+ """
+ if os.path.isdir("{}/.git".format(location)):
+ with utils.cd(location):
+ cmd = '/usr/bin/git fetch'
+ utils.sudo_check_call(user, cmd)
+ else:
+ cmd = '/usr/bin/git clone {0} {1}'.format(repo, location)
+ utils.sudo_check_call(user, cmd)
+
+
+def git_co(location, rev, user="mwdeploy", submodules=False):
+ """Checkout a git repo sha at a location as a user
+ """
+ with utils.cd(location):
+ cmd = '/usr/bin/git checkout --force --quiet {}'.format(rev)
+ utils.sudo_check_call(user, cmd)
+
+ if submodules is True:
+ cmd = '/usr/bin/git submodule update --init --recursive'
+ utils.sudo_check_call(user, cmd)
diff --git a/scap/utils.py b/scap/utils.py
index ff1a31d..24d47e6 100644
--- a/scap/utils.py
+++ b/scap/utils.py
@@ -260,6 +260,20 @@
os.unlink(filename)
[email protected]
+def cd(dirname):
+ """Context manager. Cds to dirname, moves back to previous dir on context
exit
+
+ :param dirname: directory into which it should change
+ """
+ old_path = os.getcwd()
+ try:
+ os.chdir(dirname)
+ yield
+ finally:
+ os.chdir(old_path)
+
+
def md5_file(path):
"""Compute the md5 checksum of a file's contents.
--
To view, visit https://gerrit.wikimedia.org/r/224374
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I542bb9acc0f65360452fb4f0b0c92dec4894e5d8
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/tools/scap
Gerrit-Branch: master
Gerrit-Owner: Thcipriani <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits