00001
00030 #include <pwd.h>
00031 #include "drms.h"
00032 #include "serverdefs.h"
00033 #include "cmdparams.h"
00034
00035 #define GUESTSPACE "su_guest"
00036 #define GUESTGROUP "user"
00037
00038 CmdParams_t cmdparams;
00039 ModuleArgs_t module_args[] = {
00040 {ARG_FLAG, "g", NULL, "guest"},
00041 {ARG_END}
00042 };
00043
00044 ModuleArgs_t *gModArgs = module_args;
00045 int main(int argc, char **argv) {
00046 DB_Handle_t *db_handle;
00047 char stmt[8000]={0}, *p;
00048 const char *dbhost;
00049 char *dbuser, *dbpasswd, *dbname, *namespace, *nsgrp;
00050 char *dbport = NULL;
00051 char dbHostAndPort[64];
00052 DB_Text_Result_t *qres;
00053 char *tn[] = {"drms_keyword", "drms_link", "drms_segment", "drms_series"};
00054 int guest = 0;
00055
00056
00057 if (cmdparams_parse (&cmdparams, argc, argv) == -1) goto usage;
00058 if (cmdparams_exists (&cmdparams,"h")) goto usage;
00059 guest = cmdparams_isflagset(&cmdparams, "g");
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 if ((dbhost = cmdparams_get_str(&cmdparams, "JSOC_DBHOST", NULL)) == NULL)
00077 {
00078 const char *sep = NULL;
00079
00080 dbhost = SERVER;
00081 dbport = DRMSPGPORT;
00082
00083
00084 if ((sep = strchr(dbhost, ':')) != NULL)
00085 {
00086 if (strcmp(sep + 1, dbport) != 0)
00087 {
00088 char *tmpBuf = strdup(dbhost);
00089
00090 if (tmpBuf)
00091 {
00092 tmpBuf[sep - dbhost] = '\0';
00093 fprintf(stderr, "WARNING: the port number in the SERVER localization parameter (%s) and in DRMSPGPORT (%s) conflict.\nThe DRMSPGPORT value will be used.\n", sep + 1, DRMSPGPORT);
00094
00095 snprintf(dbHostAndPort, sizeof(dbHostAndPort), "%s:%s", tmpBuf, dbport);
00096 free(tmpBuf);
00097 tmpBuf = NULL;
00098 }
00099 else
00100 {
00101 fprintf(stderr, "Out of memory.\n");
00102 goto failure;
00103 }
00104 }
00105 else
00106 {
00107 snprintf(dbHostAndPort, sizeof(dbHostAndPort), "%s", dbhost);
00108 }
00109 }
00110 else
00111 {
00112 snprintf(dbHostAndPort, sizeof(dbHostAndPort), "%s:%s", dbhost, dbport);
00113 }
00114 }
00115 else
00116 {
00117 snprintf(dbHostAndPort, sizeof(dbHostAndPort), "%s", dbhost);
00118 }
00119
00120
00121 if ((dbname = cmdparams_get_str(&cmdparams, "JSOC_DBNAME", NULL)) == NULL)
00122 dbname = DBNAME;
00123 if ((dbuser = cmdparams_get_str(&cmdparams, "dbuser", NULL)) == NULL) {
00124 struct passwd *pwd = getpwuid(geteuid());
00125 dbuser = pwd->pw_name;
00126 }
00127
00128 if ((namespace = cmdparams_get_str(&cmdparams, "namespace", NULL)) == NULL) {
00129 if (!guest) {
00130 fprintf(stderr, "Missing namespace (namespace=)\n");
00131 goto usage;
00132 } else {
00133 namespace = GUESTSPACE;
00134 }
00135 }
00136
00137 namespace = strdup(namespace);
00138
00139 if (!strcmp(namespace, "public")) {
00140 fprintf(stderr, "Can't create DRMS master tables in namespace public\n");
00141 goto usage;
00142 }
00143 if (guest) {
00144 if (!strcmp(namespace, "su_guest")) {
00145 printf("You are adding a user to the GUEST namespace. This is a shared-access namespace.\n");
00146 printf("Please encourage users in this namespace to name series as xxx_seriesname, where xxx are user initials.\n");
00147 } else {
00148 fprintf(stderr, "Can only create DRMS guest users in namespace %s\n", GUESTSPACE);
00149 goto usage;
00150 }
00151 }
00152
00153 strtolower(namespace);
00154
00155 if ((nsgrp = cmdparams_get_str(&cmdparams, "nsgrp", NULL)) == NULL) {
00156 if (!guest) {
00157 fprintf(stderr, "Missing namespace group (nsgrp=)\n");
00158 goto usage;
00159 } else {
00160 nsgrp = GUESTGROUP;
00161 }
00162 }
00163
00164 nsgrp = strdup(nsgrp);
00165
00166 strtolower(nsgrp);
00167 if (strcmp(nsgrp, "user") &&
00168 strcmp(nsgrp, "sys")) {
00169 fprintf(stderr, "Namespace group must be either user or sys\n");
00170 goto usage;
00171 }
00172
00173 dbpasswd = getpass ("Please type the password for database user \"postgres\":");
00174 if ((db_handle = db_connect (dbHostAndPort,"postgres",dbpasswd,dbname,0)) == NULL) {
00175 fprintf (stderr, "Failure to connect to DB server.\n");
00176 return 1;
00177 }
00178 printf("Connected to database '%s' on host '%s' and port '%s' as "
00179 "user '%s'.\n",db_handle->dbname, db_handle->dbhost, db_handle->dbport,
00180 db_handle->dbuser);
00181
00182 if (db_isolation_level (db_handle, DB_TRANS_SERIALIZABLE) ) {
00183 fprintf (stderr,"Failed to set database isolation level.\n");
00184 goto failure;
00185 }
00186 if ( db_start_transaction(db_handle))
00187 {
00188 fprintf(stderr,"Couldn't start database transaction.\n");
00189 goto failure;
00190 }
00191
00192
00193
00194 if (!guest) {
00195 sprintf(stmt, "select * from pg_namespace where nspname = '%s'", namespace);
00196 if ( (qres = db_query_txt(db_handle, stmt)) != NULL) {
00197 if (qres->num_rows > 0) {
00198 fprintf(stderr, "Namespace %s already exists.\n", namespace);
00199 goto failure;
00200 }
00201 }
00202
00203 sprintf(stmt, "create schema %s", namespace);
00204 if (db_dms(db_handle, NULL, stmt)) {
00205 fprintf(stderr, "Failed to create schema %s.\n", namespace);
00206 goto failure;
00207 }
00208 sprintf(stmt, "insert into admin.ns values ('%s', '%s', '%s')", namespace, nsgrp, dbuser);
00209 if (db_dms(db_handle, NULL, stmt)) {
00210 fprintf(stderr, "Failed to record namespace.\nStatement was %s\n", stmt);
00211 goto failure;
00212 }
00213 }
00214
00215 p = stmt;
00216 p += sprintf(p, "grant create, usage on schema %s to %s;", namespace, dbuser);
00217 if (!guest) {
00218 p += sprintf(p, "grant usage on schema %s to public", namespace);
00219 } else {
00220
00221 p += sprintf(p, "grant guest to %s", dbuser);
00222 }
00223 if (db_dms(db_handle, NULL, stmt)) {
00224 fprintf(stderr, "Failed to grant privileges.\n statement was %s\n", stmt);
00225 goto failure;
00226 }
00227
00228 sprintf(stmt, "set search_path to %s", namespace);
00229 if (db_dms(db_handle, NULL, stmt)) {
00230 fprintf(stderr, "Failed to set search_path to %s\n", namespace);
00231 goto failure;
00232 }
00233
00234 sprintf(stmt, "set role %s", dbuser);
00235 if (db_dms(db_handle, NULL, stmt)) {
00236 fprintf(stderr, "Failed to set role %s\n", dbuser);
00237 goto failure;
00238 }
00239
00240
00241 if (!guest) {
00242 p = stmt;
00243 p += sprintf(p,"create table %s (\n",DRMS_MASTER_SERIES_TABLE);
00244 p += sprintf(p,"seriesname %s not null,\n",db_stringtype_maxlen(DRMS_MAXSERIESNAMELEN));
00245 p += sprintf(p,"author %s not null,\n",db_stringtype_maxlen(255));
00246 p += sprintf(p,"owner %s not null,\n",db_stringtype_maxlen(255));
00247 p += sprintf(p,"unitsize %s not null,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00248 p += sprintf(p,"archive %s not null,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00249 p += sprintf(p,"retention %s not null,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00250 p += sprintf(p,"tapegroup %s not null,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00251 p += sprintf(p,"primary_idx %s not null,\n",db_stringtype_maxlen(1024));
00252 p += sprintf(p,"created %s not null,\n",db_stringtype_maxlen(30));
00253 p += sprintf(p,"description %s,\n",db_stringtype_maxlen(4000));
00254 p += sprintf(p,"dbidx %s,\n",db_stringtype_maxlen(1024));
00255 p += sprintf(p,"version %s,\n",db_stringtype_maxlen(1024));
00256 p += sprintf(p,"primary key (seriesname));\n");
00257 p += sprintf(p, "grant select on %s to public", DRMS_MASTER_SERIES_TABLE);
00258
00259 if (db_dms(db_handle,NULL, stmt))
00260 {
00261 fprintf(stderr, "failed to create '" DRMS_MASTER_SERIES_TABLE "'\n");
00262 goto failure;
00263 }
00264 printf("Created new "DRMS_MASTER_SERIES_TABLE"...\n");
00265
00266
00267 p = stmt;
00268 p += sprintf(p,"create table " DRMS_MASTER_KEYWORD_TABLE " (\n");
00269 p += sprintf(p,"seriesname %s not null,\n",db_stringtype_maxlen(DRMS_MAXSERIESNAMELEN));
00270 p += sprintf(p,"keywordname %s not null,\n",db_stringtype_maxlen(DRMS_MAXKEYNAMELEN));
00271 p += sprintf(p,"linkname %s ,\n",db_stringtype_maxlen(DRMS_MAXLINKNAMELEN));
00272 p += sprintf(p,"targetkeyw %s ,\n",db_stringtype_maxlen(DRMS_MAXLINKNAMELEN));
00273 p += sprintf(p,"type %s,\n",db_stringtype_maxlen(20));
00274 p += sprintf(p,"defaultval %s ,\n",db_stringtype_maxlen(4000));
00275 p += sprintf(p,"format %s ,\n",db_stringtype_maxlen(20));
00276 p += sprintf(p,"unit %s ,\n",db_stringtype_maxlen(64));
00277 p += sprintf(p,"islink %s default 0 ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00278 p += sprintf(p,"isconstant %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00279 p += sprintf(p,"persegment %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00280 p += sprintf(p,"description %s ,\n",db_stringtype_maxlen(4000));
00281 p += sprintf(p,"primary key (seriesname, keywordname));\n");
00282 p += sprintf(p,"grant select on %s to public", DRMS_MASTER_KEYWORD_TABLE);
00283
00284 if (db_dms(db_handle,NULL, stmt))
00285 {
00286 fprintf(stderr, "failed to create '" DRMS_MASTER_KEYWORD_TABLE"'\n");
00287 goto failure;
00288 }
00289 printf("Created new '"DRMS_MASTER_KEYWORD_TABLE"'...\n");
00290
00291
00292 p = stmt;
00293 p += sprintf(p,"create table "DRMS_MASTER_LINK_TABLE" (\n");
00294 p += sprintf(p,"seriesname %s not null,\n",db_stringtype_maxlen(DRMS_MAXSERIESNAMELEN));
00295 p += sprintf(p,"linkname %s not null,\n",db_stringtype_maxlen(DRMS_MAXLINKNAMELEN));
00296 p += sprintf(p,"target_seriesname %s not null,\n",db_stringtype_maxlen(DRMS_MAXSERIESNAMELEN));
00297 p += sprintf(p,"type %s ,\n",db_stringtype_maxlen(20));
00298 p += sprintf(p,"description %s ,\n",db_stringtype_maxlen(4000));
00299 p += sprintf(p,"primary key (seriesname, linkname));\n");
00300 p += sprintf(p,"grant select on %s to public", DRMS_MASTER_LINK_TABLE);
00301
00302 if (db_dms(db_handle,NULL, stmt))
00303 {
00304 fprintf(stderr, "failed to create '"DRMS_MASTER_LINK_TABLE"'\n");
00305 goto failure;
00306 }
00307 printf("Created new '"DRMS_MASTER_LINK_TABLE"'...\n");
00308
00309
00310
00311 p = stmt;
00312 p += sprintf(p,"create table "DRMS_MASTER_SEGMENT_TABLE" (\n");
00313 p += sprintf(p,"seriesname %s not null,\n",db_stringtype_maxlen(DRMS_MAXSERIESNAMELEN));
00314 p += sprintf(p,"segmentname %s not null,\n",db_stringtype_maxlen(DRMS_MAXSERIESNAMELEN));
00315 p += sprintf(p,"segnum %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00316 p += sprintf(p,"scope %s ,\n",db_stringtype_maxlen(10));
00317 p += sprintf(p,"type %s,\n",db_stringtype_maxlen(20));
00318 p += sprintf(p,"naxis %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00319 p += sprintf(p,"axis %s ,\n",db_stringtype_maxlen(4000));
00320 p += sprintf(p,"unit %s ,\n",db_stringtype_maxlen(64));
00321 p += sprintf(p,"protocol %s ,\n",db_stringtype_maxlen(64));
00322 p += sprintf(p,"description %s ,\n",db_stringtype_maxlen(4000));
00323 p += sprintf(p,"islink %s default 0 ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00324 p += sprintf(p,"linkname %s ,\n",db_stringtype_maxlen(DRMS_MAXLINKNAMELEN));
00325 p += sprintf(p,"targetseg %s, \n",db_stringtype_maxlen(DRMS_MAXSEGNAMELEN));
00326 p += sprintf(p,"cseg_recnum bigint default 0 ,\n");
00327 p += sprintf(p,"primary key (seriesname, segmentname));\n");
00328 p += sprintf(p,"grant select on %s to public", DRMS_MASTER_SEGMENT_TABLE);
00329
00330 if (db_dms(db_handle,NULL, stmt))
00331 {
00332 fprintf(stderr, "failed to create '"DRMS_MASTER_SEGMENT_TABLE"'\n");
00333 goto failure;
00334 }
00335 printf("Created new '" DRMS_MASTER_SEGMENT_TABLE"'...\n");
00336
00337
00338 p = stmt;
00339 p += sprintf(p,"create table "DRMS_SESSION_TABLE" (\n");
00340 p += sprintf(p,"sessionid %s not null,\n",db_type_string(drms2dbtype(DRMS_TYPE_LONGLONG)));
00341 p += sprintf(p,"hostname %s ,\n",db_stringtype_maxlen(30));
00342 p += sprintf(p,"port %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00343 p += sprintf(p,"pid %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00344 p += sprintf(p,"sunum %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_LONGLONG)));
00345 p += sprintf(p,"sudir %s ,\n",db_stringtype_maxlen(DRMS_MAXPATHLEN));
00346 p += sprintf(p,"username %s ,\n",db_stringtype_maxlen(30));
00347 p += sprintf(p,"starttime %s ,\n",db_stringtype_maxlen(30));
00348 p += sprintf(p,"lastcontact %s ,\n",db_stringtype_maxlen(30));
00349 p += sprintf(p,"endtime %s ,\n",db_stringtype_maxlen(30));
00350 p += sprintf(p,"clients %s ,\n",db_type_string(drms2dbtype(DRMS_TYPE_INT)));
00351 p += sprintf(p,"status %s ,\n",db_stringtype_maxlen(200));
00352 p += sprintf(p,"sums_thread_status %s ,\n",db_stringtype_maxlen(200));
00353 p += sprintf(p,"jsoc_version %s ,\n",db_stringtype_maxlen(200));
00354 p += sprintf(p,"primary key (sessionid));");
00355 p += sprintf(p,"grant select on %s to public", DRMS_SESSION_TABLE);
00356 if (db_dms(db_handle,NULL, stmt))
00357 {
00358 fprintf(stderr, "failed to create '"DRMS_SESSION_TABLE"'.\n");
00359 goto failure;
00360 }
00361 printf("Created new '"DRMS_SESSION_TABLE"'...\n");
00362
00363 db_sequence_create(db_handle, "drms_sessionid");
00364 printf("Created new drms_sessionid_seq sequence...\n");
00365 }
00366
00367 sprintf(stmt, "set search_path to default");
00368 if (db_dms(db_handle, NULL, stmt)) {
00369 fprintf(stderr, "Failed to set search_path to default\n");
00370 goto failure;
00371 }
00372
00373 sprintf(stmt, "set role none");
00374 if (db_dms(db_handle, NULL, stmt)) {
00375 fprintf(stderr,"Failed to set role none\n");
00376 goto failure;
00377 }
00378
00379 if (0) {
00380
00381 sprintf(stmt, "select name from admin.ns where nsgrp='%s'", nsgrp);
00382 if ( (qres = db_query_txt(db_handle, stmt)) != NULL) {
00383 for(int i = 0; i < 4; i++) {
00384 p = stmt;
00385 p += sprintf(p, "create or replace view %s_%s as\n\t(select * from %s.%s) ",
00386 nsgrp, tn[i], qres->field[0][0], tn[i]);
00387 for (int j = 1; j < qres->num_rows; j++) {
00388 p += sprintf(p, "union\n\t(select * from %s.%s) ", qres->field[j][0], tn[i]);
00389 }
00390 if (db_dms(db_handle, NULL, stmt))
00391 {
00392 fprintf(stderr, "Failed to update view.\nStatement was %s\n", stmt);
00393 goto failure;
00394 }
00395 }
00396
00397
00398 p = stmt;
00399 p += sprintf(p, "create or replace view %s_drms_session as\n\t"
00400 "(select '%s'::text as sessionns, * from %s.drms_session) ",
00401 nsgrp, qres->field[0][0], qres->field[0][0]);
00402 for (int j = 1; j < qres->num_rows; j++) {
00403 p += sprintf(p, "union\n\t(select '%s'::text as sessionns, * from %s.drms_session) ",
00404 qres->field[j][0], qres->field[j][0]);
00405 }
00406 if (db_dms(db_handle, NULL, stmt))
00407 {
00408 fprintf(stderr, "Failed to update view.\nStatement was%s\n", stmt);
00409 goto failure;
00410 }
00411 }
00412 }
00413 printf("Commiting...\n");
00414 db_commit(db_handle);
00415 db_disconnect(&db_handle);
00416 printf("Done.\n");
00417
00418 if (namespace)
00419 {
00420 free(namespace);
00421 }
00422
00423 if (nsgrp)
00424 {
00425 free(nsgrp);
00426 }
00427
00428
00429 return 0;
00430 failure:
00431 printf("Aborting...\n");
00432 db_disconnect(&db_handle);
00433 printf("Failed to create masterlists.\n");
00434
00435 if (namespace)
00436 {
00437 free(namespace);
00438 }
00439
00440 if (nsgrp)
00441 {
00442 free(nsgrp);
00443 }
00444
00445 return 1;
00446 usage:
00447 printf("Usage: %s [-h]\n"
00448 " %s [JSOC_DBHOST=] [JSOC_DBNAME=] [dbuser=] namespace= nsgrp=\n"
00449 "Options: -h: print this help message.\n"
00450 "Options: -g: add a guest user, only dbuser parameter required; default namespace=su_guest, nsgrp=user \n"
00451 " JSOC_DBHOST: DB host to connect to. default is 'hmidb'.\n"
00452 " JSOC_DBNAME: DB name to connect to. default is 'jsoc'.\n"
00453 " dbuser: DB user who owns master tables drms_*. \n"
00454 " default is the unix username.\n"
00455 " namespace: namespace where the master tables reside.\n"
00456 " nsgrp: namespace group, must be either 'user' or 'sys'.\n",
00457 argv[0], argv[0]);
00458 return 1;
00459 }
00460