Merge lp:~lifeless/python-oops-datedir-repo/extraction into lp:python-oops-datedir-repo

Proposed by Robert Collins
Status: Merged
Merged at revision: 2
Proposed branch: lp:~lifeless/python-oops-datedir-repo/extraction
Merge into: lp:python-oops-datedir-repo
Diff against target: 221 lines (+153/-7)
6 files modified
README (+23/-5)
oops_datedir_repo/__init__.py (+3/-1)
oops_datedir_repo/repository.py (+64/-0)
oops_datedir_repo/tests/__init__.py (+1/-0)
oops_datedir_repo/tests/test_repository.py (+61/-0)
setup.py (+1/-1)
To merge this branch: bzr merge lp:~lifeless/python-oops-datedir-repo/extraction
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Approve
Review via email: mp+71633@code.launchpad.net

Description of the change

This adds the core write-to-disk aspect of errorlog.py from Launchpad as 'DateDirRepo'.publish, along with the tests from Launchpad that I was able to delete as a side effect of this move.

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) wrote :

A little confusing, since at the top of the diff, you move *backward* from 0.0.3 to 0.0.2, and at the end, you move forward from 0.0.1 to 0.0.2.

review: Approve (code)
Revision history for this message
Robert Collins (lifeless) wrote :

Yes, that was a fubar in the migration :(. Didn't affect tarball building, and is resolved with this version.
Thanks!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README'
--- README 2011-08-15 05:30:39 +0000
+++ README 2011-08-16 02:31:36 +0000
@@ -35,6 +35,8 @@
35Testing Dependencies35Testing Dependencies
36====================36====================
3737
38* fixtures (http://pypi.python.org/pypi/fixtures)
39
38* subunit (http://pypi.python.org/pypi/python-subunit) (optional)40* subunit (http://pypi.python.org/pypi/python-subunit) (optional)
3941
40* testtools (http://pypi.python.org/pypi/testtools)42* testtools (http://pypi.python.org/pypi/testtools)
@@ -42,11 +44,27 @@
42Usage44Usage
43=====45=====
4446
45An OOPS report can be written to a disk file via the serializer_rfc822.write()47oops_datedir_repo is an extension package for the oops package.
46function, and read via the matching read() function. The uniquefileallocator48
47module provides a system for allocating file names on disk.49The DateDirRepo class provides an OOPS publisher (``DateDirRepo.publish``)
4850which will write OOPSes into the repository.
49More coming soon.51
52Retrieving OOPSes can be done by using the low level serializer_rfc822
53functions : an OOPS report can be written to a disk file via the
54serializer_rfc822.write() function, and read via the matching read() function.
55
56The uniquefileallocator module is used by the repository implementation and
57provides a system for allocating file names on disk.
58
59Typical usage::
60
61 >>> config = oops.Config()
62 >>> with fixtures.TempDir() as tempdir:
63 ... repo = oops_datedir_repo.DateDirRepo('/tmp/demo', 'servername')
64 ... config.publishers.append(repo.publish)
65 ... ids = config.publish({'oops': '!!!'})
66
67For more information see the oops package documentation or the api docs.
5068
51Installation69Installation
52============70============
5371
=== modified file 'oops_datedir_repo/__init__.py'
--- oops_datedir_repo/__init__.py 2011-08-15 05:30:39 +0000
+++ oops_datedir_repo/__init__.py 2011-08-16 02:31:36 +0000
@@ -25,8 +25,10 @@
25# established at this point, and setup.py will use a version of next-$(revno).25# established at this point, and setup.py will use a version of next-$(revno).
26# If the releaselevel is 'final', then the tarball will be major.minor.micro.26# If the releaselevel is 'final', then the tarball will be major.minor.micro.
27# Otherwise it is major.minor.micro~$(revno).27# Otherwise it is major.minor.micro~$(revno).
28__version__ = (0, 0, 3, 'beta', 0)28__version__ = (0, 0, 2, 'beta', 0)
2929
30__all__ = [30__all__ = [
31 'DateDirRepo',
31 ]32 ]
3233
34from oops_datedir_repo.repository import DateDirRepo
3335
=== added file 'oops_datedir_repo/repository.py'
--- oops_datedir_repo/repository.py 1970-01-01 00:00:00 +0000
+++ oops_datedir_repo/repository.py 2011-08-16 02:31:36 +0000
@@ -0,0 +1,64 @@
1#
2# Copyright (c) 2011, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17"""The primary interface to oopses stored on disk - the DateDirRepo."""
18
19__metaclass__ = type
20
21__all__ = [
22 'DateDirRepo',
23 ]
24
25import datetime
26import os
27import stat
28
29from pytz import utc
30
31import serializer_rfc822
32from uniquefileallocator import UniqueFileAllocator
33
34
35class DateDirRepo:
36 """Publish oopses to a date-dir repository."""
37
38 def __init__(self, error_dir, instance_id):
39 self.log_namer = UniqueFileAllocator(
40 output_root=error_dir,
41 log_type="OOPS",
42 log_subtype=instance_id,
43 )
44
45 def publish(self, report, now=None):
46 """Write the report to disk.
47
48 :param now: The datetime to use as the current time. Will be
49 determined if not supplied. Useful for testing.
50 """
51 if now is not None:
52 now = now.astimezone(utc)
53 else:
54 now = datetime.datetime.now(utc)
55 oopsid, filename = self.log_namer.newId(now)
56 report['id'] = oopsid
57 serializer_rfc822.write(report, open(filename, 'wb'))
58 # Set file permission to: rw-r--r-- (so that reports from
59 # umask-restricted services can be gathered by a tool running as
60 # another user).
61 wanted_permission = (
62 stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
63 os.chmod(filename, wanted_permission)
64 return report['id']
065
=== modified file 'oops_datedir_repo/tests/__init__.py'
--- oops_datedir_repo/tests/__init__.py 2011-08-15 05:30:39 +0000
+++ oops_datedir_repo/tests/__init__.py 2011-08-16 02:31:36 +0000
@@ -21,6 +21,7 @@
2121
22def test_suite():22def test_suite():
23 test_mod_names = [23 test_mod_names = [
24 'repository',
24 'uniquefileallocator',25 'uniquefileallocator',
25 'serializer_rfc822',26 'serializer_rfc822',
26 ]27 ]
2728
=== added file 'oops_datedir_repo/tests/test_repository.py'
--- oops_datedir_repo/tests/test_repository.py 1970-01-01 00:00:00 +0000
+++ oops_datedir_repo/tests/test_repository.py 2011-08-16 02:31:36 +0000
@@ -0,0 +1,61 @@
1# Copyright (c) 2010, 2011, Canonical Ltd
2#
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU Affero General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU Affero General Public License for more details.
12#
13# You should have received a copy of the GNU Affero General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15# GNU Affero General Public License version 3 (see the file LICENSE).
16
17"""Tests for the date-directory based repository."""
18
19__metaclass__ = type
20
21import datetime
22import os.path
23import stat
24
25from fixtures import TempDir
26from pytz import utc
27import testtools
28
29from oops_datedir_repo import DateDirRepo
30from oops_datedir_repo.uniquefileallocator import UniqueFileAllocator
31
32
33class TestDateDirRepo(testtools.TestCase):
34
35 def test_publish_permissions(self):
36 errordir = self.useFixture(TempDir()).path
37 repo = DateDirRepo(errordir, 'T')
38 report = {'id': 'OOPS-91T1'}
39 now = datetime.datetime(2006, 04, 01, 00, 30, 00, tzinfo=utc)
40
41 # Set up default file creation mode to rwx------ as some restrictive
42 # servers do.
43 umask_permission = stat.S_IRWXG | stat.S_IRWXO
44 old_umask = os.umask(umask_permission)
45 self.addCleanup(os.umask, old_umask)
46 repo.publish(report, now)
47
48 errorfile = os.path.join(repo.log_namer.output_dir(now), '01800.T1')
49 self.assertTrue(os.path.exists(errorfile))
50
51 # Check errorfile is set with the correct permission: rw-r--r--
52 st = os.stat(errorfile)
53 wanted_permission = (
54 stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
55 # Get only the permission bits for this file.
56 file_permission = stat.S_IMODE(st.st_mode)
57 self.assertEqual(file_permission, wanted_permission)
58
59 def test_sets_log_namer_to_a_UniqueFileAllocator(self):
60 repo = DateDirRepo(self.useFixture(TempDir()).path, 'T')
61 self.assertIsInstance(repo.log_namer, UniqueFileAllocator)
062
=== modified file 'setup.py'
--- setup.py 2011-08-15 05:30:39 +0000
+++ setup.py 2011-08-16 02:31:36 +0000
@@ -22,7 +22,7 @@
22description = file(os.path.join(os.path.dirname(__file__), 'README'), 'rb').read()22description = file(os.path.join(os.path.dirname(__file__), 'README'), 'rb').read()
2323
24setup(name="oops_datedir_repo",24setup(name="oops_datedir_repo",
25 version="0.0.1",25 version="0.0.2",
26 description="OOPS disk serialisation and repository management.",26 description="OOPS disk serialisation and repository management.",
27 long_description=description,27 long_description=description,
28 maintainer="Launchpad Developers",28 maintainer="Launchpad Developers",

Subscribers

People subscribed via source and target branches

to all changes: