blob: ee6e5b26293991442ec94eaf0c39d32794af154e [file] [log] [blame] [edit]
/*****************************************************************************\
* resv_info.c - Functions related to advanced reservation display
* mode of sview.
*****************************************************************************
* Copyright (C) 2009-2011 Lawrence Livermore National Security.
* Copyright (C) SchedMD LLC.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Morris Jette <jette@llnl.gov>
* CODE-OCEC-09-009. All rights reserved.
*
* This file is part of Slurm, a resource management program.
* For details, see <https://slurm.schedmd.com/>.
* Please also read the included file: DISCLAIMER.
*
* Slurm is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with Slurm; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\*****************************************************************************/
#include "src/common/uid.h"
#include "src/sview/sview.h"
#include "src/common/parse_time.h"
#include "src/common/proc_args.h"
#include "src/common/xstring.h"
#define _DEBUG 0
/* Collection of data for printing reports. Like data is combined here */
typedef struct {
int color_inx;
GtkTreeIter iter_ptr;
bool iter_set;
int pos;
char *resv_name;
reserve_info_t *resv_ptr;
} sview_resv_info_t;
enum {
EDIT_REMOVE = 1,
EDIT_EDIT
};
/* These need to be in alpha order (except POS and CNT) */
enum {
SORTID_POS = POS_LOC,
SORTID_ACCOUNTS,
SORTID_ACTION,
SORTID_BURST_BUFFER,
SORTID_COLOR,
SORTID_COLOR_INX,
SORTID_CORE_CNT,
SORTID_DURATION,
SORTID_FEATURES,
SORTID_FLAGS,
SORTID_GROUPS,
SORTID_LICENSES,
SORTID_MSD,
SORTID_NAME,
SORTID_NODE_CNT,
SORTID_NODELIST,
SORTID_NODE_INX,
SORTID_PARTITION,
SORTID_TIME_END,
SORTID_TIME_START,
SORTID_TRES,
SORTID_UPDATED,
SORTID_USERS,
SORTID_WATTS,
SORTID_CNT
};
/* extra field here is for choosing the type of edit you that will
* take place. If you choose EDIT_MODEL (means only display a set of
* known options) create it in function create_model_*.
*/
/* these are the settings to apply for the user
* on the first startup after a fresh slurm install.
* s/b a const probably */
static char *_initial_page_opts = "Name,Node_Count,Core_Count,NodeList,"
"Time_Start,Time_End";
static display_data_t display_data_resv[] = {
{G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_NAME, "Name", false, EDIT_NONE,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_COLOR, NULL, true, EDIT_COLOR,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_ACTION, "Action", false, EDIT_MODEL,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_NODE_CNT, "Node Count", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_CORE_CNT, "Core Count", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_NODELIST, "Node List", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_TIME_START, "Time Start", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_TIME_END, "Time End", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_DURATION, "Duration", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_ACCOUNTS, "Accounts", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_BURST_BUFFER, "BurstBuffer", false,
EDIT_TEXTBOX, refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_LICENSES, "Licenses", true, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_USERS, "Users", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_GROUPS, "Groups", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_PARTITION, "Partition", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_FEATURES, "Features", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_FLAGS, "Flags", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_POINTER, SORTID_NODE_INX, NULL, false, EDIT_NONE,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_INT, SORTID_COLOR_INX, NULL, false, EDIT_NONE,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_TRES, "TRES", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_INT, SORTID_UPDATED, NULL, false, EDIT_NONE,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_WATTS, "Watts", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_MSD, "MaxStartDelay", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
};
static display_data_t create_data_resv[] = {
{G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_NAME, "Name", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_NODE_CNT, "Node_Count", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_CORE_CNT, "Core_Count", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_NODELIST, "Node_List", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_TIME_START, "Time_Start", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_TIME_END, "Time_End", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_DURATION, "Duration", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_ACCOUNTS, "Accounts", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_BURST_BUFFER, "BurstBuffer", false,
EDIT_TEXTBOX, refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_USERS, "Users", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_GROUPS, "Groups", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_PARTITION, "Partition", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_FEATURES, "Features", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_FLAGS, "Flags", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_TRES, "TRES", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_WATTS, "Watts", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_STRING, SORTID_MSD, "MaxStartDelay", false, EDIT_TEXTBOX,
refresh_resv, create_model_resv, admin_edit_resv},
{G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
};
static display_data_t options_data_resv[] = {
{G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE},
{G_TYPE_STRING, INFO_PAGE, "Full Info", true, RESV_PAGE},
{G_TYPE_STRING, RESV_PAGE, "Remove Reservation", true, ADMIN_PAGE},
{G_TYPE_STRING, RESV_PAGE, "Edit Reservation", true, ADMIN_PAGE},
{G_TYPE_STRING, JOB_PAGE, "Jobs", true, RESV_PAGE},
{G_TYPE_STRING, PART_PAGE, "Partitions", true, RESV_PAGE},
{G_TYPE_STRING, NODE_PAGE, "Nodes", true, RESV_PAGE},
{G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
};
static display_data_t *local_display_data = NULL;
static char *got_edit_signal = NULL;
static GtkTreeModel *last_model = NULL;
static void _admin_resv(GtkTreeModel *model, GtkTreeIter *iter, char *type);
static void _process_each_resv(GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter*iter, gpointer userdata);
static void _set_active_combo_resv(GtkComboBox *combo,
GtkTreeModel *model, GtkTreeIter *iter,
int type)
{
char *temp_char = NULL;
int action = 0;
gtk_tree_model_get(model, iter, type, &temp_char, -1);
if (!temp_char)
goto end_it;
switch (type) {
case SORTID_ACTION:
if (!xstrcmp(temp_char, "none"))
action = 0;
else if (!xstrcmp(temp_char, "remove"))
action = 1;
else
action = 0;
break;
default:
break;
}
g_free(temp_char);
end_it:
gtk_combo_box_set_active(combo, action);
}
/* don't free this char */
static const char *_set_resv_msg(resv_desc_msg_t *resv_msg,
const char *new_text,
int column)
{
char *type = "";
uint32_t res_free_flags = 0;
int temp_int = 0;
uint64_t f;
/* need to clear global_edit_error here (just in case) */
global_edit_error = 0;
if (!resv_msg)
return NULL;
switch (column) {
case SORTID_ACCOUNTS:
resv_msg->accounts = xstrdup(new_text);
type = "accounts";
break;
case SORTID_ACTION:
xfree(got_edit_signal);
if (!xstrcasecmp(new_text, "None"))
got_edit_signal = NULL;
else
got_edit_signal = xstrdup(new_text);
break;
case SORTID_BURST_BUFFER:
resv_msg->burst_buffer = xstrdup(new_text);
type = "burst_buffer";
break;
case SORTID_CORE_CNT:
if (strtok_r((char *)new_text, ",", &type)) {
type = NULL;
if (global_edit_error_msg)
g_free(global_edit_error_msg);
global_edit_error_msg = g_strdup("Using a comma separated array for CoreCnt is no longer valid.");
goto return_error;
}
type = "Core Count";
resv_msg->core_cnt = slurm_atoul((char *)new_text);
break;
case SORTID_DURATION:
type = "duration";
temp_int = time_str2mins((char *)new_text);
if (temp_int <= 0)
goto return_error;
resv_msg->duration = temp_int;
break;
case SORTID_TIME_END:
resv_msg->end_time = parse_time((char *)new_text, 0);
type = "end time";
break;
case SORTID_FEATURES:
resv_msg->features = xstrdup(new_text);
type = "features";
break;
case SORTID_FLAGS:
f = parse_resv_flags(new_text, __func__, resv_msg);
type = "flags";
if (f == INFINITE64)
goto return_error;
break;
case SORTID_GROUPS:
resv_msg->groups = xstrdup(new_text);
type = "groups";
break;
case SORTID_LICENSES:
resv_msg->licenses = xstrdup(new_text);
type = "licenses";
break;
case SORTID_MSD:
type = "MaxStartDelay";
temp_int = time_str2secs((char *)new_text);
if (temp_int < 0)
goto return_error;
resv_msg->max_start_delay = temp_int;
break;
case SORTID_NAME:
resv_msg->name = xstrdup(new_text);
type = "name";
break;
case SORTID_NODE_CNT:
if (strtok_r((char *)new_text, ",", &type)) {
type = NULL;
if (global_edit_error_msg)
g_free(global_edit_error_msg);
global_edit_error_msg = g_strdup("Using a comma separated array for NodeCnt is no longer valid.");
goto return_error;
}
type = "Node Count";
resv_msg->node_cnt = slurm_atoul((char *)new_text);
break;
case SORTID_NODELIST:
resv_msg->node_list = xstrdup(new_text);
type = "Node List";
break;
case SORTID_PARTITION:
resv_msg->partition = xstrdup(new_text);
type = "partition";
break;
case SORTID_TIME_START:
resv_msg->start_time = parse_time((char *)new_text, 0);
type = "start time";
break;
case SORTID_USERS:
resv_msg->users = xstrdup(new_text);
type = "users";
break;
case SORTID_TRES:
resv_msg->tres_str = xstrdup(new_text);
type = "TRES";
break;
default:
type = "unknown";
break;
}
if (xstrcmp(type, "unknown"))
global_send_update_msg = 1;
slurm_free_resv_desc_msg_part(resv_msg, res_free_flags);
return type;
return_error:
slurm_free_resv_desc_msg_part(resv_msg, res_free_flags);
global_edit_error = 1;
return type;
}
static void _resv_info_free(sview_resv_info_t *sview_resv_info)
{
if (sview_resv_info) {
xfree(sview_resv_info->resv_name);
}
}
static void _resv_info_list_del(void *object)
{
sview_resv_info_t *sview_resv_info = (sview_resv_info_t *)object;
if (sview_resv_info) {
_resv_info_free(sview_resv_info);
xfree(sview_resv_info);
}
}
static void _admin_edit_combo_box_resv(GtkComboBox *combo,
resv_desc_msg_t *resv_msg)
{
GtkTreeModel *model = NULL;
GtkTreeIter iter;
int column = 0;
char *name = NULL;
if (!resv_msg)
return;
if (!gtk_combo_box_get_active_iter(combo, &iter)) {
g_print("nothing selected\n");
return;
}
model = gtk_combo_box_get_model(combo);
if (!model) {
g_print("nothing selected\n");
return;
}
gtk_tree_model_get(model, &iter, 0, &name, -1);
gtk_tree_model_get(model, &iter, 1, &column, -1);
_set_resv_msg(resv_msg, name, column);
g_free(name);
}
static gboolean _admin_focus_out_resv(GtkEntry *entry,
GdkEventFocus *event,
resv_desc_msg_t *resv_msg)
{
if (global_entry_changed) {
const char *col_name = NULL;
int type = gtk_entry_get_max_length(entry);
const char *name = gtk_entry_get_text(entry);
type -= DEFAULT_ENTRY_LENGTH;
col_name = _set_resv_msg(resv_msg, name, type);
if (global_edit_error && !global_edit_error_msg) {
global_edit_error_msg = g_strdup_printf(
"Reservation %s %s can't be set to %s",
resv_msg->name,
col_name,
name);
}
global_entry_changed = 0;
}
return false;
}
static GtkWidget *_admin_full_edit_resv(resv_desc_msg_t *resv_msg,
GtkTreeModel *model, GtkTreeIter *iter)
{
GtkScrolledWindow *window = create_scrolled_window();
GtkBin *bin = NULL;
GtkViewport *view = NULL;
GtkTable *table = NULL;
int i = 0, row = 0;
display_data_t *display_data = display_data_resv;
gtk_scrolled_window_set_policy(window,
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
bin = GTK_BIN(&window->container);
view = GTK_VIEWPORT(bin->child);
bin = GTK_BIN(&view->bin);
table = GTK_TABLE(bin->child);
gtk_table_resize(table, SORTID_CNT, 2);
gtk_table_set_homogeneous(table, false);
for (i = 0; i < SORTID_CNT; i++) {
while (display_data++) {
if (display_data->id == -1)
break;
if (!display_data->name)
continue;
if (display_data->id != i)
continue;
display_admin_edit(
table, resv_msg, &row, model, iter,
display_data,
G_CALLBACK(_admin_edit_combo_box_resv),
G_CALLBACK(_admin_focus_out_resv),
_set_active_combo_resv);
break;
}
display_data = display_data_resv;
}
gtk_table_resize(table, row, 2);
return GTK_WIDGET(window);
}
static void _layout_resv_record(GtkTreeView *treeview,
sview_resv_info_t *sview_resv_info,
int update)
{
GtkTreeIter iter;
char time_buf[256];
reserve_info_t *resv_ptr = sview_resv_info->resv_ptr;
char *temp_char = NULL;
GtkTreeStore *treestore =
GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_ACCOUNTS),
resv_ptr->accounts);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_BURST_BUFFER),
resv_ptr->burst_buffer);
convert_num_unit((float)resv_ptr->core_cnt,
time_buf, sizeof(time_buf), UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_CORE_CNT),
time_buf);
secs2time_str((uint32_t)difftime(resv_ptr->end_time,
resv_ptr->start_time),
time_buf, sizeof(time_buf));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_DURATION),
time_buf);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_FEATURES),
resv_ptr->features);
temp_char = reservation_flags_string(resv_ptr);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_FLAGS),
temp_char);
xfree(temp_char);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_GROUPS),
resv_ptr->groups);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_LICENSES),
resv_ptr->licenses);
if (resv_ptr->max_start_delay)
secs2time_str(resv_ptr->max_start_delay,
time_buf, sizeof(time_buf));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_MSD),
resv_ptr->max_start_delay ?
time_buf : NULL);
/* NOTE: node_cnt in reservation info from slurmctld ONE number */
convert_num_unit((float)resv_ptr->node_cnt,
time_buf, sizeof(time_buf), UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_NODE_CNT),
time_buf);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_NODELIST),
resv_ptr->node_list);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_PARTITION),
resv_ptr->partition);
slurm_make_time_str((time_t *)&resv_ptr->end_time, time_buf,
sizeof(time_buf));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_TIME_END),
time_buf);
slurm_make_time_str((time_t *)&resv_ptr->start_time, time_buf,
sizeof(time_buf));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_TIME_START),
time_buf);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_TRES),
resv_ptr->tres_str);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_resv,
SORTID_USERS),
resv_ptr->users);
}
static void _update_resv_record(sview_resv_info_t *sview_resv_info_ptr,
GtkTreeStore *treestore)
{
char tmp_duration[40], tmp_end[256], tmp_nodes[40], tmp_start[256];
char tmp_cores[40], tmp_msd[40];
char *tmp_flags;
reserve_info_t *resv_ptr = sview_resv_info_ptr->resv_ptr;
secs2time_str((uint32_t)difftime(resv_ptr->end_time,
resv_ptr->start_time),
tmp_duration, sizeof(tmp_duration));
slurm_make_time_str((time_t *)&resv_ptr->end_time, tmp_end,
sizeof(tmp_end));
tmp_flags = reservation_flags_string(resv_ptr);
convert_num_unit((float)resv_ptr->core_cnt,
tmp_cores, sizeof(tmp_cores), UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
convert_num_unit((float)resv_ptr->node_cnt,
tmp_nodes, sizeof(tmp_nodes), UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
slurm_make_time_str((time_t *)&resv_ptr->start_time, tmp_start,
sizeof(tmp_start));
if (resv_ptr->max_start_delay)
secs2time_str(resv_ptr->max_start_delay,
tmp_msd, sizeof(tmp_msd));
/* Combining these records provides a slight performance improvement */
gtk_tree_store_set(treestore, &sview_resv_info_ptr->iter_ptr,
SORTID_ACCOUNTS, resv_ptr->accounts,
SORTID_BURST_BUFFER, resv_ptr->burst_buffer,
SORTID_COLOR,
sview_colors[sview_resv_info_ptr->color_inx],
SORTID_COLOR_INX, sview_resv_info_ptr->color_inx,
SORTID_CORE_CNT, tmp_cores,
SORTID_DURATION, tmp_duration,
SORTID_FEATURES, resv_ptr->features,
SORTID_FLAGS, tmp_flags,
SORTID_GROUPS, resv_ptr->groups,
SORTID_LICENSES, resv_ptr->licenses,
SORTID_MSD, resv_ptr->max_start_delay ?
tmp_msd : NULL,
SORTID_NAME, resv_ptr->name,
SORTID_NODE_CNT, tmp_nodes,
SORTID_NODE_INX, resv_ptr->node_inx,
SORTID_NODELIST, resv_ptr->node_list,
SORTID_PARTITION, resv_ptr->partition,
SORTID_TIME_START, tmp_start,
SORTID_TIME_END, tmp_end,
SORTID_TRES, resv_ptr->tres_str,
SORTID_UPDATED, 1,
SORTID_USERS, resv_ptr->users,
-1);
xfree(tmp_flags);
return;
}
static void _append_resv_record(sview_resv_info_t *sview_resv_info_ptr,
GtkTreeStore *treestore)
{
gtk_tree_store_append(treestore, &sview_resv_info_ptr->iter_ptr, NULL);
gtk_tree_store_set(treestore, &sview_resv_info_ptr->iter_ptr,
SORTID_POS, sview_resv_info_ptr->pos, -1);
_update_resv_record(sview_resv_info_ptr, treestore);
}
static void _update_info_resv(list_t *info_list, GtkTreeView *tree_view)
{
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
char *name = NULL;
list_itr_t *itr = NULL;
sview_resv_info_t *sview_resv_info = NULL;
set_for_update(model, SORTID_UPDATED);
itr = list_iterator_create(info_list);
while ((sview_resv_info = list_next(itr))) {
/* This means the tree_store changed (added new column
or something). */
if (last_model != model)
sview_resv_info->iter_set = false;
if (sview_resv_info->iter_set) {
gtk_tree_model_get(model, &sview_resv_info->iter_ptr,
SORTID_NAME, &name, -1);
if (xstrcmp(name, sview_resv_info->resv_name)) {
/* Bad pointer */
sview_resv_info->iter_set = false;
//g_print("bad resv iter pointer\n");
}
g_free(name);
}
if (sview_resv_info->iter_set) {
_update_resv_record(sview_resv_info,
GTK_TREE_STORE(model));
} else {
_append_resv_record(sview_resv_info,
GTK_TREE_STORE(model));
sview_resv_info->iter_set = true;
}
}
list_iterator_destroy(itr);
/* remove all old reservations */
remove_old(model, SORTID_UPDATED);
last_model = model;
}
static int _sview_resv_sort_aval_dec(void *s1, void *s2)
{
sview_resv_info_t *rec_a = *(sview_resv_info_t **)s1;
sview_resv_info_t *rec_b = *(sview_resv_info_t **)s2;
int size_a;
int size_b;
size_a = rec_a->resv_ptr->node_cnt;
size_b = rec_b->resv_ptr->node_cnt;
if (size_a < size_b)
return -1;
else if (size_a > size_b)
return 1;
if (rec_a->resv_ptr->node_list && rec_b->resv_ptr->node_list) {
size_a = xstrcmp(rec_a->resv_ptr->node_list,
rec_b->resv_ptr->node_list);
if (size_a < 0)
return -1;
else if (size_a > 0)
return 1;
}
return 0;
}
static list_t *_create_resv_info_list(reserve_info_msg_t *resv_info_ptr)
{
static list_t *info_list = NULL;
list_t *last_list = NULL;
list_itr_t *last_list_itr = NULL;
int i = 0;
static reserve_info_msg_t *last_resv_info_ptr = NULL;
sview_resv_info_t *sview_resv_info_ptr = NULL;
reserve_info_t *resv_ptr = NULL;
if (info_list && (resv_info_ptr == last_resv_info_ptr))
goto update_color;
last_resv_info_ptr = resv_info_ptr;
if (info_list)
last_list = info_list;
info_list = list_create(_resv_info_list_del);
if (last_list)
last_list_itr = list_iterator_create(last_list);
for(i=0; i<resv_info_ptr->record_count; i++) {
resv_ptr = &(resv_info_ptr->reservation_array[i]);
sview_resv_info_ptr = NULL;
if (last_list_itr) {
while ((sview_resv_info_ptr =
list_next(last_list_itr))) {
if (!xstrcmp(sview_resv_info_ptr->resv_name,
resv_ptr->name)) {
list_remove(last_list_itr);
_resv_info_free(sview_resv_info_ptr);
break;
}
}
list_iterator_reset(last_list_itr);
}
if (!sview_resv_info_ptr)
sview_resv_info_ptr =
xmalloc(sizeof(sview_resv_info_t));
sview_resv_info_ptr->resv_name = xstrdup(resv_ptr->name);
sview_resv_info_ptr->pos = i;
sview_resv_info_ptr->resv_ptr = resv_ptr;
sview_resv_info_ptr->color_inx = i % sview_colors_cnt;
list_append(info_list, sview_resv_info_ptr);
}
list_sort(info_list,
(ListCmpF)_sview_resv_sort_aval_dec);
if (last_list) {
list_iterator_destroy(last_list_itr);
FREE_NULL_LIST(last_list);
}
update_color:
return info_list;
}
static void _display_info_resv(list_t *info_list, popup_info_t *popup_win)
{
specific_info_t *spec_info = popup_win->spec_info;
char *name = (char *)spec_info->search_info->gchar_data;
int found = 0;
reserve_info_t *resv_ptr = NULL;
GtkTreeView *treeview = NULL;
list_itr_t *itr = NULL;
sview_resv_info_t *sview_resv_info = NULL;
int update = 0;
int j = 0;
if (!spec_info->search_info->gchar_data) {
//info = xstrdup("No pointer given!");
goto finished;
}
need_refresh:
if (!spec_info->display_widget) {
treeview = create_treeview_2cols_attach_to_table(
popup_win->table);
spec_info->display_widget =
g_object_ref(GTK_WIDGET(treeview));
} else {
treeview = GTK_TREE_VIEW(spec_info->display_widget);
update = 1;
}
itr = list_iterator_create(info_list);
while ((sview_resv_info = list_next(itr))) {
resv_ptr = sview_resv_info->resv_ptr;
if (!xstrcmp(resv_ptr->name, name)) {
j=0;
while (resv_ptr->node_inx[j] >= 0) {
change_grid_color(
popup_win->grid_button_list,
resv_ptr->node_inx[j],
resv_ptr->node_inx[j+1],
sview_resv_info->color_inx,
true, 0);
j += 2;
}
_layout_resv_record(treeview, sview_resv_info, update);
found = 1;
break;
}
}
list_iterator_destroy(itr);
post_setup_popup_grid_list(popup_win);
if (!found) {
if (!popup_win->not_found) {
char *temp = "RESERVATION DOESN'T EXIST\n";
GtkTreeIter iter;
GtkTreeModel *model = NULL;
/* only time this will be run so no update */
model = gtk_tree_view_get_model(treeview);
add_display_treestore_line(0,
GTK_TREE_STORE(model),
&iter,
temp, "");
}
popup_win->not_found = true;
} else {
if (popup_win->not_found) {
popup_win->not_found = false;
gtk_widget_destroy(spec_info->display_widget);
goto need_refresh;
}
}
gtk_widget_show(spec_info->display_widget);
finished:
return;
}
extern GtkWidget *create_resv_entry(resv_desc_msg_t *resv_msg,
GtkTreeModel *model, GtkTreeIter *iter)
{
GtkScrolledWindow *window = create_scrolled_window();
GtkBin *bin = NULL;
GtkViewport *view = NULL;
GtkTable *table = NULL;
int i = 0, row = 0;
display_data_t *display_data = create_data_resv;
gtk_scrolled_window_set_policy(window,
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
bin = GTK_BIN(&window->container);
view = GTK_VIEWPORT(bin->child);
bin = GTK_BIN(&view->bin);
table = GTK_TABLE(bin->child);
gtk_table_resize(table, SORTID_CNT, 2);
gtk_table_set_homogeneous(table, false);
for (i = 0; i < SORTID_CNT; i++) {
while (display_data++) {
if (display_data->id == -1)
break;
if (!display_data->name)
continue;
if (display_data->id != i)
continue;
display_admin_edit(
table, resv_msg, &row, model, iter,
display_data,
G_CALLBACK(_admin_edit_combo_box_resv),
G_CALLBACK(_admin_focus_out_resv),
_set_active_combo_resv);
break;
}
display_data = create_data_resv;
}
gtk_table_resize(table, row, 2);
return GTK_WIDGET(window);
}
extern void refresh_resv(GtkAction *action, gpointer user_data)
{
popup_info_t *popup_win = (popup_info_t *)user_data;
xassert(popup_win);
xassert(popup_win->spec_info);
xassert(popup_win->spec_info->title);
popup_win->force_refresh = 1;
specific_info_resv(popup_win);
}
extern int get_new_info_resv(reserve_info_msg_t **info_ptr,
int force)
{
static reserve_info_msg_t *new_resv_ptr = NULL;
int error_code = SLURM_NO_CHANGE_IN_DATA;
time_t now = time(NULL);
static time_t last;
static bool changed = 0;
if (g_resv_info_ptr && !force
&& ((now - last) < working_sview_config.refresh_delay)) {
if (*info_ptr != g_resv_info_ptr)
error_code = SLURM_SUCCESS;
*info_ptr = g_resv_info_ptr;
if (changed)
error_code = SLURM_SUCCESS;
goto end_it;
}
last = now;
if (g_resv_info_ptr) {
error_code = slurm_load_reservations(
g_resv_info_ptr->last_update, &new_resv_ptr);
if (error_code == SLURM_SUCCESS) {
slurm_free_reservation_info_msg(g_resv_info_ptr);
changed = 1;
} else if (errno == SLURM_NO_CHANGE_IN_DATA) {
error_code = SLURM_NO_CHANGE_IN_DATA;
new_resv_ptr = g_resv_info_ptr;
changed = 0;
}
} else {
new_resv_ptr = NULL;
error_code = slurm_load_reservations((time_t) NULL,
&new_resv_ptr);
changed = 1;
}
g_resv_info_ptr = new_resv_ptr;
if (g_resv_info_ptr && (*info_ptr != g_resv_info_ptr))
error_code = SLURM_SUCCESS;
*info_ptr = g_resv_info_ptr;
end_it:
return error_code;
}
extern GtkListStore *create_model_resv(int type)
{
GtkListStore *model = NULL;
GtkTreeIter iter;
last_model = NULL; /* Reformat display */
switch(type) {
case SORTID_ACTION:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "None",
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
1, SORTID_ACTION,
0, "Remove Reservation",
-1);
break;
default:
break;
}
return model;
}
extern void admin_edit_resv(GtkCellRendererText *cell,
const char *path_string,
const char *new_text,
gpointer data)
{
GtkTreeStore *treestore = NULL;
GtkTreePath *path = NULL;
GtkTreeIter iter;
resv_desc_msg_t *resv_msg = NULL;
char *temp = NULL;
char *old_text = NULL;
const char *type = NULL;
int column;
if (!new_text || !xstrcmp(new_text, ""))
goto no_input;
if (cluster_flags & CLUSTER_FLAG_FED) {
display_fed_disabled_popup(type);
goto no_input;
}
column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "column"));
path = gtk_tree_path_new_from_string(path_string);
treestore = GTK_TREE_STORE(data);
gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
SORTID_NAME, &temp,
column, &old_text,
-1);
resv_msg = xmalloc(sizeof(resv_desc_msg_t));
slurm_init_resv_desc_msg(resv_msg);
resv_msg->name = xstrdup(temp);
g_free(temp);
type = _set_resv_msg(resv_msg, new_text, column);
if (global_edit_error)
goto print_error;
if (got_edit_signal) {
temp = got_edit_signal;
got_edit_signal = NULL;
_admin_resv(GTK_TREE_MODEL(treestore), &iter, temp);
xfree(temp);
goto no_input;
}
if (old_text && !xstrcmp(old_text, new_text)) {
temp = g_strdup_printf("No change in value.");
} else if (slurm_update_reservation(resv_msg)
== SLURM_SUCCESS) {
gtk_tree_store_set(treestore, &iter, column, new_text, -1);
temp = g_strdup_printf("Reservation %s %s changed to %s",
resv_msg->name,
type,
new_text);
} else if (errno == ESLURM_DISABLED) {
temp = g_strdup_printf(
"Can only edit %s on reservations not yet started.",
type);
} else {
print_error:
temp = g_strdup_printf("Reservation %s %s can't be "
"set to %s",
resv_msg->name,
type,
new_text);
}
display_edit_note(temp);
g_free(temp);
no_input:
slurm_free_resv_desc_msg(resv_msg);
gtk_tree_path_free(path);
g_free(old_text);
g_mutex_unlock(sview_mutex);
}
extern void get_info_resv(GtkTable *table, display_data_t *display_data)
{
int error_code = SLURM_SUCCESS;
list_t *info_list = NULL;
static int view = -1;
static reserve_info_msg_t *resv_info_ptr = NULL;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
static GtkWidget *display_widget = NULL;
int j=0;
list_itr_t *itr = NULL;
sview_resv_info_t *sview_resv_info_ptr = NULL;
reserve_info_t *resv_ptr = NULL;
time_t now = time(NULL);
GtkTreePath *path = NULL;
static bool set_opts = false;
if (!set_opts)
set_page_opts(RESV_PAGE, display_data_resv,
SORTID_CNT, _initial_page_opts);
set_opts = true;
/* reset */
if (!table && !display_data) {
if (display_widget)
gtk_widget_destroy(display_widget);
display_widget = NULL;
resv_info_ptr = NULL;
goto reset_curs;
}
if (display_data)
local_display_data = display_data;
if (!table) {
display_data_resv->set_menu = local_display_data->set_menu;
goto reset_curs;
}
if (cluster_flags & CLUSTER_FLAG_FED) {
view = ERROR_VIEW;
if (display_widget)
gtk_widget_destroy(display_widget);
label = gtk_label_new("Not available in a federated view");
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
gtk_widget_show(label);
display_widget = g_object_ref(label);
goto end_it;
}
if (display_widget && toggled) {
gtk_widget_destroy(display_widget);
display_widget = NULL;
goto display_it;
}
error_code = get_new_info_resv(&resv_info_ptr, force_refresh);
if (error_code == SLURM_NO_CHANGE_IN_DATA) {
} else if (error_code != SLURM_SUCCESS) {
if (view == ERROR_VIEW)
goto end_it;
if (display_widget)
gtk_widget_destroy(display_widget);
view = ERROR_VIEW;
sprintf(error_char, "slurm_load_reservations: %s",
slurm_strerror(errno));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
gtk_widget_show(label);
display_widget = g_object_ref(GTK_WIDGET(label));
goto end_it;
}
display_it:
info_list = _create_resv_info_list(resv_info_ptr);
if (!info_list)
goto reset_curs;
/* set up the grid */
if (display_widget && GTK_IS_TREE_VIEW(display_widget)
&& gtk_tree_selection_count_selected_rows(
gtk_tree_view_get_selection(
GTK_TREE_VIEW(display_widget)))) {
GtkTreeViewColumn *focus_column = NULL;
/* highlight the correct nodes from the last selection */
gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget),
&path, &focus_column);
}
if (!path) {
itr = list_iterator_create(info_list);
while ((sview_resv_info_ptr = list_next(itr))) {
resv_ptr = sview_resv_info_ptr->resv_ptr;
if ((resv_ptr->start_time > now) ||
(resv_ptr->end_time < now))
continue;/* only map current reservations */
j=0;
while (resv_ptr->node_inx[j] >= 0) {
change_grid_color(grid_button_list,
resv_ptr->node_inx[j],
resv_ptr->node_inx[j+1],
sview_resv_info_ptr->
color_inx,
true, 0);
j += 2;
}
}
list_iterator_destroy(itr);
change_grid_color(grid_button_list, -1, -1,
MAKE_WHITE, true, 0);
} else {
highlight_grid(GTK_TREE_VIEW(display_widget),
SORTID_NODE_INX, SORTID_COLOR_INX,
grid_button_list);
gtk_tree_path_free(path);
}
if (view == ERROR_VIEW && display_widget) {
gtk_widget_destroy(display_widget);
display_widget = NULL;
}
if (!display_widget) {
tree_view = create_treeview(local_display_data,
&grid_button_list);
gtk_tree_selection_set_mode(
gtk_tree_view_get_selection(tree_view),
GTK_SELECTION_MULTIPLE);
display_widget = g_object_ref(GTK_WIDGET(tree_view));
gtk_table_attach_defaults(table,
GTK_WIDGET(tree_view),
0, 1, 0, 1);
/* since this function sets the model of the tree_view
to the treestore we don't really care about
the return value */
create_treestore(tree_view, display_data_resv,
SORTID_CNT, SORTID_TIME_START, SORTID_COLOR);
set_column_width_fixed(tree_view, SORTID_NODELIST, 100);
}
view = INFO_VIEW;
_update_info_resv(info_list, GTK_TREE_VIEW(display_widget));
end_it:
toggled = false;
force_refresh = false;
reset_curs:
if (main_window && main_window->window)
gdk_window_set_cursor(main_window->window, NULL);
return;
}
extern void specific_info_resv(popup_info_t *popup_win)
{
int resv_error_code = SLURM_SUCCESS;
static reserve_info_msg_t *resv_info_ptr = NULL;
static reserve_info_t *resv_ptr = NULL;
specific_info_t *spec_info = popup_win->spec_info;
sview_search_info_t *search_info = spec_info->search_info;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
list_t *resv_list = NULL;
list_t *send_resv_list = NULL;
sview_resv_info_t *sview_resv_info_ptr = NULL;
int j=0;
hostset_t *hostset = NULL;
list_itr_t *itr = NULL;
if (!spec_info->display_widget) {
setup_popup_info(popup_win, display_data_resv, SORTID_CNT);
}
if (spec_info->display_widget && popup_win->toggled) {
gtk_widget_destroy(spec_info->display_widget);
spec_info->display_widget = NULL;
goto display_it;
}
if ((resv_error_code =
get_new_info_resv(&resv_info_ptr, popup_win->force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
if (!spec_info->display_widget || spec_info->view == ERROR_VIEW)
goto display_it;
} else if (resv_error_code != SLURM_SUCCESS) {
if (spec_info->view == ERROR_VIEW)
goto end_it;
spec_info->view = ERROR_VIEW;
if (spec_info->display_widget)
gtk_widget_destroy(spec_info->display_widget);
sprintf(error_char, "get_new_info_resv: %s",
slurm_strerror(errno));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(popup_win->table,
label,
0, 1, 0, 1);
gtk_widget_show(label);
spec_info->display_widget = g_object_ref(label);
goto end_it;
}
display_it:
resv_list = _create_resv_info_list(resv_info_ptr);
if (!resv_list)
return;
if (spec_info->view == ERROR_VIEW && spec_info->display_widget) {
gtk_widget_destroy(spec_info->display_widget);
spec_info->display_widget = NULL;
}
if (spec_info->type != INFO_PAGE && !spec_info->display_widget) {
tree_view = create_treeview(local_display_data,
&popup_win->grid_button_list);
gtk_tree_selection_set_mode(
gtk_tree_view_get_selection(tree_view),
GTK_SELECTION_MULTIPLE);
spec_info->display_widget =
g_object_ref(GTK_WIDGET(tree_view));
gtk_table_attach_defaults(popup_win->table,
GTK_WIDGET(tree_view),
0, 1, 0, 1);
/* since this function sets the model of the tree_view
to the treestore we don't really care about
the return value */
create_treestore(tree_view, popup_win->display_data,
SORTID_CNT, SORTID_TIME_START, SORTID_COLOR);
}
setup_popup_grid_list(popup_win);
spec_info->view = INFO_VIEW;
if (spec_info->type == INFO_PAGE) {
_display_info_resv(resv_list, popup_win);
goto end_it;
}
/* just linking to another list, don't free the inside, just
the list */
send_resv_list = list_create(NULL);
itr = list_iterator_create(resv_list);
while ((sview_resv_info_ptr = list_next(itr))) {
resv_ptr = sview_resv_info_ptr->resv_ptr;
switch(spec_info->type) {
case PART_PAGE:
case NODE_PAGE:
if (!resv_ptr->node_list)
continue;
if (!(hostset = hostset_create(
search_info->gchar_data)))
continue;
if (!hostset_intersects(hostset, resv_ptr->node_list)) {
hostset_destroy(hostset);
continue;
}
hostset_destroy(hostset);
break;
case JOB_PAGE:
if (xstrcmp(resv_ptr->name, search_info->gchar_data))
continue;
break;
case RESV_PAGE:
switch(search_info->search_type) {
case SEARCH_RESERVATION_NAME:
if (!search_info->gchar_data)
continue;
if (xstrcmp(resv_ptr->name,
search_info->gchar_data))
continue;
break;
default:
continue;
}
break;
default:
g_print("Unknown type %d\n", spec_info->type);
continue;
}
list_push(send_resv_list, sview_resv_info_ptr);
j=0;
while (resv_ptr->node_inx[j] >= 0) {
change_grid_color(
popup_win->grid_button_list,
resv_ptr->node_inx[j],
resv_ptr->node_inx[j+1],
sview_resv_info_ptr->color_inx,
true, 0);
j += 2;
}
}
list_iterator_destroy(itr);
post_setup_popup_grid_list(popup_win);
_update_info_resv(send_resv_list,
GTK_TREE_VIEW(spec_info->display_widget));
FREE_NULL_LIST(send_resv_list);
end_it:
popup_win->toggled = 0;
popup_win->force_refresh = 0;
return;
}
extern void set_menus_resv(void *arg, void *arg2, GtkTreePath *path, int type)
{
GtkTreeView *tree_view = (GtkTreeView *)arg;
popup_info_t *popup_win = (popup_info_t *)arg;
GtkMenu *menu = (GtkMenu *)arg2;
list_t *button_list = arg2;
switch(type) {
case TAB_CLICKED:
make_fields_menu(NULL, menu, display_data_resv, SORTID_CNT);
break;
case ROW_CLICKED:
make_options_menu(tree_view, path, menu, options_data_resv);
break;
case ROW_LEFT_CLICKED:
highlight_grid(tree_view, SORTID_NODE_INX,
SORTID_COLOR_INX, button_list);
break;
case FULL_CLICKED:
{
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
GtkTreeIter iter;
if (!gtk_tree_model_get_iter(model, &iter, path)) {
g_error("error getting iter from model\n");
break;
}
popup_all_resv(model, &iter, INFO_PAGE);
break;
}
case POPUP_CLICKED:
make_fields_menu(popup_win, menu,
popup_win->display_data, SORTID_CNT);
break;
default:
g_error("UNKNOWN type %d given to set_fields\n", type);
}
}
extern void popup_all_resv(GtkTreeModel *model, GtkTreeIter *iter, int id)
{
char *name = NULL;
char title[100] = {0};
list_itr_t *itr = NULL;
popup_info_t *popup_win = NULL;
GError *error = NULL;
gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1);
switch(id) {
case PART_PAGE:
snprintf(title, 100, "Partition(s) with reservation %s", name);
break;
case JOB_PAGE:
snprintf(title, 100, "Job(s) in reservation %s", name);
break;
case NODE_PAGE:
snprintf(title, 100, "Node(s) in reservation %s ", name);
break;
case SUBMIT_PAGE:
snprintf(title, 100, "Submit job in reservation %s", name);
break;
case INFO_PAGE:
snprintf(title, 100, "Full info for reservation %s", name);
break;
default:
g_print("resv got %d\n", id);
}
itr = list_iterator_create(popup_list);
while ((popup_win = list_next(itr))) {
if (popup_win->spec_info)
if (!xstrcmp(popup_win->spec_info->title, title)) {
break;
}
}
list_iterator_destroy(itr);
if (!popup_win) {
if (id == INFO_PAGE)
popup_win = create_popup_info(id, RESV_PAGE, title);
else
popup_win = create_popup_info(RESV_PAGE, id, title);
} else {
g_free(name);
gtk_window_present(GTK_WINDOW(popup_win->popup));
return;
}
/* Pass the model and the structs from the iter so we can always get
the current node_inx.
*/
popup_win->model = model;
popup_win->iter = *iter;
popup_win->node_inx_id = SORTID_NODE_INX;
switch(id) {
case JOB_PAGE:
case INFO_PAGE:
popup_win->spec_info->search_info->gchar_data = name;
//specific_info_job(popup_win);
break;
case NODE_PAGE:
case PART_PAGE:
g_free(name);
gtk_tree_model_get(model, iter, SORTID_NODELIST, &name, -1);
popup_win->spec_info->search_info->gchar_data = name;
popup_win->spec_info->search_info->search_type =
SEARCH_NODE_NAME;
//specific_info_node(popup_win);
break;
case SUBMIT_PAGE:
break;
default:
g_print("resv got unknown type %d\n", id);
}
if (!sview_thread_new((gpointer)popup_thr, popup_win, &error)) {
g_printerr ("Failed to create resv popup thread: %s\n",
error->message);
return;
}
}
static void _process_each_resv(GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter*iter, gpointer userdata)
{
char *type = userdata;
if (_DEBUG)
g_print("process_each_resv: global_multi_error = %d\n",
global_multi_error);
if (!global_multi_error) {
_admin_resv(model, iter, type);
}
}
extern void select_admin_resv(GtkTreeModel *model, GtkTreeIter *iter,
display_data_t *display_data,
GtkTreeView *treeview)
{
select_admin_common(model, iter, display_data, treeview,
SORTID_NODELIST, _process_each_resv);
}
static void _admin_resv(GtkTreeModel *model, GtkTreeIter *iter, char *type)
{
resv_desc_msg_t *resv_msg = NULL;
reservation_name_msg_t resv_name_msg;
char *resvid = NULL;
char tmp_char[100];
char *temp = NULL;
int edit_type = 0;
int response = 0;
GtkWidget *label = NULL;
GtkWidget *entry = NULL;
GtkWidget *popup = NULL;
if (cluster_flags & CLUSTER_FLAG_FED) {
display_fed_disabled_popup(type);
global_entry_changed = 0;
return;
}
popup = gtk_dialog_new_with_buttons(
type,
GTK_WINDOW(main_window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
NULL);
gtk_window_set_type_hint(GTK_WINDOW(popup),
GDK_WINDOW_TYPE_HINT_NORMAL);
gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);
gtk_tree_model_get(model, iter, SORTID_NAME, &resvid, -1);
resv_msg = xmalloc(sizeof(resv_desc_msg_t));
slurm_init_resv_desc_msg(resv_msg);
memset(&resv_name_msg, 0, sizeof(reservation_name_msg_t));
resv_msg->name = xstrdup(resvid);
if (!xstrcasecmp("Remove Reservation", type)) {
resv_name_msg.name = resvid;
label = gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_YES, GTK_RESPONSE_OK);
gtk_window_set_default(GTK_WINDOW(popup), label);
gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
snprintf(tmp_char, sizeof(tmp_char),
"Are you sure you want to remove "
"reservation %s?",
resvid);
label = gtk_label_new(tmp_char);
edit_type = EDIT_REMOVE;
} else {
label = gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_OK, GTK_RESPONSE_OK);
gtk_window_set_default(GTK_WINDOW(popup), label);
gtk_dialog_add_button(GTK_DIALOG(popup),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_window_set_default_size(GTK_WINDOW(popup), 200, 400);
snprintf(tmp_char, sizeof(tmp_char),
"Editing reservation %s think before you type",
resvid);
label = gtk_label_new(tmp_char);
edit_type = EDIT_EDIT;
entry = _admin_full_edit_resv(resv_msg, model, iter);
}
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
label, false, false, 0);
if (entry)
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
entry, true, true, 0);
gtk_widget_show_all(popup);
response = gtk_dialog_run (GTK_DIALOG(popup));
if (response == GTK_RESPONSE_OK) {
switch(edit_type) {
case EDIT_REMOVE:
if (slurm_delete_reservation(&resv_name_msg)
== SLURM_SUCCESS) {
temp = g_strdup_printf(
"Reservation %s removed successfully",
resvid);
} else {
temp = g_strdup_printf(
"Problem removing reservation %s.",
resvid);
}
display_edit_note(temp);
g_free(temp);
break;
case EDIT_EDIT:
if (got_edit_signal)
goto end_it;
if (global_edit_error) {
temp = g_strdup_printf(
"Something was wrong with the "
"values you wanted to change: %s",
global_edit_error_msg ?
global_edit_error_msg : "unknown");
if (global_edit_error_msg)
g_free(global_edit_error_msg);
} else if (!global_send_update_msg) {
temp = g_strdup_printf("No change detected.");
} else if (slurm_update_reservation(resv_msg)
== SLURM_SUCCESS) {
temp = g_strdup_printf(
"Reservation %s updated successfully",
resvid);
} else {
temp = g_strdup_printf(
"Problem updating reservation %s.",
resvid);
}
display_edit_note(temp);
g_free(temp);
break;
default:
break;
}
}
end_it:
g_free(resvid);
global_entry_changed = 0;
slurm_free_resv_desc_msg(resv_msg);
gtk_widget_destroy(popup);
if (got_edit_signal) {
type = got_edit_signal;
got_edit_signal = NULL;
_admin_resv(model, iter, type);
xfree(type);
}
return;
}
extern void cluster_change_resv(void)
{
get_info_resv(NULL, NULL);
}