Skip to content

Commit b6459dd

Browse files
authored
Merge pull request #202 from mendix/buildpack-2.2
Buildpack 2.2
2 parents 749d516 + 71ae848 commit b6459dd

3 files changed

Lines changed: 124 additions & 11 deletions

File tree

lib/instadeploy.py

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
from http.server import BaseHTTPRequestHandler, HTTPServer
21
import cgi
32
import json
4-
import shutil
5-
import time
63
import logging
7-
import mxbuild
84
import os
9-
from m2ee import logger
10-
import traceback
5+
import shutil
6+
import subprocess
117
import threading
12-
import buildpackutil
8+
import time
9+
import traceback
10+
from http.server import BaseHTTPRequestHandler, HTTPServer
11+
from urllib.parse import urljoin
12+
1313
import requests
14-
import subprocess
1514

15+
import buildpackutil
16+
import mxbuild
17+
from m2ee import logger
1618

1719
ROOT_DIR = os.getcwd() + "/"
1820
MXBUILD_FOLDER = ROOT_DIR + "mxbuild/"
@@ -24,6 +26,8 @@
2426
INTERMEDIATE_MPK_DIR = ".local/tmp_project_2"
2527
MPK_FILE = os.path.join(PROJECT_DIR, "app.mpk")
2628

29+
INSTADEPLOY_FEEDBACK_PATH = "api/1/environments/{app_id}/instadeployfeedback"
30+
2731
for directory in (
2832
MXBUILD_FOLDER,
2933
PROJECT_DIR,
@@ -233,6 +237,13 @@ def build():
233237
"Syncing project files failed: %s", traceback.format_exc()
234238
)
235239
raise
240+
try:
241+
send_metadata_to_cloudportal()
242+
except Exception:
243+
logger.warning(
244+
"Failed to send instadeploy feedback to Cloud Portal",
245+
exc_info=True,
246+
)
236247
else:
237248
logger.warning("Not syncing project files. MxBuild result: %s", result)
238249

@@ -261,3 +272,26 @@ def extract_mxbuild_response(mxbuild_response):
261272
if "message" in mxbuild_response:
262273
r["message"] = mxbuild_response["message"]
263274
return r
275+
276+
277+
def send_metadata_to_cloudportal():
278+
required_variables = ("CLOUD_PORTAL_LOCATION", "ENVIRONMENT_SIGNATURE")
279+
280+
if not all([v in os.environ for v in required_variables]):
281+
logger.info(
282+
"Required environment variables for intadeploy feedback "
283+
"are missing. Skipping instadeploy feedback."
284+
)
285+
return
286+
287+
app_id = json.loads(os.environ["VCAP_APPLICATION"])["name"]
288+
target_path = INSTADEPLOY_FEEDBACK_PATH.format(app_id=app_id)
289+
target_url = urljoin(os.environ["CLOUD_PORTAL_LOCATION"], target_path)
290+
291+
with open("/home/vcap/app/model/metadata.json", "rb") as metadata_json:
292+
files = {"file": metadata_json}
293+
headers = {
294+
"Mendix-Environment-Signature": os.environ["ENVIRONMENT_SIGNATURE"]
295+
}
296+
# We don't care about the response.
297+
requests.post(target_url, files=files, headers=headers)

lib/metrics.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import threading
66
import time
7+
78
from abc import ABCMeta, abstractmethod
89

910
BUILDPACK_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
@@ -157,7 +158,6 @@ def _inject_health(self, stats):
157158
logger.warn("Metrics: Failed to get health status, " + str(e))
158159
health["health"] = translation["critical"]
159160
health["diagnosis"] = "Health check failed unexpectedly: %s" % e
160-
161161
return stats
162162

163163
def _inject_m2ee_stats(self, stats):
@@ -285,6 +285,25 @@ def _get_number_of_files(self):
285285
raise Exception("Unexpected result from database query")
286286
return int(rows[0][0])
287287

288+
def _get_size_of_files(self):
289+
conn = self._get_db_conn()
290+
with conn.cursor() as cursor:
291+
try:
292+
cursor.execute(
293+
"SELECT sum(size) from system$filedocument WHERE hascontents=true;"
294+
)
295+
rows = cursor.fetchall()
296+
if len(rows) == 0:
297+
return 0
298+
return int(rows[0][0])
299+
except Exception as e:
300+
# We ignore errors here, as the information is not available for
301+
# older mendix versions
302+
logger.debug(
303+
"METRICS: Error retrieving file sizes", exc_info=True
304+
)
305+
return 0
306+
288307
def _get_db_conn(self):
289308
if self.db and self.db.closed != 0:
290309
self.db.close()

start.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
#!/usr/bin/env python3
22
import atexit
33
import base64
4+
import codecs
45
import datetime
6+
import itertools
57
import json
68
import logging
79
import os
810
import re
911
import signal
1012
import subprocess
1113
import sys
14+
import threading
1215
import time
1316
import traceback
1417
import uuid
@@ -24,8 +27,32 @@
2427
from nginx import get_path_config, gen_htpasswd # noqa: E402
2528
from buildpackutil import i_am_primary_instance # noqa: E402
2629

30+
HEARTBEAT_SOURCE_STRING = """Gur Mra bs Clguba, ol Gvz Crgref
31+
Ornhgvshy vf orggre guna htyl.
32+
Rkcyvpvg vf orggre guna vzcyvpvg.
33+
Fvzcyr vf orggre guna pbzcyrk.
34+
Pbzcyrk vf orggre guna pbzcyvpngrq.
35+
Syng vf orggre guna arfgrq.
36+
Fcnefr vf orggre guna qrafr.
37+
Ernqnovyvgl pbhagf.
38+
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
39+
Nygubhtu cenpgvpnyvgl orngf chevgl.
40+
Reebef fubhyq arire cnff fvyragyl.
41+
Hayrff rkcyvpvgyl fvyraprq.
42+
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
43+
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
44+
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
45+
Abj vf orggre guna arire.
46+
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
47+
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
48+
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
49+
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""
50+
HEARTBEAT_STRING_LIST = codecs.encode(HEARTBEAT_SOURCE_STRING, "rot13").split(
51+
"\n"
52+
)
53+
2754
logger.setLevel(buildpackutil.get_buildpack_loglevel())
28-
logger.info("Started Mendix Cloud Foundry Buildpack v2.1.3")
55+
logger.info("Started Mendix Cloud Foundry Buildpack v2.2.1")
2956
logging.getLogger("m2ee").propagate = False
3057

3158

@@ -228,6 +255,14 @@ def get_constants(metadata):
228255
return constants
229256

230257

258+
def set_jvm_locale(m2ee_section, java_version):
259+
javaopts = m2ee_section["javaopts"]
260+
261+
# enable locale for java8 or later
262+
if not java_version.startswith("7"):
263+
javaopts.append("-Djava.locale.providers=JRE,SPI,CLDR")
264+
265+
231266
def set_jvm_memory(m2ee_section, vcap, java_version):
232267
max_memory = os.environ.get("MEMORY_LIMIT")
233268

@@ -720,6 +755,7 @@ def set_up_m2ee_client(vcap_data):
720755
m2ee.config.get_runtime_version()
721756
)
722757
set_jvm_memory(m2ee.config._conf["m2ee"], vcap_data, java_version)
758+
set_jvm_locale(m2ee.config._conf["m2ee"], java_version)
723759
set_jetty_config(m2ee)
724760
activate_new_relic(m2ee, vcap_data["application_name"])
725761
activate_appdynamics(m2ee, vcap_data["application_name"])
@@ -818,7 +854,7 @@ def service_backups():
818854
logger.warning("Failed to contact backup service. SSLError: " + str(e))
819855
return
820856
except Exception as e:
821-
logger.warning("Failed to contact backup service: " + e)
857+
logger.warning("Failed to contact backup service: ", exc_info=True)
822858
return
823859

824860
if result.status_code == 200:
@@ -1041,6 +1077,29 @@ def start_metrics(m2ee):
10411077
thread.start()
10421078

10431079

1080+
class LoggingHeartbeatEmitterThread(threading.Thread):
1081+
def __init__(self, interval):
1082+
super().__init__()
1083+
self.interval = interval
1084+
1085+
def run(self):
1086+
logger.debug(
1087+
"Starting metrics emitter with interval %d", self.interval
1088+
)
1089+
for line in itertools.cycle(HEARTBEAT_STRING_LIST):
1090+
logger.info("MENDIX-LOGGING-HEARTBEAT: %s", line)
1091+
time.sleep(self.interval)
1092+
1093+
1094+
def start_logging_heartbeat():
1095+
logging_interval = os.getenv(
1096+
"METRICS_LOGGING_HEARTBEAT_INTERVAL", str(3600 * 6)
1097+
)
1098+
thread = LoggingHeartbeatEmitterThread(int(logging_interval))
1099+
thread.setDaemon(True)
1100+
thread.start()
1101+
1102+
10441103
def complete_start_procedure_safe_to_use_for_restart(m2ee):
10451104
buildpackutil.mkdir_p("model/lib/userlib")
10461105
set_up_logging_file()
@@ -1089,6 +1148,7 @@ def sigusr_handler(_signo, _stack_frame):
10891148
complete_start_procedure_safe_to_use_for_restart(m2ee)
10901149
set_up_instadeploy_if_deploy_password_is_set(m2ee)
10911150
start_metrics(m2ee)
1151+
start_logging_heartbeat()
10921152
start_nginx()
10931153
loop_until_process_dies(m2ee)
10941154
except Exception:

0 commit comments

Comments
 (0)