/* * as_pg_get_accts - get accounts * * IN pg_conn: database connection * IN uid: user performing the get operation * IN acct_cond: accounts to get * RET: list of accounts */ extern List as_pg_get_accts(pgsql_conn_t *pg_conn, uid_t uid, slurmdb_account_cond_t *acct_cond) { DEF_VARS; char *cond = NULL; List acct_list = NULL; ListIterator itr = NULL; int set=0, is_admin=1; slurmdb_user_rec_t user; /* no need to free lists */ char *ga_fields = "name, description, organization"; enum { F_NAME, F_DESC, F_ORG, F_COUNT }; if (check_db_connection(pg_conn) != SLURM_SUCCESS) return NULL; if (check_user_op(pg_conn, uid, PRIVATE_DATA_ACCOUNTS, &is_admin, &user) != SLURM_SUCCESS) { error("as/pg: user(%u) not found in db", uid); errno = ESLURM_USER_ID_MISSING; return NULL; } if (!is_admin && ! is_user_any_coord(pg_conn, &user)) { errno = ESLURM_ACCESS_DENIED; return NULL; } if(!acct_cond) { xstrcat(cond, "WHERE deleted=0"); goto empty; } if(acct_cond->with_deleted) xstrcat(cond, "WHERE (deleted=0 OR deleted=1)"); else xstrcat(cond, "WHERE deleted=0"); if(acct_cond->assoc_cond) concat_cond_list(acct_cond->assoc_cond->acct_list, NULL, "name", &cond); concat_cond_list(acct_cond->description_list, NULL, "description", &cond); concat_cond_list(acct_cond->organization_list, NULL, "organization", &cond); empty: if(!is_admin) { slurmdb_coord_rec_t *coord = NULL; set = 0; itr = list_iterator_create(user.coord_accts); while((coord = list_next(itr))) { if(set) { xstrfmtcat(cond, " OR name='%s'", coord->name); } else { set = 1; xstrfmtcat(cond, " AND (name='%s'", coord->name); } } list_iterator_destroy(itr); if(set) xstrcat(cond,")"); } query = xstrdup_printf("SELECT %s FROM %s %s", ga_fields, acct_table, cond); xfree(cond); result = DEF_QUERY_RET; if (!result) return NULL; acct_list = list_create(slurmdb_destroy_account_rec); if(acct_cond && acct_cond->with_assocs) { if(!acct_cond->assoc_cond) acct_cond->assoc_cond = xmalloc( sizeof(slurmdb_association_cond_t)); else if(acct_cond->assoc_cond->acct_list) list_destroy(acct_cond->assoc_cond->acct_list); acct_cond->assoc_cond->acct_list = list_create(NULL); } FOR_EACH_ROW { slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t)); list_append(acct_list, acct); acct->name = xstrdup(ROW(F_NAME)); acct->description = xstrdup(ROW(F_DESC)); acct->organization = xstrdup(ROW(F_ORG)); if(acct_cond && acct_cond->with_coords) _get_account_coords(pg_conn, acct); if(acct_cond && acct_cond->with_assocs) { list_append(acct_cond->assoc_cond->acct_list, acct->name); } } END_EACH_ROW; PQclear(result); /* get associations */ if(acct_cond && acct_cond->with_assocs && list_count(acct_cond->assoc_cond->acct_list)) { ListIterator assoc_itr = NULL; slurmdb_account_rec_t *acct = NULL; slurmdb_association_rec_t *assoc = NULL; List assoc_list = acct_storage_p_get_associations( pg_conn, uid, acct_cond->assoc_cond); if(!assoc_list) { error("as/pg: get_accounts: no associations"); return acct_list; } itr = list_iterator_create(acct_list); assoc_itr = list_iterator_create(assoc_list); while((acct = list_next(itr))) { while((assoc = list_next(assoc_itr))) { if(strcmp(assoc->acct, acct->name)) continue; if(!acct->assoc_list) acct->assoc_list = list_create( slurmdb_destroy_association_rec); list_append(acct->assoc_list, assoc); list_remove(assoc_itr); } list_iterator_reset(assoc_itr); if(!acct->assoc_list) /* problem acct */ list_remove(itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); list_destroy(assoc_list); } return acct_list; }
/* * as_pg_get_clusters - get clusters * * IN pg_conn: database connection * IN uid: user performing the get operation * IN cluster_cond: which clusters to get * RET: the clusters */ extern List as_pg_get_clusters(pgsql_conn_t *pg_conn, uid_t uid, slurmdb_cluster_cond_t *cluster_cond) { DEF_VARS; char *cond = NULL; slurmdb_association_cond_t assoc_cond; slurmdb_cluster_rec_t *cluster = NULL; slurmdb_association_rec_t *assoc = NULL; List cluster_list = NULL, assoc_list = NULL; ListIterator itr = NULL, assoc_itr = NULL; /* if this changes you will need to edit the corresponding enum */ char *gc_fields = "name,classification,control_host,control_port," "rpc_version,dimensions,flags,plugin_id_select"; enum { F_NAME, F_CLASS, F_CH, F_CP, F_VERSION, F_DIMS, F_FLAGS, F_PI_SELECT, F_COUNT }; if (check_db_connection(pg_conn) != SLURM_SUCCESS) return NULL; if(!cluster_cond) { xstrcat(cond, "WHERE deleted=0"); goto empty; } if(cluster_cond->with_deleted) xstrcat(cond, "WHERE (deleted=0 OR deleted=1)"); else xstrcat(cond, "WHERE deleted=0"); concat_cond_list(cluster_cond->cluster_list, NULL, "name", &cond); empty: query = xstrdup_printf("SELECT %s FROM %s %s", gc_fields, cluster_table, cond); xfree(cond); result = DEF_QUERY_RET; if (!result) { error("failed to get clusters"); return NULL; } cluster_list = list_create(slurmdb_destroy_cluster_rec); memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); if(cluster_cond) { /* I don't think we want the with_usage flag here. * We do need the with_deleted though. */ //assoc_cond.with_usage = cluster_cond->with_usage; assoc_cond.with_deleted = cluster_cond->with_deleted; } /* not destroyed, since owned by cluster record */ assoc_cond.cluster_list = list_create(NULL); FOR_EACH_ROW { cluster = xmalloc(sizeof(slurmdb_cluster_rec_t)); list_append(cluster_list, cluster); cluster->name = xstrdup(ROW(F_NAME)); list_append(assoc_cond.cluster_list, cluster->name); /* get the usage if requested */ if(cluster_cond && cluster_cond->with_usage) { as_pg_get_usage(pg_conn, uid, cluster, DBD_GET_CLUSTER_USAGE, cluster_cond->usage_start, cluster_cond->usage_end); } cluster->classification = atoi(ROW(F_CLASS)); cluster->control_host = xstrdup(ROW(F_CH)); cluster->control_port = atoi(ROW(F_CP)); cluster->rpc_version = atoi(ROW(F_VERSION)); cluster->dimensions = atoi(ROW(F_DIMS)); cluster->flags = atoi(ROW(F_FLAGS)); cluster->plugin_id_select = atoi(ROW(F_PI_SELECT)); get_cluster_cpu_nodes(pg_conn, cluster); } END_EACH_ROW; PQclear(result); if(!list_count(assoc_cond.cluster_list)) { list_destroy(assoc_cond.cluster_list); return cluster_list; } /* get root assoc: <cluster, root, '', ''> */ assoc_cond.acct_list = list_create(NULL); list_append(assoc_cond.acct_list, "root"); assoc_cond.user_list = list_create(NULL); list_append(assoc_cond.user_list, ""); assoc_list = acct_storage_p_get_associations(pg_conn, uid, &assoc_cond); list_destroy(assoc_cond.cluster_list); list_destroy(assoc_cond.acct_list); list_destroy(assoc_cond.user_list); if(!assoc_list) return cluster_list; itr = list_iterator_create(cluster_list); assoc_itr = list_iterator_create(assoc_list); while((cluster = list_next(itr))) { while((assoc = list_next(assoc_itr))) { if(strcmp(assoc->cluster, cluster->name)) continue; if(cluster->root_assoc) { debug("This cluster %s already has " "an association.", cluster->name); continue; } cluster->root_assoc = assoc; list_remove(assoc_itr); } list_iterator_reset(assoc_itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); if(list_count(assoc_list)) error("I have %d left over associations", list_count(assoc_list)); list_destroy(assoc_list); return cluster_list; }