forked from pulp/pulpcore
/
status.py
139 lines (119 loc) · 4.31 KB
/
status.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import logging
import shutil
from gettext import gettext as _
from django.conf import settings
from django.db.models import Sum
from drf_spectacular.utils import extend_schema
from rest_framework.response import Response
from rest_framework.views import APIView
from collections import namedtuple
from pulpcore.app.apps import pulp_plugin_configs
from pulpcore.app.models.content import Artifact
from pulpcore.app.models.status import ApiAppStatus, ContentAppStatus
from pulpcore.app.models.task import Worker
from pulpcore.app.serializers.status import StatusSerializer
from pulpcore.app.redis_connection import get_redis_connection
from pulpcore.app.util import get_domain
_logger = logging.getLogger(__name__)
StorageSpace = namedtuple("StorageSpace", ("total", "used", "free"))
def _disk_usage():
domain = get_domain()
if domain.storage_class == "pulpcore.app.models.storage.FileSystem":
storage = domain.get_storage()
try:
return shutil.disk_usage(storage.location)
except Exception:
_logger.exception(_("Failed to determine disk usage"))
else:
used = Artifact.objects.filter(pulp_domain=domain).aggregate(
size=Sum("size", default=0)
)["size"]
return StorageSpace(None, used, None)
class StatusView(APIView):
"""
Returns status information about the application
"""
# allow anyone to access the status api
authentication_classes = []
permission_classes = []
@extend_schema(
summary="Inspect status of Pulp",
operation_id="status_read",
responses={200: StatusSerializer},
)
def get(self, request):
"""
Returns status and app information about Pulp.
Information includes:
* version of pulpcore and loaded pulp plugins
* known workers
* known content apps
* database connection status
* redis connection status
* disk usage information
"""
versions = []
for app in pulp_plugin_configs():
versions.append(
{
"component": app.label,
"version": app.version,
"package": app.python_package_name,
"domain_compatible": getattr(app, "domain_compatible", False),
}
)
if settings.CACHE_ENABLED:
redis_status = {"connected": self._get_redis_conn_status()}
else:
redis_status = {"connected": False}
db_status = {"connected": self._get_db_conn_status()}
online_workers = Worker.objects.online()
online_api_apps = ApiAppStatus.objects.online()
online_content_apps = ContentAppStatus.objects.online()
content_settings = {
"content_origin": settings.CONTENT_ORIGIN,
"content_path_prefix": settings.CONTENT_PATH_PREFIX,
}
data = {
"versions": versions,
"online_workers": online_workers,
"online_api_apps": online_api_apps,
"online_content_apps": online_content_apps,
"database_connection": db_status,
"redis_connection": redis_status,
"storage": _disk_usage(),
"content_settings": content_settings,
"domain_enabled": settings.DOMAIN_ENABLED,
}
context = {"request": request}
serializer = StatusSerializer(data, context=context)
return Response(serializer.data)
@staticmethod
def _get_db_conn_status():
"""
Returns True if pulp is connected to the database
Returns:
bool: True if there's a db connection. False otherwise.
"""
try:
Worker.objects.count()
except Exception:
_logger.exception(_("Cannot connect to database during status check."))
return False
else:
return True
@staticmethod
def _get_redis_conn_status():
"""
Returns True if pulp can connect to Redis
Returns:
bool: True if pulp can connect to Redis. False otherwise.
"""
conn = get_redis_connection()
try:
conn.ping()
except Exception:
_logger.error(_("Connection to Redis failed during status check!"))
return False
else:
return True