mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Feature: Added more advanced version display in admin interface
This commit is contained in:
parent
1963031af0
commit
29dd621a08
@ -19,6 +19,7 @@
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<li class="right"><a href="/status.xsl">Public area</a></li>
|
||||
<li class="right adminlink"><a href="/admin/version.xsl">Version</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
112
admin/version.xsl
Normal file
112
admin/version.xsl
Normal file
@ -0,0 +1,112 @@
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:include href="includes/page.xsl"/>
|
||||
<xsl:variable name="title">Version</xsl:variable>
|
||||
|
||||
<xsl:template name="valuetable">
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="value">
|
||||
<xsl:if test="not(*)">
|
||||
<tr>
|
||||
<td><xsl:value-of select="@member" /></td>
|
||||
<td><xsl:value-of select="@value" /></td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="flagslist">
|
||||
<ul>
|
||||
<xsl:for-each select="value[@type='flag']">
|
||||
<xsl:if test="@value = 'true'">
|
||||
<li><xsl:value-of select="@member" /></li>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="content">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
<xsl:for-each select="/report/incident">
|
||||
<section class="box">
|
||||
<h3 class="box_title">Details</h3>
|
||||
<h4>Overview</h4>
|
||||
<xsl:for-each select="resource[@type='result']">
|
||||
<xsl:call-template name="valuetable" />
|
||||
|
||||
<xsl:for-each select="value[@member='uname']">
|
||||
<h4>uname</h4>
|
||||
<xsl:call-template name="valuetable" />
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:for-each select="value[@member='config']">
|
||||
<h4>Configuration</h4>
|
||||
<xsl:call-template name="valuetable" />
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:for-each select="value[@member='dependencies']">
|
||||
<h4>Dependencies</h4>
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Dependency</th>
|
||||
<th>Compile time version</th>
|
||||
<th>Runtime time version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="value[@type='structure']">
|
||||
<tr>
|
||||
<td><xsl:value-of select="@member" /></td>
|
||||
<td><xsl:value-of select="value[@member='compiletime']/@value" /></td>
|
||||
<td><xsl:value-of select="value[@member='runtime']/@value" /></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:for-each select="value[@member='flags']">
|
||||
<h4>Flags</h4>
|
||||
|
||||
<xsl:for-each select="value[@member='compiletime']">
|
||||
<h5>Compile time</h5>
|
||||
<xsl:call-template name="flagslist" />
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:for-each select="value[@member='runtime']">
|
||||
<h5>Runtime time</h5>
|
||||
<xsl:call-template name="flagslist" />
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
</section>
|
||||
|
||||
<section class="box">
|
||||
<h3 class="box_title">Summary for reporting</h3>
|
||||
<xsl:for-each select="resource[@type='result']">
|
||||
<pre>
|
||||
<xsl:for-each select="value[@type!='structure']"><xsl:value-of select="@member" />: <xsl:value-of select="@value" /><xsl:text>
|
||||
</xsl:text></xsl:for-each>
|
||||
<xsl:for-each select="value[@member='uname' and @state='set']/value">uname: <xsl:value-of select="@member" />: <xsl:value-of select="@value" /><xsl:text>
|
||||
</xsl:text></xsl:for-each>
|
||||
<xsl:for-each select="value[@member='config' and @state='set']/value">config: <xsl:value-of select="@member" />: <xsl:value-of select="@value" /><xsl:text>
|
||||
</xsl:text></xsl:for-each>
|
||||
<xsl:for-each select="value[@member='dependencies' and @state='set']/value">dependency: <xsl:value-of select="@member" />: <xsl:for-each select="value"><xsl:if test="@state = 'set'">[<xsl:value-of select="@member" />] <xsl:value-of select="@value" /><xsl:text> </xsl:text></xsl:if></xsl:for-each><xsl:text>
|
||||
</xsl:text></xsl:for-each>
|
||||
<xsl:for-each select="value[@member='flags' and @state='set']/value">flags: <xsl:value-of select="@member" />: <xsl:for-each select="value[@type='flag']"><xsl:if test="@value = 'true'"><xsl:value-of select="@member" /><xsl:text> </xsl:text></xsl:if></xsl:for-each><xsl:text>
|
||||
</xsl:text></xsl:for-each>
|
||||
</pre>
|
||||
</xsl:for-each>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
201
src/admin.c
201
src/admin.c
@ -23,11 +23,39 @@
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xmlversion.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_GETRLIMIT && HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
#ifdef HAVE_THEORA
|
||||
#include <theora/theora.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SPEEX
|
||||
#include <speex/speex.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
#include <curl/curlver.h>
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNAME
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include "common/net/sock.h"
|
||||
|
||||
#include "admin.h"
|
||||
@ -125,6 +153,8 @@
|
||||
#define DASHBOARD_RAW_REQUEST "dashboard"
|
||||
#define DASHBOARD_HTML_REQUEST "dashboard.xsl"
|
||||
#define DASHBOARD_JSON_REQUEST "dashboard.json"
|
||||
#define VERSION_RAW_REQUEST "version"
|
||||
#define VERSION_HTML_REQUEST "version.xsl"
|
||||
#define DEFAULT_RAW_REQUEST ""
|
||||
#define DEFAULT_HTML_REQUEST ""
|
||||
#define BUILDM3U_RAW_REQUEST "buildm3u"
|
||||
@ -160,6 +190,7 @@ static void command_buildm3u (client_t *client, source_t *source, adm
|
||||
static void command_show_log (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_mark_log (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_dashboard (client_t *client, source_t *source, admin_format_t response);
|
||||
static void command_version (client_t *client, source_t *source, admin_format_t response);
|
||||
|
||||
static const admin_command_handler_t handlers[] = {
|
||||
{ "*", ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_UNSAFE, NULL, NULL}, /* for ACL framework */
|
||||
@ -216,6 +247,8 @@ static const admin_command_handler_t handlers[] = {
|
||||
{ DASHBOARD_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, ADMINSAFE_SAFE, command_dashboard, NULL},
|
||||
{ DASHBOARD_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_dashboard, NULL},
|
||||
{ DASHBOARD_JSON_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_JSON, ADMINSAFE_SAFE, command_dashboard, NULL},
|
||||
{ VERSION_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, ADMINSAFE_SAFE, command_version, NULL},
|
||||
{ VERSION_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_version, NULL},
|
||||
{ DEFAULT_HTML_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_default_selector, NULL},
|
||||
{ DEFAULT_RAW_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_default_selector, NULL}
|
||||
};
|
||||
@ -1726,6 +1759,174 @@ static void command_dashboard (client_t *client, source_t *source, adm
|
||||
refobject_unref(report);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SPEEX
|
||||
static inline const char *get_speex_version(void)
|
||||
{
|
||||
const char *version;
|
||||
if (speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &version) != 0)
|
||||
return NULL;
|
||||
return version;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void command_version (client_t *client, source_t *source, admin_format_t response)
|
||||
{
|
||||
reportxml_t *report = client_get_reportxml("8cdfc150-094d-42f7-9c61-f9fb9a6e07e7", NULL, NULL);
|
||||
reportxml_node_t *incident = reportxml_get_node_by_type(report, REPORTXML_NODE_TYPE_INCIDENT, 0);
|
||||
reportxml_node_t *resource = reportxml_node_new(REPORTXML_NODE_TYPE_RESOURCE, NULL, NULL, NULL);
|
||||
reportxml_node_t *config = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
reportxml_node_t *dependencies = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
reportxml_node_t *flags = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
reportxml_node_t *cflags = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
reportxml_node_t *rflags = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
ice_config_t *icecast_config;
|
||||
#ifdef HAVE_CURL
|
||||
const curl_version_info_data * curl_runtime_version = curl_version_info(CURLVERSION_NOW);
|
||||
#endif
|
||||
struct {
|
||||
const char *name;
|
||||
const char *compiletime;
|
||||
const char *runtime;
|
||||
} dependency_versions[] = {
|
||||
{"libxml2", LIBXML_DOTTED_VERSION, NULL},
|
||||
#if defined(HAVE_OPENSSL) && defined(OPENSSL_VERSION_TEXT)
|
||||
{"OpenSSL", OPENSSL_VERSION_TEXT, NULL},
|
||||
#endif
|
||||
{"libvorbis", NULL, vorbis_version_string()},
|
||||
#ifdef HAVE_THEORA
|
||||
{"libtheora", NULL, theora_version_string()},
|
||||
#endif
|
||||
#ifdef HAVE_SPEEX
|
||||
{"libspeex", NULL, get_speex_version()},
|
||||
#endif
|
||||
#ifdef HAVE_CURL
|
||||
{"libcurl", LIBCURL_VERSION, curl_runtime_version->version},
|
||||
#endif
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
const char *compiletime_flags[] = {
|
||||
#ifdef HAVE_POLL
|
||||
"poll",
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
"select",
|
||||
#endif
|
||||
#ifdef HAVE_UNAME
|
||||
"uname",
|
||||
#endif
|
||||
#ifdef HAVE_GETHOSTNAME
|
||||
"gethostname",
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
"win32",
|
||||
#endif
|
||||
#ifdef DEVEL_LOGGING
|
||||
"developer-logging",
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
size_t i;
|
||||
|
||||
reportxml_node_set_attribute(resource, "type", "result");
|
||||
reportxml_node_add_child(incident, resource);
|
||||
|
||||
reportxml_helper_add_value_string(resource, "version", ICECAST_VERSION_STRING);
|
||||
reportxml_helper_add_value_int(resource, "address-bits", sizeof(void*)*8);
|
||||
|
||||
#ifdef HAVE_GETHOSTNAME
|
||||
if (true) {
|
||||
char hostname[80];
|
||||
if (gethostname(hostname, sizeof(hostname)) == 0) {
|
||||
reportxml_helper_add_value_string(resource, "gethostname", hostname);
|
||||
} else {
|
||||
reportxml_helper_add_value_string(resource, "gethostname", NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNAME
|
||||
if (true) {
|
||||
reportxml_node_t *res = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
struct utsname utsname;
|
||||
|
||||
reportxml_node_set_attribute(res, "type", "structure");
|
||||
reportxml_node_set_attribute(res, "member", "uname");
|
||||
reportxml_node_add_child(resource, res);
|
||||
|
||||
if(uname(&utsname) == 0) {
|
||||
reportxml_helper_add_value_string(res, "sysname", utsname.sysname);
|
||||
reportxml_helper_add_value_string(res, "release", utsname.release);
|
||||
reportxml_helper_add_value_string(res, "nodename", utsname.nodename);
|
||||
reportxml_helper_add_value_string(res, "version", utsname.version);
|
||||
reportxml_helper_add_value_string(res, "machine", utsname.machine);
|
||||
} else {
|
||||
reportxml_node_set_attribute(res, "state", "unset");
|
||||
}
|
||||
|
||||
refobject_unref(res);
|
||||
}
|
||||
#endif
|
||||
|
||||
reportxml_node_set_attribute(config, "type", "structure");
|
||||
reportxml_node_set_attribute(config, "member", "config");
|
||||
reportxml_node_add_child(resource, config);
|
||||
|
||||
icecast_config = config_get_config();
|
||||
reportxml_helper_add_value_string(config, "hostname", icecast_config->hostname);
|
||||
reportxml_helper_add_value_string(config, "location", icecast_config->location);
|
||||
reportxml_helper_add_value_string(config, "admin", icecast_config->admin);
|
||||
reportxml_helper_add_value_string(config, "server-id", icecast_config->server_id);
|
||||
|
||||
reportxml_helper_add_value_flag(rflags, "requested-chroot", icecast_config->chroot);
|
||||
reportxml_helper_add_value_flag(rflags, "requested-chuid", icecast_config->chuid);
|
||||
config_release_config();
|
||||
|
||||
reportxml_node_set_attribute(dependencies, "type", "structure");
|
||||
reportxml_node_set_attribute(dependencies, "member", "dependencies");
|
||||
reportxml_node_add_child(resource, dependencies);
|
||||
|
||||
for (i = 0; dependency_versions[i].name; i++) {
|
||||
reportxml_node_t *dependency = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL);
|
||||
reportxml_node_set_attribute(dependency, "type", "structure");
|
||||
reportxml_node_set_attribute(dependency, "member", dependency_versions[i].name);
|
||||
reportxml_helper_add_value_string(dependency, "compiletime", dependency_versions[i].compiletime);
|
||||
reportxml_helper_add_value_string(dependency, "runtime", dependency_versions[i].runtime);
|
||||
reportxml_node_add_child(dependencies, dependency);
|
||||
refobject_unref(dependency);
|
||||
}
|
||||
|
||||
reportxml_node_set_attribute(flags, "type", "structure");
|
||||
reportxml_node_set_attribute(flags, "member", "flags");
|
||||
reportxml_node_add_child(resource, flags);
|
||||
|
||||
reportxml_node_set_attribute(cflags, "type", "unordered-list");
|
||||
reportxml_node_set_attribute(cflags, "member", "compiletime");
|
||||
reportxml_node_add_child(flags, cflags);
|
||||
for (i = 0; compiletime_flags[i]; i++) {
|
||||
reportxml_helper_add_value_flag(cflags, compiletime_flags[i], true);
|
||||
}
|
||||
|
||||
reportxml_node_set_attribute(rflags, "type", "unordered-list");
|
||||
reportxml_node_set_attribute(rflags, "member", "runtime");
|
||||
reportxml_node_add_child(flags, rflags);
|
||||
reportxml_helper_add_value_flag(rflags, "ipv4-mapped", sock_is_ipv4_mapped_supported());
|
||||
|
||||
global_lock();
|
||||
reportxml_helper_add_value_flag(rflags, "bound-unix", listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_UNIX));
|
||||
reportxml_helper_add_value_flag(rflags, "bound-inet4", listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_INET4));
|
||||
reportxml_helper_add_value_flag(rflags, "bound-inet6", listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_INET6));
|
||||
global_unlock();
|
||||
|
||||
refobject_unref(config);
|
||||
refobject_unref(dependencies);
|
||||
refobject_unref(cflags);
|
||||
refobject_unref(rflags);
|
||||
refobject_unref(flags);
|
||||
refobject_unref(resource);
|
||||
refobject_unref(incident);
|
||||
client_send_reportxml(client, report, DOCUMENT_DOMAIN_ADMIN, VERSION_HTML_REQUEST, response, 200, NULL);
|
||||
refobject_unref(report);
|
||||
}
|
||||
|
||||
static void ui_command(client_t * client, source_t * source, admin_format_t format, resourcematch_extract_t *parameters)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user