← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~pelpsi/launchpad:ftpmaster-charm into launchpad:master

 

Simone Pelosi has proposed merging ~pelpsi/launchpad:ftpmaster-charm into launchpad:master.

Commit message:
FTPMaster charms
    
Ftpmaster publisher and uploader.
Ftpmaster publisher publishes packages to the ubuntu archives,
running scripts contained in the ubuntu-archive-publishing repository.
Ftpmaster uploader process uploads of src packages intended
for publishing to ubuntu archive.


Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~pelpsi/launchpad/+git/launchpad/+merge/446413
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~pelpsi/launchpad:ftpmaster-charm into launchpad:master.
diff --git a/charm/launchpad-ftpmaster-publisher/README.md b/charm/launchpad-ftpmaster-publisher/README.md
new file mode 100644
index 0000000..1cc4969
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/README.md
@@ -0,0 +1,3 @@
+# Launchpad ftpmaster-publisher
+
+This charm runs Launchpad ftpmaster-publisher.
diff --git a/charm/launchpad-ftpmaster-publisher/charmcraft.yaml b/charm/launchpad-ftpmaster-publisher/charmcraft.yaml
new file mode 100644
index 0000000..01c2133
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/charmcraft.yaml
@@ -0,0 +1,64 @@
+type: charm
+bases:
+  - build-on:
+    - name: ubuntu
+      channel: "20.04"
+      architectures: [amd64]
+    run-on:
+    - name: ubuntu
+      channel: "20.04"
+      architectures: [amd64]
+parts:
+  charm-wheels:
+    source: https://git.launchpad.net/~ubuntuone-hackers/ols-charm-deps/+git/wheels
+    source-commit: "59b32ae07f98051385c96d6d8e7e02ca4f197fe5"
+    source-submodules: []
+    source-type: git
+    plugin: dump
+    organize:
+      "*": charm-wheels/
+    prime:
+      - "-charm-wheels"
+  ols-layers:
+    source: https://git.launchpad.net/ols-charm-deps
+    source-commit: "56d219f60a293a6c73759b8439ef5fdb11e19d1f"
+    source-submodules: []
+    source-type: git
+    plugin: dump
+    organize:
+      "*": layers/
+    stage:
+      - layers
+    prime:
+      - "-layers"
+  launchpad-layers:
+    after:
+      - ols-layers
+    source: https://git.launchpad.net/launchpad-layers
+    source-commit: "fe273e9f446f84243be2070334cacd03c09da946"
+    source-submodules: []
+    source-type: git
+    plugin: dump
+    organize:
+      launchpad-base: layers/layer/launchpad-base
+      launchpad-db: layers/layer/launchpad-db
+      launchpad-payload: layers/layer/launchpad-payload
+      launchpad-publisher-parts: layers/layer/launchpad-publisher-parts
+    stage:
+      - layers
+    prime:
+      - "-layers"
+  launchpad-ftpmaster-publisher:
+    after:
+      - charm-wheels
+      - launchpad-layers
+    source: .
+    plugin: reactive
+    build-snaps: [charm]
+    build-packages: [libpq-dev, python3-dev]
+    build-environment:
+      - CHARM_LAYERS_DIR: $CRAFT_STAGE/layers/layer
+      - CHARM_INTERFACES_DIR: $CRAFT_STAGE/layers/interface
+      - PIP_NO_INDEX: "true"
+      - PIP_FIND_LINKS: $CRAFT_STAGE/charm-wheels
+    reactive-charm-build-arguments: [--binary-wheels-from-source]
diff --git a/charm/launchpad-ftpmaster-publisher/config.yaml b/charm/launchpad-ftpmaster-publisher/config.yaml
new file mode 100644
index 0000000..3dedb19
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/config.yaml
@@ -0,0 +1,31 @@
+options:
+  active:
+    type: boolean
+    default: true
+    description: If true, enable jobs that may change the database.
+  publisher_parts_repository:
+    type: string
+    description: Repository URL for the Ubuntu specific scripts. 
+    default: lp:ubuntu-archive-publishing
+  publisher_parts_revision: 
+    type: int
+    description: Revision number for the Ubuntu specific scripts.
+    default: 120
+  client_public_key:
+    type: string
+    description: Client public key.
+    default: ""
+  # TEMP
+  build_label:
+    type: string
+    default: fe329353bc9b398511715c0135e456204a8f39bd
+    description: Build label to run.
+  swift_container_name:
+    type: string
+    default: "launchpad-builds"
+    description: TBD
+  swift_storage_url:
+    type: string
+    default: "https://objectstorage.prodstack5.canonical.com/swift/v1/AUTH_318a449e4c8e40e2865c120a597a9644";
+    description: TBD
+  
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-publisher/layer.yaml b/charm/launchpad-ftpmaster-publisher/layer.yaml
new file mode 100644
index 0000000..597af9c
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/layer.yaml
@@ -0,0 +1,19 @@
+includes:
+  - layer:launchpad-db
+  - layer:launchpad-publisher-parts
+repo: https://git.launchpad.net/launchpad
+options:
+  apt:
+    packages:
+      - nodejs
+      - python3-convoy
+  ols-pg:
+    databases:
+      db:
+        name: launchpad_dev
+        roles:
+          - publish_ftpmaster
+          - generate_contents_files
+          - process_death_row
+  launchpad-payload:
+    build_target: build
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-publisher/metadata.yaml b/charm/launchpad-ftpmaster-publisher/metadata.yaml
new file mode 100644
index 0000000..466bfc3
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/metadata.yaml
@@ -0,0 +1,15 @@
+name: launchpad-ftpmaster-publisher
+display-name: launchpad-ftpmaster-publisher
+summary: Launchpad ftpmaster-publisher
+maintainer: Colin Watson <cjwatson@xxxxxxxxxxxxx>
+description: |
+  Launchpad is an open source suite of tools that help people and teams
+  to work together on software projects.
+
+  This charm runs a Launchpad ftpmaster-publisher.
+tags:
+  # https://juju.is/docs/charm-metadata#heading--charm-store-fields
+  - network
+series:
+  - focal
+subordinate: false
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-publisher/reactive/launchpad-ftpmaster-publisher.py b/charm/launchpad-ftpmaster-publisher/reactive/launchpad-ftpmaster-publisher.py
new file mode 100644
index 0000000..0a3c7c0
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/reactive/launchpad-ftpmaster-publisher.py
@@ -0,0 +1,87 @@
+# Copyright 2023 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+import os.path
+
+from charmhelpers.core import hookenv, host, templating
+from charms.launchpad.base import configure_email, get_service_config
+from charms.launchpad.payload import configure_cron, configure_lazr
+from charms.launchpad.publisher_parts import publisher_parts_dir
+from charms.reactive import (
+    remove_state,
+    set_state,
+    when,
+    when_not,
+    when_not_all,
+)
+from ols import base
+
+
+@when_not_all(
+    "config.set.client_public_key",
+)
+def need_client_public_key():
+    hookenv.status_set("blocked", "client_public_key must be configured")
+
+
+def configure_logrotate(config):
+    hookenv.log("Writing logrotate configuration.")
+    templating.render(
+        "logrotate.conf.j2",
+        "/etc/logrotate.d/launchpad",
+        config,
+        perms=0o644,
+    )
+
+
+@when(
+    "launchpad.db.configured",
+    "launchpad.publisher-parts.configured",
+    "config.set.client_public_key",
+)
+@when_not("service.configured")
+def configure():
+    hookenv.log("Configuring ftpmaster publisher")
+    config = get_service_config()
+    config["run_parts_location"] = publisher_parts_dir()
+    config["scripts_dir"] = os.path.join(base.code_dir(), "scripts")
+    host.mkdir(config["scripts_dir"], perms=0o755)
+    config["cronscripts_dir"] = os.path.join(base.code_dir(), "cronscripts")
+    host.mkdir(
+        config["cronscripts_dir"],
+        owner=base.user(),
+        group=base.user(),
+        perms=0o755,
+    )
+    config["lp_publish_logs_dir"] = os.path.join(base.logs_dir(), "lp_publish")
+    host.mkdir(config["lp_publish_logs_dir"], perms=0o755)
+
+    configure_lazr(
+        config,
+        "launchpad-ftpmaster-publisher-lazr.conf",
+        "launchpad-ftpmaster-publisher/launchpad-lazr.conf",
+    )
+    configure_lazr(
+        config,
+        "launchpad-ftpmaster-publisher-secrets-lazr.conf",
+        "launchpad-ftpmaster-publisher-secrets-lazr.conf",
+        secret=True,
+    )
+    configure_email(config, "launchpad-ftpmaster-publisher")
+    configure_logrotate(config)
+    configure_cron(config, "crontab.j2")
+    set_state("service.configured")
+
+
+@when("service.configured")
+def check_is_running():
+    hookenv.status_set("active", "Ready")
+
+
+@when("service.configured")
+@when_not(
+    "launchpad.db.configured",
+    "launchpad.publisher-parts.configured",
+)
+def deconfigure():
+    remove_state("service.configured")
diff --git a/charm/launchpad-ftpmaster-publisher/templates/crontab.j2 b/charm/launchpad-ftpmaster-publisher/templates/crontab.j2
new file mode 100644
index 0000000..43b8ed1
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/templates/crontab.j2
@@ -0,0 +1,17 @@
+MAILTO={{ cron_mailto }}
+LPCONFIG=ftpmaster-publisher
+
+{% if active -%}
+0 0 * * * /usr/sbin/logrotate -s ~/.logrotate.state {{ base_dir }}/etc/lp_publish_logrotate.conf
+03-58/5 * * * * umask 022; {{ cronscripts_dir }}/publish-ftpmaster.py -v -d ubuntu >> {{ lp_publish_logs_dir }}/publish-ftpmaster.log 2>&1
+02 4 * * * {{ cronscripts_dir }}/generate-contents-files.py -v --distribution=ubuntu >> {{ lp_publish_logs_dir }}/generate-contents-files.log 2>&1
+
+# cprov 20080207: parallel run of death-row, at :10 it will run simultaneously with a-f.
+10 */6 * * * {{ scripts_dir }}/process-death-row.py -d ubuntu -q --log-file=DEBUG:{{ lp_publish_logs_dir }}/process-death-row.log
+
+{% endif -%}
+
+# Catch up with publishing OOPSes that were temporarily spooled to disk due
+# to RabbitMQ being unavailable.
+*/15 * * * * {{ code_dir }}/bin/datedir2amqp --exchange oopses --host {{ rabbitmq_host }} --username {{ rabbitmq_username }} --password {{ rabbitmq_password }} --vhost {{ rabbitmq_vhost }} --repo {{ oopses_dir }} --key ""
+
diff --git a/charm/launchpad-ftpmaster-publisher/templates/launchpad-ftpmaster-publisher-lazr.conf b/charm/launchpad-ftpmaster-publisher/templates/launchpad-ftpmaster-publisher-lazr.conf
new file mode 100644
index 0000000..8178c5f
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/templates/launchpad-ftpmaster-publisher-lazr.conf
@@ -0,0 +1,15 @@
+# Public configuration data.  The contents of this file may be freely shared
+# with developers if needed for debugging.
+
+# A schema's sections, keys, and values are automatically inherited, except
+# for '.optional' sections.  Update this config to override key values.
+# Values are strings, except for numbers that look like ints.  The tokens
+# true, false, and none are treated as True, False, and None.
+
+{% from "macros.j2" import opt -%}
+
+[meta]
+extends: ../launchpad-db-lazr.conf
+
+[archivepublisher]
+run_parts_location: {{ run_parts_location }}
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-publisher/templates/launchpad-ftpmaster-publisher-secrets-lazr.conf b/charm/launchpad-ftpmaster-publisher/templates/launchpad-ftpmaster-publisher-secrets-lazr.conf
new file mode 100644
index 0000000..cbb5a20
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/templates/launchpad-ftpmaster-publisher-secrets-lazr.conf
@@ -0,0 +1,12 @@
+# Public configuration data.  The contents of this file may be freely shared
+# with developers if needed for debugging.
+
+# A schema's sections, keys, and values are automatically inherited, except
+# for '.optional' sections.  Update this config to override key values.
+# Values are strings, except for numbers that look like ints.  The tokens
+# true, false, and none are treated as True, False, and None.
+
+{% from "macros.j2" import opt -%}
+
+[signing]
+{{- opt("client_public_key", client_public_key) }}
diff --git a/charm/launchpad-ftpmaster-publisher/templates/logrotate.conf.j2 b/charm/launchpad-ftpmaster-publisher/templates/logrotate.conf.j2
new file mode 100644
index 0000000..ace92fd
--- /dev/null
+++ b/charm/launchpad-ftpmaster-publisher/templates/logrotate.conf.j2
@@ -0,0 +1,15 @@
+{{ logs_dir }}/lp_publish/*.log
+{
+    rotate 21
+    daily
+    dateext
+    delaycompress
+    compress
+    notifempty
+    missingok
+    create 0644 syslog adm
+    postrotate
+        systemctl reload convoy.service
+    endscript
+}
+
diff --git a/charm/launchpad-ftpmaster-uploader/README.md b/charm/launchpad-ftpmaster-uploader/README.md
new file mode 100644
index 0000000..0c2c211
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/README.md
@@ -0,0 +1,3 @@
+# Launchpad ftpmaster-uploader
+
+This charm runs Launchpad ftpmaster-uploader.
diff --git a/charm/launchpad-ftpmaster-uploader/charmcraft.yaml b/charm/launchpad-ftpmaster-uploader/charmcraft.yaml
new file mode 100644
index 0000000..c52d9f0
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/charmcraft.yaml
@@ -0,0 +1,64 @@
+type: charm
+bases:
+  - build-on:
+    - name: ubuntu
+      channel: "20.04"
+      architectures: [amd64]
+    run-on:
+    - name: ubuntu
+      channel: "20.04"
+      architectures: [amd64]
+parts:
+  charm-wheels:
+    source: https://git.launchpad.net/~ubuntuone-hackers/ols-charm-deps/+git/wheels
+    source-commit: "59b32ae07f98051385c96d6d8e7e02ca4f197fe5"
+    source-submodules: []
+    source-type: git
+    plugin: dump
+    organize:
+      "*": charm-wheels/
+    prime:
+      - "-charm-wheels"
+  ols-layers:
+    source: https://git.launchpad.net/ols-charm-deps
+    source-commit: "56d219f60a293a6c73759b8439ef5fdb11e19d1f"
+    source-submodules: []
+    source-type: git
+    plugin: dump
+    organize:
+      "*": layers/
+    stage:
+      - layers
+    prime:
+      - "-layers"
+  launchpad-layers:
+    after:
+      - ols-layers
+    source: https://git.launchpad.net/launchpad-layers
+    source-commit: "300b0d9fd332c055395fe209512335cea03c7af3"
+    source-submodules: []
+    source-type: git
+    plugin: dump
+    organize:
+      launchpad-base: layers/layer/launchpad-base
+      launchpad-db: layers/layer/launchpad-db
+      launchpad-payload: layers/layer/launchpad-payload
+      upload-queue-processor: layers/interface/upload-queue-processor
+    stage:
+      - layers
+    prime:
+      - "-layers"
+  launchpad-ftpmaster-uploader:
+    after:
+      - charm-wheels
+      - launchpad-layers
+    source: .
+    plugin: reactive
+    build-snaps: [charm]
+    build-packages: [libpq-dev, python3-dev]
+    build-environment:
+      - CHARM_LAYERS_DIR: $CRAFT_STAGE/layers/layer
+      - CHARM_INTERFACES_DIR: $CRAFT_STAGE/layers/interface
+      - PIP_NO_INDEX: "true"
+      - PIP_FIND_LINKS: $CRAFT_STAGE/charm-wheels
+    reactive-charm-build-arguments: [--binary-wheels-from-source]
diff --git a/charm/launchpad-ftpmaster-uploader/config.yaml b/charm/launchpad-ftpmaster-uploader/config.yaml
new file mode 100644
index 0000000..2390ead
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/config.yaml
@@ -0,0 +1,22 @@
+options:
+  active:
+    type: boolean
+    default: true
+    description: If true, enable jobs that may change the database.
+  client_public_key:
+    type: string
+    description: Client public key.
+    default: ""
+  # TEMP
+  build_label:
+    type: string
+    default: 9c952eefa65a8f4d9badef5d3bbbdb3e8e87d25f
+    description: Build label to run.
+  swift_container_name:
+    type: string
+    default: "launchpad-builds"
+    description: TBD
+  swift_storage_url:
+    type: string
+    default: "https://objectstorage.prodstack5.canonical.com/swift/v1/AUTH_318a449e4c8e40e2865c120a597a9644";
+    description: TBD
diff --git a/charm/launchpad-ftpmaster-uploader/layer.yaml b/charm/launchpad-ftpmaster-uploader/layer.yaml
new file mode 100644
index 0000000..8e14af3
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/layer.yaml
@@ -0,0 +1,18 @@
+includes:
+  - layer:launchpad-db
+  - layer:launchpad-payload
+  - interface:upload-queue-processor
+repo: https://git.launchpad.net/launchpad
+options:
+  apt:
+    packages:
+      - nodejs
+      - python3-convoy
+  ols-pg:
+    databases:
+      db:
+        name: launchpad_dev
+        roles:
+          - process_upload
+  launchpad-payload:
+    build_target: build
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-uploader/metadata.yaml b/charm/launchpad-ftpmaster-uploader/metadata.yaml
new file mode 100644
index 0000000..8e83853
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/metadata.yaml
@@ -0,0 +1,22 @@
+name: launchpad-ftpmaster-uploader
+display-name: launchpad-ftpmaster-uploader
+summary: Launchpad ftpmaster-uploader
+maintainer: Colin Watson <cjwatson@xxxxxxxxxxxxx>
+description: |
+  Launchpad is an open source suite of tools that help people and teams
+  to work together on software projects.
+
+  This charm runs a Launchpad ftpmaster-uploader.
+tags:
+  # https://juju.is/docs/charm-metadata#heading--charm-store-fields
+  - network
+series:
+  - focal
+subordinate: false
+requires:
+  session-db:
+    interface: pgsql
+provides:
+  upload-queue-processor:
+    interface: upload-queue-processor
+    scope: container
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-uploader/reactive/launchpad-ftpmaster-uploader.py b/charm/launchpad-ftpmaster-uploader/reactive/launchpad-ftpmaster-uploader.py
new file mode 100644
index 0000000..9b2d7da
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/reactive/launchpad-ftpmaster-uploader.py
@@ -0,0 +1,98 @@
+# Copyright 2023 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+import os.path
+
+from charmhelpers.core import hookenv, host, templating
+from charms.launchpad.base import configure_email, get_service_config
+from charms.launchpad.payload import configure_cron, configure_lazr
+from charms.reactive import (
+    clear_flag,
+    endpoint_from_flag,
+    remove_state,
+    set_flag,
+    set_state,
+    when,
+    when_not,
+    when_not_all,
+)
+from ols import base
+
+
+@when_not_all(
+    "config.set.client_public_key",
+)
+def need_client_public_key():
+    hookenv.status_set("blocked", "client_public_key must be configured")
+
+
+def configure_logrotate(config):
+    hookenv.log("Writing logrotate configuration.")
+    templating.render(
+        "logrotate.conf.j2",
+        "/etc/logrotate.d/launchpad",
+        config,
+        perms=0o644,
+    )
+
+
+@when(
+    "launchpad.db.configured",
+    "launchpad.payload.configured",
+    "config.set.client_public_key",
+)
+@when_not("service.configured")
+def configure():
+    hookenv.log("Configuring ftpmaster uploader")
+    config = get_service_config()
+    config["scripts_dir"] = os.path.join(base.code_dir(), "scripts")
+    host.mkdir(config["scripts_dir"], perms=0o755)
+    config["ubuntu_queue_dir"] = os.path.join(base.base_dir(), "ubuntu-queue")
+    host.mkdir(config["ubuntu_queue_dir"], perms=0o755)
+    config["lp_queue_logs_dir"] = os.path.join(base.logs_dir(), "lp_queue")
+    host.mkdir(config["lp_queue_logs_dir"], perms=0o755)
+
+    configure_lazr(
+        config,
+        "launchpad-ftpmaster-uploader-lazr.conf",
+        "launchpad-ftpmaster-uploader/launchpad-lazr.conf",
+    )
+    configure_lazr(
+        config,
+        "launchpad-ftpmaster-uploader-secrets-lazr.conf",
+        "launchpad-ftpmaster-uploader-secrets-lazr.conf",
+        secret=True,
+    )
+    configure_email(config, "launchpad-ftpmaster-uploader")
+    configure_logrotate(config)
+    configure_cron(config, "crontab.j2")
+    set_state("service.configured")
+
+
+@when("service.configured", "upload-queue-processor.available")
+@when_not("service.txpkgupload-configured")
+def configure_txpkgupload():
+    fsroot = os.path.join(base.base_dir(), "incoming")
+    txpkgupload = endpoint_from_flag("upload-queue-processor.available")
+    txpkgupload.set_config(
+        fsroot=fsroot,
+    )
+    set_flag("service.txpkgupload-configured")
+
+
+@when("service.txpkgupload-configured")
+@when_not_all("service.configured", "upload-queue-processor.available")
+def txpkgupload_deconfigured():
+    hookenv.status_set("blocked", "Txpkgupload not yet configured")
+    clear_flag("service.txpkgupload-configured")
+
+
+@when("service.configured")
+def check_is_running():
+    hookenv.status_set("active", "Ready")
+
+
+@when("service.configured")
+@when_not_all("launchpad.db.configured", "launchpad.payload.configured")
+def deconfigure():
+    remove_state("service.configured")
diff --git a/charm/launchpad-ftpmaster-uploader/templates/crontab.j2 b/charm/launchpad-ftpmaster-uploader/templates/crontab.j2
new file mode 100644
index 0000000..b2c2f44
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/templates/crontab.j2
@@ -0,0 +1,23 @@
+MAILTO={{ cron_mailto }}
+LPCONFIG=ftpmaster
+
+{% if active -%}
+* * * * * {{ scripts_dir }}/process-upload.py -C insecure -q {{ ubuntu_queue_dir }}/  --log-file=DEBUG:{{ lp_queue_logs_dir }}/process-upload.log
+
+# Per bug 62612
+# Files in that directory older than 7 days
+00 00 * * * find {{ ubuntu_queue_dir }}/accepted -maxdepth 1 -type f -mtime +7 -exec rm -f {} \; > /dev/null 2>&1
+# Directories older than 7 days (we want to treat the
+# directories as one distinct unit)
+00 00 * * * find {{ ubuntu_queue_dir }}/accepted -type d -mtime +7 -exec rm -rf {} \; > /dev/null 2>&1
+
+# Other directories older than 6 months
+00 00 * * * find {{ ubuntu_queue_dir }}/failed -maxdepth 1 -type f -mtime +180 -exec rm -f {} \; > /dev/null 2>&1
+00 00 * * * find {{ ubuntu_queue_dir }}/failed -type d -mtime +180 -exec rm -rf {} \; > /dev/null 2>&1
+00 00 * * * find {{ ubuntu_queue_dir }}/rejected -maxdepth 1 -type f -mtime +180 -exec rm -f {} \; > /dev/null 2>&1
+00 00 * * * find {{ ubuntu_queue_dir }}/rejected -type d -mtime +180 -exec rm -rf {} \; > /dev/null 2>&1
+{% endif -%}
+
+# OOPS amqp
+*/15 * * * * {{ code_dir }}/bin/datedir2amqp --exchange oopses --host {{ rabbitmq_host }} --username {{ rabbitmq_username }} --password {{ rabbitmq_password }} --vhost {{ rabbitmq_vhost }} --repo {{ oopses_dir }} --key ""
+
diff --git a/charm/launchpad-ftpmaster-uploader/templates/launchpad-ftpmaster-uploader-lazr.conf b/charm/launchpad-ftpmaster-uploader/templates/launchpad-ftpmaster-uploader-lazr.conf
new file mode 100644
index 0000000..07165b0
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/templates/launchpad-ftpmaster-uploader-lazr.conf
@@ -0,0 +1,12 @@
+# Public configuration data.  The contents of this file may be freely shared
+# with developers if needed for debugging.
+
+# A schema's sections, keys, and values are automatically inherited, except
+# for '.optional' sections.  Update this config to override key values.
+# Values are strings, except for numbers that look like ints.  The tokens
+# true, false, and none are treated as True, False, and None.
+
+{% from "macros.j2" import opt -%}
+
+[meta]
+extends: ../launchpad-db-lazr.conf
diff --git a/charm/launchpad-ftpmaster-uploader/templates/launchpad-ftpmaster-uploader-secrets-lazr.conf b/charm/launchpad-ftpmaster-uploader/templates/launchpad-ftpmaster-uploader-secrets-lazr.conf
new file mode 100644
index 0000000..310ec76
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/templates/launchpad-ftpmaster-uploader-secrets-lazr.conf
@@ -0,0 +1,12 @@
+# Public configuration data.  The contents of this file may be freely shared
+# with developers if needed for debugging.
+
+# A schema's sections, keys, and values are automatically inherited, except
+# for '.optional' sections.  Update this config to override key values.
+# Values are strings, except for numbers that look like ints.  The tokens
+# true, false, and none are treated as True, False, and None.
+
+{% from "macros.j2" import opt -%}
+
+[signing]
+{{- opt("client_public_key", client_public_key) }}
\ No newline at end of file
diff --git a/charm/launchpad-ftpmaster-uploader/templates/logrotate.conf.j2 b/charm/launchpad-ftpmaster-uploader/templates/logrotate.conf.j2
new file mode 100644
index 0000000..09ea3ec
--- /dev/null
+++ b/charm/launchpad-ftpmaster-uploader/templates/logrotate.conf.j2
@@ -0,0 +1,15 @@
+{{ logs_dir }}/lp_queue/*.log
+{
+    rotate 21
+    daily
+    dateext
+    delaycompress
+    compress
+    notifempty
+    missingok
+    create 0644 syslog adm
+    postrotate
+        systemctl reload convoy.service
+    endscript
+}
+