Merge lp:~danilo/charms/trusty/glance-simplestreams-sync/use-upstream-user-agent-support into lp:~landscape/charms/trusty/glance-simplestreams-sync/landscape

Proposed by Данило Шеган
Status: Merged
Merged at revision: 64
Proposed branch: lp:~danilo/charms/trusty/glance-simplestreams-sync/use-upstream-user-agent-support
Merge into: lp:~landscape/charms/trusty/glance-simplestreams-sync/landscape
Diff against target: 175 lines (+5/-119)
1 file modified
scripts/glance-simplestreams-sync.py (+5/-119)
To merge this branch: bzr merge lp:~danilo/charms/trusty/glance-simplestreams-sync/use-upstream-user-agent-support
Reviewer Review Type Date Requested Status
Bogdana Vereha (community) Approve
Geoff Teale (community) Approve
Review via email: mp+293110@code.launchpad.net

Description of the change

Drop the monkey-patching approach and use the built-in user-agent support in python-simplestreams that's only available in a PPA (ppa:danilo/simplestreams for now, see https://code.launchpad.net/~danilo/simplestreams/custom-user-agent/+merge/292403).

Testing instructions:

1. Deploy OPL from lp:~danilo/landscape/gs3-simplestreams-from-ppa, enable openstack-image-refresh flag and deploy a cloud
2. Note how everything still works, and even user agent is passed on (I override mirror_list to point at a URL I control [run apache on], and watch for user agent strings)

Note: You'll have to deploy the glance-simplestreams-sync with source/key set (see MP above for https://code.launchpad.net/~danilo/landscape/gs3-simplestreams-from-ppa), since it does not reconfigure or apt update when set post installation.

To post a comment you must log in.
Revision history for this message
Geoff Teale (tealeg) wrote :

+1 Approve.

review: Approve
Revision history for this message
Bogdana Vereha (bogdana) wrote :

Looks good. +1

review: Approve
Revision history for this message
Данило Шеган (danilo) wrote :

Thanks for reviews, merged and published as cs:~landscape-charmers/trusty/glance-simplestreams-sync-6

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'scripts/glance-simplestreams-sync.py'
2--- scripts/glance-simplestreams-sync.py 2016-04-15 09:13:24 +0000
3+++ scripts/glance-simplestreams-sync.py 2016-04-27 13:08:23 +0000
4@@ -44,14 +44,12 @@
5
6
7 import atexit
8-import errno
9 import fcntl
10 import glanceclient
11 from keystoneclient.v2_0 import client as keystone_client
12 import keystoneclient.exceptions as keystone_exceptions
13 import kombu
14 import os
15-import simplestreams.contentsource
16 from simplestreams.mirrors import glance, UrlMirrorReader
17 from simplestreams.objectstores.swift import SwiftObjectStore
18 from simplestreams.util import read_signed, path_from_mirror_url
19@@ -59,7 +57,6 @@
20 import sys
21 import time
22 import traceback
23-from urlparse import urlsplit
24 import yaml
25 import requests
26 import requests.exceptions
27@@ -169,117 +166,6 @@
28 os.environ['OS_REGION_NAME'] = charm_conf['region']
29
30
31-class CustomUrlMirrorReader(UrlMirrorReader):
32- """
33- A custom UrlMirrorReader to pass user agent to simplestreams.
34-
35- This monkey-patches a UrlMirrorReader._cs with a custom UrlContentSource
36- allowing passing of a url_reader in, and uses a python-requests-based
37- UrlReader that takes a user_agent parameter.
38-
39- XXX Danilo 2016-03-11: we are in the process of moving user-agent support
40- to simplestreams proper. We are using this approach so we are not blocked
41- until that gets into python-simplestreams package in trusty and xenial
42- at least.
43- """
44- def __init__(self, prefix, mirrors=None,
45- policy=simplestreams.util.policy_read_signed,
46- user_agent=None):
47- super(CustomUrlMirrorReader, self).__init__(prefix, mirrors, policy)
48- if user_agent is not None:
49- # Create a custom UrlReader with the user_agent passed in.
50- def url_reader_factory(*args, **kwargs):
51- return CustomRequestsUrlReader(
52- *args, user_agent=user_agent, **kwargs)
53-
54- # Create a custom content source with url_reader passed in.
55- def content_source_factory(path, mirrors):
56- return CustomUrlContentSource(
57- path, mirrors, url_reader=url_reader_factory)
58-
59- self._cs = content_source_factory
60-
61-
62-class CustomUrlContentSource(simplestreams.contentsource.UrlContentSource):
63- """
64- Custom UrlContentSource allowing use of a custom UrlReader.
65-
66- XXX Danilo 2016-03-11: This seems to be already supported in more recent
67- python-simplestreams versions (at least in 0.1.0~bzr423-0ubuntu1 in 16.04).
68- """
69- def __init__(self, url, mirrors=None, url_reader=None):
70- super(CustomUrlContentSource, self).__init__(url, mirrors)
71- self.url_reader = url_reader
72-
73- # This is a copy of python-simplestreams UrlContentSource._urlinfo()
74- # with the support for custom url_reader as opposed to Urllib/Requests
75- # based url readers.
76- def _urlinfo(self, url):
77- parsed = urlsplit(url)
78- if not parsed.scheme:
79- if url.startswith("/"):
80- url = "file://%s" % url
81- else:
82- url = "file://%s/%s" % (os.getcwd(), url)
83- parsed = urlsplit(url)
84-
85- if parsed.scheme == "file":
86-
87- def binopen(path, offset=None):
88- f = open(path, "rb")
89- if offset is not None:
90- f.seek(offset)
91- return f
92-
93- return (url, binopen, (parsed.path,))
94- else:
95- return (url, self.url_reader, (url,))
96-
97-
98-class CustomRequestsUrlReader(simplestreams.contentsource.RequestsUrlReader):
99- """
100- A custom UrlReader using requests and passing in a user-agent string.
101-
102- It derives and overrides user-agent string and sets it to the value
103- of the "user_agent" attribute.
104- """
105- # This is a verbatim copy of the RequestsUrlReader.__init__() with the
106- # only change being addition of the user_agent argument and passing it
107- # inside the headers with every request.
108- def __init__(self, url, buflen=None, offset=None, user_agent=None):
109- self.url = url
110- (url, user, password) = simplestreams.contentsource.parse_url_auth(url)
111- if user is None:
112- auth = None
113- else:
114- auth = (user, password)
115-
116- headers = {}
117- if user_agent is not None:
118- headers['User-Agent'] = user_agent
119- if offset is not None:
120- headers['Range'] = 'bytes=%d-' % offset
121-
122- self.req = requests.get(url, stream=True, auth=auth, headers=headers)
123- self.r_iter = None
124- if buflen is None:
125- buflen = simplestreams.contentsource.READ_BUFFER_SIZE
126- self.buflen = buflen
127- self.leftover = bytes()
128- self.consumed = False
129-
130- if (self.req.status_code == requests.codes.NOT_FOUND):
131- myerr = IOError("Unable to open %s" % url)
132- myerr.errno = errno.ENOENT
133- raise myerr
134-
135- ce = self.req.headers.get('content-encoding', '').lower()
136- if 'gzip' in ce or 'deflate' in ce:
137- self._read = self.read_compressed
138- else:
139- self._read = self.read_raw
140-
141-
142 def do_sync(charm_conf, status_exchange):
143
144 user_agent = charm_conf.get("user_agent")
145@@ -289,7 +175,7 @@
146
147 log.info("configuring sync for url {}".format(mirror_info))
148
149- smirror = CustomUrlMirrorReader(
150+ smirror = UrlMirrorReader(
151 mirror_url, policy=policy, user_agent=user_agent)
152
153 if charm_conf['use_swift']:
154@@ -347,8 +233,8 @@
155 for endpoint_type in ['publicURL', 'internalURL']:
156 catalog[endpoint_type] += "/{}".format(SWIFT_DATA_DIR)
157
158- endpoints = [e._info for e in ksc.endpoints.list()
159- if e._info['region'] == region]
160+ endpoints = [endpoint._info for endpoint in ksc.endpoints.list()
161+ if endpoint._info['region'] == region]
162 ps_services = [s for s in services
163 if s['name'] == PRODUCT_STREAMS_SERVICE_NAME]
164 if len(ps_services) != 1:
165@@ -358,8 +244,8 @@
166
167 ps_service_id = ps_services[0]['id']
168
169- ps_endpoints = [e for e in endpoints
170- if e['service_id'] == ps_service_id]
171+ ps_endpoints = [endpoint for endpoint in endpoints
172+ if endpoint['service_id'] == ps_service_id]
173
174 if len(ps_endpoints) != 1:
175 log.warning("found {} product-streams endpoints in region {},"

Subscribers

People subscribed via source and target branches