~dooferlad/linaro-android-frontend/vm_install_updates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
###############################################################################
# Copyright (c) 2011 Linaro
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
###############################################################################

import re
import urlparse
from urllib import quote as urlquote

from twisted.application import (
    internet,
    service,
    )
from twisted.internet import reactor
from twisted.web import (
    proxy,
    rewrite,
    static,
    server,
    resource,
    )

class ReverseProxyResource(resource.Resource):

    proxyClientFactoryClass = proxy.ProxyClientFactory


    def __init__(self, host, port, path, reactor=reactor):
        resource.Resource.__init__(self)
        self.host = host
        self.port = port
        self.path = path
        self.reactor = reactor


    def getChild(self, path, request):
        """
        Create and return a proxy resource with the same proxy configuration
        as this one, except that its path also contains the segment given by
        C{path} at the end.
        """
        return ReverseProxyResource(
            self.host, self.port, self.path + '/' + urlquote(path, safe=""),
            self.reactor)


    def render(self, request):
        """
        Render a request by forwarding it to the proxied server.
        """
        # RFC 2616 tells us that we can omit the port if it's the default port,
        # but we have to provide it otherwise
        #if self.port == 80:
        #    host = self.host
        #else:
        #    host = "%s:%d" % (self.host, self.port)
        #request.received_headers['host'] = host
        request.content.seek(0, 0)
        qs = urlparse.urlparse(request.uri)[4]
        if qs:
            rest = self.path + '?' + qs
        else:
            rest = self.path
        clientFactory = self.proxyClientFactoryClass(
            request.method, rest, request.clientproto,
            request.getAllHeaders(), request.content.read(), request)
        self.reactor.connectTCP(self.host, self.port, clientFactory)
        return server.NOT_DONE_YET

jenkins_proxy = ReverseProxyResource('localhost', 9090, '/jenkins')

class OutputRedirectingResource(resource.Resource):
    def __init__(self, orig):
        resource.Resource.__init__(self)
        self.orig = orig
    def getChild(self, segment, request):
        path = '/'.join(request.prepath + request.postpath[:4])
        m = re.match('^builds/~([a-z][-a-z0-9]+)/([-A-Za-z0-9_]+)/([0-9]+)/output', path)
        if m:
            request.prepath.extend(request.postpath[:3])
            del request.postpath[:4]
            job_name = '%s_%s' % (m.group(1), m.group(2))
            return ReverseProxyResource(
                'localhost', 10102, '/' + job_name + '/builds/' + m.group(3) + '/archive')
        return self.orig.getChildWithDefault(segment, request)
    def render(request):
        return self.orig.render(request)

django_proxy = ReverseProxyResource('localhost', 9000, '')

static_root = static.File('static')
root = django_proxy
root.putChild('static', static_root)
root.putChild('jenkins', jenkins_proxy)

site = server.Site(root)

application = service.Application("linaro-android-build demo")

internet.TCPServer(
    10101, server.Site(OutputRedirectingResource(root))
).setServiceParent(application)

internet.TCPServer(
    10102, server.Site(static.File('/var/lib/hudson/jobs'))
).setServiceParent(application)