Commit 69095b74 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 6bf8e336
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
# #
############################################################################## ##############################################################################
import datetime
import errno import errno
import os import os
import pkg_resources import pkg_resources
...@@ -284,6 +285,7 @@ class Software(object): ...@@ -284,6 +285,7 @@ class Software(object):
buildout_cfg = os.path.join(self.software_path, 'buildout.cfg') buildout_cfg = os.path.join(self.software_path, 'buildout.cfg')
if not os.path.exists(buildout_cfg): if not os.path.exists(buildout_cfg):
self._create_buildout_profile(buildout_cfg, self.url, self.shared_part_list) 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 = list(self._additional_buildout_parameters(extends_cache))
additional_parameters.extend(['-c', buildout_cfg]) additional_parameters.extend(['-c', buildout_cfg])
...@@ -327,6 +329,32 @@ class Software(object): ...@@ -327,6 +329,32 @@ class Software(object):
parser.write(fout) parser.write(fout)
self._set_ownership(buildout_cfg) 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): def uploadSoftwareRelease(self, tarpath):
""" """
Try to tar and upload an installed Software Release. Try to tar and upload an installed Software Release.
......
...@@ -27,8 +27,11 @@ ...@@ -27,8 +27,11 @@
import logging import logging
import os import os
import subprocess
import time import time
import unittest import unittest
import shutil
import tempfile
from slapos.slap import ComputerPartition as SlapComputerPartition from slapos.slap import ComputerPartition as SlapComputerPartition
...@@ -333,6 +336,34 @@ class TestSoftwareNetworkCacheSlapObject(MasterMixin, unittest.TestCase): ...@@ -333,6 +336,34 @@ class TestSoftwareNetworkCacheSlapObject(MasterMixin, unittest.TestCase):
software.install() software.install()
self.assertTrue(getattr(self, 'uploaded', False)) 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): class TestPartitionSlapObject(MasterMixin, unittest.TestCase):
def setUp(self): def setUp(self):
MasterMixin.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