Merge ~lgp171188/launchpad:rsync-oval-data-when-publishing-a-distro into launchpad:master

Proposed by Guruprasad
Status: Merged
Approved by: Guruprasad
Approved revision: 0c1df6f31c7bbbfc7662f639bde0d5330f503ca8
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~lgp171188/launchpad:rsync-oval-data-when-publishing-a-distro
Merge into: launchpad:master
Diff against target: 200 lines (+132/-1)
3 files modified
lib/lp/archivepublisher/scripts/publishdistro.py (+46/-0)
lib/lp/archivepublisher/tests/test_publishdistro.py (+77/-1)
lib/lp/services/config/schema-lazr.conf (+9/-0)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Jürgen Gmach Approve
Review via email: mp+439809@code.launchpad.net

Commit message

Perform OVAL data rsync when publishing a distro

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote (last edit ):

Thank you! This looks good to me.

Before you merge, please wait on a second review.

review: Approve
Revision history for this message
Colin Watson (cjwatson) :
review: Approve
Revision history for this message
Guruprasad (lgp171188) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/archivepublisher/scripts/publishdistro.py b/lib/lp/archivepublisher/scripts/publishdistro.py
2index 3b91fa5..419b1ef 100644
3--- a/lib/lp/archivepublisher/scripts/publishdistro.py
4+++ b/lib/lp/archivepublisher/scripts/publishdistro.py
5@@ -7,7 +7,9 @@ __all__ = [
6 "PublishDistro",
7 ]
8
9+import os
10 from optparse import OptionValueError
11+from subprocess import CalledProcessError, check_call
12
13 from storm.store import Store
14 from zope.component import getUtility
15@@ -19,6 +21,7 @@ from lp.archivepublisher.publishing import (
16 getPublisher,
17 )
18 from lp.archivepublisher.scripts.base import PublisherScript
19+from lp.services.config import config
20 from lp.services.limitedlist import LimitedList
21 from lp.services.scripts.base import LaunchpadScriptFailure
22 from lp.services.webapp.adapter import (
23@@ -504,11 +507,54 @@ class PublishDistro(PublisherScript):
24 # store and cause performance problems.
25 Store.of(archive).reset()
26
27+ def rsync_oval_data(self):
28+ if config.archivepublisher.oval_data_rsync_endpoint:
29+ # Ensure that the rsync paths have a trailing slash.
30+ rsync_src = os.path.join(
31+ config.archivepublisher.oval_data_rsync_endpoint, ""
32+ )
33+ rsync_dest = os.path.join(
34+ config.archivepublisher.oval_data_root, ""
35+ )
36+ rsync_command = [
37+ "/usr/bin/rsync",
38+ "-a",
39+ "-q",
40+ "--timeout={}".format(
41+ config.archivepublisher.oval_data_rsync_timeout
42+ ),
43+ "--delete",
44+ "--delete-after",
45+ rsync_src,
46+ rsync_dest,
47+ ]
48+ try:
49+ self.logger.info(
50+ "Attempting to rsync the OVAL data from '%s' to '%s'",
51+ rsync_src,
52+ rsync_dest,
53+ )
54+ check_call(rsync_command)
55+ except CalledProcessError:
56+ self.logger.exception(
57+ "Failed to rsync OVAL data from '%s' to '%s'",
58+ rsync_src,
59+ rsync_dest,
60+ )
61+ raise
62+ else:
63+ self.logger.info(
64+ "Skipping the OVAL data sync as no rsync endpoint"
65+ " has been configured."
66+ )
67+
68 def main(self, reset_store_between_archives=True):
69 """See `LaunchpadScript`."""
70 self.validateOptions()
71 self.logOptions()
72
73+ self.rsync_oval_data()
74+
75 archive_ids = []
76 for distribution in self.findDistros():
77 for archive in self.getTargetArchives(distribution):
78diff --git a/lib/lp/archivepublisher/tests/test_publishdistro.py b/lib/lp/archivepublisher/tests/test_publishdistro.py
79index fd1d1e6..3d9e0cc 100644
80--- a/lib/lp/archivepublisher/tests/test_publishdistro.py
81+++ b/lib/lp/archivepublisher/tests/test_publishdistro.py
82@@ -8,6 +8,7 @@ import shutil
83 import subprocess
84 from optparse import OptionValueError
85
86+from fixtures import MockPatch
87 from storm.store import Store
88 from testtools.matchers import Not, PathExists
89 from testtools.twistedsupport import AsynchronousDeferredRunTest
90@@ -69,7 +70,8 @@ class TestPublishDistro(TestNativePublishingBase):
91 if extra_args is not None:
92 args.extend(extra_args)
93 publish_distro = PublishDistro(test_args=args)
94- publish_distro.logger = BufferLogger()
95+ self.logger = BufferLogger()
96+ publish_distro.logger = self.logger
97 publish_distro.txn = self.layer.txn
98 switch_dbuser(config.archivepublisher.dbuser)
99 publish_distro.main()
100@@ -255,6 +257,80 @@ class TestPublishDistro(TestNativePublishingBase):
101 pub_source = self.loadPubSource(pub_source_id)
102 self.assertEqual(PackagePublishingStatus.PENDING, pub_source.status)
103
104+ def setUpOVALDataRsync(self):
105+ self.pushConfig(
106+ "archivepublisher",
107+ oval_data_rsync_endpoint="oval.internal::oval/",
108+ oval_data_root="/tmp/oval-data",
109+ oval_data_rsync_timeout=90,
110+ )
111+
112+ def testPublishDistroOVALDataRsyncEndpointNotConfigured(self):
113+ """
114+ Test what happens when the OVAL data rsync endpoint is not configured.
115+ """
116+ mock_subprocess_check_call = self.useFixture(
117+ MockPatch("lp.archivepublisher.scripts.publishdistro.check_call")
118+ ).mock
119+ self.runPublishDistro()
120+ mock_subprocess_check_call.assert_not_called()
121+ expected_log_line = (
122+ "INFO Skipping the OVAL data sync as no rsync endpoint has been "
123+ "configured."
124+ )
125+ self.assertTrue(expected_log_line in self.logger.getLogBuffer())
126+
127+ def testPublishDistroOVALDataRsyncEndpointConfigured(self):
128+ """
129+ Test the OVAL data rsync command.
130+
131+ When the endpoint is configured, verify that the command is run.
132+ """
133+ self.setUpOVALDataRsync()
134+ mock_subprocess_check_call = self.useFixture(
135+ MockPatch("lp.archivepublisher.scripts.publishdistro.check_call")
136+ ).mock
137+ self.runPublishDistro()
138+ call_args = [
139+ "/usr/bin/rsync",
140+ "-a",
141+ "-q",
142+ "--timeout=90",
143+ "--delete",
144+ "--delete-after",
145+ "oval.internal::oval/",
146+ "/tmp/oval-data/",
147+ ]
148+ mock_subprocess_check_call.assert_called_once_with(call_args)
149+
150+ def testPublishDistroOVALDataRsyncErrorsOut(self):
151+ self.setUpOVALDataRsync()
152+ mock_subprocess_check_call = self.useFixture(
153+ MockPatch(
154+ "lp.archivepublisher.scripts.publishdistro.check_call",
155+ side_effect=subprocess.CalledProcessError(
156+ cmd="foo", returncode=5
157+ ),
158+ )
159+ ).mock
160+ self.assertRaises(subprocess.CalledProcessError, self.runPublishDistro)
161+ call_args = [
162+ "/usr/bin/rsync",
163+ "-a",
164+ "-q",
165+ "--timeout=90",
166+ "--delete",
167+ "--delete-after",
168+ "oval.internal::oval/",
169+ "/tmp/oval-data/",
170+ ]
171+ mock_subprocess_check_call.assert_called_once_with(call_args)
172+ expected_log_line = (
173+ "ERROR Failed to rsync OVAL data from "
174+ "'oval.internal::oval/' to '/tmp/oval-data/'"
175+ )
176+ self.assertTrue(expected_log_line in self.logger.getLogBuffer())
177+
178 @defer.inlineCallbacks
179 def testForPPA(self):
180 """Try to run publish-distro in PPA mode.
181diff --git a/lib/lp/services/config/schema-lazr.conf b/lib/lp/services/config/schema-lazr.conf
182index db9893c..28ce035 100644
183--- a/lib/lp/services/config/schema-lazr.conf
184+++ b/lib/lp/services/config/schema-lazr.conf
185@@ -32,6 +32,15 @@ dbuser: archivepublisher
186 # datatype: string
187 run_parts_location: none
188
189+# The rsync endpoint to use for synchronizing the OVAL data.
190+oval_data_rsync_endpoint: none
191+
192+# The destination to rsync the OVAL data to.
193+oval_data_root: /srv/launchpad.net/oval-data
194+
195+# Timeout (in seconds) to use when rsync'ing OVAL data.
196+oval_data_rsync_timeout: 30
197+
198
199 [artifactory]
200 # Base URL for publishing suitably-configured archives to Artifactory.

Subscribers

People subscribed via source and target branches

to status/vote changes: