Bypass recovery checks with older servers. This is required for Greenplum which is based on PG 8.3 at present.
parent
30e546208f
commit
c6b67fc66a
|
@ -44,6 +44,19 @@ def has_any(data, keys):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def recovery_state(connection, postgres_version):
|
||||||
|
recovery_check_sql = render_template("connect/sql/#{0}#/check_recovery.sql".format(postgres_version))
|
||||||
|
|
||||||
|
status, result = connection.execute_dict(recovery_check_sql)
|
||||||
|
if status:
|
||||||
|
in_recovery = result['rows'][0]['inrecovery']
|
||||||
|
wal_paused = result['rows'][0]['isreplaypaused']
|
||||||
|
else:
|
||||||
|
in_recovery = None
|
||||||
|
wal_paused = None
|
||||||
|
return in_recovery, wal_paused
|
||||||
|
|
||||||
|
|
||||||
class ServerModule(sg.ServerGroupPluginModule):
|
class ServerModule(sg.ServerGroupPluginModule):
|
||||||
NODE_TYPE = "server"
|
NODE_TYPE = "server"
|
||||||
LABEL = gettext("Servers")
|
LABEL = gettext("Servers")
|
||||||
|
@ -74,21 +87,7 @@ class ServerModule(sg.ServerGroupPluginModule):
|
||||||
in_recovery = None
|
in_recovery = None
|
||||||
wal_paused = None
|
wal_paused = None
|
||||||
if connected:
|
if connected:
|
||||||
status, result = conn.execute_dict("""
|
in_recovery, wal_paused = recovery_state(conn, manager.version)
|
||||||
SELECT CASE WHEN usesuper
|
|
||||||
THEN pg_is_in_recovery()
|
|
||||||
ELSE FALSE
|
|
||||||
END as inrecovery,
|
|
||||||
CASE WHEN usesuper AND pg_is_in_recovery()
|
|
||||||
THEN pg_is_xlog_replay_paused()
|
|
||||||
ELSE FALSE
|
|
||||||
END as isreplaypaused
|
|
||||||
FROM pg_user WHERE usename=current_user""")
|
|
||||||
|
|
||||||
if len(result['rows']):
|
|
||||||
in_recovery = result['rows'][0]['inrecovery']
|
|
||||||
wal_paused = result['rows'][0]['isreplaypaused']
|
|
||||||
|
|
||||||
yield self.generate_browser_node(
|
yield self.generate_browser_node(
|
||||||
"%d" % (server.id),
|
"%d" % (server.id),
|
||||||
gid,
|
gid,
|
||||||
|
@ -231,19 +230,7 @@ class ServerNode(PGChildNodeView):
|
||||||
connected = conn.connected()
|
connected = conn.connected()
|
||||||
|
|
||||||
if connected:
|
if connected:
|
||||||
status, result = conn.execute_dict("""
|
in_recovery, wal_paused = recovery_state(conn, manager.version)
|
||||||
SELECT CASE WHEN usesuper
|
|
||||||
THEN pg_is_in_recovery()
|
|
||||||
ELSE FALSE
|
|
||||||
END as inrecovery,
|
|
||||||
CASE WHEN usesuper AND pg_is_in_recovery()
|
|
||||||
THEN pg_is_xlog_replay_paused()
|
|
||||||
ELSE FALSE
|
|
||||||
END as isreplaypaused
|
|
||||||
FROM pg_user WHERE usename=current_user""")
|
|
||||||
|
|
||||||
in_recovery = result['rows'][0]['inrecovery'];
|
|
||||||
wal_paused = result['rows'][0]['isreplaypaused']
|
|
||||||
else:
|
else:
|
||||||
in_recovery = None
|
in_recovery = None
|
||||||
wal_paused = None
|
wal_paused = None
|
||||||
|
@ -274,6 +261,7 @@ class ServerNode(PGChildNodeView):
|
||||||
|
|
||||||
return make_json_response(result=res)
|
return make_json_response(result=res)
|
||||||
|
|
||||||
|
|
||||||
def node(self, gid, sid):
|
def node(self, gid, sid):
|
||||||
"""Return a JSON document listing the server groups for the user"""
|
"""Return a JSON document listing the server groups for the user"""
|
||||||
server = Server.query.filter_by(user_id=current_user.id,
|
server = Server.query.filter_by(user_id=current_user.id,
|
||||||
|
@ -296,19 +284,7 @@ class ServerNode(PGChildNodeView):
|
||||||
connected = conn.connected()
|
connected = conn.connected()
|
||||||
|
|
||||||
if connected:
|
if connected:
|
||||||
status, result = conn.execute_dict("""
|
in_recovery, wal_paused = recovery_state(conn, manager.version)
|
||||||
SELECT CASE WHEN usesuper
|
|
||||||
THEN pg_is_in_recovery()
|
|
||||||
ELSE FALSE
|
|
||||||
END as inrecovery,
|
|
||||||
CASE WHEN usesuper AND pg_is_in_recovery()
|
|
||||||
THEN pg_is_xlog_replay_paused()
|
|
||||||
ELSE FALSE
|
|
||||||
END as isreplaypaused
|
|
||||||
FROM pg_user WHERE usename=current_user""")
|
|
||||||
|
|
||||||
in_recovery = result['rows'][0]['inrecovery'];
|
|
||||||
wal_paused = result['rows'][0]['isreplaypaused']
|
|
||||||
else:
|
else:
|
||||||
in_recovery = None
|
in_recovery = None
|
||||||
wal_paused = None
|
wal_paused = None
|
||||||
|
@ -849,22 +825,7 @@ class ServerNode(PGChildNodeView):
|
||||||
current_app.logger.info('Connection Established for server: \
|
current_app.logger.info('Connection Established for server: \
|
||||||
%s - %s' % (server.id, server.name))
|
%s - %s' % (server.id, server.name))
|
||||||
# Update the recovery and wal pause option for the server if connected successfully
|
# Update the recovery and wal pause option for the server if connected successfully
|
||||||
status, result = conn.execute_dict("""
|
in_recovery, wal_paused = recovery_state(conn, manager.version)
|
||||||
SELECT CASE WHEN usesuper
|
|
||||||
THEN pg_is_in_recovery()
|
|
||||||
ELSE FALSE
|
|
||||||
END as inrecovery,
|
|
||||||
CASE WHEN usesuper AND pg_is_in_recovery()
|
|
||||||
THEN pg_is_xlog_replay_paused()
|
|
||||||
ELSE FALSE
|
|
||||||
END as isreplaypaused
|
|
||||||
FROM pg_user WHERE usename=current_user""")
|
|
||||||
if status:
|
|
||||||
in_recovery = result['rows'][0]['inrecovery'];
|
|
||||||
wal_paused = result['rows'][0]['isreplaypaused']
|
|
||||||
else:
|
|
||||||
in_recovery = None
|
|
||||||
wal_paused = None
|
|
||||||
|
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
success=1,
|
success=1,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
SELECT FALSE as inrecovery, FALSE as isreplaypaused;
|
|
@ -0,0 +1,9 @@
|
||||||
|
SELECT CASE WHEN usesuper
|
||||||
|
THEN pg_is_in_recovery()
|
||||||
|
ELSE FALSE
|
||||||
|
END as inrecovery,
|
||||||
|
CASE WHEN usesuper AND pg_is_in_recovery()
|
||||||
|
THEN pg_is_xlog_replay_paused()
|
||||||
|
ELSE FALSE
|
||||||
|
END as isreplaypaused
|
||||||
|
FROM pg_user WHERE usename=current_user
|
|
@ -0,0 +1,33 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from regression import test_utils
|
||||||
|
|
||||||
|
|
||||||
|
class TestCheckRecovery(BaseTestGenerator):
|
||||||
|
|
||||||
|
versions_to_test = ["8.3_plus", "9.0_plus"]
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
|
||||||
|
cursor = test_utils.get_db_connection(self.server['db'],
|
||||||
|
self.server['username'],
|
||||||
|
self.server['db_password'],
|
||||||
|
self.server['host'],
|
||||||
|
self.server['port']).cursor()
|
||||||
|
|
||||||
|
for version in self.versions_to_test:
|
||||||
|
template_file = os.path.join(os.path.dirname(__file__), "..", version, "check_recovery.sql")
|
||||||
|
|
||||||
|
cursor.execute(open(template_file, 'r').read())
|
||||||
|
fetch_result = cursor.fetchall()
|
||||||
|
|
||||||
|
first_row = {}
|
||||||
|
for index, description in enumerate(cursor.description):
|
||||||
|
first_row[description.name] = fetch_result[0][index]
|
||||||
|
|
||||||
|
in_recovery = first_row['inrecovery']
|
||||||
|
wal_paused = first_row['isreplaypaused']
|
||||||
|
|
||||||
|
self.assertEqual(False, in_recovery)
|
||||||
|
self.assertEqual(False, wal_paused)
|
|
@ -346,9 +346,7 @@ class PGChildNodeView(NodeView):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Set the sql_path
|
# Set the sql_path
|
||||||
sql_path = ''
|
sql_path = 'depends/sql/#{0}#'.format(conn.manager.version)
|
||||||
if conn.manager.version >= 90100:
|
|
||||||
sql_path = 'depends/sql/9.1_plus'
|
|
||||||
|
|
||||||
if where is None:
|
if where is None:
|
||||||
where_clause = "WHERE dep.objid={0}::oid".format(object_id)
|
where_clause = "WHERE dep.objid={0}::oid".format(object_id)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import os
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from jinja2 import FileSystemLoader
|
from jinja2 import FileSystemLoader
|
||||||
|
from jinja2 import TemplateNotFound
|
||||||
|
|
||||||
from pgadmin import VersionedTemplateLoader
|
from pgadmin import VersionedTemplateLoader
|
||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
@ -35,11 +36,19 @@ class TestVersionedTemplateLoader(BaseTestGenerator):
|
||||||
self.assertIn("some_feature/sql/9.1_plus/some_action.sql", filename)
|
self.assertIn("some_feature/sql/9.1_plus/some_action.sql", filename)
|
||||||
|
|
||||||
def test_get_source_when_the_version_is_9_3_and_there_are_templates_for_9_2_and_9_1_returns_9_2_template(self):
|
def test_get_source_when_the_version_is_9_3_and_there_are_templates_for_9_2_and_9_1_returns_9_2_template(self):
|
||||||
|
|
||||||
content, filename, up_to_dateness = self.loader.get_source(None, "some_feature/sql/#90300#/some_action.sql")
|
content, filename, up_to_dateness = self.loader.get_source(None, "some_feature/sql/#90300#/some_action.sql")
|
||||||
|
|
||||||
self.assertEqual("Some 9.2 SQL", content)
|
self.assertEqual("Some 9.2 SQL", content)
|
||||||
self.assertIn("some_feature/sql/9.2_plus/some_action.sql", filename)
|
self.assertIn("some_feature/sql/9.2_plus/some_action.sql", filename)
|
||||||
|
|
||||||
|
def test_raise_not_found_exception_when_postgres_version_less_than_all_available_sql_templates(self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.loader.get_source(None, "some_feature/sql/#10100#/some_action.sql")
|
||||||
|
self.fail("No exception raised")
|
||||||
|
except TemplateNotFound, e:
|
||||||
|
return
|
||||||
|
|
||||||
class FakeApp(Flask):
|
class FakeApp(Flask):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -12,7 +12,9 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
|
||||||
{'name': "9.4_plus", 'number': 90400},
|
{'name': "9.4_plus", 'number': 90400},
|
||||||
{'name': "9.3_plus", 'number': 90300},
|
{'name': "9.3_plus", 'number': 90300},
|
||||||
{'name': "9.2_plus", 'number': 90200},
|
{'name': "9.2_plus", 'number': 90200},
|
||||||
{'name': "9.1_plus", 'number': 90100}
|
{'name': "9.1_plus", 'number': 90100},
|
||||||
|
{'name': "9.0_plus", 'number': 90000},
|
||||||
|
{'name': "8.3_plus", 'number': 80300}
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(template_path_parts) == 1:
|
if len(template_path_parts) == 1:
|
||||||
|
@ -29,3 +31,4 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
|
||||||
return super(VersionedTemplateLoader, self).get_source(environment, template_path)
|
return super(VersionedTemplateLoader, self).get_source(environment, template_path)
|
||||||
except TemplateNotFound:
|
except TemplateNotFound:
|
||||||
continue
|
continue
|
||||||
|
raise TemplateNotFound(template)
|
Loading…
Reference in New Issue