Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-2025 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file exchange-tools/taler-exchange-dbinit.c
18 : * @brief Create tables for the exchange database.
19 : * @author Florian Dold
20 : * @author Christian Grothoff
21 : */
22 : #include "platform.h"
23 : #include <gnunet/gnunet_util_lib.h>
24 : #include "taler_exchangedb_lib.h"
25 :
26 :
27 : /**
28 : * Return value from main().
29 : */
30 : static int global_ret;
31 :
32 : /**
33 : * -a option: inject auditor triggers
34 : */
35 : static int inject_auditor;
36 :
37 : /**
38 : * -r option: do full DB reset
39 : */
40 : static int reset_db;
41 :
42 : /**
43 : * -e option: enable custom rules
44 : */
45 : static char *enable_rules;
46 :
47 : /**
48 : * -d option: disable custom rules
49 : */
50 : static char *disable_rules;
51 :
52 : /**
53 : * -s option: clear revolving shard locks
54 : */
55 : static int clear_shards;
56 :
57 : /**
58 : * -g option: garbage collect DB
59 : */
60 : static int gc_db;
61 :
62 : /**
63 : * -P option: setup a partitioned database
64 : */
65 : static uint32_t num_partitions;
66 :
67 : /**
68 : * -f option: force partitions to be created when there is only one
69 : */
70 : static int force_create_partitions;
71 :
72 : /**
73 : * Main function that will be run.
74 : *
75 : * @param cls closure
76 : * @param args remaining command-line arguments
77 : * @param cfgfile name of the configuration file used (for saving, can be NULL!)
78 : * @param cfg configuration
79 : */
80 : static void
81 57 : run (void *cls,
82 : char *const *args,
83 : const char *cfgfile,
84 : const struct GNUNET_CONFIGURATION_Handle *cfg)
85 : {
86 : struct TALER_EXCHANGEDB_Plugin *plugin;
87 :
88 : (void) cls;
89 : (void) args;
90 : (void) cfgfile;
91 :
92 57 : if (NULL ==
93 57 : (plugin = TALER_EXCHANGEDB_plugin_load (cfg,
94 : true)))
95 : {
96 0 : fprintf (stderr,
97 : "Failed to initialize database plugin.\n");
98 0 : global_ret = EXIT_NOTINSTALLED;
99 0 : return;
100 : }
101 57 : if (reset_db)
102 : {
103 20 : if (GNUNET_OK !=
104 20 : plugin->drop_tables (plugin->cls))
105 : {
106 3 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
107 : "Could not drop tables as requested. Either database was not yet initialized, or permission denied. Consult the logs. Will still try to create new tables.\n");
108 : }
109 : }
110 57 : if (GNUNET_OK !=
111 114 : plugin->create_tables (plugin->cls,
112 57 : force_create_partitions || num_partitions > 0,
113 : num_partitions))
114 : {
115 0 : fprintf (stderr,
116 : "Failed to initialize database.\n");
117 0 : global_ret = EXIT_NOPERMISSION;
118 0 : goto exit;
119 : }
120 57 : if (gc_db || clear_shards)
121 : {
122 33 : if (GNUNET_OK !=
123 33 : plugin->preflight (plugin->cls))
124 : {
125 0 : fprintf (stderr,
126 : "Failed to prepare database.\n");
127 0 : global_ret = EXIT_NOPERMISSION;
128 0 : goto exit;
129 : }
130 33 : if (clear_shards)
131 : {
132 0 : if (GNUNET_OK !=
133 0 : plugin->delete_shard_locks (plugin->cls))
134 : {
135 0 : fprintf (stderr,
136 : "Clearing revolving shards failed!\n");
137 : }
138 : }
139 33 : if (gc_db)
140 : {
141 33 : if (GNUNET_SYSERR == plugin->gc (plugin->cls))
142 : {
143 0 : fprintf (stderr,
144 : "Garbage collection failed!\n");
145 : }
146 : }
147 : }
148 57 : if (inject_auditor)
149 : {
150 0 : if (GNUNET_SYSERR ==
151 0 : plugin->inject_auditor_triggers (plugin->cls))
152 : {
153 0 : fprintf (stderr,
154 : "Injecting auditor triggers failed!\n");
155 0 : global_ret = EXIT_FAILURE;
156 : }
157 : }
158 57 : if (NULL != disable_rules)
159 : {
160 0 : if (0 == strcasecmp (disable_rules,
161 : "exchange"))
162 : {
163 0 : fprintf (stderr,
164 : "'exchange' is not a customization rule set!\n");
165 0 : global_ret = EXIT_INVALIDARGUMENT;
166 0 : goto exit;
167 : }
168 0 : if (GNUNET_OK !=
169 0 : plugin->preflight (plugin->cls))
170 : {
171 0 : fprintf (stderr,
172 : "Preflight check failed!\n");
173 0 : global_ret = EXIT_FAILURE;
174 0 : goto exit;
175 : }
176 0 : switch (plugin->disable_rules (plugin->cls,
177 : disable_rules))
178 : {
179 0 : case GNUNET_DB_STATUS_HARD_ERROR:
180 0 : fprintf (stderr,
181 : "Hard DB error trying to disable customization!\n");
182 0 : global_ret = EXIT_FAILURE;
183 0 : goto exit;
184 0 : case GNUNET_DB_STATUS_SOFT_ERROR:
185 : /* single call, should not be possible */
186 0 : GNUNET_break (0);
187 0 : global_ret = EXIT_FAILURE;
188 0 : goto exit;
189 0 : case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
190 0 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
191 : "Nothing to do to disable customization schema `%s'\n",
192 : disable_rules);
193 0 : break;
194 0 : case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
195 0 : break;
196 : }
197 : }
198 57 : if (NULL != enable_rules)
199 : {
200 0 : if (0 == strcasecmp (enable_rules,
201 : "exchange"))
202 : {
203 0 : fprintf (stderr,
204 : "'exchange' is not a customization rule set!\n");
205 0 : global_ret = EXIT_INVALIDARGUMENT;
206 0 : goto exit;
207 : }
208 0 : if (GNUNET_OK !=
209 0 : plugin->enable_rules (plugin->cls,
210 : enable_rules))
211 : {
212 0 : fprintf (stderr,
213 : "Enabling customization `%s' failed!\n",
214 : enable_rules);
215 0 : global_ret = EXIT_FAILURE;
216 0 : goto exit;
217 : }
218 : }
219 57 : exit:
220 57 : TALER_EXCHANGEDB_plugin_unload (plugin);
221 57 : plugin = NULL;
222 : }
223 :
224 :
225 : /**
226 : * The main function of the database initialization tool.
227 : * Used to initialize the Taler Exchange's database.
228 : *
229 : * @param argc number of arguments from the command line
230 : * @param argv command line arguments
231 : * @return 0 ok, non-zero on error
232 : */
233 : int
234 57 : main (int argc,
235 : char *const *argv)
236 : {
237 57 : const struct GNUNET_GETOPT_CommandLineOption options[] = {
238 57 : GNUNET_GETOPT_option_flag ('a',
239 : "inject-auditor",
240 : "inject auditor triggers",
241 : &inject_auditor),
242 57 : GNUNET_GETOPT_option_string ('d',
243 : "disable-customization",
244 : "SCHEMA",
245 : "remove customization rules of SCHEMA",
246 : &disable_rules),
247 57 : GNUNET_GETOPT_option_string ('e',
248 : "enable-customization",
249 : "SCHEMA",
250 : "enable or update (to latest version) the customization rules of SCHEMA",
251 : &enable_rules),
252 57 : GNUNET_GETOPT_option_flag ('g',
253 : "gc",
254 : "garbage collect database",
255 : &gc_db),
256 57 : GNUNET_GETOPT_option_flag ('r',
257 : "reset",
258 : "reset database (DANGEROUS: all existing data is lost!)",
259 : &reset_db),
260 57 : GNUNET_GETOPT_option_flag ('s',
261 : "shardunlock",
262 : "unlock all revolving shard locks (use after system crash or shard size change while services are not running)",
263 : &clear_shards),
264 57 : GNUNET_GETOPT_option_uint ('P',
265 : "partition",
266 : "NUMBER",
267 : "Setup a partitioned database where each table which can be partitioned holds NUMBER partitions on a single DB node",
268 : &num_partitions),
269 57 : GNUNET_GETOPT_option_flag ('f',
270 : "force",
271 : "Force partitions to be created if there is only one partition",
272 : &force_create_partitions),
273 : GNUNET_GETOPT_OPTION_END
274 : };
275 : enum GNUNET_GenericReturnValue ret;
276 :
277 57 : ret = GNUNET_PROGRAM_run (
278 : TALER_EXCHANGE_project_data (),
279 : argc, argv,
280 : "taler-exchange-dbinit",
281 : gettext_noop ("Initialize Taler exchange database"),
282 : options,
283 : &run, NULL);
284 57 : if (GNUNET_SYSERR == ret)
285 0 : return EXIT_INVALIDARGUMENT;
286 57 : if (GNUNET_NO == ret)
287 0 : return EXIT_SUCCESS;
288 57 : return global_ret;
289 : }
290 :
291 :
292 : /* end of taler-exchange-dbinit.c */
|