From d75b80df07aa6d62971e8aa115145d7f94df3a17 Mon Sep 17 00:00:00 2001 From: Danny Auble <da@llnl.gov> Date: Tue, 29 Aug 2006 21:38:30 +0000 Subject: [PATCH] admin mode works for partitions Availablity and Nodes --- src/sview/block_info.c | 49 +++++++++--- src/sview/common.c | 153 +++++++++++++++++++++++++++++++---- src/sview/job_info.c | 100 ++++++++++++++++------- src/sview/node_info.c | 88 ++++++++++++++++++--- src/sview/part_info.c | 176 ++++++++++++++++++++++++++++++++--------- src/sview/sview.c | 52 +++++++----- src/sview/sview.h | 38 ++++++++- 7 files changed, 528 insertions(+), 128 deletions(-) diff --git a/src/sview/block_info.c b/src/sview/block_info.c index 16557e38cb4..22554a42063 100644 --- a/src/sview/block_info.c +++ b/src/sview/block_info.c @@ -67,20 +67,31 @@ enum { }; static display_data_t display_data_block[] = { - {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_block}, + {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_block, + create_model_block, admin_edit_block}, {G_TYPE_STRING, SORTID_PARTITION, "Partition", - TRUE, -1, refresh_block}, + TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, {G_TYPE_STRING, SORTID_BLOCK, "Bluegene Block", - TRUE, -1, refresh_block}, - {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_block}, - {G_TYPE_STRING, SORTID_USER, "User", TRUE, -1, refresh_block}, + TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_STRING, SORTID_USER, "User", TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, {G_TYPE_STRING, SORTID_CONN, "Connection Type", - TRUE, -1, refresh_block}, - {G_TYPE_STRING, SORTID_USE, "Node Use", TRUE, -1, refresh_block}, - {G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, -1, refresh_block}, - {G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, -1, refresh_block}, - {G_TYPE_POINTER, SORTID_POINTER, NULL, FALSE, -1, refresh_block}, - {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_block}, + TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_STRING, SORTID_USE, "Node Use", TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_POINTER, SORTID_POINTER, NULL, FALSE, -1, refresh_block, + create_model_block, admin_edit_block}, + {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_block, + create_model_block, admin_edit_block}, {G_TYPE_NONE, -1, NULL, FALSE, -1} }; @@ -738,6 +749,22 @@ extern int get_new_info_node_select(node_select_info_msg_t **node_select_ptr, return error_code; } +extern GtkListStore *create_model_block(int type) +{ + GtkListStore *model = NULL; + + return model; +} + +extern void admin_edit_block(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data) +{ + g_print("Something block related altered\n"); + g_static_mutex_unlock(&sview_mutex); +} + extern void get_info_block(GtkTable *table, display_data_t *display_data) { int part_error_code = SLURM_SUCCESS; diff --git a/src/sview/common.c b/src/sview/common.c index f2ce2467090..4dce6401813 100644 --- a/src/sview/common.c +++ b/src/sview/common.c @@ -26,6 +26,7 @@ \*****************************************************************************/ #include "src/sview/sview.h" +#include "src/common/parse_time.h" typedef struct { GtkTreeModel *model; @@ -104,13 +105,48 @@ static int _sort_iter_compare_func_int(GtkTreeModel *model, return ret; } +static void _editing_started(GtkCellRenderer *cell, + GtkCellEditable *editable, + const gchar *path, + gpointer data) +{ + g_static_mutex_lock(&sview_mutex); +} + +static void _editing_canceled(GtkCellRenderer *cell, + gpointer data) +{ + g_static_mutex_unlock(&sview_mutex); + +} + static void _add_col_to_treeview(GtkTreeView *tree_view, display_data_t *display_data) { - GtkTreeViewColumn *col; - GtkCellRenderer *renderer; - renderer = gtk_cell_renderer_text_new(); - col = gtk_tree_view_column_new(); + GtkTreeViewColumn *col = gtk_tree_view_column_new(); + GtkCellRenderer *renderer = gtk_cell_renderer_combo_new(); + GtkListStore *model = (display_data->create_model)(display_data->id); + + if(model) { + g_object_set(renderer, + "model", model, + "text-column", 0, + "has-entry", FALSE, + "editable", TRUE, + NULL); + + g_signal_connect(renderer, "editing-started", + G_CALLBACK(_editing_started), NULL); + g_signal_connect(renderer, "editing-canceled", + G_CALLBACK(_editing_canceled), NULL); + g_signal_connect(renderer, "edited", + G_CALLBACK(display_data->admin_edit), + gtk_tree_view_get_model(tree_view)); + + g_object_set_data(G_OBJECT(renderer), "column", + GINT_TO_POINTER(display_data->id)); + } + gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_add_attribute(col, renderer, "text", display_data->id); @@ -429,9 +465,9 @@ extern GtkTreeStore *create_treestore(GtkTreeView *tree_view, gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(treestore), 1, GTK_SORT_ASCENDING); - - load_header(tree_view, display_data); + gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(treestore)); + load_header(tree_view, display_data); g_object_unref(GTK_TREE_MODEL(treestore)); return treestore; @@ -455,34 +491,36 @@ extern void right_button_pressed(GtkTreeView *tree_view, } } -extern void row_clicked(GtkTreeView *tree_view, GdkEventButton *event, +extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, const display_data_t *display_data) { GtkTreePath *path = NULL; GtkTreeSelection *selection = NULL; - - if(!gtk_tree_view_get_path_at_pos(tree_view, + gboolean did_something = FALSE; + /* right click? */ + if(!gtk_tree_view_get_path_at_pos(tree_view, (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL)) { - return; + return did_something; } selection = gtk_tree_view_get_selection(tree_view); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_path(selection, path); - - /* expand/collapse row - or right mouse button - or double click? - */ + if(event->x <= 20) { if(!gtk_tree_view_expand_row(tree_view, path, FALSE)) gtk_tree_view_collapse_row(tree_view, path); + did_something = TRUE; } else if(event->button == 3) { right_button_pressed(tree_view, path, event, display_data, ROW_CLICKED); - } + did_something = TRUE; + } else if(!admin_mode) + did_something = TRUE; gtk_tree_path_free(path); + + return did_something; } extern popup_info_t *create_popup_info(int type, int dest_type, char *title) @@ -749,3 +787,86 @@ extern GtkWidget *create_pulldown_combo(display_data_t *display_data, gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); return combo; } + +/* + * str_tolower - convert string to all lower case + * upper_str IN - upper case input string + * RET - lower case version of upper_str, caller must be xfree + */ +extern char *str_tolower(char *upper_str) +{ + int i = strlen(upper_str) + 1; + char *lower_str = xmalloc(i); + + for (i=0; upper_str[i]; i++) + lower_str[i] = tolower((int) upper_str[i]); + + return lower_str; +} + +extern char *get_reason() +{ + char *reason_str = NULL; + int len = 0; + GtkWidget *table = gtk_table_new(1, 2, FALSE); + GtkWidget *label = gtk_label_new("Reason "); + GtkWidget *entry = gtk_entry_new(); + GtkWidget *popup = gtk_dialog_new_with_buttons( + "State change Reason", + GTK_WINDOW(main_window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); + //GError *error = NULL; + int response = 0; + char *user_name = NULL; + char time_buf[64], time_str[32]; + time_t now = time(NULL); + + gtk_container_set_border_width(GTK_CONTAINER(table), 10); + + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox), + table, FALSE, FALSE, 0); + + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, 0, 1); + + gtk_widget_show_all(popup); + response = gtk_dialog_run (GTK_DIALOG(popup)); + + if (response == GTK_RESPONSE_OK) + { + reason_str = xstrdup(gtk_entry_get_text(GTK_ENTRY(entry))); + len = strlen(reason_str) - 1; + /* Append user, date and time */ + xstrcat(reason_str, " ["); + user_name = getlogin(); + if (user_name) + xstrcat(reason_str, user_name); + else { + sprintf(time_buf, "%d", getuid()); + xstrcat(reason_str, time_buf); + } + slurm_make_time_str(&now, time_str, sizeof(time_str)); + snprintf(time_buf, sizeof(time_buf), "@%s]", time_str); + xstrcat(reason_str, time_buf); + /* maybe later we will update the status bar */ + /* temp = g_strdup_printf("Refresh Interval set to %d seconds.", */ +/* global_sleep_time); */ +/* gtk_statusbar_push(GTK_STATUSBAR(main_statusbar), 1, */ +/* temp); */ +/* g_free(temp); */ +/* if (!g_thread_create(_refresh_thr, NULL, FALSE, &error)) */ +/* { */ +/* g_printerr ("Failed to create refresh thread: %s\n", */ +/* error->message); */ +/* } */ + } + + gtk_widget_destroy(popup); + + return reason_str; +} diff --git a/src/sview/job_info.c b/src/sview/job_info.c index 141c3ecbf24..d1250656c76 100644 --- a/src/sview/job_info.c +++ b/src/sview/job_info.c @@ -65,49 +65,77 @@ enum { }; static display_data_t display_data_job[] = { - {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_job}, - {G_TYPE_INT, SORTID_JOBID, "JobID", TRUE, -1, refresh_job}, - {G_TYPE_INT, SORTID_ALLOC, NULL, FALSE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_PARTITION, "Partition", TRUE, -1, refresh_job}, + {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_INT, SORTID_JOBID, "JobID", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_INT, SORTID_ALLOC, NULL, FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_PARTITION, "Partition", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, #ifdef HAVE_BG - {G_TYPE_STRING, SORTID_BLOCK, "BG Block", TRUE, -1, refresh_job}, + {G_TYPE_STRING, SORTID_BLOCK, "BG Block", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, #endif - {G_TYPE_STRING, SORTID_USER, "User", TRUE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_NAME, "Name", TRUE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_TIME, "Running Time", TRUE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, -1, refresh_job}, + {G_TYPE_STRING, SORTID_USER, "User", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_NAME, "Name", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_TIME, "Running Time", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, #ifdef HAVE_BG - {G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, -1, refresh_job}, + {G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_REQ_NODELIST, "Requested BP List", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_EXC_NODELIST, "Excluded BP List", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, #else - {G_TYPE_STRING, SORTID_NODELIST, "Nodelist", TRUE, -1, refresh_job}, + {G_TYPE_STRING, SORTID_NODELIST, "Nodelist", TRUE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_REQ_NODELIST, "Requested NodeList", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_EXC_NODELIST, "Excluded NodeList", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, #endif - {G_TYPE_STRING, SORTID_SUBMIT, "Submit Time", FALSE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_START, "Start Time", FALSE, -1, refresh_job}, - {G_TYPE_STRING, SORTID_END, "End Time", FALSE, -1, refresh_job}, + {G_TYPE_STRING, SORTID_SUBMIT, "Submit Time", FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_START, "Start Time", FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_STRING, SORTID_END, "End Time", FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_SUSPEND, "Suspend Time", - FALSE, -1, refresh_job}, - {G_TYPE_INT, SORTID_PRIORITY, "Priority", FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_INT, SORTID_PRIORITY, "Priority", FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_NUM_PROCS, "Num Processors", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_TASKS, "Num Tasks", - FALSE, -1, refresh_job}, - {G_TYPE_INT, SORTID_SHARED, "Shared", FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_INT, SORTID_SHARED, "Shared", FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_CPUS_PER_TASK, "Cpus per Task", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_ACCOUNT, "Account Charged", - FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_STRING, SORTID_REASON, "Wait Reason", - FALSE, -1, refresh_job}, - {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_job}, + FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, + {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_job, + create_model_job, admin_edit_job}, {G_TYPE_NONE, -1, NULL, FALSE, -1} }; @@ -727,6 +755,22 @@ extern int get_new_info_job_step(job_step_info_response_msg_t **info_ptr, return error_code; } +extern GtkListStore *create_model_job(int type) +{ + GtkListStore *model = NULL; + + return model; +} + +extern void admin_edit_job(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data) +{ + g_print("Something job related altered\n"); + g_static_mutex_unlock(&sview_mutex); +} + extern void get_info_job(GtkTable *table, display_data_t *display_data) { int job_error_code = SLURM_SUCCESS; diff --git a/src/sview/node_info.c b/src/sview/node_info.c index 7681ddf67c3..1cb8751dca2 100644 --- a/src/sview/node_info.c +++ b/src/sview/node_info.c @@ -46,16 +46,26 @@ enum { }; static display_data_t display_data_node[] = { - {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_node}, - {G_TYPE_STRING, SORTID_NAME, "Name", TRUE, -1, refresh_node}, - {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_node}, - {G_TYPE_INT, SORTID_CPUS, "CPU Count", TRUE, -1, refresh_node}, - {G_TYPE_STRING, SORTID_MEMORY, "Real Memory", TRUE, -1, refresh_node}, - {G_TYPE_STRING, SORTID_DISK, "Tmp Disk", TRUE, -1, refresh_node}, - {G_TYPE_INT, SORTID_WEIGHT,"Weight", FALSE, -1, refresh_node}, - {G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE, -1, refresh_node}, - {G_TYPE_STRING, SORTID_REASON, "Reason", FALSE, -1, refresh_node}, - {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_node}, + {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_STRING, SORTID_NAME, "Name", TRUE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_INT, SORTID_CPUS, "CPU Count", TRUE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_STRING, SORTID_MEMORY, "Real Memory", TRUE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_STRING, SORTID_DISK, "Tmp Disk", TRUE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_INT, SORTID_WEIGHT,"Weight", FALSE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_STRING, SORTID_REASON, "Reason", FALSE, -1, refresh_node, + create_model_node, admin_edit_node}, + {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_node, + create_model_node, admin_edit_node}, {G_TYPE_NONE, -1, NULL, FALSE, -1} }; @@ -292,6 +302,64 @@ extern int get_new_info_node(node_info_msg_t **info_ptr, int force) return error_code; } +extern int update_state_node(GtkTreeStore *treestore, GtkTreeIter *iter, + int text_column, int num_column, + const char *new_text, + update_node_msg_t *node_msg) +{ + uint16_t state = (uint16_t) NO_VAL; + char *upper = NULL, *lower = NULL; + int i = 0; + int rc = SLURM_SUCCESS; + + node_msg->reason = NULL; + + if(!strcmp("drain", new_text)) { + state = NODE_STATE_DRAIN; + node_msg->reason = get_reason(); + } else if(!strcmp("NoResp", new_text)) { + state = NODE_STATE_NO_RESPOND; + } else if(!strcmp("resume", new_text)) { + state = NODE_RESUME; + } else { + for(i = 0; i < NODE_STATE_END; i++) { + upper = node_state_string(i); + lower = str_tolower(upper); + if(!strcmp(upper, "?")) + break; + if(!strcmp(lower, new_text)) { + state = i; + xfree(lower); + break; + } + xfree(lower); + } + } + node_msg->node_state = (uint16_t)state; + + rc = slurm_update_node(node_msg); + xfree(node_msg->reason); + gtk_tree_store_set(treestore, iter, text_column, new_text, + num_column, state, -1); + return rc; +} + +extern GtkListStore *create_model_node(int type) +{ + GtkListStore *model = NULL; + + return model; +} + +extern void admin_edit_node(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data) +{ + g_print("Something node related altered\n"); + g_static_mutex_unlock(&sview_mutex); +} + extern void get_info_node(GtkTable *table, display_data_t *display_data) { int error_code = SLURM_SUCCESS; diff --git a/src/sview/part_info.c b/src/sview/part_info.c index dfdcde7e862..c190726f158 100644 --- a/src/sview/part_info.c +++ b/src/sview/part_info.c @@ -85,28 +85,45 @@ enum { static display_data_t display_data_part[] = { {G_TYPE_INT, SORTID_POS, NULL, FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_NAME, "Partition", TRUE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_DEFAULT, "Default", TRUE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_AVAIL, "Availablity", TRUE, -1, refresh_part}, + {G_TYPE_STRING, SORTID_NAME, "Partition", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_DEFAULT, "Default", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_AVAIL, "Availablity", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, {G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit", - TRUE, -1, refresh_part}, + TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, {G_TYPE_STRING, SORTID_JOB_SIZE, "Job Size", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_ROOT, "Root", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_SHARE, "Share", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_GROUPS, "Groups", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_CPUS, "CPUs", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_DISK, "Temp Disk", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_MEM, "MEM", FALSE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_part}, - {G_TYPE_STRING, SORTID_WEIGHT, "Weight", TRUE, -1, refresh_part}, + {G_TYPE_STRING, SORTID_ROOT, "Root", FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_SHARE, "Share", FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_GROUPS, "Groups", FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_CPUS, "CPUs", FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_DISK, "Temp Disk", FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_MEM, "MEM", FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_STATE, "State", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_STRING, SORTID_WEIGHT, "Weight", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, #ifdef HAVE_BG - {G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, -1, refresh_part}, + {G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, #else - {G_TYPE_STRING, SORTID_NODELIST, "NodeList", TRUE, -1, refresh_part}, + {G_TYPE_STRING, SORTID_NODELIST, "NodeList", TRUE, -1, refresh_part, + create_model_part, admin_edit_part}, #endif - {G_TYPE_INT, SORTID_STATE_NUM, NULL, FALSE, -1, refresh_part}, - {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_part}, + {G_TYPE_INT, SORTID_STATE_NUM, NULL, FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, + {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, -1, refresh_part, + create_model_part, admin_edit_part}, {G_TYPE_NONE, -1, NULL, FALSE, -1} }; @@ -155,22 +172,6 @@ _build_min_max_string(char *buffer, int buf_size, int min, int max, bool range) return snprintf(buffer, buf_size, "%s+", tmp_min); } -/* - * _str_tolower - convert string to all lower case - * upper_str IN - upper case input string - * RET - lower case version of upper_str, caller must be xfree - */ -static char *_str_tolower(char *upper_str) -{ - int i = strlen(upper_str) + 1; - char *lower_str = xmalloc(i); - - for (i=0; upper_str[i]; i++) - lower_str[i] = tolower((int) upper_str[i]); - - return lower_str; -} - static void _subdivide_part(sview_part_info_t *sview_part_info, GtkTreeModel *model, GtkTreeIter *sub_iter, @@ -349,8 +350,8 @@ static void _update_part_sub_record(sview_part_sub_t *sview_part_sub, else gtk_tree_store_set(treestore, iter, SORTID_AVAIL, "down", -1); - upper = node_state_string_compact(sview_part_sub->node_state); - lower = _str_tolower(upper); + upper = node_state_string(sview_part_sub->node_state); + lower = str_tolower(upper); gtk_tree_store_set(treestore, iter, SORTID_STATE, lower, -1); xfree(lower); @@ -605,8 +606,8 @@ static void _update_sview_part_sub(sview_part_sub_t *sview_part_sub, if (sview_part_sub->node_cnt == 0) { /* first node added */ sview_part_sub->node_state = node_ptr->node_state; - sview_part_sub->features = node_ptr->features; - sview_part_sub->reason = node_ptr->reason; + sview_part_sub->features = xstrdup(node_ptr->features); + sview_part_sub->reason = xstrdup(node_ptr->reason); sview_part_sub->min_cpus = node_ptr->cpus; sview_part_sub->max_cpus = node_ptr->cpus; sview_part_sub->min_disk = node_ptr->tmp_disk; @@ -688,8 +689,8 @@ static sview_part_sub_t *_create_sview_part_sub(partition_info_t *part_ptr, sview_part_sub_ptr->min_weight = node_ptr->weight; sview_part_sub_ptr->max_weight = node_ptr->weight; - sview_part_sub_ptr->features = node_ptr->features; - sview_part_sub_ptr->reason = node_ptr->reason; + sview_part_sub_ptr->features = xstrdup(node_ptr->features); + sview_part_sub_ptr->reason = xstrdup(node_ptr->reason); sview_part_sub_ptr->hl = hostlist_create(node_ptr->name); @@ -879,6 +880,103 @@ extern int get_new_info_part(partition_info_msg_t **part_ptr, int force) return error_code; } +extern GtkListStore *create_model_part(int type) +{ + GtkListStore *model = NULL; + GtkTreeIter iter; + char *upper = NULL, *lower = NULL; + int i=0; + switch(type) { + case SORTID_AVAIL: + model = gtk_list_store_new(2, G_TYPE_STRING, + G_TYPE_INT); + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + 0, "up", + 1, i, + -1); + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + 0, "down", + 1, i, + -1); + break; + case SORTID_STATE: + model = gtk_list_store_new(2, G_TYPE_STRING, + G_TYPE_INT); + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + 0, "drain", + 1, i, + -1); + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + 0, "NoResp", + 1, i, + -1); + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, + 0, "resume", + 1, i, + -1); + for(i = 0; i < NODE_STATE_END; i++) { + upper = node_state_string(i); + gtk_list_store_append(model, &iter); + lower = str_tolower(upper); + gtk_list_store_set(model, &iter, + 0, lower, + 1, i, + -1); + xfree(lower); + } + + break; + + } + return model; +} + +extern void admin_edit_part(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data) +{ + GtkTreeStore *treestore = GTK_TREE_STORE(data); + GtkTreePath *path = gtk_tree_path_new_from_string(path_string); + GtkTreeIter iter; + update_node_msg_t node_msg; + update_part_msg_t part_msg; + + int column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), + "column")); + gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path); + switch(column) { + case SORTID_AVAIL: + slurm_init_part_desc_msg(&part_msg); + gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter, + SORTID_NAME, + &part_msg.name, -1); + if (!strcasecmp(new_text, "up")) + part_msg.state_up = 1; + else + part_msg.state_up = 0; + slurm_update_partition(&part_msg); + break; + case SORTID_STATE: + gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter, + SORTID_NODELIST, + &node_msg.node_names, -1); + update_state_node(treestore, &iter, + SORTID_STATE, SORTID_STATE_NUM, + new_text, &node_msg); + g_free(node_msg.node_names); + break; + } + gtk_tree_path_free (path); + + g_static_mutex_unlock(&sview_mutex); +} + extern void get_info_part(GtkTable *table, display_data_t *display_data) { int part_error_code = SLURM_SUCCESS; diff --git a/src/sview/sview.c b/src/sview/sview.c index d6b635c50bd..5191076187a 100644 --- a/src/sview/sview.c +++ b/src/sview/sview.c @@ -45,37 +45,46 @@ int global_sleep_time = 5; bool admin_mode = FALSE; GtkWidget *main_notebook = NULL; GtkWidget *main_statusbar = NULL; +GtkWidget *main_window = NULL; +GStaticMutex sview_mutex = G_STATIC_MUTEX_INIT; display_data_t main_display_data[] = { {G_TYPE_NONE, JOB_PAGE, "Jobs", TRUE, -1, - refresh_main, get_info_job, specific_info_job, + refresh_main, create_model_job, admin_edit_job, + get_info_job, specific_info_job, set_menus_job, NULL}, {G_TYPE_NONE, STEP_PAGE, NULL, FALSE, -1, - refresh_main, NULL, + refresh_main, NULL, NULL, NULL, NULL, NULL, NULL}, {G_TYPE_NONE, PART_PAGE, "Partitions", TRUE, -1, - refresh_main, get_info_part, specific_info_part, + refresh_main, create_model_part, admin_edit_part, + get_info_part, specific_info_part, set_menus_part, NULL}, #ifdef HAVE_BG {G_TYPE_NONE, BLOCK_PAGE, "BG Blocks", TRUE, -1, - refresh_main, get_info_block, specific_info_block, + refresh_main, NULL, NULL, + get_info_block, specific_info_block, set_menus_block, NULL}, {G_TYPE_NONE, NODE_PAGE, "Base Partitions", FALSE, -1, - refresh_main, get_info_node, specific_info_node, + refresh_main, NULL, NULL, + get_info_node, specific_info_node, set_menus_node, NULL}, #else {G_TYPE_NONE, BLOCK_PAGE, "BG Blocks", FALSE, -1, - refresh_main, get_info_block, specific_info_block, + refresh_main, NULL, NULL, + get_info_block, specific_info_block, set_menus_block, NULL}, {G_TYPE_NONE, NODE_PAGE, "Nodes", FALSE, -1, - refresh_main, get_info_node, specific_info_node, + refresh_main, NULL, NULL, + get_info_node, specific_info_node, set_menus_node, NULL}, #endif {G_TYPE_NONE, SUBMIT_PAGE, "Submit Job", FALSE, -1, - refresh_main, NULL, + refresh_main, NULL, NULL, NULL, NULL, NULL, NULL}, {G_TYPE_NONE, INFO_PAGE, NULL, FALSE, -1, refresh_main, NULL, NULL, + NULL, NULL, NULL, NULL}, {G_TYPE_NONE, -1, NULL, FALSE, -1} }; @@ -89,10 +98,12 @@ void *_page_thr(void *arg) xfree(page); while(page_running[num]) { + g_static_mutex_lock(&sview_mutex); gdk_threads_enter(); (display_data->get_info)(table, display_data); gdk_flush(); gdk_threads_leave(); + g_static_mutex_unlock(&sview_mutex); sleep(global_sleep_time); } @@ -464,7 +475,6 @@ void _search_entry(GtkEntry *entry, GtkComboBox *combo) int main(int argc, char *argv[]) { - GtkWidget *window = NULL; GtkWidget *menubar = NULL; GtkWidget *table = NULL; GtkWidget *label = NULL; @@ -492,13 +502,13 @@ int main(int argc, char *argv[]) gtk_init (&argc, &argv); /* fill in all static info for pages */ /* Make a window */ - window = gtk_dialog_new(); - g_signal_connect(G_OBJECT(window), "delete_event", + main_window = gtk_dialog_new(); + g_signal_connect(G_OBJECT(main_window), "delete_event", G_CALLBACK(_delete), NULL); - gtk_window_set_title(GTK_WINDOW(window), "Sview"); - gtk_window_set_default_size(GTK_WINDOW(window), 600, 400); - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), - 1); + gtk_window_set_title(GTK_WINDOW(main_window), "Sview"); + gtk_window_set_default_size(GTK_WINDOW(main_window), 600, 400); + gtk_container_set_border_width( + GTK_CONTAINER(GTK_DIALOG(main_window)->vbox), 1); /* Create the main notebook, place the position of the tabs */ main_notebook = gtk_notebook_new(); g_signal_connect(G_OBJECT(main_notebook), "switch_page", @@ -508,7 +518,7 @@ int main(int argc, char *argv[]) gtk_table_set_homogeneous(GTK_TABLE(table), FALSE); gtk_container_set_border_width(GTK_CONTAINER(table), 1); /* Create a menu */ - menubar = _get_menubar_menu(window, main_notebook); + menubar = _get_menubar_menu(main_window, main_notebook); gtk_table_attach_defaults(GTK_TABLE(table), menubar, 0, 1, 0, 1); label = gtk_label_new("Search "); @@ -521,7 +531,7 @@ int main(int argc, char *argv[]) GTK_SHRINK, GTK_EXPAND | GTK_FILL, 0, 0); - entry = gtk_entry_new (); + entry = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 0, 1, GTK_SHRINK, GTK_EXPAND | GTK_FILL, 0, 0); @@ -538,11 +548,11 @@ int main(int argc, char *argv[]) gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(main_statusbar), FALSE); /* Pack it all together */ - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(main_window)->vbox), table, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(main_window)->vbox), main_notebook, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(main_window)->vbox), main_statusbar, FALSE, FALSE, 0); for(i=0; i<PAGE_CNT; i++) { @@ -556,7 +566,7 @@ int main(int argc, char *argv[]) /* tell signal we are done adding */ adding = 0; popup_list = list_create(destroy_popup_info); - gtk_widget_show_all (window); + gtk_widget_show_all (main_window); /* Finished! */ gtk_main (); diff --git a/src/sview/sview.h b/src/sview/sview.h index a8c307921b8..be2e5ee5898 100644 --- a/src/sview/sview.h +++ b/src/sview/sview.h @@ -126,6 +126,11 @@ struct display_data { bool show; int extra; void (*refresh) (GtkAction *action, gpointer user_data); + GtkListStore *(*create_model)(int type); + void (*admin_edit) (GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data); void (*get_info) (GtkTable *table, display_data_t *display_data); void (*specific) (popup_info_t *popup_win); void (*set_menu) (void *arg, GtkTreePath *path, @@ -171,7 +176,8 @@ extern bool force_refresh; extern List popup_list; extern int global_sleep_time; extern bool admin_mode; - +extern GtkWidget *main_window; +extern GStaticMutex sview_mutex; extern void init_grid(node_info_msg_t *node_info_ptr); extern int set_grid(int start, int end, int count); @@ -189,6 +195,11 @@ extern void tab_pressed(GtkWidget *widget, GdkEventButton *event, // part_info.c extern void refresh_part(GtkAction *action, gpointer user_data); +extern GtkListStore *create_model_part(int type); +extern void admin_edit_part(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data); extern int get_new_info_part(partition_info_msg_t **part_ptr, int force); extern void get_info_part(GtkTable *table, display_data_t *display_data); extern void specific_info_part(popup_info_t *popup_win); @@ -198,6 +209,11 @@ extern void popup_all_part(GtkTreeModel *model, GtkTreeIter *iter, int id); // block_info.c extern void refresh_block(GtkAction *action, gpointer user_data); +extern GtkListStore *create_model_block(int type); +extern void admin_edit_block(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data); extern int get_new_info_node_select(node_select_info_msg_t **node_select_ptr, int force); extern void get_info_block(GtkTable *table, display_data_t *display_data); @@ -208,6 +224,11 @@ extern void popup_all_block(GtkTreeModel *model, GtkTreeIter *iter, int id); // job_info.c extern void refresh_job(GtkAction *action, gpointer user_data); +extern GtkListStore *create_model_job(int type); +extern void admin_edit_job(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data); extern int get_new_info_job(job_info_msg_t **info_ptr, int force); extern int get_new_info_job_step(job_step_info_response_msg_t **info_ptr, int force); @@ -219,6 +240,15 @@ extern void popup_all_job(GtkTreeModel *model, GtkTreeIter *iter, int id); // node_info.c extern void refresh_node(GtkAction *action, gpointer user_data); +extern int update_state_node(GtkTreeStore *treestore, GtkTreeIter *iter, + int text_column, int num_column, + const char *new_text, + update_node_msg_t *node_msg); +extern GtkListStore *create_model_node(int type); +extern void admin_edit_node(GtkCellRendererText *cell, + const char *path_string, + const char *new_text, + gpointer data); extern int get_new_info_node(node_info_msg_t **info_ptr, int force); extern void get_info_node(GtkTable *table, display_data_t *display_data); extern void specific_info_node(popup_info_t *popup_win); @@ -247,8 +277,8 @@ extern void right_button_pressed(GtkTreeView *tree_view, GtkTreePath *path, GdkEventButton *event, const display_data_t *display_data, int type); -extern void row_clicked(GtkTreeView *tree_view, GdkEventButton *event, - const display_data_t *display_data); +extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event, + const display_data_t *display_data); extern popup_info_t *create_popup_info(int type, int dest_type, char *title); extern void setup_popup_info(popup_info_t *popup_win, display_data_t *display_data, @@ -262,4 +292,6 @@ extern void *popup_thr(popup_info_t *popup_win); extern void remove_old(GtkTreeModel *model, int updated); extern GtkWidget *create_pulldown_combo(display_data_t *display_data, int count); +extern char *str_tolower(char *upper_str); +extern char *get_reason(); #endif -- GitLab