1
1
Relevant MCA params:

 * notifier_twitter_username: Twitter username
 * notifier_twitter_password: Twitter password

This commit was SVN r20750.
Этот коммит содержится в:
Jeff Squyres 2009-03-06 22:02:17 +00:00
родитель 2373bc36e2
Коммит 8b5e6c0425
8 изменённых файлов: 720 добавлений и 0 удалений

3
NEWS
Просмотреть файл

@ -38,6 +38,9 @@ Trunk (not on release branches yet)
1.4
---
- Added twitter notifier component. See "ompi_info --param notifier
twitter" for a list of the relevant MCA parameters that are
necessary.
- Added smtp notifier component (requires libesmtp). See "ompi_info
--param notifier smtp" for a list of the relevant MCA parameters that
are necessary.

47
orte/mca/notifier/twitter/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,47 @@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
dist_pkgdata_DATA = \
help-orte-notifier-twitter.txt
sources = \
notifier_twitter.h \
notifier_twitter_module.c \
notifier_twitter_component.c
# Make the output library in this directory, and name it either
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
# (for static builds).
if OMPI_BUILD_notifier_twitter_DSO
component_noinst =
component_install = mca_notifier_twitter.la
else
component_noinst = libmca_notifier_twitter.la
component_install =
endif
mcacomponentdir = $(pkglibdir)
mcacomponent_LTLIBRARIES = $(component_install)
mca_notifier_twitter_la_SOURCES = $(sources)
mca_notifier_twitter_la_LDFLAGS = -module -avoid-version
noinst_LTLIBRARIES = $(component_noinst)
libmca_notifier_twitter_la_SOURCES =$(sources)
libmca_notifier_twitter_la_LDFLAGS = -module -avoid-version

33
orte/mca/notifier/twitter/configure.m4 Обычный файл
Просмотреть файл

@ -0,0 +1,33 @@
# -*- shell-script -*-
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# MCA_notifier_twitter_CONFIG([action-if-found], [action-if-not-found])
# -----------------------------------------------------------
AC_DEFUN([MCA_notifier_twitter_CONFIG], [
# check for sockaddr_in (a good sign we have TCP, which we need to
# connect to the Twitter update server)
AC_CHECK_TYPES([struct sockaddr_in],
[$1],
[$2],
[AC_INCLUDES_DEFAULT
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif])
])dnl

13
orte/mca/notifier/twitter/configure.params Обычный файл
Просмотреть файл

@ -0,0 +1,13 @@
# -*- shell-script -*-
#
# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# Specific to this module
PARAM_CONFIG_FILES="Makefile"

Просмотреть файл

@ -0,0 +1,35 @@
# -*- text -*-
#
# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# This is the US/English help file for Open MPI's Twitter notifier support
#
[only supports http]
Sorry, Open MPI's Twitter component currently only supports http URLs
for Twitter updates.
URL supplied: %s
#
[unable to parse URL]
Sorry, Open MPI's Twitter component was unable to parse the Twitter
update URL that was provided.
URL supplied: %s
#
[unable to resolve server]
Sorry, Open MPI's Twitter component was unable to resolve the IP
address of the server provided in the Twitter update URL.
Server: %s
#
[tweet failed]
Oops! Open MPI's Twitter failed to send a tweet.
Reason: %s (errno: %d)
Tweet: %s
#

Просмотреть файл

@ -0,0 +1,61 @@
/* -*- C -*-
*
* Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2006 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*
*/
#ifndef NOTIFIER_TWITTER_H
#define NOTIFIER_TWITTER_H
#include "orte_config.h"
#include <netdb.h>
#include "orte/types.h"
#include "orte/mca/notifier/notifier.h"
BEGIN_C_DECLS
typedef struct {
orte_notifier_base_component_t super;
/* Twitter URL, username, and password */
char *url;
char *server;
char *uri;
char *username;
char *password;
/* struct hostent from resolved Twitter server name */
struct hostent *server_hostent;
int port;
/* Priority of this component */
int priority;
} orte_notifier_twitter_component_t;
/*
* Notifier interfaces
*/
ORTE_MODULE_DECLSPEC extern orte_notifier_twitter_component_t
mca_notifier_twitter_component;
extern orte_notifier_base_module_t orte_notifier_twitter_module;
END_C_DECLS
#endif

Просмотреть файл

@ -0,0 +1,195 @@
/* -*- C -*-
*
* Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/*
* Because we can. :-)
*/
#include "orte_config.h"
#include "opal/mca/base/mca_base_param.h"
#include "orte/constants.h"
#include "orte/util/show_help.h"
#include "notifier_twitter.h"
static int twitter_open(void);
static int twitter_component_query(mca_base_module_t **module, int *priority);
static int twitter_close(void);
static int twitter_register(void);
/*
* Struct of function pointers that need to be initialized
*/
orte_notifier_twitter_component_t mca_notifier_twitter_component = {
{
{
ORTE_NOTIFIER_BASE_VERSION_1_0_0,
"twitter",
ORTE_MAJOR_VERSION,
ORTE_MINOR_VERSION,
ORTE_RELEASE_VERSION,
twitter_open,
twitter_close,
twitter_component_query,
twitter_register,
},
{
/* The component is checkpoint ready */
MCA_BASE_METADATA_PARAM_CHECKPOINT
}
},
/* Twitter url, username, password */
"http://twitter.com/statuses/update.json",
NULL,
NULL,
NULL,
NULL,
/* Struct hostent */
NULL,
80,
/* Priority */
10,
};
static int twitter_register(void)
{
mca_base_param_reg_string(&mca_notifier_twitter_component.super.base_version,
"url",
"Twitter update URL",
false, false,
mca_notifier_twitter_component.url,
&mca_notifier_twitter_component.url);
mca_base_param_reg_string(&mca_notifier_twitter_component.super.base_version,
"username",
"Twitter username",
false, false, NULL,
&mca_notifier_twitter_component.username);
mca_base_param_reg_string(&mca_notifier_twitter_component.super.base_version,
"password",
"Twitter password",
false, false, NULL,
&mca_notifier_twitter_component.password);
mca_base_param_reg_int(&mca_notifier_twitter_component.super.base_version,
"priority",
"Priority of this component",
false, false,
mca_notifier_twitter_component.priority,
&mca_notifier_twitter_component.priority);
return ORTE_SUCCESS;
}
static int twitter_open(void)
{
/* Nothing to do */
return ORTE_SUCCESS;
}
static int twitter_close(void)
{
if (NULL != mca_notifier_twitter_component.url) {
free(mca_notifier_twitter_component.url);
}
if (NULL != mca_notifier_twitter_component.username) {
free(mca_notifier_twitter_component.username);
}
if (NULL != mca_notifier_twitter_component.password) {
free(mca_notifier_twitter_component.password);
}
return ORTE_SUCCESS;
}
static int twitter_component_query(mca_base_module_t **module,
int *priority)
{
char *str;
*priority = 10;
*module = (mca_base_module_t *)&orte_notifier_twitter_module;
/* If we have no username or password, there's no love */
if (NULL == mca_notifier_twitter_component.username ||
NULL == mca_notifier_twitter_component.password) {
return ORTE_ERR_NOT_FOUND;
}
/* Parse out the URL into a server and URI, ensuring that we can
handle it */
if (0 != strncmp(mca_notifier_twitter_component.url, "http://", 7)) {
orte_show_help("help-orte-notifier-twitter.txt", "only supports http",
true, mca_notifier_twitter_component.url);
return ORTE_ERR_NOT_SUPPORTED;
}
/* There's a / between the server name and URI */
str = strchr(mca_notifier_twitter_component.url + 7, '/');
if (NULL == str) {
orte_show_help("help-orte-notifier-twitter.txt",
"unable to parse URL",
true, mca_notifier_twitter_component.url);
return ORTE_ERR_NOT_FOUND;
}
*str = '\0';
mca_notifier_twitter_component.server =
mca_notifier_twitter_component.url + 7;
mca_notifier_twitter_component.uri = str + 1;
/* Sanity checks */
if (NULL == mca_notifier_twitter_component.server ||
NULL == mca_notifier_twitter_component.uri ||
'\0' == mca_notifier_twitter_component.server[0] ||
'\0' == mca_notifier_twitter_component.uri[0]) {
orte_show_help("help-orte-notifier-twitter.txt",
"unable to parse URL",
true, mca_notifier_twitter_component.url);
return ORTE_ERR_NOT_FOUND;
}
/* See if there's a port number in the server name */
str = strchr(mca_notifier_twitter_component.server, ':');
if (NULL != str) {
*str = '\0';
mca_notifier_twitter_component.port = atoi(str + 1);
} else {
mca_notifier_twitter_component.port = 80;
}
/* Since we have to open a socket later, try to resolve the IP
address of the server now. Save the result, or abort if we
can't resolve it. */
mca_notifier_twitter_component.server_hostent =
gethostbyname(mca_notifier_twitter_component.server);
if (NULL == mca_notifier_twitter_component.server_hostent) {
orte_show_help("help-orte-notifier-twitter.txt",
"unable to resolve server",
true, mca_notifier_twitter_component.server);
return ORTE_ERR_NOT_FOUND;
}
return ORTE_SUCCESS;
}

Просмотреть файл

@ -0,0 +1,333 @@
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/*
* Because we can. :-)
*/
#include "orte_config.h"
#include <string.h>
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include "opal/util/show_help.h"
#include "opal/util/output.h"
#include "orte/version.h"
#include "orte/constants.h"
#include "orte/mca/ess/ess.h"
#include "orte/util/name_fns.h"
#include "orte/util/show_help.h"
#include "orte/runtime/orte_globals.h"
#include "orte/mca/notifier/base/base.h"
#include "notifier_twitter.h"
/* Static API's */
static void mylog(int severity, int errcode, const char *msg, ...);
static void myhelplog(int severity, int errcode, const char *filename,
const char *topic, ...);
static void mypeerlog(int severity, int errcode, orte_process_name_t *peer_proc,
const char *msg, ...);
/* Module */
orte_notifier_base_module_t orte_notifier_twitter_module = {
NULL,
NULL,
mylog,
myhelplog,
mypeerlog
};
static char base64_convert(uint8_t i)
{
if (i < 26) {
return 'A' + i;
} else if (i < 52) {
return 'a' + i - 26;
} else if (i < 62) {
return '0' + i - 52;
} else if (62 == i) {
return '+';
} else {
return '/';
}
}
static void base64_encode(const char *input, char *output, int olen)
{
int ilen, i, j;
uint8_t c;
const char pad = '=';
/* Simplistic loop for base64 encoding */
memset(output, 0, olen);
ilen = (int) strlen(input);
for (j = i = 0; j + 4 < olen && i < ilen; i += 3) {
/* First output character is always emitted with no
complications */
c = input[i] >> 2;
output[j++] = base64_convert(c);
/* If we do not have another input character, then the next
output character is just the last 2 bits of the current
input character, shifted up 4 bits, and then output 2
='s */
if (i + 1 == ilen) {
c = (input[i] & 3) << 4;
output[j++] = base64_convert(c);
output[j++] = pad;
output[j++] = pad;
} else {
c = ((input[i] & 3) << 4) + (input[i + 1] >> 4);
output[j++] = base64_convert(c);
/* If we do not have another input character, then the
next output character is just the last 4 bits of the
current input character. Then output a single =. */
if (i + 2 == ilen) {
c = (input[i + 1] & 15) << 2;
output[j++] = base64_convert(c);
output[j++] = pad;
} else {
c = ((input[i + 1] & 15) << 2) + (input[i + 2] >> 6);
output[j++] = base64_convert(c);
c = (input[i + 2] & 63);
output[j++] = base64_convert(c);
}
}
}
if (j >= olen) {
output[sizeof(output) - 1] = '\0';
}
}
static char *auth_basic(void)
{
char *str;
static char output[256];
asprintf(&str, "%s:%s", mca_notifier_twitter_component.username,
mca_notifier_twitter_component.password);
memset(output, 0, sizeof(output));
base64_encode(str, output, sizeof(output));
free(str);
return output;
}
static char *version_string(void)
{
int i;
static char temp[BUFSIZ];
mca_base_component_t *c =
&(mca_notifier_twitter_component.super.base_version);
memset(temp, 0, sizeof(temp));
snprintf(temp, BUFSIZ - 1, "%d.%d",
c->mca_component_major_version,
c->mca_component_minor_version);
i = strlen(temp);
if (c->mca_component_release_version > 0) {
snprintf(temp + i, sizeof(temp) - i, ".%d",
c->mca_component_release_version);
i = strlen(temp);
}
if (strlen(ORTE_GREEK_VERSION) > 0) {
strncat(temp + i, ORTE_GREEK_VERSION, sizeof(temp) - i);
i = strlen(temp);
}
if (ORTE_WANT_SVN && strlen(ORTE_SVN_R) > 0) {
strncat(temp + i, ORTE_SVN_R, sizeof(temp) - i);
}
return temp;
}
static void tweet(char *msg)
{
int fd, ret, sent, len;
char *str, buf[80];
struct sockaddr_in peer;
if (NULL == msg) {
return;
}
asprintf(&str, "POST /%s HTTP/1.1\nAuthorization: Basic %s\nUser-Agent: Open MPI %s Twitter notifier\nHost: %s\nAccept: */*\nContent-Length: %d\nContent-Type: application/x-www-form-urlencoded\n\nstatus=%s",
mca_notifier_twitter_component.uri,
auth_basic(),
version_string(),
mca_notifier_twitter_component.server,
strlen(msg) + strlen("status="),
msg);
/* Get a socket */
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd < 0) {
orte_show_help("help-orte-notifier-twitter.txt",
"tweet failed",
true, "socket() system call failed", errno,
msg);
return;
}
/* Connect to the server */
memset(&peer, 0, sizeof(peer));
peer.sin_family = AF_INET;
memcpy((char *) &peer.sin_addr,
mca_notifier_twitter_component.server_hostent->h_addr,
sizeof(peer.sin_addr));
peer.sin_port = htons(mca_notifier_twitter_component.port);
ret = connect(fd, (const struct sockaddr *) &peer, sizeof(peer));
if (ret < 0) {
orte_show_help("help-orte-notifier-twitter.txt",
"tweet failed",
true, "connect() system call failed", errno,
msg);
return;
}
/* Send HTTP update */
for (len = strlen(str); sent < len; ) {
ret = write(fd, str, strlen(str));
if (ret > 0) {
str += ret;
sent += ret;
} else if (0 == ret) {
/* ??? */
break;
} else {
/* If we were interrupted by a signal, no problem */
if (EINTR == errno) {
continue;
}
break;
}
}
/* Shutdown nicely; send a FIN */
shutdown(fd, SHUT_WR);
while (1) {
ret = read(fd, buf, sizeof(buf));
if (0 == ret) {
/* Server ACK'ed the FIN */
break;
} else if (ret > 0) {
/* Print what the server sent us */
buf[ret] = '\0';
} else {
/* If we were interrupted by a signal, no problem */
if (EINTR == errno) {
continue;
}
/* Otherwise, just bail */
break;
}
}
close(fd);
}
static void mylog(int severity, int errcode, const char *msg, ...)
{
char *output;
va_list arglist;
/* If there was a message, output it */
va_start(arglist, msg);
vasprintf(&output, msg, arglist);
va_end(arglist);
if (NULL != output) {
tweet(output);
free(output);
}
}
static void myhelplog(int severity, int errcode, const char *filename,
const char *topic, ...)
{
va_list arglist;
char *output;
va_start(arglist, topic);
output = opal_show_help_vstring(filename, topic, false, arglist);
va_end(arglist);
if (NULL != output) {
tweet(output);
free(output);
}
}
static void mypeerlog(int severity, int errcode,
orte_process_name_t *peer_proc, const char *msg, ...)
{
va_list arglist;
char buf[ORTE_NOTIFIER_MAX_BUF + 1];
char *peer_host = NULL, *peer_name = NULL;
char *pos = buf;
char *errstr = (char*)orte_err2str(errcode);
int len, space = ORTE_NOTIFIER_MAX_BUF;
if (peer_proc) {
peer_host = orte_ess.proc_get_hostname(peer_proc);
peer_name = ORTE_NAME_PRINT(peer_proc);
}
len = snprintf(pos, space,
"While communicating to proc %s on node %s,"
" proc %s on node %s encountered an error ",
peer_name ? peer_name : "UNKNOWN",
peer_host ? peer_host : "UNKNOWN",
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
orte_process_info.nodename);
space -= len;
pos += len;
if (0 < space) {
if (errstr) {
len = snprintf(pos, space, "'%s':", errstr);
} else {
len = snprintf(pos, space, "(%d):", errcode);
}
space -= len;
pos += len;
}
if (0 < space) {
va_start(arglist, msg);
vsnprintf(pos, space, msg, arglist);
va_end(arglist);
}
buf[ORTE_NOTIFIER_MAX_BUF] = '\0';
tweet(buf);
}