paas-charm 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- paas_charm-0.1.0/PKG-INFO +156 -0
- paas_charm-0.1.0/README.md +138 -0
- paas_charm-0.1.0/pyproject.toml +91 -0
- paas_charm-0.1.0/requirements.txt +4 -0
- paas_charm-0.1.0/setup.cfg +4 -0
- paas_charm-0.1.0/setup.py +5 -0
- paas_charm-0.1.0/src/paas_app_charmer/__init__.py +11 -0
- paas_charm-0.1.0/src/paas_app_charmer/django/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_app_charmer/django/charm.py +10 -0
- paas_charm-0.1.0/src/paas_app_charmer/fastapi/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_app_charmer/fastapi/charm.py +11 -0
- paas_charm-0.1.0/src/paas_app_charmer/flask/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_app_charmer/flask/charm.py +10 -0
- paas_charm-0.1.0/src/paas_app_charmer/go/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_app_charmer/go/charm.py +11 -0
- paas_charm-0.1.0/src/paas_charm/__init__.py +60 -0
- paas_charm-0.1.0/src/paas_charm/_gunicorn/__init__.py +2 -0
- paas_charm-0.1.0/src/paas_charm/_gunicorn/charm.py +46 -0
- paas_charm-0.1.0/src/paas_charm/_gunicorn/webserver.py +212 -0
- paas_charm-0.1.0/src/paas_charm/_gunicorn/workload_config.py +40 -0
- paas_charm-0.1.0/src/paas_charm/_gunicorn/wsgi_app.py +58 -0
- paas_charm-0.1.0/src/paas_charm/app.py +378 -0
- paas_charm-0.1.0/src/paas_charm/charm.py +475 -0
- paas_charm-0.1.0/src/paas_charm/charm_state.py +366 -0
- paas_charm-0.1.0/src/paas_charm/charm_utils.py +66 -0
- paas_charm-0.1.0/src/paas_charm/database_migration.py +128 -0
- paas_charm-0.1.0/src/paas_charm/databases.py +98 -0
- paas_charm-0.1.0/src/paas_charm/django/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_charm/django/charm.py +124 -0
- paas_charm-0.1.0/src/paas_charm/django/cos/grafana_dashboards/django.json +985 -0
- paas_charm-0.1.0/src/paas_charm/django/cos/loki_alert_rules/.gitkeep +0 -0
- paas_charm-0.1.0/src/paas_charm/django/cos/prometheus_alert_rules/django.rule +8 -0
- paas_charm-0.1.0/src/paas_charm/exceptions.py +28 -0
- paas_charm-0.1.0/src/paas_charm/fastapi/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_charm/fastapi/charm.py +106 -0
- paas_charm-0.1.0/src/paas_charm/flask/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_charm/flask/charm.py +87 -0
- paas_charm-0.1.0/src/paas_charm/flask/cos/grafana_dashboards/flask.json +985 -0
- paas_charm-0.1.0/src/paas_charm/flask/cos/loki_alert_rules/.gitkeep +0 -0
- paas_charm-0.1.0/src/paas_charm/flask/cos/prometheus_alert_rules/flask.rule +8 -0
- paas_charm-0.1.0/src/paas_charm/framework.py +50 -0
- paas_charm-0.1.0/src/paas_charm/go/__init__.py +8 -0
- paas_charm-0.1.0/src/paas_charm/go/charm.py +94 -0
- paas_charm-0.1.0/src/paas_charm/go/cos/grafana_dashboards/go.json +664 -0
- paas_charm-0.1.0/src/paas_charm/go/cos/loki_alert_rules/.gitkeep +0 -0
- paas_charm-0.1.0/src/paas_charm/go/cos/prometheus_alert_rules/.gitkeep +0 -0
- paas_charm-0.1.0/src/paas_charm/observability.py +91 -0
- paas_charm-0.1.0/src/paas_charm/rabbitmq.py +221 -0
- paas_charm-0.1.0/src/paas_charm/secret_storage.py +143 -0
- paas_charm-0.1.0/src/paas_charm/utils.py +105 -0
- paas_charm-0.1.0/src/paas_charm.egg-info/PKG-INFO +156 -0
- paas_charm-0.1.0/src/paas_charm.egg-info/SOURCES.txt +53 -0
- paas_charm-0.1.0/src/paas_charm.egg-info/dependency_links.txt +1 -0
- paas_charm-0.1.0/src/paas_charm.egg-info/requires.txt +4 -0
- paas_charm-0.1.0/src/paas_charm.egg-info/top_level.txt +2 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: paas-charm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Companion library for PaaS app charmer.
|
|
5
|
+
Author-email: Canonical IS DevOps team <is-devops-team@canonical.com>
|
|
6
|
+
Project-URL: Repository, https://github.com/canonical/paas-charm
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: cosl
|
|
15
|
+
Requires-Dist: jsonschema<4.20,>=4.19
|
|
16
|
+
Requires-Dist: ops>=2.6
|
|
17
|
+
Requires-Dist: pydantic==2.6.4
|
|
18
|
+
|
|
19
|
+
# PaaS App Charmer
|
|
20
|
+
|
|
21
|
+
Easily deploy and operate your Flask or Django applications and associated
|
|
22
|
+
infrastructure, such as databases and ingress, using open source tooling. This
|
|
23
|
+
lets you focus on creating applications for your users backed with the
|
|
24
|
+
confidence that your operations are taken care of by world class tooling
|
|
25
|
+
developed by Canonical, the creators of Ubuntu.
|
|
26
|
+
|
|
27
|
+
Have you ever created an application and then wanted to deploy it for your users
|
|
28
|
+
only to either be forced to use a proprietary public cloud platform or manage
|
|
29
|
+
the deployment and operations yourself? PaaS App Charmer will take your
|
|
30
|
+
application and create an OCI image using Rockcraft and operations code using
|
|
31
|
+
Charmcraft for you. The full suite of tools is open source so you can see
|
|
32
|
+
exactly how it works and even contribute! After creating the app charm and
|
|
33
|
+
image, you can then deploy your application into any Kubernetes cluster using
|
|
34
|
+
Juju. Need a database? Using Juju you can deploy a range of popular open source
|
|
35
|
+
databases, such as [PostgreSQL](https://charmhub.io/postgresql) or
|
|
36
|
+
[MySQL](https://charmhub.io/mysql), and integrate them with your application
|
|
37
|
+
with a few commands. Need an ingress to serve traffic? Use Juju to deploy and
|
|
38
|
+
integrate a range of ingresses, such as
|
|
39
|
+
[Traefik](https://charmhub.io/traefik-k8s), and expose your application to
|
|
40
|
+
external traffic in seconds.
|
|
41
|
+
|
|
42
|
+
## Getting Started
|
|
43
|
+
|
|
44
|
+
There are 2 requirements for the flask application:
|
|
45
|
+
|
|
46
|
+
* There is a `requirements.txt` file in the project root
|
|
47
|
+
* The WSGI path is `app:app`
|
|
48
|
+
|
|
49
|
+
Make sure that you have the `latest/edge` version of Charmcraft and Rockcraft
|
|
50
|
+
installed:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
sudo snap install charmcraft --channel latest/edge --classic
|
|
54
|
+
sudo snap install rockcraft --channel latest/edge --classic
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Both have the `flask-framework` profile to create the required files
|
|
58
|
+
and include the `flask-framework` extension which will do all the hard
|
|
59
|
+
operational work for you and you just need to fill in some metadata in the
|
|
60
|
+
`rockcraft.yaml` and `charmcraft.yaml` files. To create the necessary files:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
rockcraft init --profile flask-framework
|
|
64
|
+
mkdir charm
|
|
65
|
+
cd charm
|
|
66
|
+
charmcraft init --profile flask-framework
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
After packing the rock and charm using `rockcraft pack` and `charmcraft pack`
|
|
70
|
+
and uploading the rock to a k8s registry, you can juju deploy your flask
|
|
71
|
+
application, integrate it with ingress and start serving traffic to your users!
|
|
72
|
+
|
|
73
|
+
Read the
|
|
74
|
+
[comprehensive getting started tutorial](https://juju.is/docs/sdk/write-your-first-kubernetes-charm-for-a-flask-app)
|
|
75
|
+
for more!
|
|
76
|
+
|
|
77
|
+
Additional resources:
|
|
78
|
+
* [Tutorial to build a rock for a Flask application](https://documentation.ubuntu.com/rockcraft/en/latest/tutorial/flask/)
|
|
79
|
+
* [Charmcraft `flask-framework` reference](https://juju.is/docs/sdk/charmcraft-extension-flask-framework)
|
|
80
|
+
* [Charmcraft `flask-framework` how to guides](https://juju.is/docs/sdk/build-a-paas-charm)
|
|
81
|
+
* [Rockcraft `flask-framework` reference](https://documentation.ubuntu.com/rockcraft/en/latest/reference/extensions/flask-framework/)
|
|
82
|
+
|
|
83
|
+
## Contributing
|
|
84
|
+
|
|
85
|
+
Is there something missing from the PaaS App Charmer framework? PaaS App Charmer
|
|
86
|
+
welcomes contributions! This section covers how to add a new integration and a
|
|
87
|
+
new framework.
|
|
88
|
+
|
|
89
|
+
### Add an Integration
|
|
90
|
+
|
|
91
|
+
There are a few recommended steps to add a new integration which we'll go
|
|
92
|
+
through below.
|
|
93
|
+
|
|
94
|
+
1. Please write a proposal on the
|
|
95
|
+
[charm topic on discourse](https://discourse.charmhub.io/c/charm/41). This
|
|
96
|
+
should cover things like:
|
|
97
|
+
* The integration you intend add
|
|
98
|
+
* For each of the frameworks that PaaS App Charmer supports:
|
|
99
|
+
- The commonly used package(s) to make use of the integration
|
|
100
|
+
- The environment variables, configuration etc. that would be made available
|
|
101
|
+
to the app
|
|
102
|
+
- An example for how to use the integration within an app
|
|
103
|
+
* The proposed implementation in `paas-app`. Take a look at
|
|
104
|
+
[`charm.py`](paas_charm/_gunicorn/charm.py) for `gunicorn` based
|
|
105
|
+
frameworks for integration examples.
|
|
106
|
+
1. Update the
|
|
107
|
+
[reference](https://juju.is/docs/sdk/charmcraft-extension-flask-framework)
|
|
108
|
+
with the new integration
|
|
109
|
+
1. Raise a pull request to this repository adding support for the integration.
|
|
110
|
+
1. Add a commented entry for `requires` to all the relevant Charmcraft
|
|
111
|
+
[templates](https://github.com/canonical/charmcraft/tree/main/charmcraft/templates)
|
|
112
|
+
for the new integration
|
|
113
|
+
|
|
114
|
+
### Add a Framework
|
|
115
|
+
|
|
116
|
+
There are a few recommended steps to add a new framework which we'll go through
|
|
117
|
+
below.
|
|
118
|
+
|
|
119
|
+
1. Please write a proposal on the
|
|
120
|
+
[charm topic on discourse](https://discourse.charmhub.io/c/charm/41). This
|
|
121
|
+
should cover things like:
|
|
122
|
+
* The programming language and framework you are thinking of
|
|
123
|
+
* Create an example `rockcraft.yaml` file and build a working OCI image. To
|
|
124
|
+
see an example for `flask`, install Rockcraft and run
|
|
125
|
+
`rockcraft init --profile flask-framework` and run
|
|
126
|
+
`rockcraft expand-extensions` and inspect the output.
|
|
127
|
+
* Create an example `charmcraft.yaml` file and build a working charm. To see
|
|
128
|
+
an example for `flask`, install Charmcraft and run
|
|
129
|
+
`charmcraft init --profile flask-framework` and run
|
|
130
|
+
`charmcraft expand-extensions` and inspect the output.
|
|
131
|
+
* How the configuration options of the charm map to environment variables,
|
|
132
|
+
configurations or another method of passing the information to the app
|
|
133
|
+
* The requirements and conventions for how users need to configure their app
|
|
134
|
+
to work with PaaS App Charmer
|
|
135
|
+
* Which web server to use
|
|
136
|
+
1. Raise a pull request to [rockcraft](https://github.com/canonical/rockcraft)
|
|
137
|
+
adding a new extension and profile for the framework. This is the flask
|
|
138
|
+
[profile](https://github.com/canonical/rockcraft/blob/fdd2dee18c81b12f25e6624a5a48f9f1ac9fdb90/rockcraft/commands/init.py#L79)
|
|
139
|
+
and
|
|
140
|
+
[extension](https://github.com/canonical/rockcraft/blob/fdd2dee18c81b12f25e6624a5a48f9f1ac9fdb90/rockcraft/extensions/gunicorn.py#L176).
|
|
141
|
+
The OCI image should work standalone, not just with the charm for the
|
|
142
|
+
framework.
|
|
143
|
+
1. Raise a pull request to this repository adding a new parent class that can be
|
|
144
|
+
used by the app charms. The following is the
|
|
145
|
+
[example for flask](./paas_charm/flask/charm.py).
|
|
146
|
+
1. Raise a pull request to
|
|
147
|
+
[charmcraft](https://github.com/canonical/charmcraft) adding a new extension
|
|
148
|
+
and profile for the framework. This is the flask
|
|
149
|
+
[profile](https://github.com/canonical/charmcraft/tree/main/charmcraft/templates/init-flask-framework)
|
|
150
|
+
and
|
|
151
|
+
[extension](https://github.com/canonical/charmcraft/blob/b6baa10566e3f3933cbd42392a0fe62cc79d2b6b/charmcraft/extensions/gunicorn.py#L167).
|
|
152
|
+
1. Write a tutorial and reference documentation for the framework. As an
|
|
153
|
+
example, this is the flask
|
|
154
|
+
[tutorial](https://juju.is/docs/sdk/write-your-first-kubernetes-charm-for-a-flask-app)
|
|
155
|
+
and [reference](https://juju.is/docs/sdk/charmcraft-extension-flask-framework)
|
|
156
|
+
documentation.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# PaaS App Charmer
|
|
2
|
+
|
|
3
|
+
Easily deploy and operate your Flask or Django applications and associated
|
|
4
|
+
infrastructure, such as databases and ingress, using open source tooling. This
|
|
5
|
+
lets you focus on creating applications for your users backed with the
|
|
6
|
+
confidence that your operations are taken care of by world class tooling
|
|
7
|
+
developed by Canonical, the creators of Ubuntu.
|
|
8
|
+
|
|
9
|
+
Have you ever created an application and then wanted to deploy it for your users
|
|
10
|
+
only to either be forced to use a proprietary public cloud platform or manage
|
|
11
|
+
the deployment and operations yourself? PaaS App Charmer will take your
|
|
12
|
+
application and create an OCI image using Rockcraft and operations code using
|
|
13
|
+
Charmcraft for you. The full suite of tools is open source so you can see
|
|
14
|
+
exactly how it works and even contribute! After creating the app charm and
|
|
15
|
+
image, you can then deploy your application into any Kubernetes cluster using
|
|
16
|
+
Juju. Need a database? Using Juju you can deploy a range of popular open source
|
|
17
|
+
databases, such as [PostgreSQL](https://charmhub.io/postgresql) or
|
|
18
|
+
[MySQL](https://charmhub.io/mysql), and integrate them with your application
|
|
19
|
+
with a few commands. Need an ingress to serve traffic? Use Juju to deploy and
|
|
20
|
+
integrate a range of ingresses, such as
|
|
21
|
+
[Traefik](https://charmhub.io/traefik-k8s), and expose your application to
|
|
22
|
+
external traffic in seconds.
|
|
23
|
+
|
|
24
|
+
## Getting Started
|
|
25
|
+
|
|
26
|
+
There are 2 requirements for the flask application:
|
|
27
|
+
|
|
28
|
+
* There is a `requirements.txt` file in the project root
|
|
29
|
+
* The WSGI path is `app:app`
|
|
30
|
+
|
|
31
|
+
Make sure that you have the `latest/edge` version of Charmcraft and Rockcraft
|
|
32
|
+
installed:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
sudo snap install charmcraft --channel latest/edge --classic
|
|
36
|
+
sudo snap install rockcraft --channel latest/edge --classic
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Both have the `flask-framework` profile to create the required files
|
|
40
|
+
and include the `flask-framework` extension which will do all the hard
|
|
41
|
+
operational work for you and you just need to fill in some metadata in the
|
|
42
|
+
`rockcraft.yaml` and `charmcraft.yaml` files. To create the necessary files:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
rockcraft init --profile flask-framework
|
|
46
|
+
mkdir charm
|
|
47
|
+
cd charm
|
|
48
|
+
charmcraft init --profile flask-framework
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
After packing the rock and charm using `rockcraft pack` and `charmcraft pack`
|
|
52
|
+
and uploading the rock to a k8s registry, you can juju deploy your flask
|
|
53
|
+
application, integrate it with ingress and start serving traffic to your users!
|
|
54
|
+
|
|
55
|
+
Read the
|
|
56
|
+
[comprehensive getting started tutorial](https://juju.is/docs/sdk/write-your-first-kubernetes-charm-for-a-flask-app)
|
|
57
|
+
for more!
|
|
58
|
+
|
|
59
|
+
Additional resources:
|
|
60
|
+
* [Tutorial to build a rock for a Flask application](https://documentation.ubuntu.com/rockcraft/en/latest/tutorial/flask/)
|
|
61
|
+
* [Charmcraft `flask-framework` reference](https://juju.is/docs/sdk/charmcraft-extension-flask-framework)
|
|
62
|
+
* [Charmcraft `flask-framework` how to guides](https://juju.is/docs/sdk/build-a-paas-charm)
|
|
63
|
+
* [Rockcraft `flask-framework` reference](https://documentation.ubuntu.com/rockcraft/en/latest/reference/extensions/flask-framework/)
|
|
64
|
+
|
|
65
|
+
## Contributing
|
|
66
|
+
|
|
67
|
+
Is there something missing from the PaaS App Charmer framework? PaaS App Charmer
|
|
68
|
+
welcomes contributions! This section covers how to add a new integration and a
|
|
69
|
+
new framework.
|
|
70
|
+
|
|
71
|
+
### Add an Integration
|
|
72
|
+
|
|
73
|
+
There are a few recommended steps to add a new integration which we'll go
|
|
74
|
+
through below.
|
|
75
|
+
|
|
76
|
+
1. Please write a proposal on the
|
|
77
|
+
[charm topic on discourse](https://discourse.charmhub.io/c/charm/41). This
|
|
78
|
+
should cover things like:
|
|
79
|
+
* The integration you intend add
|
|
80
|
+
* For each of the frameworks that PaaS App Charmer supports:
|
|
81
|
+
- The commonly used package(s) to make use of the integration
|
|
82
|
+
- The environment variables, configuration etc. that would be made available
|
|
83
|
+
to the app
|
|
84
|
+
- An example for how to use the integration within an app
|
|
85
|
+
* The proposed implementation in `paas-app`. Take a look at
|
|
86
|
+
[`charm.py`](paas_charm/_gunicorn/charm.py) for `gunicorn` based
|
|
87
|
+
frameworks for integration examples.
|
|
88
|
+
1. Update the
|
|
89
|
+
[reference](https://juju.is/docs/sdk/charmcraft-extension-flask-framework)
|
|
90
|
+
with the new integration
|
|
91
|
+
1. Raise a pull request to this repository adding support for the integration.
|
|
92
|
+
1. Add a commented entry for `requires` to all the relevant Charmcraft
|
|
93
|
+
[templates](https://github.com/canonical/charmcraft/tree/main/charmcraft/templates)
|
|
94
|
+
for the new integration
|
|
95
|
+
|
|
96
|
+
### Add a Framework
|
|
97
|
+
|
|
98
|
+
There are a few recommended steps to add a new framework which we'll go through
|
|
99
|
+
below.
|
|
100
|
+
|
|
101
|
+
1. Please write a proposal on the
|
|
102
|
+
[charm topic on discourse](https://discourse.charmhub.io/c/charm/41). This
|
|
103
|
+
should cover things like:
|
|
104
|
+
* The programming language and framework you are thinking of
|
|
105
|
+
* Create an example `rockcraft.yaml` file and build a working OCI image. To
|
|
106
|
+
see an example for `flask`, install Rockcraft and run
|
|
107
|
+
`rockcraft init --profile flask-framework` and run
|
|
108
|
+
`rockcraft expand-extensions` and inspect the output.
|
|
109
|
+
* Create an example `charmcraft.yaml` file and build a working charm. To see
|
|
110
|
+
an example for `flask`, install Charmcraft and run
|
|
111
|
+
`charmcraft init --profile flask-framework` and run
|
|
112
|
+
`charmcraft expand-extensions` and inspect the output.
|
|
113
|
+
* How the configuration options of the charm map to environment variables,
|
|
114
|
+
configurations or another method of passing the information to the app
|
|
115
|
+
* The requirements and conventions for how users need to configure their app
|
|
116
|
+
to work with PaaS App Charmer
|
|
117
|
+
* Which web server to use
|
|
118
|
+
1. Raise a pull request to [rockcraft](https://github.com/canonical/rockcraft)
|
|
119
|
+
adding a new extension and profile for the framework. This is the flask
|
|
120
|
+
[profile](https://github.com/canonical/rockcraft/blob/fdd2dee18c81b12f25e6624a5a48f9f1ac9fdb90/rockcraft/commands/init.py#L79)
|
|
121
|
+
and
|
|
122
|
+
[extension](https://github.com/canonical/rockcraft/blob/fdd2dee18c81b12f25e6624a5a48f9f1ac9fdb90/rockcraft/extensions/gunicorn.py#L176).
|
|
123
|
+
The OCI image should work standalone, not just with the charm for the
|
|
124
|
+
framework.
|
|
125
|
+
1. Raise a pull request to this repository adding a new parent class that can be
|
|
126
|
+
used by the app charms. The following is the
|
|
127
|
+
[example for flask](./paas_charm/flask/charm.py).
|
|
128
|
+
1. Raise a pull request to
|
|
129
|
+
[charmcraft](https://github.com/canonical/charmcraft) adding a new extension
|
|
130
|
+
and profile for the framework. This is the flask
|
|
131
|
+
[profile](https://github.com/canonical/charmcraft/tree/main/charmcraft/templates/init-flask-framework)
|
|
132
|
+
and
|
|
133
|
+
[extension](https://github.com/canonical/charmcraft/blob/b6baa10566e3f3933cbd42392a0fe62cc79d2b6b/charmcraft/extensions/gunicorn.py#L167).
|
|
134
|
+
1. Write a tutorial and reference documentation for the framework. As an
|
|
135
|
+
example, this is the flask
|
|
136
|
+
[tutorial](https://juju.is/docs/sdk/write-your-first-kubernetes-charm-for-a-flask-app)
|
|
137
|
+
and [reference](https://juju.is/docs/sdk/charmcraft-extension-flask-framework)
|
|
138
|
+
documentation.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Copyright 2024 Canonical Ltd.
|
|
2
|
+
# See LICENSE file for licensing details.
|
|
3
|
+
[project]
|
|
4
|
+
name = "paas-charm"
|
|
5
|
+
version = "0.1.0"
|
|
6
|
+
description = "Companion library for PaaS app charmer."
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Canonical IS DevOps team", email="is-devops-team@canonical.com"},
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dynamic = ["dependencies"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: Apache Software License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Repository = "https://github.com/canonical/paas-charm"
|
|
24
|
+
|
|
25
|
+
[tool.setuptools.dynamic]
|
|
26
|
+
dependencies = {file = ["requirements.txt"]}
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.package-data]
|
|
29
|
+
paas_charm = ["**/cos/**", "**/cos/**/.**"]
|
|
30
|
+
|
|
31
|
+
# Testing tools configuration
|
|
32
|
+
[tool.coverage.run]
|
|
33
|
+
branch = true
|
|
34
|
+
|
|
35
|
+
[tool.coverage.report]
|
|
36
|
+
fail_under = 90
|
|
37
|
+
show_missing = true
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
minversion = "6.0"
|
|
41
|
+
log_cli_level = "INFO"
|
|
42
|
+
|
|
43
|
+
# Formatting tools configuration
|
|
44
|
+
[tool.black]
|
|
45
|
+
line-length = 99
|
|
46
|
+
target-version = ["py38"]
|
|
47
|
+
extend-exclude = '''
|
|
48
|
+
|
|
49
|
+
(
|
|
50
|
+
examples/flask/lib/.*
|
|
51
|
+
| examples/django/charm/lib/.*
|
|
52
|
+
| examples/fastapi/charm/lib/.*
|
|
53
|
+
| examples/go/charm/lib/.*
|
|
54
|
+
)
|
|
55
|
+
'''
|
|
56
|
+
|
|
57
|
+
[tool.isort]
|
|
58
|
+
line_length = 99
|
|
59
|
+
profile = "black"
|
|
60
|
+
|
|
61
|
+
# Linting tools configuration
|
|
62
|
+
[tool.flake8]
|
|
63
|
+
max-line-length = 99
|
|
64
|
+
max-doc-length = 99
|
|
65
|
+
max-complexity = 10
|
|
66
|
+
exclude = [".git", "__pycache__", ".tox", "build", "dist", "*.egg_info", "venv", "examples/*/lib/**"]
|
|
67
|
+
select = ["E", "W", "F", "C", "N", "R", "D", "H"]
|
|
68
|
+
# Ignore W503, E501 because using black creates errors with this
|
|
69
|
+
# Ignore D107 Missing docstring in __init__
|
|
70
|
+
ignore = ["W503", "E501", "D107"]
|
|
71
|
+
# D100, D101, D102, D103: Ignore missing docstrings in tests
|
|
72
|
+
per-file-ignores = [
|
|
73
|
+
"tests/*:D100,D101,D102,D103,D104,D205,D212,D415,DCO020,DCO030,DCO050",
|
|
74
|
+
]
|
|
75
|
+
docstring-convention = "google"
|
|
76
|
+
# Check for properly formatted copyright header in each file
|
|
77
|
+
copyright-check = "True"
|
|
78
|
+
copyright-author = "Canonical Ltd."
|
|
79
|
+
copyright-regexp = "Copyright\\s\\d{4}([-,]\\d{4})*\\s+%(author)s"
|
|
80
|
+
|
|
81
|
+
[tool.bandit]
|
|
82
|
+
exclude_dirs = ["venv/", "tests/"]
|
|
83
|
+
|
|
84
|
+
[tool.mypy]
|
|
85
|
+
ignore_missing_imports = true
|
|
86
|
+
check_untyped_defs = true
|
|
87
|
+
disallow_untyped_defs = true
|
|
88
|
+
|
|
89
|
+
[[tool.mypy.overrides]]
|
|
90
|
+
module = "tests.*"
|
|
91
|
+
disallow_untyped_defs = false
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Copyright 2024 Canonical Ltd.
|
|
2
|
+
# See LICENSE file for licensing details.
|
|
3
|
+
|
|
4
|
+
"""Deprecated entrypoints for charms.
|
|
5
|
+
|
|
6
|
+
This module can be removed when paas_charm>=2.0
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
warnings.warn("paas_app_charmer package is deprecated", DeprecationWarning, stacklevel=2)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright 2024 Canonical Ltd.
|
|
4
|
+
# See LICENSE file for licensing details.
|
|
5
|
+
|
|
6
|
+
"""Module __init__."""
|
|
7
|
+
|
|
8
|
+
from paas_charm import exceptions
|
|
9
|
+
|
|
10
|
+
# Try the charm library imports to check whether they are present
|
|
11
|
+
try:
|
|
12
|
+
import charms.traefik_k8s.v2.ingress # noqa: F401
|
|
13
|
+
except ImportError as import_error:
|
|
14
|
+
raise exceptions.MissingCharmLibraryError(
|
|
15
|
+
"Missing charm library, please run `charmcraft fetch-lib charms.traefik_k8s.v2.ingress`"
|
|
16
|
+
) from import_error
|
|
17
|
+
try:
|
|
18
|
+
import charms.observability_libs.v0.juju_topology # noqa: F401
|
|
19
|
+
except ImportError as import_error:
|
|
20
|
+
raise exceptions.MissingCharmLibraryError(
|
|
21
|
+
"Missing charm library, please run "
|
|
22
|
+
"`charmcraft fetch-lib charms.observability_libs.v0.juju_topology`"
|
|
23
|
+
) from import_error
|
|
24
|
+
try:
|
|
25
|
+
import charms.grafana_k8s.v0.grafana_dashboard # noqa: F401
|
|
26
|
+
except ImportError as import_error:
|
|
27
|
+
raise exceptions.MissingCharmLibraryError(
|
|
28
|
+
"Missing charm library, please run "
|
|
29
|
+
"`charmcraft fetch-lib charms.grafana_k8s.v0.grafana_dashboard`"
|
|
30
|
+
) from import_error
|
|
31
|
+
try:
|
|
32
|
+
import charms.loki_k8s.v1.loki_push_api # noqa: F401
|
|
33
|
+
except ImportError as import_error:
|
|
34
|
+
try:
|
|
35
|
+
import charms.loki_k8s.v0.loki_push_api # noqa: F401
|
|
36
|
+
except ImportError:
|
|
37
|
+
raise exceptions.MissingCharmLibraryError(
|
|
38
|
+
"Missing charm library, please run "
|
|
39
|
+
"`charmcraft fetch-lib charms.loki_k8s.v1.loki_push_api`"
|
|
40
|
+
) from import_error
|
|
41
|
+
try:
|
|
42
|
+
import charms.prometheus_k8s.v0.prometheus_scrape # noqa: F401
|
|
43
|
+
except ImportError as import_error:
|
|
44
|
+
raise exceptions.MissingCharmLibraryError(
|
|
45
|
+
"Missing charm library, please run "
|
|
46
|
+
"`charmcraft fetch-lib charms.prometheus_k8s.v0.prometheus_scrape`"
|
|
47
|
+
) from import_error
|
|
48
|
+
try:
|
|
49
|
+
import charms.data_platform_libs.v0.data_interfaces # noqa: F401
|
|
50
|
+
except ImportError as import_error:
|
|
51
|
+
raise exceptions.MissingCharmLibraryError(
|
|
52
|
+
"Missing charm library, please run "
|
|
53
|
+
"`charmcraft fetch-lib charms.data_platform_libs.v0.data_interfaces`"
|
|
54
|
+
) from import_error
|
|
55
|
+
try:
|
|
56
|
+
import charms.redis_k8s.v0.redis # noqa: F401
|
|
57
|
+
except ImportError as import_error:
|
|
58
|
+
raise exceptions.MissingCharmLibraryError(
|
|
59
|
+
"Missing charm library, please run `charmcraft fetch-lib charms.redis_k8s.v0.redis`"
|
|
60
|
+
) from import_error
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright 2024 Canonical Ltd.
|
|
2
|
+
# See LICENSE file for licensing details.
|
|
3
|
+
|
|
4
|
+
"""The base charm class for all charms."""
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from paas_charm._gunicorn.webserver import GunicornWebserver, WebserverConfig
|
|
8
|
+
from paas_charm._gunicorn.workload_config import create_workload_config
|
|
9
|
+
from paas_charm._gunicorn.wsgi_app import WsgiApp
|
|
10
|
+
from paas_charm.app import App, WorkloadConfig
|
|
11
|
+
from paas_charm.charm import PaasCharm
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GunicornBase(PaasCharm):
|
|
17
|
+
"""Gunicorn-based charm service mixin."""
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def _workload_config(self) -> WorkloadConfig:
|
|
21
|
+
"""Return a WorkloadConfig instance."""
|
|
22
|
+
return create_workload_config(
|
|
23
|
+
framework_name=self._framework_name, unit_name=self.unit.name
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
def _create_app(self) -> App:
|
|
27
|
+
"""Build an App instance for the Gunicorn based charm.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
A new App instance.
|
|
31
|
+
"""
|
|
32
|
+
charm_state = self._create_charm_state()
|
|
33
|
+
|
|
34
|
+
webserver = GunicornWebserver(
|
|
35
|
+
webserver_config=WebserverConfig.from_charm_config(dict(self.config)),
|
|
36
|
+
workload_config=self._workload_config,
|
|
37
|
+
container=self.unit.get_container(self._workload_config.container_name),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return WsgiApp(
|
|
41
|
+
container=self._container,
|
|
42
|
+
charm_state=charm_state,
|
|
43
|
+
workload_config=self._workload_config,
|
|
44
|
+
webserver=webserver,
|
|
45
|
+
database_migration=self._database_migration,
|
|
46
|
+
)
|