Merge ~pjdc/ubuntu-mirror-charm/+git/ubuntu-mirror-charm:linuxcontainers into ubuntu-mirror-charm:master

Proposed by Paul Collins
Status: Merged
Approved by: Paul Collins
Approved revision: f08fd0ed505169a5de682cd77cfee04228dfa68e
Merged at revision: c69b05c81bc8af2b1f25e38872d99f58576db775
Proposed branch: ~pjdc/ubuntu-mirror-charm/+git/ubuntu-mirror-charm:linuxcontainers
Merge into: ubuntu-mirror-charm:master
Diff against target: 1231 lines (+1038/-9)
13 files modified
config.yaml (+80/-1)
files/check-mirror.sh (+11/-2)
files/mirror-linuxcontainers.sh (+97/-0)
hooks/Config.py (+1/-0)
hooks/hooks.py (+34/-6)
keys/juju-tools.asc (+51/-0)
keys/lxc-devel.asc (+29/-0)
templates/apache-linuxcontainers-api.include.tmpl (+41/-0)
templates/apache-linuxcontainers-tls.include.tmpl (+16/-0)
templates/apache-linuxcontainers.tmpl (+74/-0)
tests/unit/test_linuxcontainers.py (+56/-0)
tests/unit/testdata/linuxcontainers/linuxcontainers.txt (+429/-0)
tests/unit/testdata/linuxcontainers/thirdparty.txt (+119/-0)
Reviewer Review Type Date Requested Status
Barry Price Approve
Canonical IS Reviewers Pending
Review via email: mp+396537@code.launchpad.net

Commit message

add linuxcontainers support

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Barry Price (barryprice) wrote :

LGTM

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision c69b05c81bc8af2b1f25e38872d99f58576db775

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/config.yaml b/config.yaml
index f2b4616..2f5f38c 100644
--- a/config.yaml
+++ b/config.yaml
@@ -511,7 +511,7 @@ options:
511 type: string511 type: string
512 description: "Root location of mirrored files for the MAAS images mirror"512 description: "Root location of mirrored files for the MAAS images mirror"
513 mirror_maas-images_description:513 mirror_maas-images_description:
514 default: "Ubuntu Old Releases"514 default: "MAAS images"
515 type: string515 type: string
516 description: "A brief welcome message for the MAAS images mirror"516 description: "A brief welcome message for the MAAS images mirror"
517 mirror_maas-images_rsync_log:517 mirror_maas-images_rsync_log:
@@ -563,6 +563,85 @@ options:
563 description: >563 description: >
564 Local path of the key file to use when triggering downstream564 Local path of the key file to use when triggering downstream
565 mirrors. If empty, downstream mirrors are not triggered.565 mirrors. If empty, downstream mirrors are not triggered.
566 mirror_linuxcontainers_name:
567 default: "images.linuxcontainers.org"
568 type: string
569 description: >
570 FQDN of the Linux Containers image mirror.
571
572 When set to "image.linuxcontainers.org", the virtualhost will
573 redirect to the uk or us subdomain based on the source IP
574 location as determined by GeoIP.
575 mirror_linuxcontainers_aliases:
576 default: '["uk.images.linuxcontainers.org", "us.images.linuxcontainers.org"]'
577 type: string
578 description: >
579 List of Apache aliases for the Linux Containers image mirror.
580
581 When mirror_linuxcontainers_name is set to "images.linuxcontainers.org",
582 a separate virtualhost will be generated for each alias to act
583 as destinations for GeoIP-based redirects and to log traffic to
584 each alias separately.
585
586 Otherwise, these aliases will simple be declared as standard
587 Apache aliases using the ServerAlias directive.
588 mirror_linuxcontainers_path:
589 default: "/srv/ftp.root/lxc-images"
590 type: string
591 description: "Root location of mirrored files for the Linux Containers image mirror"
592 mirror_linuxcontainers_description:
593 default: "Linux Containers (LXC/LXD) Images"
594 type: string
595 description: "A brief welcome message for the Linux Containers image mirror"
596 mirror_linuxcontainers_rsync_log:
597 default: false
598 type: boolean
599 description: "Whether to log rsync requests for the Linux Containers image mirror"
600 mirror_linuxcontainers_command:
601 default: "mirror-linuxcontainers.sh"
602 type: string
603 description: "The command to use to sync the Linux Containers image mirror"
604 mirror_linuxcontainers_source_url:
605 default: "rsync://rsync.images.linuxcontainers.org/lxc-images"
606 type: string
607 description: "The URL the Linux Containers image mirror will be fetched from"
608 mirror_linuxcontainers_rsync_auth:
609 default: '{}'
610 type: string
611 description: "Optional rsync authentication details for mirror_linuxcontainers_source_url"
612 mirror_linuxcontainers_rsync_module:
613 default: "lxc-images"
614 type: string
615 description: "The name of the rsync module for this mirror role"
616 mirror_linuxcontainers_sync_time:
617 default: "ondemand"
618 type: string
619 description: "When mirror updates should be run. Either a cron(5) format time specification or 'ondemand' for ssh triggering"
620 mirror_linuxcontainers_trigger:
621 default: ""
622 type: string
623 description: "A base64 string containing the ssh trigger public key"
624 mirror_linuxcontainers_apache_early_extra:
625 default: ""
626 type: string
627 description: "A base64 string containing apache configuration options to be included early in the config file"
628 mirror_linuxcontainers_apache_late_extra:
629 default: ""
630 type: string
631 description: "A base64 string containing apache configuration options to be included late in the config file"
632 mirror_linuxcontainers_downstream_mirrors:
633 default: ""
634 type: "string"
635 description: >
636 A space-separated list of mirrors to trigger following a sync.
637 Username defaults to the mirror_user config setting, and
638 otherwise may be specified by "user@host" syntax.
639 mirror_linuxcontainers_trigger_keyfile:
640 default: ""
641 type: "string"
642 description: >
643 Local path of the key file to use when triggering downstream
644 mirrors. If empty, downstream mirrors are not triggered.
566 mirror_old-releases_name:645 mirror_old-releases_name:
567 default: "old-releases.ubuntu.com"646 default: "old-releases.ubuntu.com"
568 type: string647 type: string
diff --git a/files/check-mirror.sh b/files/check-mirror.sh
index a04d177..003b48a 100755
--- a/files/check-mirror.sh
+++ b/files/check-mirror.sh
@@ -63,14 +63,17 @@ case ${role} in
63 unsigned=xenial/current/SHA256SUMS63 unsigned=xenial/current/SHA256SUMS
64 signed=${unsigned}.gpg64 signed=${unsigned}.gpg
65 ;;65 ;;
66 linuxcontainers)
67 unsigned=streams/v1/index.json
68 signed=${unsigned}.gpg
69 ;;
66 old-releases)70 old-releases)
67 unsigned=ubuntu/dists/warty/Release71 unsigned=ubuntu/dists/warty/Release
68 signed=${unsigned}.gpg72 signed=${unsigned}.gpg
69 ;;73 ;;
70 simple-streams)74 simple-streams)
71 # TODO(pjdc): key is not packaged; fetch from install hook?
72 unsigned=juju/images/releases/streams/v1/index.json75 unsigned=juju/images/releases/streams/v1/index.json
73 signed=${unsigned}.gpg # not used76 signed=${unsigned}.gpg
74 ;;77 ;;
75 maas-images)78 maas-images)
76 # NOTE(pjdc): ephemeral-v3 is the current stuff and seems to have no fixed paths to signed files we could check79 # NOTE(pjdc): ephemeral-v3 is the current stuff and seems to have no fixed paths to signed files we could check
@@ -99,12 +102,18 @@ case ${role} in
99 cloud-images)102 cloud-images)
100 keyring_file=/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg103 keyring_file=/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg
101 ;;104 ;;
105 linuxcontainers)
106 keyring_file=/usr/local/share/ubuntu-mirror-charm.gpg
107 ;;
102 old-releases)108 old-releases)
103 keyring_file=/usr/share/keyrings/ubuntu-archive-removed-keys.gpg109 keyring_file=/usr/share/keyrings/ubuntu-archive-removed-keys.gpg
104 ;;110 ;;
105 ubuntu-cloud-archive)111 ubuntu-cloud-archive)
106 keyring_file=/usr/share/keyrings/ubuntu-cloud-keyring.gpg112 keyring_file=/usr/share/keyrings/ubuntu-cloud-keyring.gpg
107 ;;113 ;;
114 simple-streams)
115 keyring_file=/usr/local/share/ubuntu-mirror-charm.gpg
116 ;;
108 *)117 *)
109 keyring_file=/usr/share/keyrings/ubuntu-archive-keyring.gpg118 keyring_file=/usr/share/keyrings/ubuntu-archive-keyring.gpg
110 ;;119 ;;
diff --git a/files/mirror-linuxcontainers.sh b/files/mirror-linuxcontainers.sh
111new file mode 100755120new file mode 100755
index 0000000..4f0e3fb
--- /dev/null
+++ b/files/mirror-linuxcontainers.sh
@@ -0,0 +1,97 @@
1#!/bin/bash
2#
3#-------------------------------------------------------#
4# This file is Juju managed - do not make local changes #
5#-------------------------------------------------------#
6#
7# Author: Chris Stratford <chris.stratford@canonical.com>
8# Copyright 2014,2021 Canonical Ltd.
9#
10# Triple-pass rsync mirror for images.linuxcontainers.org
11#
12# ${role}.conf should look like:
13# DEST_DIR=/srv/ftp.root/lxc-images
14# SOURCE_URL=rsync://rsync.image.linuxcontainers.org/lxc-images
15# RSYNC_PASSWORD=secret
16
17if [ $# -lt 1 ]; then
18 myname=$(basename $0)
19 echo "Usage: ${myname} <role>"
20 exit 1
21fi
22
23role=$1
24myhostname=$(hostname)
25logfile=${HOME}/log/mirror-${role}.log
26
27# Magic to make sure things keep running in the background
28# after ssh has gone away
29if [ "$2" != "go" ]; then
30 annotate-output $0 $1 go > ${logfile} 2>&1 &
31 exit 0
32fi
33
34set -u
35
36function log {
37 echo $1
38}
39
40function fatal {
41 log $1
42 exit 1
43}
44
45if [ -f ${HOME}/mirror-config/${role}.conf ]; then
46 . ${HOME}/mirror-config/${role}.conf
47else
48 fatal "${role}.conf file missing - aborting"
49fi
50
51export RSYNC_PASSWORD
52lockfile="Archive-Update-in-Progress-${role}-${myhostname}"
53lockpath="${DEST_DIR}/${lockfile}"
54
55if lockfile -! -l 43200 -r 0 "${lockpath}"; then
56 fatal "${myhostname} is unable to start an rsync for ${role}. Lockfile exists"
57fi
58trap "rm -f ${lockpath} > /dev/null 2>&1" exit
59
60if [ ! -d ${DEST_DIR} ]; then
61 log "${DEST_DIR} does not exist yet, trying to create it..."
62 mkdir -p ${DEST_DIR} || fatal "Creation of ${DEST_DIR} failed."
63fi
64
65if [ -n "${RSYNC_USER}" ]; then
66 url=$(echo ${SOURCE_URL}|sed -e "s,//,//${RSYNC_USER}@,")
67else
68 url=${SOURCE_URL}
69fi
70
71# If upstream is close to us and triggers us via ssh, we may start
72# syncing before it has deleted its local lock file, which then
73# becomes a "file has vanished" and non-zero exit, causing the trace
74# file to not update, which makes the mirror seem stale when it isn't.
75# Therefore, let's just:
76log "== Sleeping to allow upstream delete its lock file =="
77sleep 5
78
79
80# Here we use a three-phase sunc as per RT#126178.
81log "== Phase 1: Syncing new images from source =="
82rsync --timeout 10800 -a --include='/images/***' --exclude='*' ${SOURCE_URL} ${DEST_DIR} || fatal "Phase 1 sync from $url failed"
83
84log "== Phase 2: Syncing metadata from source =="
85rsync --timeout 10800 -a --exclude "${lockpath}" --exclude '/images/***' --delete ${SOURCE_URL} ${DEST_DIR} || fatal "Phase 2 sync from $url failed"
86
87log "== Phase 3: Removing images no longer present on source =="
88rsync --timeout 10800 -a --include='/images/***' --exclude='*' --delete ${SOURCE_URL} ${DEST_DIR} || fatal "Phase 3 sync from $url failed"
89
90if [ -n "${DOWNSTREAM_MIRRORS}" -a -n "${TRIGGER_KEYFILE}" ]; then
91 t=15m
92 log "== Triggering downstream mirrors (will give up after $t) =="
93 timeout $t ${SCRIPT_DIR}/trigger-downstream-mirrors.sh $role $TRIGGER_KEYFILE $DOWNSTREAM_MIRRORS
94fi
95
96savelog ${logfile} > /dev/null 2>&1
97rm -f ${lockpath} > /dev/null 2>&1
diff --git a/hooks/Config.py b/hooks/Config.py
index 03f840a..5f41727 100755
--- a/hooks/Config.py
+++ b/hooks/Config.py
@@ -241,6 +241,7 @@ class Config:
241 return [241 return [
242 "cdimage",242 "cdimage",
243 "cloud-image",243 "cloud-image",
244 "linuxcontainers",
244 "maas-images",245 "maas-images",
245 "old-releases",246 "old-releases",
246 "ports",247 "ports",
diff --git a/hooks/hooks.py b/hooks/hooks.py
index 3c1b3b4..24a6cc8 100755
--- a/hooks/hooks.py
+++ b/hooks/hooks.py
@@ -18,6 +18,8 @@ import sys
18import types18import types
19import yaml19import yaml
2020
21from glob import glob
22
21from charmhelpers.core.host import (23from charmhelpers.core.host import (
22 adduser,24 adduser,
23 lsb_release,25 lsb_release,
@@ -63,11 +65,13 @@ required_pkgs = [
63 'apache2',65 'apache2',
64 'curl', # for check-mirror.sh66 'curl', # for check-mirror.sh
65 'devscripts', # provides annotate-output67 'devscripts', # provides annotate-output
68 'geoip-database',
69 'libapache2-mod-geoip',
66 'logrotate',70 'logrotate',
67 'procmail', # provides lockfile71 'procmail', # provides lockfile
68 'rsync',72 'rsync',
69 'vsftpd',
70 'ubuntu-cloud-keyring', # for check-mirror.sh73 'ubuntu-cloud-keyring', # for check-mirror.sh
74 'vsftpd',
71 'xinetd',75 'xinetd',
72]76]
7377
@@ -75,6 +79,7 @@ service_affecting_packages = ['apache2']
7579
76apache_modules = [80apache_modules = [
77 'expires',81 'expires',
82 'geoip',
78 'headers',83 'headers',
79 'rewrite',84 'rewrite',
80]85]
@@ -82,6 +87,7 @@ apache_modules = [
82scripts_to_copy = [87scripts_to_copy = [
83 'mirror-1stage.sh',88 'mirror-1stage.sh',
84 'mirror-2stage.sh',89 'mirror-2stage.sh',
90 'mirror-linuxcontainers.sh',
85 'check-mirror.sh',91 'check-mirror.sh',
86 'check-updates.sh',92 'check-updates.sh',
87]93]
@@ -522,8 +528,15 @@ def configure_apache(conf, hostname): # noqa: C901
522 tmpl_data["logdir"] = apache_logdir528 tmpl_data["logdir"] = apache_logdir
523 tmpl_data["addresses"] = role_config.get('addresses', ['*'])529 tmpl_data["addresses"] = role_config.get('addresses', ['*'])
524 all_addresses.update(tmpl_data["addresses"])530 all_addresses.update(tmpl_data["addresses"])
525 tmpl_data["ports"] = [80, 443] if role_config.get('https') else [80]531
526 all_ports.update(tmpl_data["ports"])532 ports = [80]
533 if role_config.get('https'):
534 ports.append(443)
535 if role == 'linuxcontainers':
536 ports.append(8443)
537 all_ports.update(ports)
538 tmpl_data["ports"] = ports
539
527 file_from_template(mirror['tmpl_file'], sites_available, tmpl_data)540 file_from_template(mirror['tmpl_file'], sites_available, tmpl_data)
528 ensure_symlink(sites_available, sites_enabled)541 ensure_symlink(sites_available, sites_enabled)
529542
@@ -543,8 +556,11 @@ def configure_apache(conf, hostname): # noqa: C901
543 os.chown(mirror["path"], mirror_userinfo.pw_uid, mirror_userinfo.pw_gid)556 os.chown(mirror["path"], mirror_userinfo.pw_uid, mirror_userinfo.pw_gid)
544 ensure_symlink(mirror["path"], linkdest)557 ensure_symlink(mirror["path"], linkdest)
545558
546 # Update ports file559 # archive.ubuntu.com must not open port 443. Three factors align
547 all_addresses.discard('*') # archive.ubuntu.com must not open port 443.560 # to prevent this: 1) we do not set "addresses" or "https" in the
561 # role_map; 2) the template doesn't make non-port-80 sockets for
562 # members of "addresses"; 3) the wildcard address is discarded.
563 all_addresses.discard('*')
548 file_from_template('apache-listen-ports.conf.tmpl', '/etc/apache2/ports.conf',564 file_from_template('apache-listen-ports.conf.tmpl', '/etc/apache2/ports.conf',
549 {'addresses': sorted(all_addresses), 'ports': sorted(all_ports)})565 {'addresses': sorted(all_addresses), 'ports': sorted(all_ports)})
550566
@@ -939,7 +955,10 @@ def configure_nrpe(conf, hostname): # noqa: C901
939 tmpl_data["hostname"] = hostname955 tmpl_data["hostname"] = hostname
940 tmpl_data["use"] = "active-service"956 tmpl_data["use"] = "active-service"
941 tmpl_data["nagios_hostname"] = conf.nagios_hostname()957 tmpl_data["nagios_hostname"] = conf.nagios_hostname()
942 tmpl_data["tracepath"] = os.path.join(mirror["path"], ".trace", mirror["base_role"] + "-" + hostname)958 if role == "linuxcontainers":
959 tmpl_data["tracepath"] = os.path.join(mirror["path"], ".serial")
960 else:
961 tmpl_data["tracepath"] = os.path.join(mirror["path"], ".trace", mirror["base_role"] + "-" + hostname)
943962
944 for check, check_details in role_checks.items():963 for check, check_details in role_checks.items():
945 if check_details.get('when') and not role_config.get(check_details['when']):964 if check_details.get('when') and not role_config.get(check_details['when']):
@@ -1104,6 +1123,14 @@ def configure_directories(conf, hostname):
1104 mkdir("/srv/ftp.root")1123 mkdir("/srv/ftp.root")
11051124
11061125
1126def configure_keyring(conf, hostname):
1127 import_cmd = [
1128 '/usr/bin/gpg', '--no-default-keyring', '--keyring', '/usr/local/share/ubuntu-mirror-charm.gpg', '--import']
1129 keys = glob(os.path.join(charm_dir(), 'keys', '*.asc'))
1130 import_cmd.extend(keys)
1131 check_call(import_cmd)
1132
1133
1107@hooks.hook("install.real")1134@hooks.hook("install.real")
1108def install():1135def install():
1109 conf = Config()1136 conf = Config()
@@ -1134,6 +1161,7 @@ def config_changed():
1134 configure_nrpe(conf, hostname)1161 configure_nrpe(conf, hostname)
1135 configure_log_archiving(conf, hostname)1162 configure_log_archiving(conf, hostname)
1136 configure_sysctl(conf, hostname)1163 configure_sysctl(conf, hostname)
1164 configure_keyring(conf, hostname)
11371165
11381166
1139@hooks.hook("upgrade-charm")1167@hooks.hook("upgrade-charm")
diff --git a/keys/juju-tools.asc b/keys/juju-tools.asc
1140new file mode 1006441168new file mode 100644
index 0000000..0bf2290
--- /dev/null
+++ b/keys/juju-tools.asc
@@ -0,0 +1,51 @@
1-----BEGIN PGP PUBLIC KEY BLOCK-----
2
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
50=hQAI
51-----END PGP PUBLIC KEY BLOCK-----
diff --git a/keys/lxc-devel.asc b/keys/lxc-devel.asc
0new file mode 10064452new file mode 100644
index 0000000..90af404
--- /dev/null
+++ b/keys/lxc-devel.asc
@@ -0,0 +1,29 @@
1-----BEGIN PGP PUBLIC KEY BLOCK-----
2
3mQINBFLQvwwBEADNVxfLfsKibZbF5v2Tct9N0gxdFViOzVd/IRDrJ6pTEAcMlWdS
4h3VM3lV0qd1WtMlqCTgcbbk6zUAYnPQ2RsagCpOlaIZqbZ8Cv4390PuVAhG2QQvt
59YrED00unJBomsC3QuF+xg0SBpHChmFUgJxomsFuAjowdMoh8XExM2v4TEe+vm9Z
67ohBCxkw7C5cV9cQHeC1XiGBCccRe1Ib1U7+GmPUxAtGzHUsQQ4MjE/j830dmPJw
7w/ZNauKyNqSzpBsMnEiX+8RwqYEeYtqBAw9pnA3BMSshfA5L5ORw3zYecowUWt+l
8r5lhzBq2v3LLjzjwsb4wel8L7HZnUD+1bQe0QQkxWDKlHOIsB02DCwmz3fc9bvBI
9KZwRQZ8al7HicpWc4zJPBb7U0BSHE+YwTdOffFFL7YfbRS+4yfn0JBSmtyfTPaOp
10FvHV8MES52Mam3vyXWCKXC//3EXcWhhX4ZHfkcWJtEkDf1FwupptV6HEgx2d6UTZ
110vEK20Dx+Hzlg0mpR10SS/ltch8w1Zl2co467oTMspdnPosTrxG0p2G+s/gUA/+E
12LY8fB/heXfNSb5IB3JJ8OTI+cwqN1Aw9X4aKPQcvPGvfQ5Mz8FZ4gkV38QzzMHsr
136eeZGUPcCctP6FVfCHO0Mzxwv2VOnTbH+k72Acni2piTwn0APd9LKilXOwARAQAB
14tDpMWEMgcHJlLWJ1aWx0IGltYWdlcyA8bHhjLWRldmVsQGxpc3RzLmxpbnV4Y29u
15dGFpbmVycy5vcmc+iQI4BBMBAgAiBQJS0L8MAhsDBgsJCAcDAgYVCAIJCgsEFgID
16AQIeAQIXgAAKCRC67/iMIvbiFtzVD/933Dv/NsyPAiwT6BFLlqtq/Tl3NxcUogDS
17Rkv1oMiIunaKZRE/pQbLJVTSbt/eC3Kz7I40juDNsFGXXhD/sQCovMc58NpTKNPR
18zs3jC5vDIW721cLOhYqITvdWN+RKDCJqxBBNJztKEv29uA0PONssKBmC/apTdB6D
19QLLy3ddO/LzxDrCtC8ePLGjeVoEelZHR3tg8QZE+oVBuL3ZC2NTg/XaLSDO4zGCg
20Jyd1IHGKhi20Q/sBLmsFifnWt5b6ovmRqwlsZXqcS+a7Z+WSmZWT9hKIR2XSzYUW
21pmlJNO4VPzHgEcaCxlw3HxQqX0Loz4R8Y91shKuJ591ZMtmyf4j6Yl9KZfLs+lZH
22iX7uazhw4miXdpCvOKe8fPLa+68JGIYPxG22l2jqPJ9FIOtpSrJX3D/i8xed5h2V
23Vd38fZBn+cH1Wqbw1Ni94/f66Rp5GzJyMoVO7A016Ek3wx920SmX4HkCSEel77pF
24gvCBZkQDiD6TNCJxjHQpxoSGo6SDEfP0FjntB0yVy0zi+Iij9F3O1bPIIuses4OQ
25FkUGJb6V0L1wXl5hOARmVtgn6klwhsLf0EsjuH9yJN2GCuaKdjAdR8J1TsjW+q4h
26DKMvYOZ99YJUE+qujz9u93tJRZTuD8pQsGRez7qrZ0LUAdd/aOjNDLWzJ8AzeQE+
27OKVNmCzO9A==
28=euOK
29-----END PGP PUBLIC KEY BLOCK-----
diff --git a/templates/apache-linuxcontainers-api.include.tmpl b/templates/apache-linuxcontainers-api.include.tmpl
0new file mode 10064430new file mode 100644
index 0000000..36cf273
--- /dev/null
+++ b/templates/apache-linuxcontainers-api.include.tmpl
@@ -0,0 +1,41 @@
1## This template does not use any Cheetah features (yet?) but for
2## consistency it is not included raw, and therefore $ is escaped.
3 # LXD: Recursive queries
4 RewriteCond %{QUERY_STRING} recursion=1
5 RewriteRule ^/1.0.*\$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
6
7 # LXD: Normal queries
8 RewriteRule ^/1.0.*\$ /meta/lxd%{REQUEST_URI}/index.json [L]
9
10 <Location />
11 Require all granted
12 </Location>
13
14 # LXC: Allow image listing
15 <Location /images>
16 Options +Indexes
17 </Location>
18
19 # LXD: API root
20 <Location /1.0/>
21 ErrorDocument 404 /meta/lxd/404.json
22 Options -Indexes
23 </Location>
24
25 # LXD: images
26 <Location /1.0/images/>
27 ErrorDocument 404 /meta/lxd/1.0/images/404.json
28 Options +FollowSymlinks
29 </Location>
30
31 # LXD: aliases
32 <Location /1.0/images/aliases/>
33 ErrorDocument 404 /meta/lxd/404.json
34 </Location>
35
36 # LXD: downloads
37 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
38 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
39 </LocationMatch>
40 # Simplestreams: redirect
41 RewriteRule ^/streams(.*)\$ /meta/simplestreams\$1 [L]
diff --git a/templates/apache-linuxcontainers-tls.include.tmpl b/templates/apache-linuxcontainers-tls.include.tmpl
0new file mode 10064442new file mode 100644
index 0000000..3851d19
--- /dev/null
+++ b/templates/apache-linuxcontainers-tls.include.tmpl
@@ -0,0 +1,16 @@
1#if $port == 80
2#set $proto = 'http'
3#else if $port == 443
4#set $proto = 'https'
5#else
6#set $proto = 'https'
7#end if
8 # SSL configuration
9 SSLEngine On
10 SSLCertificateFile /etc/ssl/certs/${name}.crt
11 SSLCertificateKeyFile /etc/ssl/private/${name}.key
12 SSLCertificateChainFile /etc/ssl/certs/${name}_chain.crt
13 Header always set Strict-Transport-Security "max-age=31536000"
14 RequestHeader set X_FORWARDED_PORT "${port}"
15 RequestHeader set X_FORWARDED_PROTO "${proto}"
16
diff --git a/templates/apache-linuxcontainers.tmpl b/templates/apache-linuxcontainers.tmpl
0new file mode 10064417new file mode 100644
index 0000000..f2c9391
--- /dev/null
+++ b/templates/apache-linuxcontainers.tmpl
@@ -0,0 +1,74 @@
1#for $port in $ports
2#set global $port = $port
3#set $sockets = ' '.join(sorted(['{}:{}'.format(address, port) for address in $addresses]))
4#if $port == 80
5#set global $proto = 'http'
6#set $uk_url = 'http://uk.{}/'.format($name)
7#set $us_url = 'http://us.{}/'.format($name)
8#else if $port == 443
9#set global $proto = 'https'
10#set $uk_url = 'https://uk.{}/'.format($name)
11#set $us_url = 'https://us.{}/'.format($name)
12#else
13#set global $proto = 'https'
14#set $uk_url = 'https://uk.{}:{}/'.format($name, $port)
15#set $us_url = 'https://us.{}:{}/'.format($name, $port)
16#end if
17<VirtualHost ${sockets}>
18 ServerName ${name}
19#if $name != "images.linuxcontainers.org"
20 #for $alias in $aliases
21 ServerAlias ${alias}
22 #end for
23#end if
24 CustomLog \${APACHE_LOG_DIR}/${name}.log vhost_combined
25 DocumentRoot /srv/${name}/www
26
27 <Location />
28 Require all granted
29 </Location>
30
31#if $proto == "https"
32#include 'templates/apache-linuxcontainers-tls.include.tmpl'
33#end if
34 RewriteEngine on
35 AllowEncodedSlashes On
36
37#if $name == "images.linuxcontainers.org"
38 # GeoIP: Redirect everything to appropriate country server
39 GeoIPEnable On
40 GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
41 GeoIPDBFile /usr/share/GeoIP/GeoIPv6.dat
42
43 # Send North America, Oceania and South America to the US server
44 RewriteCond %{ENV:GEOIP_CONTINENT_CODE} ^(NA|OC|SA)\$
45 RewriteRule ^/(.*)\$ ${us_url}\$1 [R=301,L]
46 RewriteCond %{ENV:GEOIP_CONTINENT_CODE_V6} ^(NA|OC|SA)\$
47 RewriteRule ^/(.*)\$ ${us_url}\$1 [R=301,L]
48
49 # Send Africa, Antarctica, Asia, Europe, and all else to the UK server
50 RewriteRule ^/(.*)\$ ${uk_url}\$1 [R=301,L]
51#else
52#include 'templates/apache-linuxcontainers-api.include.tmpl'
53#end if
54</VirtualHost>
55
56#if $name == "images.linuxcontainers.org"
57#for $alias in $aliases
58<VirtualHost ${sockets}>
59 ServerName ${alias}
60 CustomLog \${APACHE_LOG_DIR}/${alias}.log vhost_combined
61 DocumentRoot /srv/${name}/www
62
63#if $proto == "https"
64#include 'templates/apache-linuxcontainers-tls.include.tmpl'
65#end if
66 RewriteEngine on
67 AllowEncodedSlashes On
68
69#include 'templates/apache-linuxcontainers-api.include.tmpl'
70</VirtualHost>
71
72#end for
73#end if
74#end for
diff --git a/tests/unit/test_linuxcontainers.py b/tests/unit/test_linuxcontainers.py
0new file mode 10064475new file mode 100644
index 0000000..5a485ea
--- /dev/null
+++ b/tests/unit/test_linuxcontainers.py
@@ -0,0 +1,56 @@
1import os
2import pytest
3import unittest
4
5from Cheetah.Template import Template
6
7TEMPLATE = 'apache-linuxcontainers.tmpl'
8
9THIRDPARTY_SEARCH_LIST = {
10 'addresses': ['*'],
11 'name': 'lxd.example.net',
12 'aliases': ['uk.lxd.example.net', 'us.lxd.example.net'],
13 'ports': [80, 443],
14}
15
16LINUXCONTAINERS_SEARCH_LIST = {
17 'addresses': ['91.189.88.247', '[2001:67c:1360:8001::33]'],
18 'name': 'images.linuxcontainers.org',
19 'aliases': ['uk.images.linuxcontainers.org', 'us.images.linuxcontainers.org'],
20 'ports': [80, 443, 8443],
21}
22
23
24class TestLinuxcontainers(unittest.TestCase):
25 def setUp(self):
26 self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
27 self.maxDiff = None
28 self.testdata_dir = os.path.join(os.path.dirname(__file__), 'testdata', 'linuxcontainers')
29
30 def _template_compare(self, template, search_list, wanted_file):
31 template_file = os.path.join(os.getcwd(), template)
32 template = Template(file=template_file, searchList=search_list)
33 wanted = open(wanted_file).read()
34 self.assertEqual(str(template), wanted)
35
36 # Cheetah warns about using the Python version of NameMapper, so
37 # we ignore it here. Matching more closely by the message doesn't
38 # seem to work, probably because it begins with a newline and
39 # Python's warnings matching code anchors the message regexp.
40 @pytest.mark.filterwarnings("ignore::UserWarning:Cheetah")
41 def test_template_linuxcontainers(self):
42 self._template_compare(
43 os.path.join(os.getcwd(), 'templates', TEMPLATE),
44 LINUXCONTAINERS_SEARCH_LIST,
45 os.path.join(self.testdata_dir, 'linuxcontainers.txt'))
46
47 # Cheetah warns about using the Python version of NameMapper, so
48 # we ignore it here. Matching more closely by the message doesn't
49 # seem to work, probably because it begins with a newline and
50 # Python's warnings matching code anchors the message regexp.
51 @pytest.mark.filterwarnings("ignore::UserWarning:Cheetah")
52 def test_template_thirdparty(self):
53 self._template_compare(
54 os.path.join(os.getcwd(), 'templates', TEMPLATE),
55 THIRDPARTY_SEARCH_LIST,
56 os.path.join(self.testdata_dir, 'thirdparty.txt'))
diff --git a/tests/unit/testdata/linuxcontainers/linuxcontainers.txt b/tests/unit/testdata/linuxcontainers/linuxcontainers.txt
0new file mode 10064457new file mode 100644
index 0000000..1056067
--- /dev/null
+++ b/tests/unit/testdata/linuxcontainers/linuxcontainers.txt
@@ -0,0 +1,429 @@
1<VirtualHost 91.189.88.247:80 [2001:67c:1360:8001::33]:80>
2 ServerName images.linuxcontainers.org
3 CustomLog ${APACHE_LOG_DIR}/images.linuxcontainers.org.log vhost_combined
4 DocumentRoot /srv/images.linuxcontainers.org/www
5
6 <Location />
7 Require all granted
8 </Location>
9
10 RewriteEngine on
11 AllowEncodedSlashes On
12
13 # GeoIP: Redirect everything to appropriate country server
14 GeoIPEnable On
15 GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
16 GeoIPDBFile /usr/share/GeoIP/GeoIPv6.dat
17
18 # Send North America, Oceania and South America to the US server
19 RewriteCond %{ENV:GEOIP_CONTINENT_CODE} ^(NA|OC|SA)$
20 RewriteRule ^/(.*)$ http://us.images.linuxcontainers.org/$1 [R=301,L]
21 RewriteCond %{ENV:GEOIP_CONTINENT_CODE_V6} ^(NA|OC|SA)$
22 RewriteRule ^/(.*)$ http://us.images.linuxcontainers.org/$1 [R=301,L]
23
24 # Send Africa, Antarctica, Asia, Europe, and all else to the UK server
25 RewriteRule ^/(.*)$ http://uk.images.linuxcontainers.org/$1 [R=301,L]
26</VirtualHost>
27
28<VirtualHost 91.189.88.247:80 [2001:67c:1360:8001::33]:80>
29 ServerName uk.images.linuxcontainers.org
30 CustomLog ${APACHE_LOG_DIR}/uk.images.linuxcontainers.org.log vhost_combined
31 DocumentRoot /srv/images.linuxcontainers.org/www
32
33 RewriteEngine on
34 AllowEncodedSlashes On
35
36 # LXD: Recursive queries
37 RewriteCond %{QUERY_STRING} recursion=1
38 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
39
40 # LXD: Normal queries
41 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
42
43 <Location />
44 Require all granted
45 </Location>
46
47 # LXC: Allow image listing
48 <Location /images>
49 Options +Indexes
50 </Location>
51
52 # LXD: API root
53 <Location /1.0/>
54 ErrorDocument 404 /meta/lxd/404.json
55 Options -Indexes
56 </Location>
57
58 # LXD: images
59 <Location /1.0/images/>
60 ErrorDocument 404 /meta/lxd/1.0/images/404.json
61 Options +FollowSymlinks
62 </Location>
63
64 # LXD: aliases
65 <Location /1.0/images/aliases/>
66 ErrorDocument 404 /meta/lxd/404.json
67 </Location>
68
69 # LXD: downloads
70 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
71 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
72 </LocationMatch>
73 # Simplestreams: redirect
74 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
75</VirtualHost>
76
77<VirtualHost 91.189.88.247:80 [2001:67c:1360:8001::33]:80>
78 ServerName us.images.linuxcontainers.org
79 CustomLog ${APACHE_LOG_DIR}/us.images.linuxcontainers.org.log vhost_combined
80 DocumentRoot /srv/images.linuxcontainers.org/www
81
82 RewriteEngine on
83 AllowEncodedSlashes On
84
85 # LXD: Recursive queries
86 RewriteCond %{QUERY_STRING} recursion=1
87 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
88
89 # LXD: Normal queries
90 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
91
92 <Location />
93 Require all granted
94 </Location>
95
96 # LXC: Allow image listing
97 <Location /images>
98 Options +Indexes
99 </Location>
100
101 # LXD: API root
102 <Location /1.0/>
103 ErrorDocument 404 /meta/lxd/404.json
104 Options -Indexes
105 </Location>
106
107 # LXD: images
108 <Location /1.0/images/>
109 ErrorDocument 404 /meta/lxd/1.0/images/404.json
110 Options +FollowSymlinks
111 </Location>
112
113 # LXD: aliases
114 <Location /1.0/images/aliases/>
115 ErrorDocument 404 /meta/lxd/404.json
116 </Location>
117
118 # LXD: downloads
119 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
120 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
121 </LocationMatch>
122 # Simplestreams: redirect
123 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
124</VirtualHost>
125
126<VirtualHost 91.189.88.247:443 [2001:67c:1360:8001::33]:443>
127 ServerName images.linuxcontainers.org
128 CustomLog ${APACHE_LOG_DIR}/images.linuxcontainers.org.log vhost_combined
129 DocumentRoot /srv/images.linuxcontainers.org/www
130
131 <Location />
132 Require all granted
133 </Location>
134
135 # SSL configuration
136 SSLEngine On
137 SSLCertificateFile /etc/ssl/certs/images.linuxcontainers.org.crt
138 SSLCertificateKeyFile /etc/ssl/private/images.linuxcontainers.org.key
139 SSLCertificateChainFile /etc/ssl/certs/images.linuxcontainers.org_chain.crt
140 Header always set Strict-Transport-Security "max-age=31536000"
141 RequestHeader set X_FORWARDED_PORT "443"
142 RequestHeader set X_FORWARDED_PROTO "https"
143
144 RewriteEngine on
145 AllowEncodedSlashes On
146
147 # GeoIP: Redirect everything to appropriate country server
148 GeoIPEnable On
149 GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
150 GeoIPDBFile /usr/share/GeoIP/GeoIPv6.dat
151
152 # Send North America, Oceania and South America to the US server
153 RewriteCond %{ENV:GEOIP_CONTINENT_CODE} ^(NA|OC|SA)$
154 RewriteRule ^/(.*)$ https://us.images.linuxcontainers.org/$1 [R=301,L]
155 RewriteCond %{ENV:GEOIP_CONTINENT_CODE_V6} ^(NA|OC|SA)$
156 RewriteRule ^/(.*)$ https://us.images.linuxcontainers.org/$1 [R=301,L]
157
158 # Send Africa, Antarctica, Asia, Europe, and all else to the UK server
159 RewriteRule ^/(.*)$ https://uk.images.linuxcontainers.org/$1 [R=301,L]
160</VirtualHost>
161
162<VirtualHost 91.189.88.247:443 [2001:67c:1360:8001::33]:443>
163 ServerName uk.images.linuxcontainers.org
164 CustomLog ${APACHE_LOG_DIR}/uk.images.linuxcontainers.org.log vhost_combined
165 DocumentRoot /srv/images.linuxcontainers.org/www
166
167 # SSL configuration
168 SSLEngine On
169 SSLCertificateFile /etc/ssl/certs/images.linuxcontainers.org.crt
170 SSLCertificateKeyFile /etc/ssl/private/images.linuxcontainers.org.key
171 SSLCertificateChainFile /etc/ssl/certs/images.linuxcontainers.org_chain.crt
172 Header always set Strict-Transport-Security "max-age=31536000"
173 RequestHeader set X_FORWARDED_PORT "443"
174 RequestHeader set X_FORWARDED_PROTO "https"
175
176 RewriteEngine on
177 AllowEncodedSlashes On
178
179 # LXD: Recursive queries
180 RewriteCond %{QUERY_STRING} recursion=1
181 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
182
183 # LXD: Normal queries
184 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
185
186 <Location />
187 Require all granted
188 </Location>
189
190 # LXC: Allow image listing
191 <Location /images>
192 Options +Indexes
193 </Location>
194
195 # LXD: API root
196 <Location /1.0/>
197 ErrorDocument 404 /meta/lxd/404.json
198 Options -Indexes
199 </Location>
200
201 # LXD: images
202 <Location /1.0/images/>
203 ErrorDocument 404 /meta/lxd/1.0/images/404.json
204 Options +FollowSymlinks
205 </Location>
206
207 # LXD: aliases
208 <Location /1.0/images/aliases/>
209 ErrorDocument 404 /meta/lxd/404.json
210 </Location>
211
212 # LXD: downloads
213 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
214 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
215 </LocationMatch>
216 # Simplestreams: redirect
217 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
218</VirtualHost>
219
220<VirtualHost 91.189.88.247:443 [2001:67c:1360:8001::33]:443>
221 ServerName us.images.linuxcontainers.org
222 CustomLog ${APACHE_LOG_DIR}/us.images.linuxcontainers.org.log vhost_combined
223 DocumentRoot /srv/images.linuxcontainers.org/www
224
225 # SSL configuration
226 SSLEngine On
227 SSLCertificateFile /etc/ssl/certs/images.linuxcontainers.org.crt
228 SSLCertificateKeyFile /etc/ssl/private/images.linuxcontainers.org.key
229 SSLCertificateChainFile /etc/ssl/certs/images.linuxcontainers.org_chain.crt
230 Header always set Strict-Transport-Security "max-age=31536000"
231 RequestHeader set X_FORWARDED_PORT "443"
232 RequestHeader set X_FORWARDED_PROTO "https"
233
234 RewriteEngine on
235 AllowEncodedSlashes On
236
237 # LXD: Recursive queries
238 RewriteCond %{QUERY_STRING} recursion=1
239 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
240
241 # LXD: Normal queries
242 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
243
244 <Location />
245 Require all granted
246 </Location>
247
248 # LXC: Allow image listing
249 <Location /images>
250 Options +Indexes
251 </Location>
252
253 # LXD: API root
254 <Location /1.0/>
255 ErrorDocument 404 /meta/lxd/404.json
256 Options -Indexes
257 </Location>
258
259 # LXD: images
260 <Location /1.0/images/>
261 ErrorDocument 404 /meta/lxd/1.0/images/404.json
262 Options +FollowSymlinks
263 </Location>
264
265 # LXD: aliases
266 <Location /1.0/images/aliases/>
267 ErrorDocument 404 /meta/lxd/404.json
268 </Location>
269
270 # LXD: downloads
271 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
272 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
273 </LocationMatch>
274 # Simplestreams: redirect
275 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
276</VirtualHost>
277
278<VirtualHost 91.189.88.247:8443 [2001:67c:1360:8001::33]:8443>
279 ServerName images.linuxcontainers.org
280 CustomLog ${APACHE_LOG_DIR}/images.linuxcontainers.org.log vhost_combined
281 DocumentRoot /srv/images.linuxcontainers.org/www
282
283 <Location />
284 Require all granted
285 </Location>
286
287 # SSL configuration
288 SSLEngine On
289 SSLCertificateFile /etc/ssl/certs/images.linuxcontainers.org.crt
290 SSLCertificateKeyFile /etc/ssl/private/images.linuxcontainers.org.key
291 SSLCertificateChainFile /etc/ssl/certs/images.linuxcontainers.org_chain.crt
292 Header always set Strict-Transport-Security "max-age=31536000"
293 RequestHeader set X_FORWARDED_PORT "8443"
294 RequestHeader set X_FORWARDED_PROTO "https"
295
296 RewriteEngine on
297 AllowEncodedSlashes On
298
299 # GeoIP: Redirect everything to appropriate country server
300 GeoIPEnable On
301 GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
302 GeoIPDBFile /usr/share/GeoIP/GeoIPv6.dat
303
304 # Send North America, Oceania and South America to the US server
305 RewriteCond %{ENV:GEOIP_CONTINENT_CODE} ^(NA|OC|SA)$
306 RewriteRule ^/(.*)$ https://us.images.linuxcontainers.org:8443/$1 [R=301,L]
307 RewriteCond %{ENV:GEOIP_CONTINENT_CODE_V6} ^(NA|OC|SA)$
308 RewriteRule ^/(.*)$ https://us.images.linuxcontainers.org:8443/$1 [R=301,L]
309
310 # Send Africa, Antarctica, Asia, Europe, and all else to the UK server
311 RewriteRule ^/(.*)$ https://uk.images.linuxcontainers.org:8443/$1 [R=301,L]
312</VirtualHost>
313
314<VirtualHost 91.189.88.247:8443 [2001:67c:1360:8001::33]:8443>
315 ServerName uk.images.linuxcontainers.org
316 CustomLog ${APACHE_LOG_DIR}/uk.images.linuxcontainers.org.log vhost_combined
317 DocumentRoot /srv/images.linuxcontainers.org/www
318
319 # SSL configuration
320 SSLEngine On
321 SSLCertificateFile /etc/ssl/certs/images.linuxcontainers.org.crt
322 SSLCertificateKeyFile /etc/ssl/private/images.linuxcontainers.org.key
323 SSLCertificateChainFile /etc/ssl/certs/images.linuxcontainers.org_chain.crt
324 Header always set Strict-Transport-Security "max-age=31536000"
325 RequestHeader set X_FORWARDED_PORT "8443"
326 RequestHeader set X_FORWARDED_PROTO "https"
327
328 RewriteEngine on
329 AllowEncodedSlashes On
330
331 # LXD: Recursive queries
332 RewriteCond %{QUERY_STRING} recursion=1
333 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
334
335 # LXD: Normal queries
336 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
337
338 <Location />
339 Require all granted
340 </Location>
341
342 # LXC: Allow image listing
343 <Location /images>
344 Options +Indexes
345 </Location>
346
347 # LXD: API root
348 <Location /1.0/>
349 ErrorDocument 404 /meta/lxd/404.json
350 Options -Indexes
351 </Location>
352
353 # LXD: images
354 <Location /1.0/images/>
355 ErrorDocument 404 /meta/lxd/1.0/images/404.json
356 Options +FollowSymlinks
357 </Location>
358
359 # LXD: aliases
360 <Location /1.0/images/aliases/>
361 ErrorDocument 404 /meta/lxd/404.json
362 </Location>
363
364 # LXD: downloads
365 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
366 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
367 </LocationMatch>
368 # Simplestreams: redirect
369 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
370</VirtualHost>
371
372<VirtualHost 91.189.88.247:8443 [2001:67c:1360:8001::33]:8443>
373 ServerName us.images.linuxcontainers.org
374 CustomLog ${APACHE_LOG_DIR}/us.images.linuxcontainers.org.log vhost_combined
375 DocumentRoot /srv/images.linuxcontainers.org/www
376
377 # SSL configuration
378 SSLEngine On
379 SSLCertificateFile /etc/ssl/certs/images.linuxcontainers.org.crt
380 SSLCertificateKeyFile /etc/ssl/private/images.linuxcontainers.org.key
381 SSLCertificateChainFile /etc/ssl/certs/images.linuxcontainers.org_chain.crt
382 Header always set Strict-Transport-Security "max-age=31536000"
383 RequestHeader set X_FORWARDED_PORT "8443"
384 RequestHeader set X_FORWARDED_PROTO "https"
385
386 RewriteEngine on
387 AllowEncodedSlashes On
388
389 # LXD: Recursive queries
390 RewriteCond %{QUERY_STRING} recursion=1
391 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
392
393 # LXD: Normal queries
394 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
395
396 <Location />
397 Require all granted
398 </Location>
399
400 # LXC: Allow image listing
401 <Location /images>
402 Options +Indexes
403 </Location>
404
405 # LXD: API root
406 <Location /1.0/>
407 ErrorDocument 404 /meta/lxd/404.json
408 Options -Indexes
409 </Location>
410
411 # LXD: images
412 <Location /1.0/images/>
413 ErrorDocument 404 /meta/lxd/1.0/images/404.json
414 Options +FollowSymlinks
415 </Location>
416
417 # LXD: aliases
418 <Location /1.0/images/aliases/>
419 ErrorDocument 404 /meta/lxd/404.json
420 </Location>
421
422 # LXD: downloads
423 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
424 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
425 </LocationMatch>
426 # Simplestreams: redirect
427 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
428</VirtualHost>
429
diff --git a/tests/unit/testdata/linuxcontainers/thirdparty.txt b/tests/unit/testdata/linuxcontainers/thirdparty.txt
0new file mode 100644430new file mode 100644
index 0000000..0b1e58d
--- /dev/null
+++ b/tests/unit/testdata/linuxcontainers/thirdparty.txt
@@ -0,0 +1,119 @@
1<VirtualHost *:80>
2 ServerName lxd.example.net
3 ServerAlias uk.lxd.example.net
4 ServerAlias us.lxd.example.net
5 CustomLog ${APACHE_LOG_DIR}/lxd.example.net.log vhost_combined
6 DocumentRoot /srv/lxd.example.net/www
7
8 <Location />
9 Require all granted
10 </Location>
11
12 RewriteEngine on
13 AllowEncodedSlashes On
14
15 # LXD: Recursive queries
16 RewriteCond %{QUERY_STRING} recursion=1
17 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
18
19 # LXD: Normal queries
20 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
21
22 <Location />
23 Require all granted
24 </Location>
25
26 # LXC: Allow image listing
27 <Location /images>
28 Options +Indexes
29 </Location>
30
31 # LXD: API root
32 <Location /1.0/>
33 ErrorDocument 404 /meta/lxd/404.json
34 Options -Indexes
35 </Location>
36
37 # LXD: images
38 <Location /1.0/images/>
39 ErrorDocument 404 /meta/lxd/1.0/images/404.json
40 Options +FollowSymlinks
41 </Location>
42
43 # LXD: aliases
44 <Location /1.0/images/aliases/>
45 ErrorDocument 404 /meta/lxd/404.json
46 </Location>
47
48 # LXD: downloads
49 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
50 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
51 </LocationMatch>
52 # Simplestreams: redirect
53 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
54</VirtualHost>
55
56<VirtualHost *:443>
57 ServerName lxd.example.net
58 ServerAlias uk.lxd.example.net
59 ServerAlias us.lxd.example.net
60 CustomLog ${APACHE_LOG_DIR}/lxd.example.net.log vhost_combined
61 DocumentRoot /srv/lxd.example.net/www
62
63 <Location />
64 Require all granted
65 </Location>
66
67 # SSL configuration
68 SSLEngine On
69 SSLCertificateFile /etc/ssl/certs/lxd.example.net.crt
70 SSLCertificateKeyFile /etc/ssl/private/lxd.example.net.key
71 SSLCertificateChainFile /etc/ssl/certs/lxd.example.net_chain.crt
72 Header always set Strict-Transport-Security "max-age=31536000"
73 RequestHeader set X_FORWARDED_PORT "443"
74 RequestHeader set X_FORWARDED_PROTO "https"
75
76 RewriteEngine on
77 AllowEncodedSlashes On
78
79 # LXD: Recursive queries
80 RewriteCond %{QUERY_STRING} recursion=1
81 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index-rec.json [L]
82
83 # LXD: Normal queries
84 RewriteRule ^/1.0.*$ /meta/lxd%{REQUEST_URI}/index.json [L]
85
86 <Location />
87 Require all granted
88 </Location>
89
90 # LXC: Allow image listing
91 <Location /images>
92 Options +Indexes
93 </Location>
94
95 # LXD: API root
96 <Location /1.0/>
97 ErrorDocument 404 /meta/lxd/404.json
98 Options -Indexes
99 </Location>
100
101 # LXD: images
102 <Location /1.0/images/>
103 ErrorDocument 404 /meta/lxd/1.0/images/404.json
104 Options +FollowSymlinks
105 </Location>
106
107 # LXD: aliases
108 <Location /1.0/images/aliases/>
109 ErrorDocument 404 /meta/lxd/404.json
110 </Location>
111
112 # LXD: downloads
113 <LocationMatch "^/1.0/images/[0-9a-f]*/export">
114 Header set Content-Type "multipart/form-data; boundary=f012e447-25dd-4f6d-8a14-105c3b27a768"
115 </LocationMatch>
116 # Simplestreams: redirect
117 RewriteRule ^/streams(.*)$ /meta/simplestreams$1 [L]
118</VirtualHost>
119

Subscribers

People subscribed via source and target branches