launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #30299
[Merge] ~cjwatson/launchpad:charm-librarian-frontend-relations into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:charm-librarian-frontend-relations into launchpad:master.
Commit message:
charm: Set up frontend relations for the librarian
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/447543
The Apache configuration files here are lifted fairly directly from production, although qastaging and staging are much the same. The `service_name` settings are passed through the stack of Juju relations (with Squid and Apache) and can be used in Apache `balancer://` URLs with no extra configuration required.
At the moment, the public and restricted librarians are on different sets of IP addresses. I _think_ that this was mostly due to historical issues around issuing TLS certificates that are no longer an issue, so I'm going to try to get things working with a single set of public IP addresses on (qa)staging; if that doesn't work out then I'll fall back to splitting the `vhost-config` relation into two and deploying two Apache applications, but it doesn't end up being all that fundamentally different.
This depends on https://code.launchpad.net/~cjwatson/launchpad-layers/+git/launchpad-layers/+merge/447537, and before I land this I'd expect to fix up `source` and `source-commit` and make sure that all our charms stay in sync.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:charm-librarian-frontend-relations into launchpad:master.
diff --git a/charm/launchpad-librarian/charmcraft.yaml b/charm/launchpad-librarian/charmcraft.yaml
index 77e67e8..569c452 100644
--- a/charm/launchpad-librarian/charmcraft.yaml
+++ b/charm/launchpad-librarian/charmcraft.yaml
@@ -34,12 +34,13 @@ parts:
launchpad-layers:
after:
- ols-layers
- source: https://git.launchpad.net/launchpad-layers
- source-commit: "42a4b4c4f62936b1d050c775e84f7364dfb5efc0"
+ source: https://git.launchpad.net/~cjwatson/launchpad-layers
+ source-commit: "8b7d25a29b8297d491abe6a0c6b69f34e39dddba"
source-submodules: []
source-type: git
plugin: dump
organize:
+ apache-vhost-config: layers/interface/apache-vhost-config
launchpad-base: layers/layer/launchpad-base
launchpad-db: layers/layer/launchpad-db
launchpad-payload: layers/layer/launchpad-payload
diff --git a/charm/launchpad-librarian/config.yaml b/charm/launchpad-librarian/config.yaml
index 937f30d..b48a704 100644
--- a/charm/launchpad-librarian/config.yaml
+++ b/charm/launchpad-librarian/config.yaml
@@ -3,6 +3,11 @@ options:
type: boolean
default: true
description: If true, enable jobs that may change the database.
+ domain_librarian_aliases:
+ type: string
+ default: "[]"
+ description: >
+ A YAML-encoded list of aliases for the librarian's primary domain.
haproxy_server_options:
type: string
description: Options to add to HAProxy "server" lines.
diff --git a/charm/launchpad-librarian/layer.yaml b/charm/launchpad-librarian/layer.yaml
index ce520c3..6efe850 100644
--- a/charm/launchpad-librarian/layer.yaml
+++ b/charm/launchpad-librarian/layer.yaml
@@ -1,5 +1,6 @@
includes:
- layer:launchpad-db
+ - interface:apache-vhost-config
- interface:http
repo: https://git.launchpad.net/launchpad
options:
diff --git a/charm/launchpad-librarian/metadata.yaml b/charm/launchpad-librarian/metadata.yaml
index 5fb0de8..f114ffa 100644
--- a/charm/launchpad-librarian/metadata.yaml
+++ b/charm/launchpad-librarian/metadata.yaml
@@ -19,3 +19,5 @@ requires:
provides:
loadbalancer:
interface: http
+ vhost-config:
+ interface: apache-vhost-config
diff --git a/charm/launchpad-librarian/reactive/launchpad-librarian.py b/charm/launchpad-librarian/reactive/launchpad-librarian.py
index 516e537..be74fe0 100644
--- a/charm/launchpad-librarian/reactive/launchpad-librarian.py
+++ b/charm/launchpad-librarian/reactive/launchpad-librarian.py
@@ -3,6 +3,7 @@
import os.path
import subprocess
+from urllib.parse import urlparse
import yaml
from charmhelpers.core import hookenv, host, templating
@@ -210,7 +211,7 @@ def configure_loadbalancer():
unit_ip = hookenv.unit_private_ip()
services = [
{
- "service_name": config["librarian_download_host"],
+ "service_name": "launchpad_librarian_download",
"service_port": config["librarian_download_port"],
"service_host": "0.0.0.0",
"service_options": list(service_options_download),
@@ -225,7 +226,7 @@ def configure_loadbalancer():
],
},
{
- "service_name": config["librarian_upload_host"],
+ "service_name": "launchpad_librarian_upload",
"service_port": config["librarian_upload_port"],
"service_host": "0.0.0.0",
"service_options": list(service_options_upload),
@@ -241,7 +242,7 @@ def configure_loadbalancer():
],
},
{
- "service_name": config["librarian_restricted_download_host"],
+ "service_name": "launchpad_librarian_restricted_download",
"service_port": config["librarian_restricted_download_port"],
"service_host": "0.0.0.0",
"service_options": list(service_options_download),
@@ -256,7 +257,7 @@ def configure_loadbalancer():
],
},
{
- "service_name": config["librarian_restricted_upload_host"],
+ "service_name": "launchpad_librarian_restricted_upload",
"service_port": config["librarian_restricted_upload_port"],
"service_host": "0.0.0.0",
"service_options": list(service_options_upload),
@@ -291,3 +292,41 @@ def configure_loadbalancer():
)
def deconfigure_loadbalancer():
remove_state("launchpad.loadbalancer.configured")
+
+
+@when(
+ "config.set.librarian_download_url",
+ "vhost-config.available",
+ "service.configured",
+)
+@when_not("launchpad.vhost.configured")
+def configure_vhost():
+ vhost_config = endpoint_from_flag("vhost-config.available")
+ config = dict(hookenv.config())
+ config["domain_librarian"] = urlparse(
+ config["librarian_download_url"]
+ ).hostname
+ config["domain_librarian_aliases"] = yaml.safe_load(
+ config["domain_librarian_aliases"]
+ )
+ vhost_config.publish_vhosts(
+ [
+ vhost_config.make_vhost(
+ 80, templating.render("librarian-http.conf.j2", None, config)
+ ),
+ vhost_config.make_vhost(
+ 443, templating.render("librarian-https.conf.j2", None, config)
+ ),
+ ]
+ )
+ set_state("launchpad.vhost.configured")
+
+
+@when("launchpad.vhost.configured")
+@when_not_all(
+ "config.set.librarian_download_url",
+ "vhost-config.available",
+ "service.configured",
+)
+def deconfigure_vhost():
+ remove_state("launchpad.vhost.configured")
diff --git a/charm/launchpad-librarian/templates/librarian-http.conf.j2 b/charm/launchpad-librarian/templates/librarian-http.conf.j2
new file mode 100644
index 0000000..2b18e2d
--- /dev/null
+++ b/charm/launchpad-librarian/templates/librarian-http.conf.j2
@@ -0,0 +1,36 @@
+<VirtualHost *:80>
+ ServerName {{ domain_librarian }}
+{%- for domain_librarian_alias in domain_librarian_aliases %}
+ ServerAlias {{ domain_librarian_alias }}
+{%- endfor %}
+
+ CustomLog /var/log/apache2/{{ domain_librarian }}-access.log combined
+ ErrorLog /var/log/apache2/{{ domain_librarian }}-error.log
+
+ ProxyRequests off
+ <Proxy *>
+ Require all granted
+ </Proxy>
+
+ SetEnv force-proxy-request-1.0 1
+
+ # Tokens may only be used on restricted librarian URLs.
+ ProxyPass "\?.*token=" !
+
+ ProxyPreserveHost on
+ ProxyPass / balancer://launchpad_librarian_download/
+ ProxyPassReverse / balancer://launchpad_librarian_download/
+</VirtualHost>
+
+<VirtualHost *:80>
+ ServerName wildcard.restricted.{{ domain_librarian }}
+ ServerAlias *.restricted.{{ domain_librarian }}
+
+ CustomLog /var/log/apache2/wildcard.restricted.{{ domain_librarian }}-access.log combined
+ ErrorLog /var/log/apache2/wildcard.restricted.{{ domain_librarian }}-error.log
+
+ # The restricted librarian is only available over HTTPS.
+ RewriteEngine on
+ RewriteRule ^/(.*)$ - [R=403,L]
+</VirtualHost>
+
diff --git a/charm/launchpad-librarian/templates/librarian-https.conf.j2 b/charm/launchpad-librarian/templates/librarian-https.conf.j2
new file mode 100644
index 0000000..12b22b1
--- /dev/null
+++ b/charm/launchpad-librarian/templates/librarian-https.conf.j2
@@ -0,0 +1,67 @@
+<VirtualHost *:443>
+ ServerName {{ domain_librarian }}
+{%- for domain_librarian_alias in domain_librarian_aliases %}
+ ServerAlias {{ domain_librarian_alias }}
+{%- endfor %}
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/{{ domain_librarian }}.crt
+ SSLCertificateKeyFile /etc/ssl/private/{{ domain_librarian }}.key
+
+ CustomLog /var/log/apache2/{{ domain_librarian }}-access.log combined
+ ErrorLog /var/log/apache2/{{ domain_librarian }}-error.log
+
+ # Make build log files auto-decompress and be viewable from the browser.
+ <Location ~ ".*/buildlog_[^/]*\.txt\.gz">
+ AddEncoding x-gzip gz
+ </Location>
+
+ SetEnv force-proxy-request-1.0 1
+
+ ProxyRequests off
+ <Proxy *>
+ Require all granted
+ </Proxy>
+
+ # Tokens may only be used on restricted librarian URLs.
+ ProxyPass "\?.*token=" !
+
+ ProxyPreserveHost on
+ ProxyPass / balancer://launchpad_librarian_download/
+ ProxyPassReverse / balancer://launchpad_librarian_download/
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName wildcard.restricted.{{ domain_librarian }}
+ ServerAlias *.restricted.{{ domain_librarian }}
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/{{ domain_librarian }}.crt
+ SSLCertificateKeyFile /etc/ssl/private/{{ domain_librarian }}.key
+
+ CustomLog /var/log/apache2/{{ domain_librarian }}-access.log combined
+ ErrorLog /var/log/apache2/{{ domain_librarian }}-error.log
+
+ # Make build log files auto-decompress and be viewable from the browser.
+ <Location ~ ".*/buildlog_[^/]*\.txt\.gz">
+ AddEncoding x-gzip gz
+ </Location>
+
+ SetEnv force-proxy-request-1.0 1
+
+ ProxyRequests off
+ <Proxy *>
+ Require all granted
+ </Proxy>
+
+ ProxyPreserveHost on
+ # nocanon per https://portal.admin.canonical.com/C42560 to avoid
+ # problems with Launchpad's handling of e.g. %2B.
+ ProxyPass / balancer://launchpad_librarian_download/ nocanon
+ ProxyPassReverse / balancer://launchpad_librarian_download/
+
+ <Location />
+ Header set Cache-Control "max-age=604800"
+ </Location>
+</VirtualHost>
+
Follow ups