mirror of https://github.com/citusdata/citus.git
Remove CheckForUpdates
https://reports.citusdata.com/v1/releases/latest We haven't updated the version CheckForUpdates sees since 7.1.0pull/2925/head
parent
077f5e26af
commit
28d964240f
|
@ -329,15 +329,6 @@ CitusMaintenanceDaemonMain(Datum main_arg)
|
||||||
FlushDistTableCache();
|
FlushDistTableCache();
|
||||||
WarnIfSyncDNS();
|
WarnIfSyncDNS();
|
||||||
statsCollectionSuccess = CollectBasicUsageStatistics();
|
statsCollectionSuccess = CollectBasicUsageStatistics();
|
||||||
if (statsCollectionSuccess)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Checking for updates only when collecting statistics succeeds,
|
|
||||||
* so we don't log update messages twice when we retry statistics
|
|
||||||
* collection in a minute.
|
|
||||||
*/
|
|
||||||
CheckForUpdates();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -48,18 +48,11 @@ typedef struct utsname
|
||||||
|
|
||||||
static size_t StatisticsCallback(char *contents, size_t size, size_t count,
|
static size_t StatisticsCallback(char *contents, size_t size, size_t count,
|
||||||
void *userData);
|
void *userData);
|
||||||
static size_t CheckForUpdatesCallback(char *contents, size_t size, size_t count,
|
|
||||||
void *userData);
|
|
||||||
static bool JsonbFieldInt32(Jsonb *jsonb, const char *fieldName, int32 *result);
|
|
||||||
static bool JsonbFieldStr(Jsonb *jsonb, const char *fieldName, StringInfo result);
|
|
||||||
static uint64 NextPow2(uint64 n);
|
static uint64 NextPow2(uint64 n);
|
||||||
static uint64 DistributedTablesSize(List *distTableOids);
|
static uint64 DistributedTablesSize(List *distTableOids);
|
||||||
static bool UrlEncode(StringInfo buf, const char *str);
|
|
||||||
static bool SendHttpPostJsonRequest(const char *url, const char *postFields,
|
static bool SendHttpPostJsonRequest(const char *url, const char *postFields,
|
||||||
long timeoutSeconds,
|
long timeoutSeconds,
|
||||||
curl_write_callback responseCallback);
|
curl_write_callback responseCallback);
|
||||||
static bool SendHttpGetJsonRequest(const char *url, long timeoutSeconds,
|
|
||||||
curl_write_callback responseCallback);
|
|
||||||
static bool PerformHttpRequest(CURL *curl);
|
static bool PerformHttpRequest(CURL *curl);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static int uname(struct utsname *buf);
|
static int uname(struct utsname *buf);
|
||||||
|
@ -187,190 +180,6 @@ StatisticsCallback(char *contents, size_t size, size_t count, void *userData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* CheckForUpdates queries Citus servers for newer releases of Citus. */
|
|
||||||
void
|
|
||||||
CheckForUpdates(void)
|
|
||||||
{
|
|
||||||
StringInfo url = makeStringInfo();
|
|
||||||
appendStringInfoString(url, REPORTS_BASE_URL "/v1/releases/latest?edition=");
|
|
||||||
|
|
||||||
if (!UrlEncode(url, CITUS_EDITION))
|
|
||||||
{
|
|
||||||
ereport(WARNING, (errmsg("url encoding '%s' failed", CITUS_EDITION)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SendHttpGetJsonRequest(url->data, HTTP_TIMEOUT_SECONDS,
|
|
||||||
&CheckForUpdatesCallback))
|
|
||||||
{
|
|
||||||
ereport(WARNING, (errmsg("checking for updates failed")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CheckForUpdatesCallback receives the response for the request sent by
|
|
||||||
* CheckForUpdates(). It processes the response, and if there is a newer release
|
|
||||||
* of Citus available, logs a LOG message. This function returns 0 if there are
|
|
||||||
* any errors in the received response, which means we didn't consume the data.
|
|
||||||
* Otherwise, it returns (size * count) which means we consumed all of the data.
|
|
||||||
*/
|
|
||||||
static size_t
|
|
||||||
CheckForUpdatesCallback(char *contents, size_t size, size_t count, void *userData)
|
|
||||||
{
|
|
||||||
const int32 citusVersionMajor = CITUS_VERSION_NUM / 10000;
|
|
||||||
const int32 citusVersionMinor = (CITUS_VERSION_NUM / 100) % 100;
|
|
||||||
const int32 citusVersionPatch = CITUS_VERSION_NUM % 100;
|
|
||||||
Jsonb *responseJsonb = NULL;
|
|
||||||
StringInfo releaseVersion = makeStringInfo();
|
|
||||||
int32 releaseMajor = 0;
|
|
||||||
int32 releaseMinor = 0;
|
|
||||||
int32 releasePatch = 0;
|
|
||||||
char *updateType = NULL;
|
|
||||||
MemoryContext savedContext = CurrentMemoryContext;
|
|
||||||
|
|
||||||
StringInfo responseNullTerminated = makeStringInfo();
|
|
||||||
appendBinaryStringInfo(responseNullTerminated, contents, size * count);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start a subtransaction so we can rollback database's state to it in case
|
|
||||||
* of error.
|
|
||||||
*/
|
|
||||||
BeginInternalSubTransaction(NULL);
|
|
||||||
|
|
||||||
/* jsonb_in can throw errors */
|
|
||||||
PG_TRY();
|
|
||||||
{
|
|
||||||
Datum responseCStringDatum = CStringGetDatum(responseNullTerminated->data);
|
|
||||||
Datum responseJasonbDatum = DirectFunctionCall1(jsonb_in, responseCStringDatum);
|
|
||||||
responseJsonb = DatumGetJsonbP(responseJasonbDatum);
|
|
||||||
ReleaseCurrentSubTransaction();
|
|
||||||
}
|
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
MemoryContextSwitchTo(savedContext);
|
|
||||||
FlushErrorState();
|
|
||||||
RollbackAndReleaseCurrentSubTransaction();
|
|
||||||
responseJsonb = NULL;
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returning here instead of in PG_CATCH() because PG_END_TRY() resets
|
|
||||||
* couple of global variables.
|
|
||||||
*/
|
|
||||||
if (responseJsonb == NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!JsonbFieldStr(responseJsonb, "version", releaseVersion) ||
|
|
||||||
!JsonbFieldInt32(responseJsonb, "major", &releaseMajor) ||
|
|
||||||
!JsonbFieldInt32(responseJsonb, "minor", &releaseMinor) ||
|
|
||||||
!JsonbFieldInt32(responseJsonb, "patch", &releasePatch))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((releaseMajor > citusVersionMajor) ||
|
|
||||||
(releaseMajor == citusVersionMajor && releaseMinor > citusVersionMinor))
|
|
||||||
{
|
|
||||||
updateType = "major";
|
|
||||||
}
|
|
||||||
else if (releaseMajor == citusVersionMajor &&
|
|
||||||
releaseMinor == citusVersionMinor &&
|
|
||||||
releasePatch > citusVersionPatch)
|
|
||||||
{
|
|
||||||
updateType = "patch";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateType != NULL)
|
|
||||||
{
|
|
||||||
ereport(LOG, (errmsg("a new %s release of Citus (%s) is available",
|
|
||||||
updateType, releaseVersion->data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return size * count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* JsonbFieldInt32 sets the given output variable to the int32 value of the given
|
|
||||||
* field in the given JSONB object. If the field doesn't exist or its value is
|
|
||||||
* not an integer that fits in 32-bits, this function returns false.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
JsonbFieldInt32(Jsonb *jsonb, const char *fieldName, int32 *result)
|
|
||||||
{
|
|
||||||
MemoryContext savedContext = CurrentMemoryContext;
|
|
||||||
bool success = false;
|
|
||||||
JsonbValue *fieldValue = NULL;
|
|
||||||
JsonbValue key;
|
|
||||||
memset(&key, 0, sizeof(key));
|
|
||||||
key.type = jbvString;
|
|
||||||
key.val.string.len = strlen(fieldName);
|
|
||||||
key.val.string.val = (char *) fieldName;
|
|
||||||
|
|
||||||
fieldValue = findJsonbValueFromContainer(&(jsonb->root), JB_FOBJECT, &key);
|
|
||||||
if (fieldValue == NULL || fieldValue->type != jbvNumeric)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start a subtransaction so we can rollback database's state to it in case
|
|
||||||
* of error.
|
|
||||||
*/
|
|
||||||
BeginInternalSubTransaction(NULL);
|
|
||||||
|
|
||||||
/* numeric_int4 can throw errors */
|
|
||||||
PG_TRY();
|
|
||||||
{
|
|
||||||
Datum resultNumericDatum = NumericGetDatum(fieldValue->val.numeric);
|
|
||||||
*result = DatumGetInt32(DirectFunctionCall1(numeric_int4, resultNumericDatum));
|
|
||||||
success = true;
|
|
||||||
ReleaseCurrentSubTransaction();
|
|
||||||
}
|
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
MemoryContextSwitchTo(savedContext);
|
|
||||||
FlushErrorState();
|
|
||||||
success = false;
|
|
||||||
RollbackAndReleaseCurrentSubTransaction();
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* JsonbFieldStr appends string value of the given field in the given JSONB
|
|
||||||
* object to the given string buffer. If the field doesn't exist or its value is
|
|
||||||
* not string, this function returns false. Otherwise it returns true.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
JsonbFieldStr(Jsonb *jsonb, const char *fieldName, StringInfo result)
|
|
||||||
{
|
|
||||||
JsonbValue *fieldValue = NULL;
|
|
||||||
JsonbValue key;
|
|
||||||
memset(&key, 0, sizeof(key));
|
|
||||||
key.type = jbvString;
|
|
||||||
key.val.string.len = strlen(fieldName);
|
|
||||||
key.val.string.val = (char *) fieldName;
|
|
||||||
|
|
||||||
fieldValue = findJsonbValueFromContainer(&(jsonb->root), JB_FOBJECT, &key);
|
|
||||||
if (fieldValue == NULL || fieldValue->type != jbvString)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
appendBinaryStringInfo(result, fieldValue->val.string.val,
|
|
||||||
fieldValue->val.string.len);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DistributedTablesSize returns total size of data store in the cluster consisting
|
* DistributedTablesSize returns total size of data store in the cluster consisting
|
||||||
* of given distributed tables. We ignore tables which we cannot get their size.
|
* of given distributed tables. We ignore tables which we cannot get their size.
|
||||||
|
@ -447,36 +256,6 @@ NextPow2(uint64 n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UrlEncode URL encodes the given string and appends it to the given buffer.
|
|
||||||
* If either libcurl initialization or encoding fails, returns false.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
UrlEncode(StringInfo buf, const char *str)
|
|
||||||
{
|
|
||||||
bool success = false;
|
|
||||||
CURL *curl = NULL;
|
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
||||||
curl = curl_easy_init();
|
|
||||||
if (curl)
|
|
||||||
{
|
|
||||||
char *urlEncodedStr = curl_easy_escape(curl, str, strlen(str));
|
|
||||||
if (urlEncodedStr)
|
|
||||||
{
|
|
||||||
appendStringInfoString(buf, urlEncodedStr);
|
|
||||||
curl_free(urlEncodedStr);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_global_cleanup();
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SendHttpPostJsonRequest sends a HTTP/HTTPS POST request to the given URL with
|
* SendHttpPostJsonRequest sends a HTTP/HTTPS POST request to the given URL with
|
||||||
* the given json object. responseCallback is called with the content of response.
|
* the given json object. responseCallback is called with the content of response.
|
||||||
|
@ -515,42 +294,6 @@ SendHttpPostJsonRequest(const char *url, const char *jsonObj, long timeoutSecond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SendHttpGetJsonRequest sends an HTTP/HTTPS GET request to the given URL, and
|
|
||||||
* expects a JSON response from server. GET parameters should be added to the url.
|
|
||||||
* responseCallback is called with the content of response.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
SendHttpGetJsonRequest(const char *url, long timeoutSeconds,
|
|
||||||
curl_write_callback responseCallback)
|
|
||||||
{
|
|
||||||
bool success = false;
|
|
||||||
CURL *curl = NULL;
|
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
||||||
curl = curl_easy_init();
|
|
||||||
if (curl)
|
|
||||||
{
|
|
||||||
struct curl_slist *headers = NULL;
|
|
||||||
headers = curl_slist_append(headers, "Accept: application/json");
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeoutSeconds);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseCallback);
|
|
||||||
|
|
||||||
success = PerformHttpRequest(curl);
|
|
||||||
|
|
||||||
curl_slist_free_all(headers);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_global_cleanup();
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PerformHttpRequest sends the HTTP request with the parameters set in the given
|
* PerformHttpRequest sends the HTTP request with the parameters set in the given
|
||||||
* curl object, and returns if it was successful or not. If the request was not
|
* curl object, and returns if it was successful or not. If the request was not
|
||||||
|
|
|
@ -32,7 +32,6 @@ extern bool EnableStatisticsCollection;
|
||||||
|
|
||||||
extern void WarnIfSyncDNS(void);
|
extern void WarnIfSyncDNS(void);
|
||||||
extern bool CollectBasicUsageStatistics(void);
|
extern bool CollectBasicUsageStatistics(void);
|
||||||
extern void CheckForUpdates(void);
|
|
||||||
|
|
||||||
#endif /* HAVE_LIBCURL */
|
#endif /* HAVE_LIBCURL */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue