Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add NGINX rock #9

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .licenserc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ header:
paths-ignore:
- '.github/**'
- '.trivyignore'
- '**/*.conf'
- '**/*.json'
- '**/*.md'
- '**/*.txt'
Expand Down
5 changes: 5 additions & 0 deletions charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@ resources:
maubot-image:
type: oci-image
description: OCI image for maubot
maubot-nginx-image:
type: oci-image
description: OCI image for nginx Maubot

containers:
maubot:
resource: maubot-image
maubot-nginx:
resource: maubot-nginx-image

type: charm
base: [email protected]
Expand Down
70 changes: 70 additions & 0 deletions nginx_rock/etc/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
user nginx nginx;
daemon off;

events {
worker_connections 1024;
}
http {
include mime.types;
server_tokens off;

gzip on;
gzip_disable "msie6";
gzip_min_length 256;

gzip_proxied any;
gzip_http_version 1.1;
gzip_types
application/font-woff
application/font-woff2
application/x-javascript
application/xml
application/xml+rss
image/png

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: probably don't need to compress PNG files.

image/x-icon
font/woff2
text/css
text/javascript
text/plain
text/xml;

add_header X-Content-Type-Options 'nosniff';
add_header X-Frame-Options 'SAMEORIGIN';
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header X-XSS-Protection "1; mode=block";

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$http_x_forwarded_proto"';
access_log /var/log/nginx/access.log main;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the access log should be logged to stdout, as the error log is logged to stderr?


map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}

server {
listen 8080;
listen [::]:8080;
error_log stderr error;

location / {
root /var/empty/nginx;
proxy_hide_header Cache-Control;
add_header Cache-Control 'no-cache,private';
include common_headers.conf;
client_max_body_size 0;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:29316;
}

location /health {
access_log off;
add_header 'Content-Type' 'application/json';
return 204;
}

}
}
35 changes: 35 additions & 0 deletions nginx_rock/rockcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.

name: maubot-nginx
summary: maubot nginx rock
description: Nginx OCI image for the maubot charm
version: "1.0"
base: [email protected]
build-base: [email protected]
license: Apache-2.0
platforms:
amd64:
parts:
add-user:
plugin: nil
overlay-script: |
chmod 755 $CRAFT_OVERLAY/etc
groupadd -R $CRAFT_OVERLAY --gid 2000 nginx
useradd -R $CRAFT_OVERLAY --system --gid 2000 --uid 2000 --no-create-home nginx
nginx-conf:
plugin: dump
source: etc
organize:
nginx.conf: etc/nginx/nginx.conf
nginx:
stage-packages:
- logrotate
- nginx
plugin: nil
override-build: |
craftctl default
rm $CRAFT_PART_INSTALL/etc/nginx/nginx.conf
override-prime: |
craftctl default
mkdir run
3 changes: 2 additions & 1 deletion src-docs/charm.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ Maubot charm service.
---------------
- **MAUBOT_SERVICE_NAME**
- **MAUBOT_CONTAINER_NAME**
- **NGINX_NAME**


---

## <kbd>class</kbd> `MaubotCharm`
Maubot charm.

<a href="../src/charm.py#L25"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm.py#L26"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

Expand Down
29 changes: 29 additions & 0 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

MAUBOT_SERVICE_NAME = "maubot"
MAUBOT_CONTAINER_NAME = "maubot"
NGINX_NAME = "maubot-nginx"


class MaubotCharm(ops.CharmBase):
Expand All @@ -30,6 +31,9 @@ def __init__(self, *args: typing.Any):
"""
super().__init__(*args)
self.framework.observe(self.on.maubot_pebble_ready, self._on_maubot_pebble_ready)
self.framework.observe(
self.on.maubot_nginx_pebble_ready, self._on_maubot_nginx_pebble_ready
)
self.framework.observe(self.on.config_changed, self._on_config_changed)

def _on_maubot_pebble_ready(self, _: ops.PebbleReadyEvent) -> None:
Expand All @@ -51,6 +55,15 @@ def _on_config_changed(self, _: ops.ConfigChangedEvent) -> None:
container.replan()
self.unit.status = ops.ActiveStatus()

def _on_maubot_nginx_pebble_ready(self, _: ops.PebbleReadyEvent) -> None:
"""Handle nginx pebble ready event."""
container = self.unit.get_container(NGINX_NAME)
if not container.can_connect():
return
container.add_layer(NGINX_NAME, self._nginx_pebble_layer, combine=True)
container.replan()
self.unit.status = ops.ActiveStatus()

@property
def _pebble_layer(self) -> pebble.LayerDict:
"""Return a dictionary representing a Pebble layer."""
Expand All @@ -67,6 +80,22 @@ def _pebble_layer(self) -> pebble.LayerDict:
},
}

@property
def _nginx_pebble_layer(self) -> pebble.LayerDict:
"""Return a dictionary representing a Pebble layer."""
return {
"summary": "Maubot NGINX layer",
"description": "Maubot NGINX layer",
"services": {
NGINX_NAME: {
"override": "replace",
"summary": "Maubot NGINX service",
"command": "/usr/sbin/nginx",
"startup": "enabled",
},
},
}


if __name__ == "__main__": # pragma: nocover
ops.main.main(MaubotCharm)
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ def pytest_addoption(parser):
"""
parser.addoption("--charm-file", action="store")
parser.addoption("--maubot-image", action="store")
parser.addoption("--maubot-nginx-image", action="store")
29 changes: 28 additions & 1 deletion tests/unit/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,41 @@ def test_maubot_pebble_ready(self):
"summary": "maubot",
"command": "bash -c \"python3 -c 'import maubot'; sleep 10\"",
"startup": "enabled",
}
},
},
}

self.harness.container_pebble_ready("maubot")
self.harness.container_pebble_ready("maubot-nginx")

updated_plan = self.harness.get_container_pebble_plan("maubot").to_dict()
self.assertEqual(expected_plan, updated_plan)
service = self.harness.model.unit.get_container("maubot").get_service("maubot")
self.assertTrue(service.is_running())
self.assertEqual(self.harness.model.unit.status, ops.ActiveStatus())

def test_maubot_nginx_pebble_ready(self):
"""
arrange: initialize the testing harness.
act: retrieve the pebble plan for maubot nginx.
assert: ensure the maubot nginx pebble plan matches the expectations,
the service is running and the charm is active.
"""
expected_plan = {
"services": {
"maubot-nginx": {
"override": "replace",
"summary": "Maubot NGINX service",
"command": "/usr/sbin/nginx",
"startup": "enabled",
},
},
}

self.harness.container_pebble_ready("maubot-nginx")

updated_plan = self.harness.get_container_pebble_plan("maubot-nginx").to_dict()
self.assertEqual(expected_plan, updated_plan)
service = self.harness.model.unit.get_container("maubot-nginx").get_service("maubot-nginx")
self.assertTrue(service.is_running())
self.assertEqual(self.harness.model.unit.status, ops.ActiveStatus())
Loading