|
7 | 7 | import signal
|
8 | 8 | import subprocess
|
9 | 9 | import threading
|
10 |
| -import tempfile |
11 |
| -import platform |
12 | 10 | from queue import Queue
|
13 | 11 |
|
14 | 12 | import time
|
@@ -692,9 +690,6 @@ def _try_shutdown(self, max_attempts, with_force=False):
|
692 | 690 | ps_output,
|
693 | 691 | ps_command)
|
694 | 692 |
|
695 |
| - def _release_resources(self): |
696 |
| - self.free_port() |
697 |
| - |
698 | 693 | @staticmethod
|
699 | 694 | def _throw_bugcheck__unexpected_result_of_ps(result, cmd):
|
700 | 695 | assert type(result) == str # noqa: E721
|
@@ -1326,25 +1321,18 @@ def pg_ctl(self, params):
|
1326 | 1321 |
|
1327 | 1322 | return execute_utility2(self.os_ops, _params, self.utils_log_file)
|
1328 | 1323 |
|
| 1324 | + def release_resources(self): |
| 1325 | + """ |
| 1326 | + Release resorces owned by this node. |
| 1327 | + """ |
| 1328 | + return self._release_resources() |
| 1329 | + |
1329 | 1330 | def free_port(self):
|
1330 | 1331 | """
|
1331 | 1332 | Reclaim port owned by this node.
|
1332 | 1333 | NOTE: this method does not release manually defined port but reset it.
|
1333 | 1334 | """
|
1334 |
| - assert type(self._should_free_port) == bool # noqa: E721 |
1335 |
| - |
1336 |
| - if not self._should_free_port: |
1337 |
| - self._port = None |
1338 |
| - else: |
1339 |
| - assert type(self._port) == int # noqa: E721 |
1340 |
| - |
1341 |
| - assert self._port_manager is not None |
1342 |
| - assert isinstance(self._port_manager, PortManager) |
1343 |
| - |
1344 |
| - port = self._port |
1345 |
| - self._should_free_port = False |
1346 |
| - self._port = None |
1347 |
| - self._port_manager.release_port(port) |
| 1335 | + return self._free_port() |
1348 | 1336 |
|
1349 | 1337 | def cleanup(self, max_attempts=3, full=False, release_resources=False):
|
1350 | 1338 | """
|
@@ -2158,6 +2146,25 @@ def upgrade_from(self, old_node, options=None, expect_error=False):
|
2158 | 2146 |
|
2159 | 2147 | return self.os_ops.exec_command(upgrade_command, expect_error=expect_error)
|
2160 | 2148 |
|
| 2149 | + def _release_resources(self): |
| 2150 | + self._free_port() |
| 2151 | + |
| 2152 | + def _free_port(self): |
| 2153 | + assert type(self._should_free_port) == bool # noqa: E721 |
| 2154 | + |
| 2155 | + if not self._should_free_port: |
| 2156 | + self._port = None |
| 2157 | + else: |
| 2158 | + assert type(self._port) == int # noqa: E721 |
| 2159 | + |
| 2160 | + assert self._port_manager is not None |
| 2161 | + assert isinstance(self._port_manager, PortManager) |
| 2162 | + |
| 2163 | + port = self._port |
| 2164 | + self._should_free_port = False |
| 2165 | + self._port = None |
| 2166 | + self._port_manager.release_port(port) |
| 2167 | + |
2161 | 2168 | def _get_bin_path(self, filename):
|
2162 | 2169 | assert self._os_ops is not None
|
2163 | 2170 | assert isinstance(self._os_ops, OsOperations)
|
@@ -2352,164 +2359,3 @@ def delect_port_conflict(log_reader: PostgresNodeLogReader) -> bool:
|
2352 | 2359 | return True
|
2353 | 2360 |
|
2354 | 2361 | return False
|
2355 |
| - |
2356 |
| - |
2357 |
| -class NodeApp: |
2358 |
| - |
2359 |
| - def __init__(self, test_path=None, nodes_to_cleanup=None, os_ops=None): |
2360 |
| - assert os_ops is None or isinstance(os_ops, OsOperations) |
2361 |
| - |
2362 |
| - if os_ops is None: |
2363 |
| - os_ops = LocalOperations.get_single_instance() |
2364 |
| - |
2365 |
| - assert isinstance(os_ops, OsOperations) |
2366 |
| - |
2367 |
| - if test_path: |
2368 |
| - if os.path.isabs(test_path): |
2369 |
| - self.test_path = test_path |
2370 |
| - else: |
2371 |
| - self.test_path = os_ops.build_path(os_ops.cwd(), test_path) |
2372 |
| - else: |
2373 |
| - self.test_path = os_ops.cwd() |
2374 |
| - self.nodes_to_cleanup = nodes_to_cleanup if nodes_to_cleanup else [] |
2375 |
| - self.os_ops = os_ops |
2376 |
| - |
2377 |
| - def make_empty( |
2378 |
| - self, |
2379 |
| - base_dir=None, |
2380 |
| - port=None, |
2381 |
| - bin_dir=None): |
2382 |
| - real_base_dir = self.os_ops.build_path(self.test_path, base_dir) |
2383 |
| - self.os_ops.rmdirs(real_base_dir, ignore_errors=True) |
2384 |
| - self.os_ops.makedirs(real_base_dir) |
2385 |
| - |
2386 |
| - node = PostgresNode(base_dir=real_base_dir, port=port, bin_dir=bin_dir) |
2387 |
| - self.nodes_to_cleanup.append(node) |
2388 |
| - |
2389 |
| - return node |
2390 |
| - |
2391 |
| - def make_simple( |
2392 |
| - self, |
2393 |
| - base_dir=None, |
2394 |
| - port=None, |
2395 |
| - set_replication=False, |
2396 |
| - ptrack_enable=False, |
2397 |
| - initdb_params=[], |
2398 |
| - pg_options={}, |
2399 |
| - checksum=True, |
2400 |
| - bin_dir=None): |
2401 |
| - assert type(pg_options) == dict # noqa: E721 |
2402 |
| - |
2403 |
| - if checksum and '--data-checksums' not in initdb_params: |
2404 |
| - initdb_params.append('--data-checksums') |
2405 |
| - node = self.make_empty(base_dir, port, bin_dir=bin_dir) |
2406 |
| - node.init( |
2407 |
| - initdb_params=initdb_params, allow_streaming=set_replication) |
2408 |
| - |
2409 |
| - # set major version |
2410 |
| - pg_version_file = self.os_ops.read(self.os_ops.build_path(node.data_dir, 'PG_VERSION')) |
2411 |
| - node.major_version_str = str(pg_version_file.rstrip()) |
2412 |
| - node.major_version = float(node.major_version_str) |
2413 |
| - |
2414 |
| - # Set default parameters |
2415 |
| - options = { |
2416 |
| - 'max_connections': 100, |
2417 |
| - 'shared_buffers': '10MB', |
2418 |
| - 'fsync': 'off', |
2419 |
| - 'wal_level': 'logical', |
2420 |
| - 'hot_standby': 'off', |
2421 |
| - 'log_line_prefix': '%t [%p]: [%l-1] ', |
2422 |
| - 'log_statement': 'none', |
2423 |
| - 'log_duration': 'on', |
2424 |
| - 'log_min_duration_statement': 0, |
2425 |
| - 'log_connections': 'on', |
2426 |
| - 'log_disconnections': 'on', |
2427 |
| - 'restart_after_crash': 'off', |
2428 |
| - 'autovacuum': 'off', |
2429 |
| - # unix_socket_directories will be defined later |
2430 |
| - } |
2431 |
| - |
2432 |
| - # Allow replication in pg_hba.conf |
2433 |
| - if set_replication: |
2434 |
| - options['max_wal_senders'] = 10 |
2435 |
| - |
2436 |
| - if ptrack_enable: |
2437 |
| - options['ptrack.map_size'] = '1' |
2438 |
| - options['shared_preload_libraries'] = 'ptrack' |
2439 |
| - |
2440 |
| - if node.major_version >= 13: |
2441 |
| - options['wal_keep_size'] = '200MB' |
2442 |
| - else: |
2443 |
| - options['wal_keep_segments'] = '12' |
2444 |
| - |
2445 |
| - # Apply given parameters |
2446 |
| - for option_name, option_value in iteritems(pg_options): |
2447 |
| - options[option_name] = option_value |
2448 |
| - |
2449 |
| - # Define delayed propertyes |
2450 |
| - if not ("unix_socket_directories" in options.keys()): |
2451 |
| - options["unix_socket_directories"] = __class__._gettempdir_for_socket() |
2452 |
| - |
2453 |
| - # Set config values |
2454 |
| - node.set_auto_conf(options) |
2455 |
| - |
2456 |
| - # kludge for testgres |
2457 |
| - # https://github.com/postgrespro/testgres/issues/54 |
2458 |
| - # for PG >= 13 remove 'wal_keep_segments' parameter |
2459 |
| - if node.major_version >= 13: |
2460 |
| - node.set_auto_conf({}, 'postgresql.conf', ['wal_keep_segments']) |
2461 |
| - |
2462 |
| - return node |
2463 |
| - |
2464 |
| - @staticmethod |
2465 |
| - def _gettempdir_for_socket(): |
2466 |
| - platform_system_name = platform.system().lower() |
2467 |
| - |
2468 |
| - if platform_system_name == "windows": |
2469 |
| - return __class__._gettempdir() |
2470 |
| - |
2471 |
| - # |
2472 |
| - # [2025-02-17] Hot fix. |
2473 |
| - # |
2474 |
| - # Let's use hard coded path as Postgres likes. |
2475 |
| - # |
2476 |
| - # pg_config_manual.h: |
2477 |
| - # |
2478 |
| - # #ifndef WIN32 |
2479 |
| - # #define DEFAULT_PGSOCKET_DIR "/tmp" |
2480 |
| - # #else |
2481 |
| - # #define DEFAULT_PGSOCKET_DIR "" |
2482 |
| - # #endif |
2483 |
| - # |
2484 |
| - # On the altlinux-10 tempfile.gettempdir() may return |
2485 |
| - # the path to "private" temp directiry - "/temp/.private/<username>/" |
2486 |
| - # |
2487 |
| - # But Postgres want to find a socket file in "/tmp" (see above). |
2488 |
| - # |
2489 |
| - |
2490 |
| - return "/tmp" |
2491 |
| - |
2492 |
| - @staticmethod |
2493 |
| - def _gettempdir(): |
2494 |
| - v = tempfile.gettempdir() |
2495 |
| - |
2496 |
| - # |
2497 |
| - # Paranoid checks |
2498 |
| - # |
2499 |
| - if type(v) != str: # noqa: E721 |
2500 |
| - __class__._raise_bugcheck("tempfile.gettempdir returned a value with type {0}.".format(type(v).__name__)) |
2501 |
| - |
2502 |
| - if v == "": |
2503 |
| - __class__._raise_bugcheck("tempfile.gettempdir returned an empty string.") |
2504 |
| - |
2505 |
| - if not os.path.exists(v): |
2506 |
| - __class__._raise_bugcheck("tempfile.gettempdir returned a not exist path [{0}].".format(v)) |
2507 |
| - |
2508 |
| - # OK |
2509 |
| - return v |
2510 |
| - |
2511 |
| - @staticmethod |
2512 |
| - def _raise_bugcheck(msg): |
2513 |
| - assert type(msg) == str # noqa: E721 |
2514 |
| - assert msg != "" |
2515 |
| - raise Exception("[BUG CHECK] " + msg) |
0 commit comments