add pg_dump
This commit is contained in:
parent
a657dce572
commit
eefd04dbfc
|
@ -1,5 +1,5 @@
|
|||
FROM fenglc/pgadmin4
|
||||
|
||||
MAINTAINER Bo-Yi Wu <appleboy.tw@gmail.com>
|
||||
ADD pg /usr/bin
|
||||
MAINTAINER Huadong Zuo <admin@zuohuadong.cn>
|
||||
|
||||
EXPOSE 5050
|
||||
|
|
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/perl -w
|
||||
# Call a PostgreSQL client program with the version, cluster and default
|
||||
# database specified in ~/.postgresqlrc or
|
||||
# /etc/postgresql-common/user_clusters.
|
||||
#
|
||||
# (C) 2005-2009 Martin Pitt <mpitt@debian.org>
|
||||
# (C) 2013-2014 Christoph Berg <myon@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
use strict;
|
||||
use POSIX;
|
||||
use PgCommon;
|
||||
|
||||
my ($version, $cluster, $db, $port, $host);
|
||||
|
||||
$host = $ENV{'PGHOST'};
|
||||
|
||||
# Check for PGCLUSTER in %ENV
|
||||
if (defined $ENV{'PGCLUSTER'}) {
|
||||
($version, $cluster) = split ('/', $ENV{'PGCLUSTER'}, 2);
|
||||
error 'Invalid version specified with $PGCLUSTER' unless version_exists $version;
|
||||
error 'No cluster specified with $PGCLUSTER' unless $cluster;
|
||||
}
|
||||
|
||||
# Check for --cluster argument and filter it out, and check if --port is specified
|
||||
my $port_specified = exists $ENV{'PGPORT'};
|
||||
for (my $i = 0; $i <= $#ARGV; ++$i) {
|
||||
last if $ARGV[$i] eq '--';
|
||||
|
||||
if ($ARGV[$i] eq '--cluster') {
|
||||
error '--cluster option needs an argument (<version>/<cluster>)' if ($i >= $#ARGV);
|
||||
|
||||
($version, $cluster) = split ('/', $ARGV[$i+1], 2);
|
||||
$host = undef; # --cluster overrides $PGHOST env var
|
||||
error 'Invalid version specified with --cluster' unless version_exists $version;
|
||||
error 'No cluster specified with --cluster' unless $cluster;
|
||||
|
||||
splice @ARGV, $i, 2;
|
||||
last;
|
||||
} elsif ($ARGV[$i] =~ /^--cluster=(\d+\.?\d)\/(.+)/) {
|
||||
($version, $cluster) = ($1, $2);
|
||||
$host = undef; # --cluster overrides $PGHOST env var
|
||||
error 'Invalid version specified with --cluster' unless version_exists $version;
|
||||
error 'No cluster specified with --cluster' unless $cluster;
|
||||
|
||||
splice @ARGV, $i, 1;
|
||||
last;
|
||||
}
|
||||
|
||||
$port_specified = 1 if $ARGV[$i] =~ /^--port\b/ || $ARGV[$i] =~ /^-\w*p\w*\d*$/;
|
||||
$host = '.from.commandline' if $ARGV[$i] =~ /^--host\b/ || $ARGV[$i] =~ /^-\w*h\w*$/;
|
||||
}
|
||||
|
||||
# Determine $version, $cluster, $db, $port from map files
|
||||
($version, $cluster, $db) = user_cluster_map() unless $cluster;
|
||||
|
||||
# check if we have a network cluster
|
||||
if (!$host && $cluster && !cluster_exists $version, $cluster) {
|
||||
if ($cluster =~ /^(\S+):(\d*)$/) {
|
||||
$host = $1;
|
||||
$port = $2 || 5432;
|
||||
} else {
|
||||
error 'Specified cluster does not exist locally and does not specify a remote cluster';
|
||||
}
|
||||
}
|
||||
|
||||
if (!$host && $cluster) {
|
||||
$port = get_cluster_port($version, $cluster);
|
||||
|
||||
unless ($ENV{'PGHOST'}) {
|
||||
# default to cluster specific Unix socket directory
|
||||
$ENV{'PGHOST'} = get_cluster_socketdir $version, $cluster;
|
||||
}
|
||||
}
|
||||
|
||||
$ENV{'PGSYSCONFDIR'} = '/etc/postgresql-common' if !$ENV{'PGSYSCONFDIR'};
|
||||
$ENV{'PGPORT'} = $port if $port && !$ENV{'PGPORT'};
|
||||
$ENV{'PGDATABASE'} = $db if $db && !$ENV{'PGDATABASE'};
|
||||
$ENV{'PGHOST'} = $host if $host && $host ne '.from.commandline';
|
||||
|
||||
# if we only have a port, but no version here, use the latest version
|
||||
# TODO: this could be improved by better argument parsing and mapping back the
|
||||
# port to a cluster version/name
|
||||
if (!$version and $port_specified) {
|
||||
$version = get_newest_version;
|
||||
}
|
||||
|
||||
unless ($version) {
|
||||
if (get_versions) {
|
||||
error 'No existing local cluster is suitable as a default target. Please see man pg_wrapper(1) how to specify one.';
|
||||
} else {
|
||||
error 'You must install at least one postgresql-client-<version> package.';
|
||||
}
|
||||
}
|
||||
|
||||
error 'Invalid PostgreSQL cluster version' unless -d "$PgCommon::binroot$version";
|
||||
my $cmdname = (split '/', $0)[-1];
|
||||
my $cmd;
|
||||
|
||||
# for psql we always want the latest version, as this is backwards compatible
|
||||
# to every major version that that we support
|
||||
if ($cmdname eq 'pg_wrapper') {
|
||||
error "pg_wrapper should not be called directly, but through a symlink";
|
||||
} elsif ($cmdname =~ /^(psql|pg_archivecleanup|pg_isready)$/) {
|
||||
$cmd = get_program_path ($cmdname, get_newest_version);
|
||||
} else {
|
||||
$cmd = get_program_path ($cmdname, $version);
|
||||
}
|
||||
|
||||
# libreadline is a lot better than libedit, so prefer that
|
||||
if ($cmdname eq 'psql' and not $PgCommon::rpm) {
|
||||
my @readlines;
|
||||
# non-multiarch path
|
||||
@readlines = sort(</lib/libreadline.so.?>);
|
||||
|
||||
unless (@readlines) {
|
||||
# get multiarch dir for our architecture
|
||||
if (open PS, '-|', '/usr/bin/ldd', $cmd) {
|
||||
my $out;
|
||||
read PS, $out, 10000;
|
||||
close PS;
|
||||
if ($out =~ m!/libreadline.so!) {
|
||||
# already linked against libreadline
|
||||
@readlines = ();
|
||||
}
|
||||
else
|
||||
{
|
||||
my ($lib_path) = $out =~ m!(/lib/.*)/libedit.so!;
|
||||
|
||||
@readlines = sort(<$lib_path/libreadline.so.?>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (@readlines) {
|
||||
$ENV{'LD_PRELOAD'} = ($ENV{'LD_PRELOAD'} or '') . ':' . $readlines[-1];
|
||||
}
|
||||
}
|
||||
|
||||
error "pg_wrapper: $cmdname was not found in $PgCommon::binroot$version/bin" unless $cmd;
|
||||
unshift @ARGV, $cmd;
|
||||
exec @ARGV;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
pg_wrapper - wrapper for PostgreSQL client commands
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
I<client-program> [B<--cluster> I<version>/I<cluster>] [...]
|
||||
|
||||
(I<client-program>: B<psql>, B<createdb>, B<dropuser>, and all other client
|
||||
programs installed in C</usr/lib/postgresql/>I<version>C</bin>).
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This program is run only as a link to names which correspond to PostgreSQL
|
||||
programs in C</usr/lib/postgresql/>I<version>C</bin>. It determines the
|
||||
configured cluster and database for the user and calls the appropriate version
|
||||
of the desired program to connect to that cluster and database, supplying any
|
||||
specified options to that command.
|
||||
|
||||
The target cluster is selected by the following means, in descending order of
|
||||
precedence:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
explicit specification with the B<--host> option
|
||||
|
||||
=item 2.
|
||||
|
||||
explicit specification with the B<--cluster> option
|
||||
|
||||
=item 3.
|
||||
|
||||
if the B<PGHOST> environment variable is set, no further cluster selection is
|
||||
performed. The default PostgreSQL version and port number (from the command
|
||||
line, the environment variable B<PGPORT>, or default 5432) will be used.
|
||||
|
||||
=item 4.
|
||||
|
||||
explicit specification with the B<PGCLUSTER> environment variable
|
||||
|
||||
=item 5.
|
||||
|
||||
matching entry in C<~/.postgresqlrc> (see L<postgresqlrc(5)>), if that
|
||||
file exists
|
||||
|
||||
=item 6.
|
||||
|
||||
matching entry in C</etc/postgresql-common/user_clusters> (see
|
||||
L<user_clusters(5)>), if that file exists
|
||||
|
||||
=item 7.
|
||||
|
||||
If only one local cluster exists, that one will be selected.
|
||||
|
||||
=item 8.
|
||||
|
||||
If several local clusters exist, the one listening on the default port 5432
|
||||
will be selected.
|
||||
|
||||
=back
|
||||
|
||||
If none of these rules match, B<pg_wrapper> aborts with an error.
|
||||
|
||||
For B<psql>, B<pg_archivecleanup>, and B<pg_isready>, B<pg_wrapper> will always use the binary from
|
||||
the newest PostgreSQL version installed, as these are downwards compatible.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item B<--cluster> I<version>B</>I<cluster>
|
||||
|
||||
I<cluster> is either the name of a local cluster, or takes the form
|
||||
I<host>:I<port> for a remote cluster. If I<port> is left empty (i. e. you just
|
||||
specify I<host:>), it defaults to 5432.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
|
||||
=over
|
||||
|
||||
=item B<PGCLUSTER>
|
||||
|
||||
If C<$PGCLUSTER> is set, its value (of the form I<version>/I<cluster>)
|
||||
specifies the desired cluster, similar to the B<--cluster> option. However, if
|
||||
B<--cluster> is specified, it overrides the value of C<$PGCLUSTER>.
|
||||
|
||||
=item B<PG_CLUSTER_CONF_ROOT>
|
||||
|
||||
This specifies an alternative base directory for cluster configurations. This
|
||||
is usually C</etc/postgresql/>, but for testing/development purposes you can
|
||||
change this to point to e. g. your home directory, so that you can use the
|
||||
postgresql-common tools without root privileges.
|
||||
|
||||
=item B<PGSYSCONFDIR>
|
||||
|
||||
This is the location of PostgreSQL's and postgresql-common's global
|
||||
configuration (e. g. C<pg_service.conf>, L<user_clusters(5)>). The default is
|
||||
C</etc/postgresql-common/>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 FILES
|
||||
|
||||
=over
|
||||
|
||||
=item C</etc/postgresql-common/user_clusters>
|
||||
|
||||
stores the default cluster and database for users and groups as set by
|
||||
the administrators.
|
||||
|
||||
=item C<$HOME/.postgresqlrc>
|
||||
|
||||
stores defaults set by the user himself.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<user_clusters(5)>, L<postgresqlrc(5)>
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Martin Pitt L<E<lt>mpitt@debian.orgE<gt>>
|
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/perl -w
|
||||
# Call a PostgreSQL client program with the version, cluster and default
|
||||
# database specified in ~/.postgresqlrc or
|
||||
# /etc/postgresql-common/user_clusters.
|
||||
#
|
||||
# (C) 2005-2009 Martin Pitt <mpitt@debian.org>
|
||||
# (C) 2013-2014 Christoph Berg <myon@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
use strict;
|
||||
use POSIX;
|
||||
use PgCommon;
|
||||
|
||||
my ($version, $cluster, $db, $port, $host);
|
||||
|
||||
$host = $ENV{'PGHOST'};
|
||||
|
||||
# Check for PGCLUSTER in %ENV
|
||||
if (defined $ENV{'PGCLUSTER'}) {
|
||||
($version, $cluster) = split ('/', $ENV{'PGCLUSTER'}, 2);
|
||||
error 'Invalid version specified with $PGCLUSTER' unless version_exists $version;
|
||||
error 'No cluster specified with $PGCLUSTER' unless $cluster;
|
||||
}
|
||||
|
||||
# Check for --cluster argument and filter it out, and check if --port is specified
|
||||
my $port_specified = exists $ENV{'PGPORT'};
|
||||
for (my $i = 0; $i <= $#ARGV; ++$i) {
|
||||
last if $ARGV[$i] eq '--';
|
||||
|
||||
if ($ARGV[$i] eq '--cluster') {
|
||||
error '--cluster option needs an argument (<version>/<cluster>)' if ($i >= $#ARGV);
|
||||
|
||||
($version, $cluster) = split ('/', $ARGV[$i+1], 2);
|
||||
$host = undef; # --cluster overrides $PGHOST env var
|
||||
error 'Invalid version specified with --cluster' unless version_exists $version;
|
||||
error 'No cluster specified with --cluster' unless $cluster;
|
||||
|
||||
splice @ARGV, $i, 2;
|
||||
last;
|
||||
} elsif ($ARGV[$i] =~ /^--cluster=(\d+\.?\d)\/(.+)/) {
|
||||
($version, $cluster) = ($1, $2);
|
||||
$host = undef; # --cluster overrides $PGHOST env var
|
||||
error 'Invalid version specified with --cluster' unless version_exists $version;
|
||||
error 'No cluster specified with --cluster' unless $cluster;
|
||||
|
||||
splice @ARGV, $i, 1;
|
||||
last;
|
||||
}
|
||||
|
||||
$port_specified = 1 if $ARGV[$i] =~ /^--port\b/ || $ARGV[$i] =~ /^-\w*p\w*\d*$/;
|
||||
$host = '.from.commandline' if $ARGV[$i] =~ /^--host\b/ || $ARGV[$i] =~ /^-\w*h\w*$/;
|
||||
}
|
||||
|
||||
# Determine $version, $cluster, $db, $port from map files
|
||||
($version, $cluster, $db) = user_cluster_map() unless $cluster;
|
||||
|
||||
# check if we have a network cluster
|
||||
if (!$host && $cluster && !cluster_exists $version, $cluster) {
|
||||
if ($cluster =~ /^(\S+):(\d*)$/) {
|
||||
$host = $1;
|
||||
$port = $2 || 5432;
|
||||
} else {
|
||||
error 'Specified cluster does not exist locally and does not specify a remote cluster';
|
||||
}
|
||||
}
|
||||
|
||||
if (!$host && $cluster) {
|
||||
$port = get_cluster_port($version, $cluster);
|
||||
|
||||
unless ($ENV{'PGHOST'}) {
|
||||
# default to cluster specific Unix socket directory
|
||||
$ENV{'PGHOST'} = get_cluster_socketdir $version, $cluster;
|
||||
}
|
||||
}
|
||||
|
||||
$ENV{'PGSYSCONFDIR'} = '/etc/postgresql-common' if !$ENV{'PGSYSCONFDIR'};
|
||||
$ENV{'PGPORT'} = $port if $port && !$ENV{'PGPORT'};
|
||||
$ENV{'PGDATABASE'} = $db if $db && !$ENV{'PGDATABASE'};
|
||||
$ENV{'PGHOST'} = $host if $host && $host ne '.from.commandline';
|
||||
|
||||
# if we only have a port, but no version here, use the latest version
|
||||
# TODO: this could be improved by better argument parsing and mapping back the
|
||||
# port to a cluster version/name
|
||||
if (!$version and $port_specified) {
|
||||
$version = get_newest_version;
|
||||
}
|
||||
|
||||
unless ($version) {
|
||||
if (get_versions) {
|
||||
error 'No existing local cluster is suitable as a default target. Please see man pg_wrapper(1) how to specify one.';
|
||||
} else {
|
||||
error 'You must install at least one postgresql-client-<version> package.';
|
||||
}
|
||||
}
|
||||
|
||||
error 'Invalid PostgreSQL cluster version' unless -d "$PgCommon::binroot$version";
|
||||
my $cmdname = (split '/', $0)[-1];
|
||||
my $cmd;
|
||||
|
||||
# for psql we always want the latest version, as this is backwards compatible
|
||||
# to every major version that that we support
|
||||
if ($cmdname eq 'pg_wrapper') {
|
||||
error "pg_wrapper should not be called directly, but through a symlink";
|
||||
} elsif ($cmdname =~ /^(psql|pg_archivecleanup|pg_isready)$/) {
|
||||
$cmd = get_program_path ($cmdname, get_newest_version);
|
||||
} else {
|
||||
$cmd = get_program_path ($cmdname, $version);
|
||||
}
|
||||
|
||||
# libreadline is a lot better than libedit, so prefer that
|
||||
if ($cmdname eq 'psql' and not $PgCommon::rpm) {
|
||||
my @readlines;
|
||||
# non-multiarch path
|
||||
@readlines = sort(</lib/libreadline.so.?>);
|
||||
|
||||
unless (@readlines) {
|
||||
# get multiarch dir for our architecture
|
||||
if (open PS, '-|', '/usr/bin/ldd', $cmd) {
|
||||
my $out;
|
||||
read PS, $out, 10000;
|
||||
close PS;
|
||||
if ($out =~ m!/libreadline.so!) {
|
||||
# already linked against libreadline
|
||||
@readlines = ();
|
||||
}
|
||||
else
|
||||
{
|
||||
my ($lib_path) = $out =~ m!(/lib/.*)/libedit.so!;
|
||||
|
||||
@readlines = sort(<$lib_path/libreadline.so.?>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (@readlines) {
|
||||
$ENV{'LD_PRELOAD'} = ($ENV{'LD_PRELOAD'} or '') . ':' . $readlines[-1];
|
||||
}
|
||||
}
|
||||
|
||||
error "pg_wrapper: $cmdname was not found in $PgCommon::binroot$version/bin" unless $cmd;
|
||||
unshift @ARGV, $cmd;
|
||||
exec @ARGV;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
pg_wrapper - wrapper for PostgreSQL client commands
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
I<client-program> [B<--cluster> I<version>/I<cluster>] [...]
|
||||
|
||||
(I<client-program>: B<psql>, B<createdb>, B<dropuser>, and all other client
|
||||
programs installed in C</usr/lib/postgresql/>I<version>C</bin>).
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This program is run only as a link to names which correspond to PostgreSQL
|
||||
programs in C</usr/lib/postgresql/>I<version>C</bin>. It determines the
|
||||
configured cluster and database for the user and calls the appropriate version
|
||||
of the desired program to connect to that cluster and database, supplying any
|
||||
specified options to that command.
|
||||
|
||||
The target cluster is selected by the following means, in descending order of
|
||||
precedence:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
explicit specification with the B<--host> option
|
||||
|
||||
=item 2.
|
||||
|
||||
explicit specification with the B<--cluster> option
|
||||
|
||||
=item 3.
|
||||
|
||||
if the B<PGHOST> environment variable is set, no further cluster selection is
|
||||
performed. The default PostgreSQL version and port number (from the command
|
||||
line, the environment variable B<PGPORT>, or default 5432) will be used.
|
||||
|
||||
=item 4.
|
||||
|
||||
explicit specification with the B<PGCLUSTER> environment variable
|
||||
|
||||
=item 5.
|
||||
|
||||
matching entry in C<~/.postgresqlrc> (see L<postgresqlrc(5)>), if that
|
||||
file exists
|
||||
|
||||
=item 6.
|
||||
|
||||
matching entry in C</etc/postgresql-common/user_clusters> (see
|
||||
L<user_clusters(5)>), if that file exists
|
||||
|
||||
=item 7.
|
||||
|
||||
If only one local cluster exists, that one will be selected.
|
||||
|
||||
=item 8.
|
||||
|
||||
If several local clusters exist, the one listening on the default port 5432
|
||||
will be selected.
|
||||
|
||||
=back
|
||||
|
||||
If none of these rules match, B<pg_wrapper> aborts with an error.
|
||||
|
||||
For B<psql>, B<pg_archivecleanup>, and B<pg_isready>, B<pg_wrapper> will always use the binary from
|
||||
the newest PostgreSQL version installed, as these are downwards compatible.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item B<--cluster> I<version>B</>I<cluster>
|
||||
|
||||
I<cluster> is either the name of a local cluster, or takes the form
|
||||
I<host>:I<port> for a remote cluster. If I<port> is left empty (i. e. you just
|
||||
specify I<host:>), it defaults to 5432.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
|
||||
=over
|
||||
|
||||
=item B<PGCLUSTER>
|
||||
|
||||
If C<$PGCLUSTER> is set, its value (of the form I<version>/I<cluster>)
|
||||
specifies the desired cluster, similar to the B<--cluster> option. However, if
|
||||
B<--cluster> is specified, it overrides the value of C<$PGCLUSTER>.
|
||||
|
||||
=item B<PG_CLUSTER_CONF_ROOT>
|
||||
|
||||
This specifies an alternative base directory for cluster configurations. This
|
||||
is usually C</etc/postgresql/>, but for testing/development purposes you can
|
||||
change this to point to e. g. your home directory, so that you can use the
|
||||
postgresql-common tools without root privileges.
|
||||
|
||||
=item B<PGSYSCONFDIR>
|
||||
|
||||
This is the location of PostgreSQL's and postgresql-common's global
|
||||
configuration (e. g. C<pg_service.conf>, L<user_clusters(5)>). The default is
|
||||
C</etc/postgresql-common/>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 FILES
|
||||
|
||||
=over
|
||||
|
||||
=item C</etc/postgresql-common/user_clusters>
|
||||
|
||||
stores the default cluster and database for users and groups as set by
|
||||
the administrators.
|
||||
|
||||
=item C<$HOME/.postgresqlrc>
|
||||
|
||||
stores defaults set by the user himself.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<user_clusters(5)>, L<postgresqlrc(5)>
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Martin Pitt L<E<lt>mpitt@debian.orgE<gt>>
|
Loading…
Reference in New Issue