~free.ekanayaka/landscape-client/intrepid-updates-1.4.4-0ubuntu0.8.10

« back to all changes in this revision

Viewing changes to landscape/lib/fetch.py

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2009-09-21 15:45:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090921154558-09vqvxgle7akpdme
Tags: 1.3.2.3-0ubuntu0.8.10.0
* New upstream release (LP: #347983):
  - Don't clear the hash_id_requests table upon resynchronize (LP #417122)
  - Include the README file in landscape-client (LP: #396260)
  - Fix client capturing stderr from run_command when constructing
    hash-id-databases url (LP: #397480)
  - Use substvars to conditionally depend on update-motd or
    libpam-modules (LP: #393454)
  - Fix reporting wrong version to the server (LP: #391225)
  - The init script does not wait for the network to be available
    before checking for EC2 user data (LP: #383336)
  - When the broker is restarted by the watchdog, the state of the client
    is inconsistent (LP: #380633)
  - Package stays unknown forever in the client with hash-id-databases
    support (LP: #381356)
  - Standard error not captured when calling smart-update (LP: #387441)
  - Changer calls reporter without switching groups, just user (LP: #388092)
  - Run smart update in the package-reporter instead of having a cronjob (LP: #362355)
  - Package changer does not inherit proxy settings (LP: #381241)
  - The ./test script doesn't work in landscape-client (LP: #381613)
  - The source package should build on all supported releases (LP: #385098)
  - Strip smart update's output (LP: #387331)
  - The fetch() timeout isn't based on activity (#389224)
  - Client can use a UUID of "None" when fetching the hash-id-database (LP: #381291)
  - Registration should use the fqdn rather than just the hostname (LP: #385730)
  - Apply a fix for segfault bug involving curl timeouts. (LP: #360510)
  - Add a timeout to HTTP operations to avoid hanging (LP: #349737)
  - Clean up environment variables on startup to avoid propagating
    variables that will corrupt package installation (LP: #348681)
  - Clean up FDs on startup for the same reason (LP: #352458)
  - Catch and handle certain errors from smart (such as invalid package
    data) to avoid "stuck" Landscape activities (LP: #268745)
  - Don't print warnings meant for developers to the console (LP: #336669)
  - Invalidate package cache when server UUID changes (LP: #339948)
  - Improve the "cloud mode" introduced in 1.0.26 to send more
    disambiguation data (LP: #343942) and allow the EC2 user data to specify
    the exchange and ping URLs (LP: #343947)
  - Allow importing of initial configurations (along with public SSL
    certificates) when running landscape-config (LP: #341705)
  - Support a non-root mode which allows running the client without the
    management functionality (LP: #82159)
  - Automatic cloud registration when there's no user-data to specify an OTP
    now works (LP: #344323)
  - Add support for custom graphs (LP: #306360)
  - Multiple custom graphs can be used at the same time (LP: #307314)
  - PATH is now set for scripts in script execution (LP: #257018)
* debian/landscape-common.postinst: Only chown parts of /var/lib/landscape
  because we now store files in it that should maintain their ownership
  (LP: #307321).
* debian/landscape-client.postinst: Work around chfn/system user problem
  by not specifying a --gecos (LP: #238755)
* debian/landscape-client.logrotate: logrotate no longer reports spurious
  errors when the client isn't running (LP: #271767)

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
import pycurl
6
6
 
7
 
 
8
 
def fetch(url, post=False, data="", headers={}, cainfo=None, curl=None):
 
7
from twisted.internet.threads import deferToThread
 
8
 
 
9
class FetchError(Exception):
 
10
    pass
 
11
 
 
12
class HTTPCodeError(FetchError):
 
13
 
 
14
    def __init__(self, http_code, body):
 
15
        self.http_code = http_code
 
16
        self.body = body
 
17
 
 
18
    def __str__(self):
 
19
        return "Server returned HTTP code %d" % self.http_code
 
20
 
 
21
    def __repr__(self):
 
22
        return "<HTTPCodeError http_code=%d>" % self.http_code
 
23
 
 
24
 
 
25
class PyCurlError(FetchError):
 
26
    def __init__(self, error_code, message):
 
27
        self.error_code = error_code
 
28
        self.message = message
 
29
 
 
30
    def __str__(self):
 
31
        return "Error %d: %s" % (self.error_code, self.message)
 
32
 
 
33
    def __repr__(self):
 
34
        return "<PyCurlError args=(%d, '%s')>" % (self.error_code,
 
35
                                                  self.message)
 
36
 
 
37
def fetch(url, post=False, data="", headers={}, cainfo=None, curl=None,
 
38
          connect_timeout=30, total_timeout=600):
9
39
    """Retrieve a URL and return the content.
10
40
 
11
41
    @param url: The url to be fetched.
38
68
    curl.setopt(pycurl.URL, url)
39
69
    curl.setopt(pycurl.FOLLOWLOCATION, True)
40
70
    curl.setopt(pycurl.MAXREDIRS, 5)
 
71
    curl.setopt(pycurl.CONNECTTIMEOUT, connect_timeout)
 
72
    curl.setopt(pycurl.LOW_SPEED_LIMIT, 1)
 
73
    curl.setopt(pycurl.LOW_SPEED_TIME, total_timeout)
 
74
    curl.setopt(pycurl.NOSIGNAL, 1)
41
75
    curl.setopt(pycurl.WRITEFUNCTION, input.write)
42
 
    curl.perform()
43
 
 
44
 
    return input.getvalue()
 
76
 
 
77
    try:
 
78
        curl.perform()
 
79
    except pycurl.error, e:
 
80
        raise PyCurlError(e.args[0], e.args[1])
 
81
 
 
82
    body = input.getvalue()
 
83
 
 
84
    http_code = curl.getinfo(pycurl.HTTP_CODE)
 
85
    if http_code != 200:
 
86
        raise HTTPCodeError(http_code, body)
 
87
 
 
88
    return body
45
89
 
46
90
 
47
91
def test(args):
48
92
    parser = OptionParser()
49
 
    parser.add_option("--method", default="GET")
 
93
    parser.add_option("--post", action="store_true")
50
94
    parser.add_option("--data", default="")
51
95
    parser.add_option("--cainfo")
52
96
    options, (url,) = parser.parse_args(args)
53
 
    print fetch(url, options.method, data=options.data, cainfo=options.cainfo)
 
97
    print fetch(url, post=options.post, data=options.data,
 
98
                cainfo=options.cainfo)
 
99
 
 
100
 
 
101
def fetch_async(*args, **kwargs):
 
102
    return deferToThread(fetch, *args, **kwargs)
54
103
 
55
104
 
56
105
if __name__ == "__main__":