Commit 58ab95ab authored by Jérome Perrin's avatar Jérome Perrin

grid: note git revision when installing from a git checkout

Installing from a git checkout is a bad practice for production, but it's a
common thing during development. One problem I often face is that I have a
software release installed from a given revision and I want to make a small
change to the software, but not recompile everything. To achieve this, I need
to use the exact same git revision that was installed before, but most of the
time, I don't remember what revision I have been using last time I installed.

This change is about adding a buildout comment in the generated buildout.cfg
made to install the profile, with the revision that was used for installing, so
that we can re-install the same software again.
parent 232274df
Pipeline #15233 running with stage
in 0 seconds
......@@ -28,6 +28,7 @@
#
##############################################################################
import datetime
import errno
import os
import pkg_resources
......@@ -284,6 +285,7 @@ class Software(object):
buildout_cfg = os.path.join(self.software_path, 'buildout.cfg')
if not os.path.exists(buildout_cfg):
self._create_buildout_profile(buildout_cfg, self.url, self.shared_part_list)
self._note_git_revision(buildout_cfg, self.url)
additional_parameters = list(self._additional_buildout_parameters(extends_cache))
additional_parameters.extend(['-c', buildout_cfg])
......@@ -327,6 +329,32 @@ class Software(object):
parser.write(fout)
self._set_ownership(buildout_cfg)
def _note_git_revision(self, buildout_cfg, url):
"""Add a comment with the revision if the profile is a git checkout.
This makes it easier to rebuild the same revision.
"""
git_revision = None
if os.path.exists(url):
try:
git_revision = subprocess.check_output(
('git', 'describe', '--all', '--long', '--dirty'),
cwd=os.path.dirname(url),
).decode()
except (OSError, subprocess.CalledProcessError):
self.logger.debug(
'Error guessing git revision for profile %s',
url,
exc_info=True)
if git_revision:
with open(buildout_cfg) as f:
if git_revision in f.readlines()[-1]:
self.logger.debug('Current revision was already noted')
return
with open(buildout_cfg, 'a') as f:
f.write(
"# %s git revision: %s" % (datetime.datetime.utcnow(), git_revision))
def uploadSoftwareRelease(self, tarpath):
"""
Try to tar and upload an installed Software Release.
......
......@@ -27,8 +27,11 @@
import logging
import os
import subprocess
import time
import unittest
import shutil
import tempfile
from slapos.slap import ComputerPartition as SlapComputerPartition
......@@ -333,6 +336,34 @@ class TestSoftwareNetworkCacheSlapObject(MasterMixin, unittest.TestCase):
software.install()
self.assertTrue(getattr(self, 'uploaded', False))
def test_software_install_note_git_revision(self):
tmpdir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, tmpdir)
subprocess.check_call(('git', 'init'), cwd=tmpdir)
profile_url = os.path.join(tmpdir, 'software.cfg')
open(profile_url, 'w').close()
subprocess.check_call(('git', 'add', 'software.cfg'), cwd=tmpdir)
subprocess.check_call(
('git', 'commit', '-m', 'first commit'),
cwd=tmpdir,
env=dict(
os.environ,
GIT_AUTHOR_NAME='nobody',
GIT_AUTHOR_EMAIL='nobody@example.com',
GIT_COMMITTER_NAME='nobody',
GIT_COMMITTER_EMAIL='nobody@example.com',))
software = Software(
url=profile_url,
software_root=self.software_root,
buildout=self.buildout,
logger=logging.getLogger())
software.install()
with open(os.path.join(software.software_path, 'buildout.cfg')) as f:
self.assertIn("git revision: heads/master-0-g", f.read())
class TestPartitionSlapObject(MasterMixin, unittest.TestCase):
def setUp(self):
MasterMixin.setUp(self)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment