|
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