← Back to team overview

yellow team mailing list archive

[Merge] lp:~bac/lpsetup/addheaders into lp:lpsetup

 

Brad Crittenden has proposed merging lp:~bac/lpsetup/addheaders into lp:lpsetup.

Requested reviews:
  Yellow Squad (yellow): code

For more details, see:
https://code.launchpad.net/~bac/lpsetup/addheaders/+merge/113270

Add headers to created or modified system files.  Here's what one looks like:

"""
#!/bin/sh
# Copyright 2012 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

# This file created at 2012-07-03T17:36:53.075414UTC by
# /home/bac/lpsetup/addheaders/lp-setup, version 0.2.2.

# Run the Launchpad build inside LXC.

# Assumptions:
#  * This script is run as root.
"""



-- 
https://code.launchpad.net/~bac/lpsetup/addheaders/+merge/113270
Your team Yellow Squad is requested to review the proposed merge of lp:~bac/lpsetup/addheaders into lp:lpsetup.
=== modified file 'README.rst'
--- README.rst	2012-06-27 10:17:46 +0000
+++ README.rst	2012-07-03 18:06:17 +0000
@@ -22,7 +22,7 @@
 
     lp-setup install
 
-If instead tou want to install the Launchpad environment inside an LXC::
+If instead you want to install the Launchpad environment inside an LXC::
 
     lp-setup lxc-install
 

=== modified file 'lpsetup/subcommands/get.py'
--- lpsetup/subcommands/get.py	2012-06-27 09:10:56 +0000
+++ lpsetup/subcommands/get.py	2012-07-03 18:06:17 +0000
@@ -84,9 +84,10 @@
     """Create a repo for the Launchpad code and retrieve it."""
     # TODO Add --no-trees handling.
     with su(user):
-        # Set up the repository.
+        # Set up the repository, but only if it needs it.
         mkdirs(directory)
-        call('bzr', 'init-repo', '--2a', directory)
+        if not os.path.exists(os.path.join(directory, '.bzr')):
+            call('bzr', 'init-repo', '--2a', directory)
     # Set up the codebase.
     checkout_dir = os.path.join(directory, LP_CHECKOUT)
     setup_codebase(user, checkout_dir, dependencies_dir, valid_ssh_keys)

=== modified file 'lpsetup/subcommands/inithost.py'
--- lpsetup/subcommands/inithost.py	2012-07-03 16:45:18 +0000
+++ lpsetup/subcommands/inithost.py	2012-07-03 18:06:17 +0000
@@ -37,7 +37,10 @@
     LP_PACKAGES,
     SSH_KEY_NAME,
     )
-from lpsetup.utils import call
+from lpsetup.utils import (
+    call,
+    get_file_header,
+    )
 
 
 def write_file_contents(filename, contents, mode):
@@ -120,7 +123,14 @@
             (auth_file, public_key, 'a'),
             (known_hosts, known_host_content, 'a'),
             ]:
+<<<<<<< TREE
             write_file_contents(filename, contents, mode)
+=======
+            with open(filename, mode) as f:
+                f.write(get_file_header() + '\n')
+                f.write(contents + '\n')
+            os.chmod(filename, 0644)
+>>>>>>> MERGE-SOURCE
         os.chmod(ssh_key_path, 0600)
         # Set up bzr and Launchpad authentication.
         call('bzr', 'whoami', formataddr([full_name, email]))

=== modified file 'lpsetup/subcommands/initlxc.py'
--- lpsetup/subcommands/initlxc.py	2012-06-28 17:22:45 +0000
+++ lpsetup/subcommands/initlxc.py	2012-07-03 18:06:17 +0000
@@ -41,6 +41,7 @@
 from lpsetup.utils import (
     call,
     get_container_path,
+    get_file_header,
     get_lxc_gateway,
     lxc_stopped,
     render_to_file,
@@ -79,6 +80,7 @@
             'Error: LXC bridge interface not found.')
     content = LXC_OPTIONS.format(interface=lxc_gateway)
     with open(LXC_CONFIG_TEMPLATE, 'w') as f:
+        f.write(get_file_header() + '\n')
         f.write(content)
     # Creating container.
     call(

=== modified file 'lpsetup/subcommands/install.py'
--- lpsetup/subcommands/install.py	2012-06-27 09:10:56 +0000
+++ lpsetup/subcommands/install.py	2012-07-03 18:06:17 +0000
@@ -40,6 +40,7 @@
 from lpsetup.utils import (
     call,
     ConfigParser,
+    get_file_header,
     )
 
 
@@ -92,6 +93,7 @@
             for option, value in options.items():
                 parser.set(section, option, value.format(**context))
         with open(path, 'w') as f:
+            f.write(get_file_header() + '\n')
             parser.write(f)
 
 

=== modified file 'lpsetup/subcommands/lxcinstall.py'
--- lpsetup/subcommands/lxcinstall.py	2012-06-28 17:04:14 +0000
+++ lpsetup/subcommands/lxcinstall.py	2012-07-03 18:06:17 +0000
@@ -30,6 +30,7 @@
     install,
     )
 from lpsetup.utils import (
+    get_file_header,
     render_to_file,
     sshlxc as ssh,
     this_command,
@@ -38,11 +39,13 @@
 
 def create_scripts(lxc_name, ssh_key_path, user):
     """Create scripts to update the Launchpad environment and run tests."""
+
     context = {
         'lxcip': LXC_IP_COMMAND[0],
         'lxc_name': lxc_name,
         'ssh_key_path': ssh_key_path,
         'user': user,
+        'installation_header': get_file_header(initial_indent=''),
         }
     scripts = []
     # Generate the scripts.
@@ -56,6 +59,7 @@
     sudoers_contents = '{user} ALL = (ALL) NOPASSWD: {scripts}\n'.format(
         user=user, scripts=', '. join(scripts))
     with open(sudoers_file, 'w') as sudoers:
+        sudoers.write(get_file_header() + '\n')
         sudoers.write(sudoers_contents)
     # The sudoers must have this mode or it will be ignored.
     os.chmod(sudoers_file, 0440)
@@ -72,7 +76,7 @@
     # Use ssh to call this script from inside the container.
     args = [
         'install', '-u', user, '-s', 'setup_apt', 'setup_launchpad',
-        '-d', dependencies_dir, '-c', directory
+        '-d', dependencies_dir, '-c', directory,
         ]
     cmd = this_command(directory, args)
     ssh(lxc_name, cmd, key=ssh_key_path)

=== modified file 'lpsetup/templates/lp-setup-lxc-build'
--- lpsetup/templates/lp-setup-lxc-build	2012-05-24 17:25:39 +0000
+++ lpsetup/templates/lp-setup-lxc-build	2012-07-03 18:06:17 +0000
@@ -2,6 +2,8 @@
 # Copyright 2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
+# {installation_header}
+
 # Run the Launchpad build inside LXC.
 
 # Assumptions:

=== modified file 'lpsetup/templates/lp-setup-lxc-cleanup'
--- lpsetup/templates/lp-setup-lxc-cleanup	2012-04-10 17:16:25 +0000
+++ lpsetup/templates/lp-setup-lxc-cleanup	2012-07-03 18:06:17 +0000
@@ -2,6 +2,8 @@
 # Copyright 2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
+# {installation_header}
+
 # Cleanup remnants of LXC containers from previous runs.
 
 # Runs of LXC may leave cruft laying around that interferes with

=== modified file 'lpsetup/templates/lp-setup-lxc-test'
--- lpsetup/templates/lp-setup-lxc-test	2012-06-27 17:59:09 +0000
+++ lpsetup/templates/lp-setup-lxc-test	2012-07-03 18:06:17 +0000
@@ -2,6 +2,8 @@
 # Copyright 2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
+# {installation_header}
+
 # Test Launchpad using LXC ephemeral instances.
 
 # Assumptions:

=== modified file 'lpsetup/tests/test_utils.py'
--- lpsetup/tests/test_utils.py	2012-05-15 13:53:23 +0000
+++ lpsetup/tests/test_utils.py	2012-07-03 18:06:17 +0000
@@ -4,6 +4,7 @@
 
 """Tests for the utils module."""
 
+from datetime import datetime
 import getpass
 import os
 import shutil
@@ -12,6 +13,7 @@
 import tempfile
 import unittest
 
+from lpsetup import get_version
 from lpsetup.settings import (
     LXC_LP_DIR_PATTERN,
     LXC_LP_TEST_DIR_PATTERN,
@@ -20,6 +22,7 @@
 from lpsetup.utils import (
     ConfigParser,
     get_container_path,
+    get_file_header,
     get_lxc_gateway,
     get_network_interfaces,
     get_running_containers,
@@ -63,6 +66,41 @@
             get_container_path('mycontainer', 'home'))
 
 
+class GetFileHeaderTest(unittest.TestCase):
+
+    def setUp(self):
+        self.version = get_version()
+        self.t = datetime(1969, 7, 20, 20, 18)
+        self.fake_program = 'fake_program'
+
+    def test_getfileheader_time(self):
+        header = get_file_header(program=self.fake_program, now=self.t)
+        expected = '# This file created at {}UTC'.format(self.t.isoformat())
+        self.assertTrue(header.startswith(expected))
+
+    def test_getfileheader_executable(self):
+        header = get_file_header(program=self.fake_program, now=self.t)
+        expected = 'by ' + self.fake_program
+        self.assertIn(expected, header)
+
+    def test_getfileheader_version(self):
+        version = '{}.'.format(get_version())
+        header = get_file_header(program=self.fake_program, now=self.t)
+        self.assertTrue(header.endswith(version))
+
+    def test_getfileheader_indents(self):
+        long_program_name = "/opt/usr/local/bin/program/name/really/long.rb"
+        initial = '* '
+        subsequent = '** '
+        header = get_file_header(
+            program=long_program_name, now=self.t,
+            initial_indent=initial, subsequent_indent=subsequent)
+        lines = header.split('\n')
+        self.assertTrue(lines[0].startswith(initial))
+        for line in lines[1:]:
+            self.assertTrue(line.startswith(subsequent))
+
+
 class GetLXCGatewayTest(unittest.TestCase):
 
     interfaces = ('eth0', 'virbr0', 'lxcbr0', 'lo')

=== modified file 'lpsetup/utils.py'
--- lpsetup/utils.py	2012-06-22 15:01:49 +0000
+++ lpsetup/utils.py	2012-07-03 18:06:17 +0000
@@ -8,6 +8,7 @@
 __all__ = [
     'call',
     'get_container_path',
+    'get_file_header',
     'get_lxc_gateway',
     'get_network_interfaces',
     'get_running_containers',
@@ -22,6 +23,7 @@
     ]
 
 from ConfigParser import RawConfigParser
+from datetime import datetime
 from functools import (
     partial,
     wraps,
@@ -32,6 +34,7 @@
 import subprocess
 import shutil
 import sys
+import textwrap
 import time
 
 from shelltoolbox import (
@@ -41,7 +44,10 @@
     ssh,
     )
 
-from lpsetup import exceptions
+from lpsetup import (
+    exceptions,
+    get_version,
+    )
 from lpsetup.settings import (
     LXC_LP_DIR_PATTERN,
     LXC_LP_TEST_DIR_PATTERN,
@@ -143,6 +149,23 @@
 lxc_stopped = partial(lxc_in_state, 'STOPPED')
 
 
+def get_file_header(program=sys.argv[0], now=None,
+                    initial_indent='# ', subsequent_indent='# '):
+    if now is None:
+        now = datetime.utcnow()
+    header = (
+        'This file created at {date}UTC by {program}, '
+        'version {version}.'.format(
+            date=datetime.isoformat(now),
+            program=program,
+            version=get_version(),
+            )
+        )
+    return textwrap.fill(
+        header, initial_indent=initial_indent,
+        subsequent_indent=subsequent_indent)
+
+
 def render_to_file(template_name, context, dest, templates_dir=None):
     """Render `template_name` using `context`. Write the result inside `dest`.
 


Follow ups