~stub/charms/precise/postgresql/docs

« back to all changes in this revision

Viewing changes to hooks/hooks.py

  • Committer: Stuart Bishop
  • Date: 2014-01-08 08:25:32 UTC
  • mfrom: (75.1.16 postgresql)
  • Revision ID: stuart@stuartbishop.net-20140108082532-nr07k6j73jqrijlx
Fix manual performance tuning kerel settings, cleanups and unittest framework. Merge lp:~chad.smith/charms/precise/postgresql/postgresql-manual-tune-kernel-params-fix per https://code.launchpad.net/~chad.smith/charms/precise/postgresql/postgresql-manual-tune-kernel-params-fix/+merge/200730

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
    '''
49
49
    myname = hookenv.local_unit().replace('/', '-')
50
50
    ts = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
51
 
    with open('/var/log/juju/{}-debug.log'.format(myname), 'a') as f:
 
51
    with open('{}/{}-debug.log'.format(juju_log_dir, myname), 'a') as f:
52
52
        f.write('{} {}: {}\n'.format(ts, lvl, msg))
53
53
    hookenv.log(msg, lvl)
54
54
 
121
121
def volume_get_volid_from_volume_map():
122
122
    volume_map = {}
123
123
    try:
124
 
        volume_map = yaml.load(config_data['volume-map'].strip())
 
124
        volume_map = yaml.load(hookenv.config('volume-map').strip())
125
125
        if volume_map:
126
126
            return volume_map.get(os.environ['JUJU_UNIT_NAME'])
127
127
    except ConstructorError as e:
154
154
# @returns  volid
155
155
#           None    config state is invalid - we should not serve
156
156
def volume_get_volume_id():
157
 
    ephemeral_storage = config_data['volume-ephemeral-storage']
 
157
    ephemeral_storage = hookenv.config('volume-ephemeral-storage')
158
158
    volid = volume_get_volid_from_volume_map()
159
159
    juju_unit_name = hookenv.local_unit()
160
160
    if ephemeral_storage in [True, 'yes', 'Yes', 'true', 'True']:
195
195
 
196
196
 
197
197
def postgresql_autostart(enabled):
 
198
    postgresql_config_dir = _get_postgresql_config_dir()
198
199
    startup_file = os.path.join(postgresql_config_dir, 'start.conf')
199
200
    if enabled:
200
201
        log("Enabling PostgreSQL startup in {}".format(startup_file))
202
203
    else:
203
204
        log("Disabling PostgreSQL startup in {}".format(startup_file))
204
205
        mode = 'manual'
205
 
    contents = Template(open("templates/start_conf.tmpl").read()).render(
206
 
        {'mode': mode})
 
206
    template_file = "{}/templates/start_conf.tmpl".format(hookenv.charm_dir())
 
207
    contents = Template(open(template_file).read()).render({'mode': mode})
207
208
    host.write_file(
208
209
        startup_file, contents, 'postgres', 'postgres', perms=0o644)
209
210
 
229
230
    if status != 0:
230
231
        return False
231
232
    # e.g. output: "Running clusters: 9.1/main"
232
 
    vc = "%s/%s" % (config_data["version"], config_data["cluster_name"])
 
233
    vc = "%s/%s" % (hookenv.config("version"), hookenv.config("cluster_name"))
233
234
    return vc in output.decode('utf8').split()
234
235
 
235
236
 
253
254
            # success = host.service_restart('postgresql')
254
255
            try:
255
256
                run('pg_ctlcluster -force {version} {cluster_name} '
256
 
                    'restart'.format(**config_data))
 
257
                    'restart'.format(**hookenv.config()))
257
258
                success = True
258
259
            except subprocess.CalledProcessError:
259
260
                success = False
327
328
    return success
328
329
 
329
330
 
330
 
def get_service_port(postgresql_config):
 
331
def get_service_port(config_file):
331
332
    '''Return the port PostgreSQL is listening on.'''
332
 
    if not os.path.exists(postgresql_config):
 
333
    if not os.path.exists(config_file):
333
334
        return None
334
 
    postgresql_config = open(postgresql_config, 'r').read()
 
335
    postgresql_config = open(config_file, 'r').read()
335
336
    port = re.search("port.*=(.*)", postgresql_config).group(1).strip()
336
337
    try:
337
338
        return int(port)
339
340
        return None
340
341
 
341
342
 
342
 
def create_postgresql_config(postgresql_config):
 
343
def _get_system_ram():
 
344
    """ Return the system ram in Megabytes """
 
345
    import psutil
 
346
    return psutil.phymem_usage()[0] / (1024 ** 2)
 
347
 
 
348
 
 
349
def _get_page_size():
 
350
    """ Return the operating system's configured PAGE_SIZE """
 
351
    return int(run("getconf PAGE_SIZE"))   # frequently 4096
 
352
 
 
353
 
 
354
def create_postgresql_config(config_file):
343
355
    '''Create the postgresql.conf file'''
 
356
    config_data = hookenv.config()
344
357
    if config_data["performance_tuning"] == "auto":
345
358
        # Taken from:
346
359
        # http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
347
360
        # num_cpus is not being used ... commenting it out ... negronjl
348
361
        #num_cpus = run("cat /proc/cpuinfo | grep processor | wc -l")
349
 
        total_ram = run("free -m | grep Mem | awk '{print $2}'")
 
362
        total_ram = _get_system_ram()
350
363
        if not config_data["effective_cache_size"]:
351
364
            config_data["effective_cache_size"] = \
352
365
                "%sMB" % (int(int(total_ram) * 0.75),)
357
370
            else:
358
371
                config_data["shared_buffers"] = \
359
372
                    "%sMB" % (int(int(total_ram) * 0.15),)
360
 
        # XXX: This is very messy - should probably be a subordinate charm
361
 
        conf_file = open("/etc/sysctl.d/50-postgresql.conf", "w")
362
 
        conf_file.write("kernel.sem = 250 32000 100 1024\n")
363
 
        conf_file.write("kernel.shmall = %s\n" %
364
 
                        ((int(total_ram) * 1024 * 1024) + 1024),)
365
 
        conf_file.write("kernel.shmmax = %s\n" %
366
 
                        ((int(total_ram) * 1024 * 1024) + 1024),)
367
 
        conf_file.close()
368
 
        run("sysctl -p /etc/sysctl.d/50-postgresql.conf")
 
373
        config_data["kernel_shmmax"] = (int(total_ram) * 1024 * 1024) + 1024
 
374
        config_data["kernel_shmall"] = config_data["kernel_shmmax"]
 
375
 
 
376
    # XXX: This is very messy - should probably be a subordinate charm
 
377
    lines = ["kernel.sem = 250 32000 100 1024\n"]
 
378
    if config_data["kernel_shmall"] > 0:
 
379
        # Convert config kernel_shmall (bytes) to pages
 
380
        page_size = _get_page_size()
 
381
        num_pages = config_data["kernel_shmall"] / page_size
 
382
        if (config_data["kernel_shmall"] % page_size) > 0:
 
383
            num_pages += 1
 
384
        lines.append("kernel.shmall = %s\n" % num_pages)
 
385
    if config_data["kernel_shmmax"] > 0:
 
386
        lines.append("kernel.shmmax = %s\n" % config_data["kernel_shmmax"])
 
387
    host.write_file(postgresql_sysctl, ''.join(lines), perms=0600)
 
388
    run("sysctl -p {}".format(postgresql_sysctl))
369
389
 
370
390
    # If we are replicating, some settings may need to be overridden to
371
391
    # certain minimum levels.
383
403
 
384
404
    # Send config data to the template
385
405
    # Return it as pg_config
 
406
    charm_dir = hookenv.charm_dir()
 
407
    template_file = "{}/templates/postgresql.conf.tmpl".format(charm_dir)
386
408
    pg_config = Template(
387
 
        open("templates/postgresql.conf.tmpl").read()).render(config_data)
 
409
        open(template_file).read()).render(config_data)
388
410
    host.write_file(
389
 
        postgresql_config, pg_config,
 
411
        config_file, pg_config,
390
412
        owner="postgres",  group="postgres", perms=0600)
391
413
 
392
414
    local_state['saved_config'] = config_data
393
415
    local_state.save()
394
416
 
395
417
 
396
 
def create_postgresql_ident(postgresql_ident):
 
418
def create_postgresql_ident(output_file):
397
419
    '''Create the pg_ident.conf file.'''
398
420
    ident_data = {}
399
 
    pg_ident_template = Template(
400
 
        open("templates/pg_ident.conf.tmpl").read())
 
421
    charm_dir = hookenv.charm_dir()
 
422
    template_file = "{}/templates/pg_ident.conf.tmpl".format(charm_dir)
 
423
    pg_ident_template = Template(open(template_file).read())
401
424
    host.write_file(
402
 
        postgresql_ident, pg_ident_template.render(ident_data),
 
425
        output_file, pg_ident_template.render(ident_data),
403
426
        owner="postgres", group="postgres", perms=0600)
404
427
 
405
428
 
406
429
def generate_postgresql_hba(
407
 
        postgresql_hba, user=None, schema_user=None, database=None):
 
430
        output_file, user=None, schema_user=None, database=None):
408
431
    '''Create the pg_hba.conf file.'''
409
432
 
410
433
    # Per Bug #1117542, when generating the postgresql_hba file we
429
452
                return output.rstrip(".")  # trailing dot
430
453
            return addr
431
454
 
 
455
    config_data = hookenv.config()
432
456
    allowed_units = set()
433
457
    relation_data = []
434
458
    relids = hookenv.relation_ids('db') + hookenv.relation_ids('db-admin')
525
549
                'private-address': munge_address(admin_ip)}
526
550
            relation_data.append(admin_host)
527
551
 
528
 
    pg_hba_template = Template(open("templates/pg_hba.conf.tmpl").read())
 
552
    template_file = "{}/templates/pg_hba.conf.tmpl".format(hookenv.charm_dir())
 
553
    pg_hba_template = Template(open(template_file).read())
529
554
    host.write_file(
530
 
        postgresql_hba, pg_hba_template.render(access_list=relation_data),
 
555
        output_file, pg_hba_template.render(access_list=relation_data),
531
556
        owner="postgres", group="postgres", perms=0600)
532
557
    postgresql_reload()
533
558
 
539
564
            relid, {"allowed-units": " ".join(unit_sorted(allowed_units))})
540
565
 
541
566
 
542
 
def install_postgresql_crontab(postgresql_ident):
 
567
def install_postgresql_crontab(output_file):
543
568
    '''Create the postgres user's crontab'''
 
569
    config_data = hookenv.config()
544
570
    crontab_data = {
545
571
        'backup_schedule': config_data["backup_schedule"],
546
572
        'scripts_dir': postgresql_scripts_dir,
547
573
        'backup_days': config_data["backup_retention_count"],
548
574
    }
 
575
    charm_dir = hookenv.charm_dir()
 
576
    template_file = "{}/templates/postgres.cron.tmpl".format(charm_dir)
549
577
    crontab_template = Template(
550
 
        open("templates/postgres.cron.tmpl").read()).render(crontab_data)
551
 
    host.write_file('/etc/cron.d/postgres', crontab_template, perms=0600)
 
578
        open(template_file).read()).render(crontab_data)
 
579
    host.write_file(output_file, crontab_template, perms=0600)
552
580
 
553
581
 
554
582
def create_recovery_conf(master_host, restart_on_change=False):
 
583
    version = hookenv.config('version')
 
584
    cluster_name = hookenv.config('cluster_name')
 
585
    postgresql_cluster_dir = os.path.join(
 
586
        postgresql_data_dir, version, cluster_name)
 
587
 
555
588
    recovery_conf_path = os.path.join(postgresql_cluster_dir, 'recovery.conf')
556
589
    if os.path.exists(recovery_conf_path):
557
590
        old_recovery_conf = open(recovery_conf_path, 'r').read()
558
591
    else:
559
592
        old_recovery_conf = None
560
593
 
561
 
    recovery_conf = Template(
562
 
        open("templates/recovery.conf.tmpl").read()).render({
 
594
    charm_dir = hookenv.charm_dir()
 
595
    template_file = "{}/templates/recovery.conf.tmpl".format(charm_dir)
 
596
    recovery_conf = Template(open(template_file).read()).render({
563
597
        'host': master_host,
564
598
        'password': local_state['replication_password']})
565
599
    log(recovery_conf, DEBUG)
578
612
#                          Returns a string containing the postgresql config or
579
613
#                          None
580
614
#------------------------------------------------------------------------------
581
 
def load_postgresql_config(postgresql_config):
582
 
    if os.path.isfile(postgresql_config):
583
 
        return(open(postgresql_config).read())
 
615
def load_postgresql_config(config_file):
 
616
    if os.path.isfile(config_file):
 
617
        return(open(config_file).read())
584
618
    else:
585
619
        return(None)
586
620
 
677
711
#     - manipulate /var/lib/postgresql/VERSION/CLUSTER symlink
678
712
#------------------------------------------------------------------------------
679
713
def config_changed_volume_apply():
680
 
    data_directory_path = postgresql_cluster_dir
 
714
    version = hookenv.config('version')
 
715
    cluster_name = hookenv.config('cluster_name')
 
716
    data_directory_path = os.path.join(
 
717
        postgresql_data_dir, version, cluster_name)
 
718
 
681
719
    assert(data_directory_path)
682
720
    volid = volume_get_volume_id()
683
721
    if volid:
698
736
        mount_point = volume_mount_point_from_volid(volid)
699
737
        new_pg_dir = os.path.join(mount_point, "postgresql")
700
738
        new_pg_version_cluster_dir = os.path.join(
701
 
            new_pg_dir, config_data["version"], config_data["cluster_name"])
 
739
            new_pg_dir, version, cluster_name)
702
740
        if not mount_point:
703
741
            log(
704
742
                "invalid mount point from volid = {}, "
724
762
        #   /var/lib/postgresql/9.1/main
725
763
        curr_dir_stat = os.stat(data_directory_path)
726
764
        for new_dir in [new_pg_dir,
727
 
                        os.path.join(new_pg_dir, config_data["version"]),
 
765
                        os.path.join(new_pg_dir, version),
728
766
                        new_pg_version_cluster_dir]:
729
767
            if not os.path.isdir(new_dir):
730
768
                log("mkdir %s".format(new_dir))
781
819
 
782
820
@hooks.hook()
783
821
def config_changed(force_restart=False):
784
 
    update_repos_and_packages()
 
822
    config_data = hookenv.config()
 
823
    update_repos_and_packages(config_data["version"])
785
824
 
786
825
    # Trigger volume initialization logic for permanent storage
787
826
    volid = volume_get_volume_id()
813
852
                "Disabled and stopped postgresql service "
814
853
                "(config_changed_volume_apply failure)", ERROR)
815
854
            sys.exit(1)
 
855
 
 
856
    postgresql_config_dir = _get_postgresql_config_dir(config_data)
 
857
    postgresql_config = os.path.join(postgresql_config_dir, "postgresql.conf")
 
858
    postgresql_hba = os.path.join(postgresql_config_dir, "pg_hba.conf")
 
859
    postgresql_ident = os.path.join(postgresql_config_dir, "pg_ident.conf")
 
860
 
816
861
    current_service_port = get_service_port(postgresql_config)
817
862
    create_postgresql_config(postgresql_config)
818
863
    generate_postgresql_hba(postgresql_hba)
819
864
    create_postgresql_ident(postgresql_ident)
 
865
 
820
866
    updated_service_port = config_data["listen_port"]
821
867
    update_service_port(current_service_port, updated_service_port)
822
868
    update_nrpe_checks()
832
878
            if os.path.isfile(f) and os.access(f, os.X_OK):
833
879
                subprocess.check_call(['sh', '-c', f])
834
880
 
835
 
    update_repos_and_packages()
836
 
 
 
881
    config_data = hookenv.config()
 
882
    update_repos_and_packages(config_data["version"])
837
883
    if not 'state' in local_state:
838
884
        # Fresh installation. Because this function is invoked by both
839
885
        # the install hook and the upgrade-charm hook, we need to guard
848
894
        run("pg_createcluster --locale='{}' --encoding='{}' 9.1 main".format(
849
895
            config_data['locale'], config_data['encoding']))
850
896
 
 
897
    postgresql_backups_dir = (
 
898
        config_data['backup_dir'].strip() or
 
899
        os.path.join(postgresql_data_dir, 'backups'))
 
900
 
851
901
    host.mkdir(postgresql_backups_dir, owner="postgres", perms=0o755)
852
902
    host.mkdir(postgresql_scripts_dir, owner="postgres", perms=0o755)
853
903
    host.mkdir(postgresql_logs_dir, owner="postgres", perms=0o755)
857
907
        'scripts_dir': postgresql_scripts_dir,
858
908
        'logs_dir': postgresql_logs_dir,
859
909
    }
860
 
    dump_script = Template(
861
 
        open("templates/dump-pg-db.tmpl").read()).render(paths)
862
 
    backup_job = Template(
863
 
        open("templates/pg_backup_job.tmpl").read()).render(paths)
 
910
    charm_dir = hookenv.charm_dir()
 
911
    template_file = "{}/templates/dump-pg-db.tmpl".format(charm_dir)
 
912
    dump_script = Template(open(template_file).read()).render(paths)
 
913
    template_file = "{}/templates/pg_backup_job.tmpl".format(charm_dir)
 
914
    backup_job = Template(open(template_file).read()).render(paths)
864
915
    host.write_file(
865
916
        '{}/dump-pg-db'.format(postgresql_scripts_dir),
866
917
        dump_script, perms=0755)
1176
1227
    log("Client relations {}".format(local_state['client_relations']))
1177
1228
    local_state.publish()
1178
1229
 
 
1230
    postgresql_hba = os.path.join(_get_postgresql_config_dir(), "pg_hba.conf")
1179
1231
    generate_postgresql_hba(postgresql_hba, user=user,
1180
1232
                            schema_user=schema_user,
1181
1233
                            database=database)
1213
1265
    log("Client relations {}".format(local_state['client_relations']))
1214
1266
    local_state.publish()
1215
1267
 
 
1268
    postgresql_hba = os.path.join(_get_postgresql_config_dir(), "pg_hba.conf")
1216
1269
    generate_postgresql_hba(postgresql_hba)
1217
1270
 
1218
1271
    snapshot_relations()
1245
1298
        run_sql_as_postgres(sql, AsIs(quote_identifier(database)),
1246
1299
                            AsIs(quote_identifier(user + "_schema")))
1247
1300
 
 
1301
    postgresql_hba = os.path.join(_get_postgresql_config_dir(), "pg_hba.conf")
1248
1302
    generate_postgresql_hba(postgresql_hba)
1249
1303
 
1250
1304
    # Cleanup our local state.
1261
1315
            sql = "ALTER USER %s NOSUPERUSER"
1262
1316
            run_sql_as_postgres(sql, AsIs(quote_identifier(user)))
1263
1317
 
 
1318
    postgresql_hba = os.path.join(_get_postgresql_config_dir(), "pg_hba.conf")
1264
1319
    generate_postgresql_hba(postgresql_hba)
1265
1320
 
1266
1321
    # Cleanup our local state.
1267
1322
    snapshot_relations()
1268
1323
 
1269
1324
 
1270
 
def update_repos_and_packages():
 
1325
def update_repos_and_packages(version):
1271
1326
    extra_repos = hookenv.config('extra_archives')
1272
1327
    extra_repos_added = local_state.setdefault('extra_repos_added', set())
1273
1328
    if extra_repos:
1284
1339
    # It might have been better for debversion and plpython to only get
1285
1340
    # installed if they were listed in the extra-packages config item,
1286
1341
    # but they predate this feature.
1287
 
    packages = ["postgresql-%s" % config_data["version"],
1288
 
                "postgresql-contrib-%s" % config_data["version"],
1289
 
                "postgresql-plpython-%s" % config_data["version"],
1290
 
                "postgresql-%s-debversion" % config_data["version"],
 
1342
    packages = ["python-psutil",  # to obtain system RAM from python
 
1343
                "libc-bin",       # for getconf
 
1344
                "postgresql-%s" % version,
 
1345
                "postgresql-contrib-%s" % version,
 
1346
                "postgresql-plpython-%s" % version,
 
1347
                "postgresql-%s-debversion" % version,
1291
1348
                "python-jinja2", "syslinux", "python-psycopg2"]
1292
1349
    packages.extend((hookenv.config('extra-packages') or '').split())
1293
1350
    packages = fetch.filter_installed_packages(packages)
1351
1408
 
1352
1409
def promote_database():
1353
1410
    '''Take the database out of recovery mode.'''
 
1411
    config_data = hookenv.config()
 
1412
    version = config_data['version']
 
1413
    cluster_name = config_data['cluster_name']
 
1414
    postgresql_cluster_dir = os.path.join(
 
1415
        postgresql_data_dir, version, cluster_name)
1354
1416
    recovery_conf = os.path.join(postgresql_cluster_dir, 'recovery.conf')
1355
1417
    if os.path.exists(recovery_conf):
1356
1418
        # Rather than using 'pg_ctl promote', we do the promotion
1554
1616
            del local_state['paused_at_failover']
1555
1617
 
1556
1618
        publish_hot_standby_credentials()
 
1619
        postgresql_hba = os.path.join(
 
1620
            _get_postgresql_config_dir(), "pg_hba.conf")
1557
1621
        generate_postgresql_hba(postgresql_hba)
1558
1622
 
1559
1623
    local_state.publish()
1706
1770
    lock.
1707
1771
    '''
1708
1772
    import psycopg2
1709
 
    key = long(config_data['advisory_lock_restart_key'])
 
1773
    key = long(hookenv.config('advisory_lock_restart_key'))
1710
1774
    if exclusive:
1711
1775
        lock_function = 'pg_advisory_lock'
1712
1776
    else:
1749
1813
        postgresql_stop()
1750
1814
        log("Cloning master {}".format(master_unit))
1751
1815
 
 
1816
        config_data = hookenv.config()
 
1817
        version = config_data['version']
 
1818
        cluster_name = config_data['cluster_name']
 
1819
        postgresql_cluster_dir = os.path.join(
 
1820
            postgresql_data_dir, version, cluster_name)
 
1821
        postgresql_config_dir = _get_postgresql_config_dir(config_data)
1752
1822
        cmd = [
1753
1823
            'sudo', '-E',  # -E needed to locate pgpass file.
1754
1824
            '-u', 'postgres', 'pg_basebackup', '-D', postgresql_cluster_dir,
1802
1872
 
1803
1873
 
1804
1874
def postgresql_is_in_backup_mode():
 
1875
    version = hookenv.config('version')
 
1876
    cluster_name = hookenv.config('cluster_name')
 
1877
    postgresql_cluster_dir = os.path.join(
 
1878
        postgresql_data_dir, version, cluster_name)
 
1879
 
1805
1880
    return os.path.exists(
1806
1881
        os.path.join(postgresql_cluster_dir, 'backup_label'))
1807
1882
 
1919
1994
        host.service_reload('nagios-nrpe-server')
1920
1995
 
1921
1996
 
 
1997
def _get_postgresql_config_dir(config_data=None):
 
1998
    """ Return the directory path of the postgresql configuration files. """
 
1999
    if config_data == None:
 
2000
        config_data = hookenv.config()
 
2001
    version = config_data['version']
 
2002
    cluster_name = config_data['cluster_name']
 
2003
    return os.path.join("/etc/postgresql", version, cluster_name)
 
2004
 
1922
2005
###############################################################################
1923
2006
# Global variables
1924
2007
###############################################################################
1925
 
config_data = hookenv.config()
1926
 
version = config_data['version']
1927
 
cluster_name = config_data['cluster_name']
1928
2008
postgresql_data_dir = "/var/lib/postgresql"
1929
 
postgresql_cluster_dir = os.path.join(
1930
 
    postgresql_data_dir, version, cluster_name)
1931
 
postgresql_bin_dir = os.path.join('/usr/lib/postgresql', version, 'bin')
1932
 
postgresql_config_dir = os.path.join("/etc/postgresql", version, cluster_name)
1933
 
postgresql_config = os.path.join(postgresql_config_dir, "postgresql.conf")
1934
 
postgresql_ident = os.path.join(postgresql_config_dir, "pg_ident.conf")
1935
 
postgresql_hba = os.path.join(postgresql_config_dir, "pg_hba.conf")
 
2009
postgresql_scripts_dir = os.path.join(postgresql_data_dir, 'scripts')
 
2010
postgresql_logs_dir = os.path.join(postgresql_data_dir, 'logs')
 
2011
 
 
2012
postgresql_sysctl = "/etc/sysctl.d/50-postgresql.conf"
1936
2013
postgresql_crontab = "/etc/cron.d/postgresql"
1937
2014
postgresql_service_config_dir = "/var/run/postgresql"
1938
 
postgresql_scripts_dir = os.path.join(postgresql_data_dir, 'scripts')
1939
 
postgresql_backups_dir = (
1940
 
    config_data['backup_dir'].strip() or
1941
 
    os.path.join(postgresql_data_dir, 'backups'))
1942
 
postgresql_logs_dir = os.path.join(postgresql_data_dir, 'logs')
1943
 
hook_name = os.path.basename(sys.argv[0])
1944
2015
replication_relation_types = ['master', 'slave', 'replication']
1945
2016
local_state = State('local_state.pickle')
 
2017
hook_name = os.path.basename(sys.argv[0])
 
2018
juju_log_dir = "/var/log/juju"
1946
2019
 
1947
2020
 
1948
2021
if __name__ == '__main__':