Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d537b6909 | ||
|
|
ea33ab308e | ||
|
|
e0639602e6 | ||
|
|
296c23784f | ||
|
|
3132fa175a | ||
|
|
20637bcacc | ||
|
|
a01ee87749 | ||
|
|
4c86079654 | ||
|
|
291e645d77 | ||
|
|
8e467788a3 | ||
|
|
71e40a7299 | ||
|
|
d9847ed1f3 | ||
|
|
db95414cf1 | ||
|
|
df7de2ef71 | ||
|
|
731ba32e81 | ||
|
|
32197a8405 | ||
|
|
2570f7d75c | ||
|
|
f65eb546b7 | ||
|
|
aeb42b1059 | ||
|
|
0d3cd2d466 | ||
|
|
76217ffa8f | ||
|
|
b27a884bda | ||
|
|
85d1459372 | ||
|
|
e5a91d30bf | ||
|
|
3fc0cc3e92 | ||
|
|
44cc7a308a | ||
|
|
c1e80ac38a | ||
|
|
be090552f8 | ||
|
|
e54ccb1302 | ||
|
|
2036e9d9a8 | ||
|
|
1b850ff616 | ||
|
|
a5a83da045 | ||
|
|
751b6c28b5 | ||
|
|
4c660f2155 | ||
|
|
701f21186b | ||
|
|
1317e4254b | ||
|
|
589663d7d9 | ||
|
|
884d9db54b | ||
|
|
617440e1db | ||
|
|
5372467569 | ||
|
|
9089750e21 | ||
|
|
2f9a29f663 | ||
|
|
447a1c9dd7 | ||
|
|
530eb3972b | ||
|
|
5d098fe4b0 | ||
|
|
3a50c17110 | ||
|
|
85b40ee4f0 | ||
|
|
9e85fb3de3 | ||
|
|
181bec62ce | ||
|
|
9c7691c891 | ||
|
|
14036b7aeb | ||
|
|
02c3863e8c | ||
|
|
6683522491 | ||
|
|
ee679e39e5 | ||
|
|
db1eb75298 | ||
|
|
cb3801a5e8 | ||
|
|
73b6b95fbc | ||
|
|
18f055fa5e | ||
|
|
9e90350e44 | ||
|
|
65d9f88c63 | ||
|
|
eca8e706dd | ||
|
|
b41557b54b | ||
|
|
0ccf2dad22 | ||
|
|
2097d37f76 | ||
|
|
0ca4426dd0 | ||
|
|
bc3c857b35 | ||
|
|
b948f43dda | ||
|
|
f7214b7cfe | ||
|
|
75f887f5dc | ||
|
|
e10dd6a80f | ||
|
|
960433dd90 | ||
|
|
32e3da7857 | ||
|
|
2a4ba132ad | ||
|
|
6e7ca8c4b0 | ||
|
|
7dc6181d1e | ||
|
|
921c0ac71a | ||
|
|
ad656a9d41 | ||
|
|
56cc1f0aaf | ||
|
|
bf56a6723b | ||
|
|
179bac3fd0 | ||
|
|
08df09af96 | ||
|
|
3c1dc18656 | ||
|
|
12276b6033 | ||
|
|
a12a02cc14 | ||
|
|
740d411524 | ||
|
|
2e68c6ff75 | ||
|
|
102ffd141c | ||
|
|
a0271c7656 | ||
|
|
358af42c50 | ||
|
|
48e257e5af | ||
|
|
36f76f5e2c | ||
|
|
ab642344d4 | ||
|
|
e230787f21 | ||
|
|
b563040cf3 | ||
|
|
addcf2c6e2 | ||
|
|
3f563d8cbf | ||
|
|
88c0968cab | ||
|
|
e5407ab2bd | ||
|
|
13db981445 | ||
|
|
446c2a19a5 | ||
|
|
0e03712a85 | ||
|
|
b18001ce57 | ||
|
|
f46cab6862 | ||
|
|
20c9082b8d | ||
|
|
e20f26c500 | ||
|
|
048c90a695 | ||
|
|
dca9745e97 | ||
|
|
45fa74ae46 | ||
|
|
f92b0961ee | ||
|
|
57ed02a9aa | ||
|
|
3e09f1bf40 | ||
|
|
91ca746c27 | ||
|
|
a2f626046a | ||
|
|
32cdfa2969 | ||
|
|
c71315f8cd | ||
|
|
57a2559f11 | ||
|
|
850afd7402 | ||
|
|
ddf7f04c94 | ||
|
|
9bee91b6f6 | ||
|
|
b3ca172f3a | ||
|
|
9fa29457a4 | ||
|
|
459c6ab796 | ||
|
|
da9f9017a9 | ||
|
|
94d2ad9584 | ||
|
|
9229156cf6 | ||
|
|
02f9b72d3e | ||
|
|
c0ef0a893d | ||
|
|
a60cfd3cc3 | ||
|
|
d4a3e4d92c | ||
|
|
5afa4f1995 | ||
|
|
0c8226ff39 | ||
|
|
065bda37b4 | ||
|
|
a2edf317a9 | ||
|
|
f86f58dc56 | ||
|
|
f0debdd513 | ||
|
|
6ead597b43 | ||
|
|
9a47e574e3 | ||
|
|
0bd77937de | ||
|
|
6a43c3d90b | ||
|
|
9dd357a9ee | ||
|
|
1a756efe82 | ||
|
|
18e4b30634 | ||
|
|
6589f82e77 | ||
|
|
3f089f31a3 | ||
|
|
0fcfe63092 | ||
|
|
d55555c544 | ||
|
|
90004119af | ||
|
|
f8497d4e7a | ||
|
|
eb3cd689a1 | ||
|
|
3687472201 | ||
|
|
b372f08a59 | ||
|
|
5198a881b7 | ||
|
|
233736897d | ||
|
|
cd5243ac6d | ||
|
|
d1f5511566 | ||
|
|
6fce58f2ad | ||
|
|
26bbc0e877 | ||
|
|
98b7603ebd | ||
|
|
f9087475d4 | ||
|
|
dbb4a46d46 | ||
|
|
3012778def | ||
|
|
4c9853f10d | ||
|
|
5448de2d3f | ||
|
|
a92595012f | ||
|
|
c933771016 | ||
|
|
ed5fc20ee2 | ||
|
|
a0ff0e30fb | ||
|
|
3def9792be | ||
|
|
a7b8d77ed7 | ||
|
|
cb0a914099 | ||
|
|
21333490ef | ||
|
|
5f5818ba78 | ||
|
|
c4d9ef9210 | ||
|
|
52780079f3 | ||
|
|
6475a70514 | ||
|
|
296d22ad83 | ||
|
|
c79614786f | ||
|
|
c7ae5024d5 | ||
|
|
f403e61b66 | ||
|
|
86fb879a0e | ||
|
|
ab5632d5eb | ||
|
|
eee23aa642 | ||
|
|
bb25e85834 | ||
|
|
375e2e0d13 | ||
|
|
9450065850 | ||
|
|
98ce8a298a | ||
|
|
7286d13d19 | ||
|
|
530cc19f58 | ||
|
|
bfa26be7f0 | ||
|
|
ca4db8871e | ||
|
|
146da066b0 | ||
|
|
12dc2c418d | ||
|
|
1c5cb63aff | ||
|
|
794bd50ed1 | ||
|
|
26b3bc3f74 | ||
|
|
64e6570f00 | ||
|
|
783b7516a7 | ||
|
|
abd0748a77 | ||
|
|
fb51ef569e | ||
|
|
b54cf2edca | ||
|
|
55e50144f3 | ||
|
|
a2f4628590 | ||
|
|
ce14696165 | ||
|
|
29c3c0cf7f | ||
|
|
3e2a1c4eca | ||
|
|
17ce84dd0a | ||
|
|
5839e7cda8 | ||
|
|
ebf5e871e0 | ||
|
|
5370bb4515 | ||
|
|
be386e77f2 | ||
|
|
a026f339c3 |
No files matched your search
@@ -0,0 +1,8 @@
|
||||
.git
|
||||
web/node_modules
|
||||
web/*.log
|
||||
web/regression
|
||||
web/**/tests/
|
||||
.DS_Store
|
||||
web/pgadmin/messages.pot
|
||||
web/pgadmin/translations/??/LC_MESSAGES/messages.po
|
||||
@@ -19,11 +19,12 @@
|
||||
/redhat-build
|
||||
/src-build
|
||||
/win-build
|
||||
/win-temp
|
||||
_build
|
||||
/build-*
|
||||
pgadmin4.log
|
||||
pkg/win32/installer.iss
|
||||
pkg/mac/codesign.conf
|
||||
pkg/mac/codesign.confx
|
||||
pkg/mac/framework.conf
|
||||
runtime/.qmake.cache
|
||||
runtime/.qmake.stash
|
||||
@@ -51,4 +52,8 @@ auditjs.html
|
||||
auditpy.txt
|
||||
/venv/
|
||||
.scannerwork/
|
||||
web/coverage/
|
||||
web/coverage/
|
||||
web/.coverage
|
||||
web/regression/.coverage
|
||||
web/regression/covhtml/
|
||||
web/regression/htmlcov/
|
||||
@@ -12,19 +12,22 @@
|
||||
# and clean up the web/ source code
|
||||
#########################################################################
|
||||
|
||||
FROM node:12-alpine3.11 AS app-builder
|
||||
FROM alpine:3.13 AS app-builder
|
||||
|
||||
RUN apk add --no-cache \
|
||||
autoconf \
|
||||
automake \
|
||||
bash \
|
||||
g++ \
|
||||
git \
|
||||
libc6-compat \
|
||||
libjpeg-turbo-dev \
|
||||
libpng-dev \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
git \
|
||||
nodejs \
|
||||
yarn \
|
||||
zlib-dev
|
||||
|
||||
# Create the /pgadmin4 directory and copy the source into it. Explicitly
|
||||
@@ -41,15 +44,7 @@ RUN rm -rf /pgadmin4/web/*.log \
|
||||
WORKDIR /pgadmin4/web
|
||||
|
||||
# Build the JS vendor code in the app-builder, and then remove the vendor source.
|
||||
RUN npm install && \
|
||||
npm audit fix && \
|
||||
rm -f yarn.lock && \
|
||||
yarn import && \
|
||||
# Commented the below line to avoid vulnerability in lodash package.
|
||||
# Refer https://www.npmjs.com/advisories/1523.
|
||||
# Once fixed we will uncomment it.
|
||||
# yarn audit && \
|
||||
rm -f package-lock.json && \
|
||||
RUN yarn install && \
|
||||
yarn run bundle && \
|
||||
rm -rf node_modules \
|
||||
yarn.lock \
|
||||
@@ -60,28 +55,39 @@ RUN npm install && \
|
||||
karma.conf.js \
|
||||
./pgadmin/static/js/generated/.cache
|
||||
|
||||
#########################################################################
|
||||
# Next, create the base environment for Python
|
||||
#########################################################################
|
||||
|
||||
FROM alpine:3.13 as env-builder
|
||||
|
||||
# Install dependencies
|
||||
COPY requirements.txt /
|
||||
RUN apk add --no-cache \
|
||||
make \
|
||||
python3 \
|
||||
py3-pip && \
|
||||
apk add --no-cache --virtual build-deps \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libffi-dev \
|
||||
postgresql-dev \
|
||||
krb5-dev \
|
||||
rust \
|
||||
cargo \
|
||||
python3-dev && \
|
||||
python3 -m venv --system-site-packages --without-pip /venv && \
|
||||
/venv/bin/python3 -m pip install --no-cache-dir -r requirements.txt && \
|
||||
apk del --no-cache build-deps
|
||||
|
||||
#########################################################################
|
||||
# Now, create a documentation build container for the Sphinx docs
|
||||
#########################################################################
|
||||
|
||||
FROM python:3.8-alpine3.11 as docs-builder
|
||||
FROM env-builder as docs-builder
|
||||
|
||||
# Install only dependencies absolutely required for documentation building
|
||||
RUN apk add --no-cache \
|
||||
make \
|
||||
build-base \
|
||||
openssl-dev \
|
||||
libffi-dev && \
|
||||
pip install --no-cache-dir \
|
||||
sphinx \
|
||||
flask_security_too \
|
||||
flask_paranoid \
|
||||
python-dateutil \
|
||||
flask_sqlalchemy \
|
||||
flask_gravatar \
|
||||
flask_migrate \
|
||||
simplejson \
|
||||
cryptography
|
||||
# Install Sphinx
|
||||
RUN /venv/bin/python3 -m pip install --no-cache-dir sphinx
|
||||
|
||||
# Copy the docs from the local tree. Explicitly remove any existing builds that
|
||||
# may be present
|
||||
@@ -90,26 +96,26 @@ COPY web /pgadmin4/web
|
||||
RUN rm -rf /pgadmin4/docs/en_US/_build
|
||||
|
||||
# Build the docs
|
||||
RUN LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 make -C /pgadmin4/docs/en_US -f Makefile.sphinx html
|
||||
RUN LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 /venv/bin/sphinx-build /pgadmin4/docs/en_US /pgadmin4/docs/en_US/_build/html
|
||||
|
||||
# Cleanup unwanted files
|
||||
RUN rm -rf /pgadmin4/docs/en_US/_build/html/.doctrees
|
||||
RUN rm -rf /pgadmin4/docs/en_US/_build/html/_sources
|
||||
RUN rm -rf /pgadmin4/docs/en_US/_build/html/_static/*.png
|
||||
|
||||
#########################################################################
|
||||
# Create additional builders to get all of the PostgreSQL utilities
|
||||
#########################################################################
|
||||
|
||||
FROM postgres:9.5-alpine as pg95-builder
|
||||
FROM postgres:9.6-alpine as pg96-builder
|
||||
FROM postgres:10-alpine as pg10-builder
|
||||
FROM postgres:11-alpine as pg11-builder
|
||||
FROM postgres:12-alpine as pg12-builder
|
||||
FROM postgres:13-alpine as pg13-builder
|
||||
|
||||
FROM alpine:3.11 as tool-builder
|
||||
FROM alpine:3.13 as tool-builder
|
||||
|
||||
# Copy the PG binaries
|
||||
COPY --from=pg95-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-9.5/
|
||||
COPY --from=pg95-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-9.5/
|
||||
COPY --from=pg95-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-9.5/
|
||||
COPY --from=pg95-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-9.5/
|
||||
|
||||
COPY --from=pg96-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-9.6/
|
||||
COPY --from=pg96-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-9.6/
|
||||
COPY --from=pg96-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-9.6/
|
||||
@@ -130,12 +136,21 @@ COPY --from=pg12-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-12/
|
||||
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-13/
|
||||
|
||||
#########################################################################
|
||||
# Assemble everything into the final container.
|
||||
#########################################################################
|
||||
|
||||
FROM python:3.8-alpine3.11
|
||||
FROM alpine:3.13
|
||||
|
||||
# Copy in the Python packages
|
||||
COPY --from=env-builder /venv /venv
|
||||
|
||||
# Copy in the tools
|
||||
COPY --from=tool-builder /usr/local/pgsql /usr/local/
|
||||
|
||||
WORKDIR /pgadmin4
|
||||
@@ -144,54 +159,36 @@ ENV PYTHONPATH=/pgadmin4
|
||||
# Copy in the code and docs
|
||||
COPY --from=app-builder /pgadmin4/web /pgadmin4
|
||||
COPY --from=docs-builder /pgadmin4/docs/en_US/_build/html/ /pgadmin4/docs
|
||||
COPY requirements.txt /pgadmin4/requirements.txt
|
||||
COPY pkg/docker/run_pgadmin.py /pgadmin4
|
||||
COPY pkg/docker/gunicorn_config.py /pgadmin4
|
||||
COPY pkg/docker/entrypoint.sh /entrypoint.sh
|
||||
|
||||
# License files
|
||||
COPY LICENSE /pgadmin4/LICENSE
|
||||
COPY DEPENDENCIES /pgadmin4/DEPENDENCIES
|
||||
|
||||
# Install build-dependencies, build & install C extensions and purge deps in
|
||||
# one RUN step
|
||||
RUN apk add --no-cache --virtual \
|
||||
build-deps \
|
||||
build-base \
|
||||
postgresql-dev \
|
||||
libffi-dev \
|
||||
linux-headers && \
|
||||
apk add \
|
||||
# Install runtime dependencies and configure everything in one RUN step
|
||||
RUN apk add \
|
||||
python3 \
|
||||
py3-pip \
|
||||
postfix \
|
||||
postgresql-client \
|
||||
postgresql-libs \
|
||||
krb5-libs \
|
||||
shadow \
|
||||
sudo \
|
||||
libedit \
|
||||
libcap && \
|
||||
pip install --upgrade pip && \
|
||||
pip install --no-cache-dir -r requirements.txt && \
|
||||
pip install --no-cache-dir gunicorn==19.9.0 && \
|
||||
apk del --no-cache build-deps && \
|
||||
echo "pgadmin ALL = NOPASSWD: /usr/sbin/postfix start" > /etc/sudoers.d/postfix
|
||||
|
||||
# We need the v12 libpq, which is only in the 'edge' build of Alpine at present
|
||||
COPY --from=pg12-builder /usr/local/lib/libpq.so.5.12 /usr/lib/
|
||||
RUN ln -sf /usr/lib/libpq.so.5.12 /usr/lib/libpq.so.5
|
||||
|
||||
# Copy the runner script
|
||||
COPY pkg/docker/run_pgadmin.py /pgadmin4
|
||||
COPY pkg/docker/gunicorn_config.py /pgadmin4
|
||||
COPY pkg/docker/entrypoint.sh /entrypoint.sh
|
||||
|
||||
# Precompile and optimize python code to save time and space on startup
|
||||
RUN python -O -m compileall -x node_modules /pgadmin4
|
||||
|
||||
RUN groupadd -g 5050 pgadmin && \
|
||||
/venv/bin/python3 -m pip install --no-cache-dir gunicorn && \
|
||||
find / -type d -name '__pycache__' -exec rm -rf {} + && \
|
||||
groupadd -g 5050 pgadmin && \
|
||||
useradd -r -u 5050 -g pgadmin pgadmin && \
|
||||
mkdir -p /var/lib/pgadmin && \
|
||||
chown pgadmin:pgadmin /var/lib/pgadmin && \
|
||||
mkdir -p /var/log/pgadmin && \
|
||||
chown pgadmin:pgadmin /var/log/pgadmin && \
|
||||
touch /pgadmin4/config_distro.py && \
|
||||
chown pgadmin:pgadmin /pgadmin4/config_distro.py && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/python3.8
|
||||
setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/python3.8 && \
|
||||
echo "pgadmin ALL = NOPASSWD: /usr/sbin/postfix start" > /etc/sudoers.d/postfix
|
||||
|
||||
USER pgadmin
|
||||
|
||||
# Finish up
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pgAdmin 4
|
||||
|
||||
Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose, without fee, and without a written agreement is
|
||||
|
||||
@@ -3,6 +3,7 @@ SETLOCAL
|
||||
|
||||
SET WD=%CD%
|
||||
SET "BUILDROOT=%WD%\win-build"
|
||||
SET "TMPDIR=%WD%\win-temp"
|
||||
SET "DISTROOT=%WD%\dist"
|
||||
|
||||
SET CMDOPTIONS=""
|
||||
@@ -18,19 +19,13 @@ IF "%1" == "clean" (
|
||||
EXIT /B %ERRORLEVEL%
|
||||
)
|
||||
|
||||
set "ARCHITECTURE=x64"
|
||||
if "%Platform%" == "X86" (
|
||||
set "ARCHITECTURE=x86"
|
||||
)
|
||||
|
||||
REM Main build sequence
|
||||
CALL :SET_ENVIRONMENT
|
||||
CALL :VALIDATE_ENVIRONMENT || EXIT /B 1
|
||||
CALL :CLEAN || EXIT /B 1
|
||||
CALL :CREATE_VIRTUAL_ENV || EXIT /B 1
|
||||
CALL :CREATE_RUNTIME_ENV || EXIT /B 1
|
||||
CALL :CREATE_PYTHON_ENV || EXIT /B 1
|
||||
CALL :CLEANUP_ENV || EXIT /B 1
|
||||
CALL :CREATE_RUNTIME_ENV || EXIT /B 1
|
||||
CALL :CREATE_INSTALLER || EXIT /B 1
|
||||
CALL :SIGN_INSTALLER || EXIT /B 1
|
||||
|
||||
@@ -42,7 +37,10 @@ REM Main build sequence Ends
|
||||
ECHO Removing build directory...
|
||||
IF EXIST "%BUILDROOT%" RD "%BUILDROOT%" /S /Q > nul || EXIT /B 1
|
||||
|
||||
ECHO Removing temp build directory...
|
||||
ECHO Removing tmp directory...
|
||||
IF EXIST "%TMPDIR%" RD "%TMPDIR%" /S /Q > nul || EXIT /B 1
|
||||
|
||||
ECHO Removing installer build directory...
|
||||
IF EXIST "%WD%\pkg\win32\Output" rd "%WD%\pkg\win32\Output" /S /Q > nul || EXIT /B 1
|
||||
|
||||
ECHO Removing installer configuration script...
|
||||
@@ -54,14 +52,14 @@ REM Main build sequence Ends
|
||||
:SET_ENVIRONMENT
|
||||
ECHO Configuring the environment...
|
||||
IF "%PGADMIN_PYTHON_DIR%" == "" SET "PGADMIN_PYTHON_DIR=C:\Python38"
|
||||
IF "%PGADMIN_QT_DIR%" == "" SET "PGADMIN_QT_DIR=C:\Qt\5.14.2\msvc2017_64"
|
||||
IF "%PGADMIN_KRB5_DIR%" == "" SET "PGADMIN_KRB5_DIR=C:\Program Files\MIT\Kerberos"
|
||||
IF "%PGADMIN_POSTGRES_DIR%" == "" SET "PGADMIN_POSTGRES_DIR=C:\Program Files (x86)\PostgreSQL\12"
|
||||
IF "%PGADMIN_INNOTOOL_DIR%" == "" SET "PGADMIN_INNOTOOL_DIR=C:\Program Files (x86)\Inno Setup 6"
|
||||
IF "%PGADMIN_VCREDIST_DIR%" == "" SET "PGADMIN_VCREDIST_DIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.16.27012"
|
||||
IF "%PGADMIN_SIGNTOOL_DIR%" == "" SET "PGADMIN_SIGNTOOL_DIR=C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64"
|
||||
|
||||
REM Set REDIST_NAME (the filename)
|
||||
set "VCREDIST_FILE=vcredist_%ARCHITECTURE%.exe"
|
||||
set "VCREDIST_FILE=vcredist_x64.exe"
|
||||
|
||||
REM Set additional variables we need
|
||||
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_MAJOR=%%a
|
||||
@@ -73,13 +71,13 @@ REM Main build sequence Ends
|
||||
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a
|
||||
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "print('%APP_NAME%'.lower().replace(' ', ''))"') DO SET APP_SHORTNAME=%%G
|
||||
SET APP_VERSION=%APP_MAJOR%.%APP_MINOR%
|
||||
SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%APP_VERSION_SUFFIX%-%ARCHITECTURE%.exe
|
||||
IF "%APP_VERSION_SUFFIX%" == "" SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%ARCHITECTURE%.exe
|
||||
SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%APP_VERSION_SUFFIX%-x64.exe
|
||||
IF "%APP_VERSION_SUFFIX%" == "" SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-x64.exe
|
||||
|
||||
REM get Python version for the runtime build ex. 2.7.1 will be 27
|
||||
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
|
||||
FOR /f "tokens=2 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MINOR=%%G
|
||||
SET "PYTHON_VERSION=%PYTHON_MAJOR%%PYTHON_MINOR%"
|
||||
FOR /f "tokens=3 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_REVISION=%%G
|
||||
|
||||
EXIT /B 0
|
||||
|
||||
@@ -93,10 +91,9 @@ REM Main build sequence Ends
|
||||
ECHO Installer name: %INSTALLERNAME%
|
||||
ECHO.
|
||||
ECHO Python directory: %PGADMIN_PYTHON_DIR%
|
||||
ECHO Python DLL: %PGADMIN_PYTHON_DIR%\Python%PYTHON_VERSION%.dll
|
||||
ECHO Python version: %PYTHON_MAJOR%.%PYTHON_MINOR%
|
||||
ECHO Python version: %PYTHON_MAJOR%.%PYTHON_MINOR%.%PYTHON_REVISION%
|
||||
ECHO.
|
||||
ECHO Qt directory: %PGADMIN_QT_DIR%
|
||||
ECHO KRB5 directory: %PGADMIN_KRB5_DIR%
|
||||
ECHO PostgreSQL directory: %PGADMIN_POSTGRES_DIR%
|
||||
ECHO.
|
||||
ECHO VC++ redist directory: %PGADMIN_VCREDIST_DIR%
|
||||
@@ -123,15 +120,9 @@ REM Main build sequence Ends
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
IF NOT EXIST "%PGADMIN_QT_DIR%" (
|
||||
ECHO !PGADMIN_QT_DIR! does not exist.
|
||||
ECHO Please install Qt and set the PGADMIN_QT_DIR environment variable.
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
IF NOT EXIST "%PGADMIN_QT_DIR%\bin\qmake.exe" (
|
||||
ECHO !QMAKE! does not exist.
|
||||
ECHO Please install Qt and set the PGADMIN_QT_DIR environment variable.
|
||||
IF NOT EXIST "%PGADMIN_KRB5_DIR%" (
|
||||
ECHO !PGADMIN_KRB5_DIR! does not exist.
|
||||
ECHO Please install MIT Kerberos for Windows and set the PGADMIN_KRB5_DIR environment variable.
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
@@ -141,12 +132,6 @@ REM Main build sequence Ends
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
IF NOT EXIST "%PGADMIN_PYTHON_DIR%\Python%PYTHON_VERSION%.dll" (
|
||||
ECHO !PGADMIN_PYTHON_DIR!\Python!PYTHON_VERSION!.dll does not exist.
|
||||
ECHO Please check your Python installation is complete.
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
IF NOT EXIST "%PGADMIN_POSTGRES_DIR%" (
|
||||
ECHO !PGADMIN_POSTGRES_DIR! does not exist.
|
||||
ECHO Please install PostgreSQL and set the PGADMIN_POSTGRES_DIR environment variable.
|
||||
@@ -166,47 +151,75 @@ REM Main build sequence Ends
|
||||
|
||||
:CREATE_VIRTUAL_ENV
|
||||
ECHO Creating virtual environment...
|
||||
IF NOT EXIST "%BUILDROOT%" MKDIR "%BUILDROOT%"
|
||||
|
||||
CD "%BUILDROOT%"
|
||||
IF NOT EXIST "%TMPDIR%" MKDIR "%TMPDIR%"
|
||||
|
||||
CD "%TMPDIR%"
|
||||
|
||||
REM Note that we must use virtualenv.exe here, as the venv module doesn't allow python.exe to relocate.
|
||||
"%PGADMIN_PYTHON_DIR%\Scripts\virtualenv.exe" venv
|
||||
|
||||
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\DLLs" "%BUILDROOT%\venv\DLLs" > nul || EXIT /B 1
|
||||
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\Lib" "%BUILDROOT%\venv\Lib" > nul || EXIT /B 1
|
||||
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\DLLs" "%TMPDIR%\venv\DLLs" > nul || EXIT /B 1
|
||||
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\Lib" "%TMPDIR%\venv\Lib" > nul || EXIT /B 1
|
||||
|
||||
ECHO Activating virtual environment - %BUILDROOT%\venv...
|
||||
CALL "%BUILDROOT%\venv\Scripts\activate" || EXIT /B 1
|
||||
ECHO Activating virtual environment - %TMPDIR%\venv...
|
||||
CALL "%TMPDIR%\venv\Scripts\activate" || EXIT /B 1
|
||||
|
||||
ECHO Installing dependencies...
|
||||
CALL pip install -r "%WD%\requirements.txt" || EXIT /B 1
|
||||
CALL pip install sphinx || EXIT /B 1
|
||||
|
||||
REM If this is Python 3.6+, we need to remove the hack above or it will break qmake. Sigh.
|
||||
IF %PYTHON_VERSION% GEQ 36 SET CL=
|
||||
CALL python -m pip install --upgrade pip || EXIT /B 1
|
||||
CALL pip install --only-binary=cryptography -r "%WD%\requirements.txt" || EXIT /B 1
|
||||
|
||||
CD %WD%
|
||||
EXIT /B 0
|
||||
|
||||
|
||||
:CREATE_PYTHON_ENV
|
||||
ECHO Staging Python...
|
||||
MKDIR "%BUILDROOT%\python\Lib" || EXIT /B 1
|
||||
|
||||
ECHO Downloading embedded Python...
|
||||
REM Get the python embeddable and extract it to %BUILDROOT%\python
|
||||
CD "%TMPDIR%
|
||||
%PGADMIN_PYTHON_DIR%\python -c "import sys; from urllib.request import urlretrieve; urlretrieve('https://www.python.org/ftp/python/' + sys.version.split(' ')[0] + '/python-' + sys.version.split(' ')[0] + '-embed-amd64.zip', 'python-embedded.zip')" || EXIT /B 1
|
||||
%PGADMIN_PYTHON_DIR%\python -c "import zipfile; z = zipfile.ZipFile('python-embedded.zip', 'r'); z.extractall('../win-build/python/')" || EXIT /B 1
|
||||
|
||||
ECHO Copying site-packages...
|
||||
XCOPY /S /I /E /H /Y "%TMPDIR%\venv\Lib\site-packages" "%BUILDROOT%\python\Lib\site-packages" > nul || EXIT /B 1
|
||||
|
||||
REM NOTE: There is intentionally no space after "site" in the line below, to prevent Python barfing if there's one in the file
|
||||
ECHO import site>> "%BUILDROOT%\python\python%PYTHON_MAJOR%%PYTHON_MINOR%._pth"
|
||||
|
||||
ECHO Staging Kerberos components...
|
||||
COPY "%PGADMIN_KRB5_DIR%\bin\kinit.exe" "%BUILDROOT%\python" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_KRB5_DIR%\bin\krb5_64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_KRB5_DIR%\bin\comerr64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_KRB5_DIR%\bin\k5sprt64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_KRB5_DIR%\bin\gssapi64.dll" "%BUILDROOT%\python" > nul || EXIT /B 1
|
||||
|
||||
ECHO Cleaning up unnecessary .pyc and .pyo files...
|
||||
FOR /R "%BUILDROOT%\python" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
|
||||
ECHO Removing tests...
|
||||
FOR /R "%BUILDROOT%\python\Lib" %%f in (test tests) do RD /Q /S "%%f" 1> nul 2>&1
|
||||
|
||||
EXIT /B 0
|
||||
|
||||
|
||||
:CREATE_RUNTIME_ENV
|
||||
IF NOT EXIST "%BUILDROOT%" MKDIR "%BUILDROOT%"
|
||||
MKDIR "%BUILDROOT%\runtime"
|
||||
|
||||
CD "%WD%\web"
|
||||
|
||||
ECHO Installing javascript dependencies...
|
||||
CALL yarn install || EXIT /B 1
|
||||
|
||||
ECHO Bundling javascript...
|
||||
CALL yarn run bundle || EXIT /B 1
|
||||
|
||||
ECHO Removing webpack caches...
|
||||
RD /Q /S "%WD%\web\pgadmin\static\js\generated\.cache" 1> nul 2>&1
|
||||
|
||||
ECHO Copying web directory...
|
||||
XCOPY /S /I /E /H /Y "%WD%\web" "%BUILDROOT%\web" > nul || EXIT /B 1
|
||||
|
||||
ECHO Installing javascript dependencies...
|
||||
CD "%BUILDROOT%\web"
|
||||
CALL yarn install || EXIT /B 1
|
||||
|
||||
ECHO Bundling javascript...
|
||||
CALL yarn run bundle || EXIT /B 1
|
||||
|
||||
ECHO Cleaning up unnecessary .pyc and .pyo files...
|
||||
FOR /R "%BUILDROOT%\web" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
|
||||
ECHO Removing tests, Python caches and node modules...
|
||||
@@ -232,51 +245,59 @@ REM Main build sequence Ends
|
||||
ECHO } >> "%BUILDROOT%\web\config_distro.py"
|
||||
|
||||
ECHO Building docs...
|
||||
CALL pip install sphinx || EXIT /B 1
|
||||
MKDIR "%BUILDROOT%\docs\en_US\html"
|
||||
CD "%WD%\docs\en_US"
|
||||
CALL "%BUILDROOT%\venv\Scripts\python.exe" build_code_snippet.py || EXIT /B 1
|
||||
CALL "%BUILDROOT%\venv\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%BUILDROOT%\docs\en_US\html" || EXIT /B 1
|
||||
CALL "%TMPDIR%\venv\Scripts\python.exe" build_code_snippet.py || EXIT /B 1
|
||||
CALL "%TMPDIR%\venv\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%BUILDROOT%\docs\en_US\html" || EXIT /B 1
|
||||
|
||||
ECHO Removing Sphinx
|
||||
CALL pip uninstall -y sphinx Pygments alabaster colorama docutils imagesize requests snowballstemmer
|
||||
REM Remove unnecessary doc files
|
||||
DEL /q "%BUILDROOT%\docs\en_US\html\_static\*.png" 1> nul 2>&1
|
||||
RD /Q /S "%BUILDROOT%\docs\en_US\html\_sources" 1> nul 2>&1
|
||||
|
||||
ECHO Assembling runtime environment...
|
||||
CD "%WD%\runtime"
|
||||
ECHO Staging runtime components...
|
||||
XCOPY /S /I /E /H /Y "%WD%\runtime\assets" "%BUILDROOT%\runtime\assets" > nul || EXIT /B 1
|
||||
XCOPY /S /I /E /H /Y "%WD%\runtime\src" "%BUILDROOT%\runtime\src" > nul || EXIT /B 1
|
||||
|
||||
ECHO Running qmake...
|
||||
CALL set "PGADMIN_PYTHON_DIR=%PGADMIN_PYTHON_DIR%" && "%PGADMIN_QT_DIR%\bin\qmake.exe" || EXIT /B 1
|
||||
COPY "%WD%\runtime\package.json" "%BUILDROOT%\runtime\" > nul || EXIT /B 1
|
||||
CD "%BUILDROOT%\runtime\"
|
||||
CALL yarn install --production=true || EXIT /B 1
|
||||
|
||||
ECHO Cleaning the build directory...
|
||||
CALL nmake clean || EXIT /B 1
|
||||
ECHO Downloading NWjs to %TMPDIR%...
|
||||
REM Get a fresh copy of nwjs.
|
||||
REM NOTE: The nw download servers seem to be very unreliable, so at the moment we're using wget which retries
|
||||
|
||||
ECHO Running make...
|
||||
CALL nmake || EXIT /B 1
|
||||
REM YARN
|
||||
REM CALL yarn --cwd "%TMPDIR%" add nw || EXIT /B
|
||||
REM YARN END
|
||||
|
||||
ECHO Staging pgAdmin4.exe...
|
||||
COPY "%WD%\runtime\release\pgAdmin4.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
REM WGET
|
||||
FOR /f "tokens=2 delims='" %%i IN ('yarn info nw ^| findstr "latest: "') DO SET "NW_VERSION=%%i"
|
||||
:GET_NW
|
||||
wget https://dl.nwjs.io/v%NW_VERSION%/nwjs-v%NW_VERSION%-win-x64.zip -O "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64.zip"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO GET_NW
|
||||
|
||||
ECHO Staging Qt components...
|
||||
COPY "%PGADMIN_QT_DIR%\bin\Qt5Core.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_QT_DIR%\bin\Qt5Gui.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_QT_DIR%\bin\Qt5Widgets.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_QT_DIR%\bin\Qt5Network.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_QT_DIR%\bin\Qt5Svg.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
MKDIR "%BUILDROOT%\runtime\platforms" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_QT_DIR%\plugins\platforms\qwindows.dll" "%BUILDROOT%\runtime\platforms" > nul || EXIT /B 1
|
||||
MKDIR "%BUILDROOT%\runtime\imageformats" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_QT_DIR%\plugins\imageformats\qsvg.dll" "%BUILDROOT%\runtime\imageformats" > nul || EXIT /B 1
|
||||
ECHO [Paths] > "%BUILDROOT%\runtime\qt.conf"
|
||||
ECHO Plugins=plugins >> "%BUILDROOT%\runtime\qt.conf"
|
||||
tar -C "%TMPDIR%" -xvf "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64.zip" || EXIT /B 1
|
||||
REM WGET END
|
||||
|
||||
REM YARN
|
||||
REM XCOPY /S /I /E /H /Y "%TMPDIR%\node_modules\nw\nwjs\*" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
REM YARN END
|
||||
|
||||
REM WGET
|
||||
XCOPY /S /I /E /H /Y "%TMPDIR%\nwjs-v%NW_VERSION%-win-x64\*" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
REM WGET END
|
||||
|
||||
MOVE "%BUILDROOT%\runtime\nw.exe" "%BUILDROOT%\runtime\pgAdmin4.exe"
|
||||
|
||||
ECHO Replacing executable icon...
|
||||
CALL yarn --cwd "%TMPDIR%" add winresourcer || EXIT /B
|
||||
"%TMPDIR%\node_modules\winresourcer\bin\Resourcer.exe" -op:upd -src:"%BUILDROOT%\runtime\pgAdmin4.exe" -type:Icongroup -name:IDR_MAINFRAME -file:"%WD%\pkg\win32\Resources\pgAdmin4.ico"
|
||||
|
||||
ECHO Staging PostgreSQL components...
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libpq.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
IF "%ARCHITECTURE%" == "x64" (
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libcrypto-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libssl-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
) ELSE (
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libcrypto-1_1.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libssl-1_1.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
)
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libcrypto-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\libssl-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
IF EXIST "%PGADMIN_POSTGRES_DIR%\bin\libintl-*.dll" COPY "%PGADMIN_POSTGRES_DIR%\bin\libintl-*.dll" "%BUILDROOT%\runtime" > nul
|
||||
IF EXIST "%PGADMIN_POSTGRES_DIR%\bin\libiconv-*.dll" COPY "%PGADMIN_POSTGRES_DIR%\bin\libiconv-*.dll" "%BUILDROOT%\runtime" > nul
|
||||
COPY "%PGADMIN_POSTGRES_DIR%\bin\zlib.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
@@ -291,22 +312,6 @@ REM Main build sequence Ends
|
||||
|
||||
CD %WD%
|
||||
EXIT /B 0
|
||||
|
||||
|
||||
:CREATE_PYTHON_ENV
|
||||
ECHO Staging Python...
|
||||
COPY %PGADMIN_PYTHON_DIR%\python%PYTHON_VERSION%.dll "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY %PGADMIN_PYTHON_DIR%\python.exe "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
COPY %PGADMIN_PYTHON_DIR%\pythonw.exe "%BUILDROOT%\runtime" > nul || EXIT /B 1
|
||||
|
||||
ECHO Cleaning up unnecessary .pyc and .pyo files...
|
||||
FOR /R "%BUILDROOT%\venv" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
|
||||
ECHO Removing tests...
|
||||
FOR /R "%BUILDROOT%\venv\Lib" %%f in (test tests) do RD /Q /S "%%f" 1> nul 2>&1
|
||||
ECHO Removing TCL...
|
||||
RD /Q /S "%BUILDROOT%\venv\tcl" 1> nul 2>&1
|
||||
|
||||
EXIT /B 0
|
||||
|
||||
|
||||
:CREATE_INSTALLER
|
||||
@@ -322,12 +327,7 @@ REM Main build sequence Ends
|
||||
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in" "-o" "%WD%\pkg\win32\installer.iss.in_stage1" "-s" MYAPP_NAME -r """%APP_NAME%"""
|
||||
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage1" "-o" "%WD%\pkg\win32\installer.iss.in_stage2" "-s" MYAPP_FULLVERSION -r """%APP_VERSION%"""
|
||||
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage2" "-o" "%WD%\pkg\win32\installer.iss.in_stage3" "-s" MYAPP_VERSION -r """v%APP_MAJOR%"""
|
||||
|
||||
SET ARCMODE=
|
||||
IF "%ARCHITECTURE%" == "x64" (
|
||||
set ARCMODE="x64"
|
||||
)
|
||||
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage3" "-o" "%WD%\pkg\win32\installer.iss.in_stage4" "-s" MYAPP_ARCHITECTURESMODE -r """%ARCMODE%"""
|
||||
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage3" "-o" "%WD%\pkg\win32\installer.iss.in_stage4" "-s" MYAPP_ARCHITECTURESMODE -r """x64"""
|
||||
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage4" "-o" "%WD%\pkg\win32\installer.iss" "-s" MYAPP_VCDIST -r """%PGADMIN_VCREDIST_DIRNAME%\%VCREDIST_FILE%"""
|
||||
|
||||
ECHO Cleaning up...
|
||||
@@ -348,7 +348,7 @@ REM Main build sequence Ends
|
||||
|
||||
:SIGN_INSTALLER
|
||||
ECHO Attempting to sign the installer...
|
||||
CALL "%PGADMIN_SIGNTOOL_DIR%\signtool.exe" sign /t http://timestamp.verisign.com/scripts/timstamp.dll "%DISTROOT%\%INSTALLERNAME%"
|
||||
CALL "%PGADMIN_SIGNTOOL_DIR%\signtool.exe" sign /t http://time.certum.pl "%DISTROOT%\%INSTALLERNAME%"
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
ECHO.
|
||||
ECHO ************************************************************
|
||||
@@ -360,14 +360,6 @@ REM Main build sequence Ends
|
||||
EXIT /B 0
|
||||
|
||||
|
||||
:CLEANUP_ENV
|
||||
ECHO Cleaning the build environment...
|
||||
RD "%BUILDROOT%\venv\Include" /S /Q 1> nul 2>&1
|
||||
DEL /s "%BUILDROOT%\venv\pip-selfcheck.json" 1> nul 2>&1
|
||||
|
||||
EXIT /B 0
|
||||
|
||||
|
||||
:USAGE
|
||||
ECHO Invalid command line options.
|
||||
ECHO Usage: "Make.bat [clean]"
|
||||
|
||||
@@ -20,7 +20,7 @@ APP_REVISION := $(shell grep ^APP_REVISION web/config.py | awk -F"=" '{print $$N
|
||||
# Include only platform-independent builds in all
|
||||
all: docs pip src runtime
|
||||
|
||||
appbundle: docs
|
||||
appbundle:
|
||||
./pkg/mac/build.sh
|
||||
|
||||
install-node:
|
||||
|
||||
@@ -1,321 +0,0 @@
|
||||
pgAdmin 4
|
||||
=========
|
||||
|
||||
pgAdmin 4 is a rewrite of the popular pgAdmin3 management tool for the
|
||||
PostgreSQL (http://www.postgresql.org) database.
|
||||
|
||||
In the following documentation and examples, "$PGADMIN4_SRC/" is used to denote
|
||||
the top-level directory of a copy of the pgAdmin source tree, either from a
|
||||
tarball or a git checkout.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
|
||||
pgAdmin 4 is written as a web application in Python, using jQuery and Bootstrap
|
||||
for the client side processing and UI. On the server side, Flask is being
|
||||
utilised.
|
||||
|
||||
Although developed using web technologies, pgAdmin 4 can be deployed either on
|
||||
a web server using a browser, or standalone on a workstation. The runtime/
|
||||
subdirectory contains a QT based runtime application intended to allow this -
|
||||
it is essentially a Python application server that runs in the system tray
|
||||
and allows the user to connect to the application using their web browser.
|
||||
|
||||
Building the Runtime
|
||||
--------------------
|
||||
|
||||
To build the runtime, the following packages must be installed:
|
||||
|
||||
- QT 5 (Use the VC++ build on Windows, not MinGW).
|
||||
- Python 3.4+
|
||||
|
||||
An environment variable named PGADMIN_PYTHON_DIR must be set to the directory
|
||||
in which Python has been installed, for example:
|
||||
|
||||
- /usr
|
||||
- /usr/local/python-3.8
|
||||
- C:\Python38
|
||||
|
||||
Assuming both qmake is in the path:
|
||||
|
||||
dpage@hal:~/git/pgadmin4$ cd runtime
|
||||
dpage@hal:~/git/pgadmin4/runtime$ export PGADMIN_PYTHON_DIR=/opt/local
|
||||
dpage@hal:~/git/pgadmin4/runtime$ qmake
|
||||
Project MESSAGE: ==================================
|
||||
Project MESSAGE: Configuring the pgAdmin 4 runtime.
|
||||
Project MESSAGE: ==================================
|
||||
Project MESSAGE: Qt version: 5
|
||||
Project MESSAGE: Platform: macOS
|
||||
Project MESSAGE: Python executable: /opt/local/bin/python3
|
||||
Project MESSAGE: Python version: 3.8 (38)
|
||||
Project MESSAGE: Python config: /opt/local/bin/python3-config
|
||||
Project MESSAGE: CXXFLAGS: -pipe -stdlib=libc++ -I/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8 -I/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8
|
||||
Project MESSAGE: LDFLAGS: -stdlib=libc++ -L/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/config-3.8-darwin -ldl -framework CoreFoundation
|
||||
Project MESSAGE: LIBS: -lpython3.8 -ldl -framework CoreFoundation
|
||||
dpage@hal:~/git/pgadmin4/runtime$ make
|
||||
...
|
||||
|
||||
To build the runtime in debug mode, use the option below with qmake:
|
||||
$ qmake CONFIG+=debug
|
||||
|
||||
To build the runtime in release mode, use the option below with qmake:
|
||||
$ qmake CONFIG+=release
|
||||
|
||||
By default, the runtime application will be built in release mode.
|
||||
|
||||
On Linux, an executable called 'pgAdmin4' will be built, on Windows,
|
||||
'pgAdmin4.exe', and on Mac OS X, an app bundle called pgAdmin4.app will be
|
||||
created.
|
||||
|
||||
You can also use Qt Creator to build, develop and debug the runtime. Simply
|
||||
open the $PGADMIN4_SRC/runtime/pgAdmin4.pro project file in Qt Creator and
|
||||
configure the project with a supported version of Qt when prompted.
|
||||
|
||||
Create Database Migrations
|
||||
--------------------------
|
||||
|
||||
In order to make changes to the SQLite DB, navigate to the 'web' directory:
|
||||
|
||||
(pgadmin4) $ cd $PGADMIN4_SRC/web
|
||||
|
||||
Create a migration file with the following command:
|
||||
|
||||
(pgadmin4) $ FLASK_APP=pgAdmin4.py flask db revision
|
||||
|
||||
This will create a file in: $PGADMIN4_SRC/web/migrations/versions/ .
|
||||
Add any changes to the 'upgrade' function.
|
||||
Increment the SCHEMA_VERSION in $PGADMIN4_SRC/web/pgadmin/model/__init__.py file.
|
||||
|
||||
There is no need to increment the SETTINGS_SCHEMA_VERSION.
|
||||
|
||||
Configuring the Python Environment
|
||||
----------------------------------
|
||||
|
||||
In order to run the Python code, a suitable runtime environment is required.
|
||||
Python version 3.4 and later are currently supported. It is recommended that a
|
||||
Python Virtual Environment is setup for this purpose, rather than using the
|
||||
system Python environment. On Linux and Mac systems, the process is fairly
|
||||
simple - adapt as required for your distribution:
|
||||
|
||||
1) Install the virtualenv packages into the system Python environment
|
||||
|
||||
$ sudo pip install virtualenv virtualenvwrapper
|
||||
|
||||
2) Source the virtualenv wrapper tools script. You may want to add this command
|
||||
to your ~/.bash_profile file for future convenience:
|
||||
|
||||
$ source /usr/local/bin/virtualenvwrapper.sh
|
||||
|
||||
3) Create a virtual environment:
|
||||
|
||||
$ mkvirtualenv pgadmin4
|
||||
|
||||
To make use of the virtual environment in the future, use the following
|
||||
command to re-activate it:
|
||||
|
||||
$ workon pgadmin4
|
||||
|
||||
4) Ensure that a PostgreSQL installation's bin/ directory is in the path (so
|
||||
pg_config can be found for building psycopg2), and install the required
|
||||
packages:
|
||||
|
||||
(pgadmin4) $ PATH=$PATH:/usr/local/pgsql/bin pip install -r $PGADMIN4_SRC/requirements.txt
|
||||
|
||||
If you are planning to run the regression tests, you also need to install
|
||||
additional requirements from web/regression/requirements.txt:
|
||||
|
||||
(pgadmin4) $ pip install -r $PGADMIN4_SRC/web/regression/requirements.txt
|
||||
|
||||
5) Create a local configuration file for pgAdmin. Edit
|
||||
$PGADMIN4_SRC/web/config_local.py and add any desired configuration options
|
||||
(use the config.py file as a reference - any settings duplicated in
|
||||
config_local.py will override those in config.py). A typical development
|
||||
configuration may look like:
|
||||
|
||||
from config import *
|
||||
|
||||
# Debug mode
|
||||
DEBUG = True
|
||||
|
||||
# App mode
|
||||
SERVER_MODE = True
|
||||
|
||||
# Enable the test module
|
||||
MODULE_BLACKLIST.remove('test')
|
||||
|
||||
# Log
|
||||
CONSOLE_LOG_LEVEL = DEBUG
|
||||
FILE_LOG_LEVEL = DEBUG
|
||||
|
||||
DEFAULT_SERVER = '127.0.0.1'
|
||||
|
||||
UPGRADE_CHECK_ENABLED = True
|
||||
|
||||
# Use a different config DB for each server mode.
|
||||
if SERVER_MODE == False:
|
||||
SQLITE_PATH = os.path.join(
|
||||
DATA_DIR,
|
||||
'pgadmin4-desktop.db'
|
||||
)
|
||||
else:
|
||||
SQLITE_PATH = os.path.join(
|
||||
DATA_DIR,
|
||||
'pgadmin4-server.db'
|
||||
)
|
||||
|
||||
This configuration allows easy switching between server and desktop modes
|
||||
for testing.
|
||||
|
||||
6) The initial setup of the configuration database is interactive in server
|
||||
mode, and non-interactive in desktop mode. You can run it either by
|
||||
running:
|
||||
|
||||
(pgadmin4) $ python $PGADMIN4_SRC/web/setup.py
|
||||
|
||||
or by starting pgAdmin 4:
|
||||
|
||||
(pgadmin4) $ python $PGADMIN4_SRC/web/pgAdmin4.py
|
||||
|
||||
Whilst it is possible to automatically run setup in desktop mode by running
|
||||
the runtime, that will not work in server mode as the runtime doesn't allow
|
||||
command line interaction with the setup program.
|
||||
|
||||
At this point you will be able to run pgAdmin 4 from the command line in either
|
||||
server or desktop mode, and access it from a web browser using the URL shown in
|
||||
the terminal once pgAdmin has started up.
|
||||
|
||||
Setup of an environment on Windows is somewhat more complicated unfortunately,
|
||||
please see pkg/win32/README.txt for complete details.
|
||||
|
||||
Once a virtual environment has been created and enabled, setup can continue
|
||||
from step 4 above.
|
||||
|
||||
Building the Web Assets
|
||||
-----------------------
|
||||
|
||||
pgAdmin is dependent on a number of third party Javascript libraries. These,
|
||||
along with it's own Javascript code, SCSS/CSS code and images must be
|
||||
compiled into a "bundle" which is transferred to the browser for execution
|
||||
and rendering. This is far more efficient than simply requesting each
|
||||
asset as it's needed by the client.
|
||||
|
||||
To create the bundle, you will need the 'yarn' package management tool to be
|
||||
installed. Then, you can run the following commands on a *nix system to
|
||||
download the required packages and build the bundle:
|
||||
|
||||
(pgadmin4) $ cd $PGADMIN4_SRC
|
||||
(pgadmin4) $ make install-node
|
||||
(pgadmin4) $ make bundle
|
||||
|
||||
On Windows systems (where "make" is not available, the following commands
|
||||
can be used:
|
||||
|
||||
C:\> cd $PGADMIN4_SRC\web
|
||||
C:\$PGADMIN4_SRC\web> yarn install
|
||||
C:\$PGADMIN4_SRC\web> yarn run bundle
|
||||
|
||||
Creating pgAdmin themes
|
||||
-----------------------
|
||||
|
||||
To create a pgAdmin theme, you need to create a directory under
|
||||
web/pgadmin/static/scss/resources.
|
||||
Copy the sample file _theme.variables.scss.sample to the new directory and
|
||||
rename it to _theme.variables.scss. Change the desired hexadecimal values of
|
||||
the colors and bundle pgAdmin. You can also add a preview image in the theme
|
||||
directory with the name as <dir name>_preview.png. It is recommended that the
|
||||
preview image should not be larger in size as it may take time to load on slow
|
||||
networks. Run the yarn run bundle and you're good to go. No other changes are
|
||||
required, pgAdmin bundle will read the directory and create other required
|
||||
entries to make them available in preferences.
|
||||
|
||||
The name of the theme is derived from the directory name. Underscores (_) and
|
||||
hyphens (-) will be replaced with spaces and the result will be camel cased.
|
||||
|
||||
Configuring the Runtime
|
||||
-----------------------
|
||||
|
||||
The pgAdmin 4 Runtime maintains it's own Python Path to avoid conflicts with
|
||||
packages or other issues in the system Python installation. It will also search
|
||||
a number of known locations for the pgAdmin4.py file needed to run pgAdmin
|
||||
(including relative locations in a source code tree), however you can specify
|
||||
an alternate path if needed.
|
||||
|
||||
If either a working environment or pgAdmin4.py cannot be found at startup, the
|
||||
runtime will prompt for the locations. Alternatively, you can click the try
|
||||
icon and select the Configuration option to open the configuration dialogue.
|
||||
|
||||
On a Linux/Mac system, the Python Path will typically consist of a single path
|
||||
to the virtual environment's site-packages directory, e.g.
|
||||
|
||||
/Users/<USERNAME>/.virtualenvs/pgadmin4/lib/python3.8/site-packages
|
||||
|
||||
On Windows, multiple paths are likely to be required, e.g.
|
||||
|
||||
C:\Users\dpage\.virtualenvs\pgadmin4\Lib\site-packages;C:\Users\dpage\.virtualenvs\pgadmin4\Lib;C:\Users\dpage\.virtualenvs\pgadmin4\Lib\lib-tk;C:\Users\dpage\.virtualenvs\pgadmin4\DLLs
|
||||
|
||||
If you wish to specify a specific copy of the Python code to run, you can set
|
||||
the Application Path to a directory containing pgAdmin4.py, e.g.
|
||||
|
||||
/Users/<USERNAME>/git/pgadmin4-test/web/
|
||||
|
||||
Building the documentation
|
||||
--------------------------
|
||||
|
||||
In order to build the docs, an additional Python package is required in the
|
||||
virtual environment. This can be installed with the pip package manager:
|
||||
|
||||
$ workon pgadmin4
|
||||
(pgadmin4) $ pip install Sphinx
|
||||
|
||||
The docs can then be built using the Makefile in $PGADMIN4_SRC, e.g.
|
||||
|
||||
(pgadmin4) $ make docs
|
||||
|
||||
The output can be found in $PGADMIN4_SRC/docs/en_US/_build/html/index.html
|
||||
|
||||
Building packages
|
||||
-----------------
|
||||
|
||||
Most packages can be built using the Makefile in $PGADMIN4_SRC, provided all
|
||||
the setup and configuration above has been completed.
|
||||
|
||||
To build a source tarball:
|
||||
|
||||
(pgadmin4) $ make src
|
||||
|
||||
To build a PIP Wheel, activate either a Python 2 or Python 3 virtual
|
||||
environment as desired, configured with all the required packages, and then
|
||||
run:
|
||||
|
||||
(pgadmin4) $ make pip
|
||||
|
||||
To build the macOS AppBundle, please see pkg/mac/README.
|
||||
|
||||
To build the Windows installer, please see pkg/win32/README.txt.
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
See https://www.pgadmin.org/support/ for support options.
|
||||
|
||||
Project info
|
||||
------------
|
||||
|
||||
The source code repository can be found here:
|
||||
|
||||
http://git.postgresql.org/gitweb/?p=pgadmin4.git;a=summary
|
||||
|
||||
A Redmine project for pgAdmin 4 can be found at the address below. A PostgreSQL
|
||||
community account is required to access this site. Please note that at present
|
||||
only project developers can log bug and feature requests:
|
||||
|
||||
https://redmine.postgresql.org/projects/pgadmin4
|
||||
|
||||
If you wish to discuss pgAdmin 4, or contribute to the project, please use the
|
||||
pgAdmin Hackers mailing list:
|
||||
|
||||
pgadmin-hackers@postgresql.org
|
||||
|
||||
--
|
||||
Dave Page
|
||||
pgAdmin Project Lead
|
||||
@@ -0,0 +1,251 @@
|
||||
# pgAdmin 4
|
||||
|
||||
pgAdmin 4 is a rewrite of the popular pgAdmin3 management tool for the
|
||||
PostgreSQL (http://www.postgresql.org) database.
|
||||
|
||||
In the following documentation and examples, *$PGADMIN4_SRC/* is used to denote
|
||||
the top-level directory of a copy of the pgAdmin source tree, either from a
|
||||
tarball or a git checkout.
|
||||
|
||||
## Architecture
|
||||
|
||||
pgAdmin 4 is written as a web application in Python, using jQuery and Bootstrap
|
||||
for the client side processing and UI. On the server side, Flask is being
|
||||
utilised.
|
||||
|
||||
Although developed using web technologies, pgAdmin 4 can be deployed either on
|
||||
a web server using a browser, or standalone on a workstation. The runtime/
|
||||
subdirectory contains an NWjs based runtime application intended to allow this,
|
||||
which will execute the Python server and display the UI.
|
||||
|
||||
## Building the Runtime
|
||||
|
||||
To build the runtime, the following packages must be installed:
|
||||
|
||||
* NodeJS 12+
|
||||
* Yarn
|
||||
|
||||
Change into the runtime directory, and run *yarn install*. This will install the
|
||||
dependencies required.
|
||||
|
||||
In order to use the runtime in a development environment, you'll need to copy
|
||||
*dev_config.json.in* file to *dev_config.json*, and edit the paths to the Python
|
||||
executable and *pgAdmin.py* file, otherwise the runtime will use the default
|
||||
paths it would expect to find in the standard package for your platform.
|
||||
|
||||
You can then execute the runtime by running something like:
|
||||
|
||||
node_modules/nw/nwjs/nw .
|
||||
|
||||
or on macOS:
|
||||
|
||||
node_modules/nw/nwjs/nwjs.app/Contents/MacOS/nwjs .
|
||||
|
||||
# Create Database Migrations
|
||||
|
||||
In order to make changes to the SQLite DB, navigate to the 'web' directory:
|
||||
|
||||
(pgadmin4) $ cd $PGADMIN4_SRC/web
|
||||
|
||||
Create a migration file with the following command:
|
||||
|
||||
(pgadmin4) $ FLASK_APP=pgAdmin4.py flask db revision
|
||||
|
||||
This will create a file in: $PGADMIN4_SRC/web/migrations/versions/ .
|
||||
Add any changes to the 'upgrade' function.
|
||||
Increment the SCHEMA_VERSION in $PGADMIN4_SRC/web/pgadmin/model/__init__.py file.
|
||||
|
||||
There is no need to increment the SETTINGS_SCHEMA_VERSION.
|
||||
|
||||
# Configuring the Python Environment
|
||||
|
||||
In order to run the Python code, a suitable runtime environment is required.
|
||||
Python version 3.5 and later are currently supported. It is recommended that a
|
||||
Python Virtual Environment is setup for this purpose, rather than using the
|
||||
system Python environment. On Linux and Mac systems, the process is fairly
|
||||
simple - adapt as required for your distribution:
|
||||
|
||||
1. Install the virtualenv packages into the system Python environment
|
||||
|
||||
$ sudo pip install virtualenv virtualenvwrapper
|
||||
|
||||
2. Source the virtualenv wrapper tools script. You may want to add this command
|
||||
to your ~/.bash_profile file for future convenience:
|
||||
|
||||
$ source /usr/local/bin/virtualenvwrapper.sh
|
||||
|
||||
3. Create a virtual environment:
|
||||
|
||||
$ mkvirtualenv pgadmin4
|
||||
|
||||
To make use of the virtual environment in the future, use the following
|
||||
command to re-activate it:
|
||||
|
||||
$ workon pgadmin4
|
||||
|
||||
4. Ensure that a PostgreSQL installation's bin/ directory is in the path (so
|
||||
pg_config can be found for building psycopg2), and install the required
|
||||
packages:
|
||||
|
||||
(pgadmin4) $ PATH=$PATH:/usr/local/pgsql/bin pip install -r $PGADMIN4_SRC/requirements.txt
|
||||
|
||||
If you are planning to run the regression tests, you also need to install
|
||||
additional requirements from web/regression/requirements.txt:
|
||||
|
||||
(pgadmin4) $ pip install -r $PGADMIN4_SRC/web/regression/requirements.txt
|
||||
|
||||
5. Create a local configuration file for pgAdmin. Edit
|
||||
$PGADMIN4_SRC/web/config_local.py and add any desired configuration options
|
||||
(use the config.py file as a reference - any settings duplicated in
|
||||
config_local.py will override those in config.py). A typical development
|
||||
configuration may look like:
|
||||
```python
|
||||
from config import *
|
||||
|
||||
# Debug mode
|
||||
DEBUG = True
|
||||
|
||||
# App mode
|
||||
SERVER_MODE = True
|
||||
|
||||
# Enable the test module
|
||||
MODULE_BLACKLIST.remove('test')
|
||||
|
||||
# Log
|
||||
CONSOLE_LOG_LEVEL = DEBUG
|
||||
FILE_LOG_LEVEL = DEBUG
|
||||
|
||||
DEFAULT_SERVER = '127.0.0.1'
|
||||
|
||||
UPGRADE_CHECK_ENABLED = True
|
||||
|
||||
# Use a different config DB for each server mode.
|
||||
if SERVER_MODE == False:
|
||||
SQLITE_PATH = os.path.join(
|
||||
DATA_DIR,
|
||||
'pgadmin4-desktop.db'
|
||||
)
|
||||
else:
|
||||
SQLITE_PATH = os.path.join(
|
||||
DATA_DIR,
|
||||
'pgadmin4-server.db'
|
||||
)
|
||||
```
|
||||
This configuration allows easy switching between server and desktop modes
|
||||
for testing.
|
||||
|
||||
6. The initial setup of the configuration database is interactive in server
|
||||
mode, and non-interactive in desktop mode. You can run it either by
|
||||
running:
|
||||
|
||||
(pgadmin4) $ python $PGADMIN4_SRC/web/setup.py
|
||||
|
||||
or by starting pgAdmin 4:
|
||||
|
||||
(pgadmin4) $ python $PGADMIN4_SRC/web/pgAdmin4.py
|
||||
|
||||
Whilst it is possible to automatically run setup in desktop mode by running
|
||||
the runtime, that will not work in server mode as the runtime doesn't allow
|
||||
command line interaction with the setup program.
|
||||
|
||||
At this point you will be able to run pgAdmin 4 from the command line in either
|
||||
server or desktop mode, and access it from a web browser using the URL shown in
|
||||
the terminal once pgAdmin has started up.
|
||||
|
||||
Setup of an environment on Windows is somewhat more complicated unfortunately,
|
||||
please see *pkg/win32/README.txt* for complete details.
|
||||
|
||||
Once a virtual environment has been created and enabled, setup can continue
|
||||
from step 4 above.
|
||||
|
||||
## Building the Web Assets
|
||||
|
||||
pgAdmin is dependent on a number of third party Javascript libraries. These,
|
||||
along with it's own Javascript code, SCSS/CSS code and images must be
|
||||
compiled into a "bundle" which is transferred to the browser for execution
|
||||
and rendering. This is far more efficient than simply requesting each
|
||||
asset as it's needed by the client.
|
||||
|
||||
To create the bundle, you will need the 'yarn' package management tool to be
|
||||
installed. Then, you can run the following commands on a *nix system to
|
||||
download the required packages and build the bundle:
|
||||
|
||||
(pgadmin4) $ cd $PGADMIN4_SRC
|
||||
(pgadmin4) $ make install-node
|
||||
(pgadmin4) $ make bundle
|
||||
|
||||
On Windows systems (where "make" is not available), the following commands
|
||||
can be used:
|
||||
|
||||
C:\> cd $PGADMIN4_SRC\web
|
||||
C:\$PGADMIN4_SRC\web> yarn install
|
||||
C:\$PGADMIN4_SRC\web> yarn run bundle
|
||||
|
||||
## Creating pgAdmin themes
|
||||
|
||||
To create a pgAdmin theme, you need to create a directory under
|
||||
*web/pgadmin/static/scss/resources*.
|
||||
Copy the sample file *_theme.variables.scss.sample* to the new directory and
|
||||
rename it to *_theme.variables.scss*. Change the desired hexadecimal values of
|
||||
the colors and bundle pgAdmin. You can also add a preview image in the theme
|
||||
directory with the name as *\<dir name>_preview.png*. It is recommended that the
|
||||
preview image should not be larger in size as it may take time to load on slow
|
||||
networks. Run the *yarn run bundle* and you're good to go. No other changes are
|
||||
required, pgAdmin bundle will read the directory and create other required
|
||||
entries to make them available in preferences.
|
||||
|
||||
The name of the theme is derived from the directory name. Underscores (_) and
|
||||
hyphens (-) will be replaced with spaces and the result will be camel cased.
|
||||
|
||||
# Building the documentation
|
||||
|
||||
In order to build the docs, an additional Python package is required in the
|
||||
virtual environment. This can be installed with the pip package manager:
|
||||
|
||||
$ workon pgadmin4
|
||||
(pgadmin4) $ pip install Sphinx
|
||||
|
||||
The docs can then be built using the Makefile in *$PGADMIN4_SRC*, e.g.
|
||||
|
||||
(pgadmin4) $ make docs
|
||||
|
||||
The output can be found in *$PGADMIN4_SRC/docs/en_US/_build/html/index.html*
|
||||
|
||||
# Building packages
|
||||
|
||||
Most packages can be built using the Makefile in $PGADMIN4_SRC, provided all
|
||||
the setup and configuration above has been completed.
|
||||
|
||||
To build a source tarball:
|
||||
|
||||
(pgadmin4) $ make src
|
||||
|
||||
To build a PIP Wheel, activate either a Python 3 virtual environment, configured
|
||||
with all the required packages, and then run:
|
||||
|
||||
(pgadmin4) $ make pip
|
||||
|
||||
To build the macOS AppBundle, please see *pkg/mac/README*.
|
||||
|
||||
To build the Windows installer, please see *pkg/win32/README.txt*.
|
||||
|
||||
## Support
|
||||
|
||||
See https://www.pgadmin.org/support/ for support options.
|
||||
|
||||
## Project info
|
||||
|
||||
The source code repository can be found here:
|
||||
|
||||
http://git.postgresql.org/gitweb/?p=pgadmin4.git;a=summary
|
||||
|
||||
A Redmine project for pgAdmin 4 can be found at the address below. A PostgreSQL
|
||||
community account is required to access this site. Please note that at present
|
||||
only project developers can log bug and feature requests:
|
||||
|
||||
https://redmine.postgresql.org/projects/pgadmin4
|
||||
|
||||
If you wish to discuss pgAdmin 4, or contribute to the project, please use the
|
||||
pgAdmin Hackers mailing list:
|
||||
|
||||
pgadmin-hackers@postgresql.org
|
||||
@@ -7,14 +7,14 @@
|
||||
The bulk of pgAdmin is a Python web application written using the Flask framework
|
||||
on the backend, and HTML5 with CSS3, Bootstrap and jQuery on the front end. A
|
||||
desktop runtime is also included for users that prefer a desktop application to
|
||||
a web application, which is written in C++ using the QT framework.
|
||||
a web application, which is written using NWjs (Node Webkit).
|
||||
|
||||
Runtime
|
||||
*******
|
||||
|
||||
The runtime is essentially a Python webserver and browser in a box. Found in the
|
||||
**/runtime** directory in the source tree, it is a relatively simple QT
|
||||
application that is most easily modified using the **QT Creator** application.
|
||||
The runtime is based on NWjs which integrates a browser and the Python server
|
||||
creating a standalone application. The source code can be found in the
|
||||
**/runtime** directory in the source tree.
|
||||
|
||||
Web Application
|
||||
***************
|
||||
@@ -213,4 +213,4 @@ divided each module in small chunks as much as possible. Not all javascript
|
||||
modules are required to be loaded (i.e. loading a javascript module for
|
||||
database will make sense only when a server node is loaded completely.) Please
|
||||
look at the the javascript files node.js, browser.js, menu.js, panel.js, etc for
|
||||
better understanding of the code.
|
||||
better understanding of the code.
|
||||
@@ -16,46 +16,46 @@ review process for any patches submitted for inclusion in pgAdmin.
|
||||
bulk updates every year). The start date should always be 2013, and the end year
|
||||
the current year, e.g.
|
||||
|
||||
Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
|
||||
Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
|
||||
* Ensure there's a blank line immediately following any copyright headers.
|
||||
|
||||
* Include PyDoc comments for functions, classes and modules. Node modules should
|
||||
* Include PyDoc comments for functions, classes and modules. Node modules should
|
||||
be """Implements the XXXX node""".
|
||||
|
||||
* Ensure that any generated SQL does not have any leading or trailing blank lines
|
||||
and consistently uses 4 space indents for nice formatting.
|
||||
|
||||
* Don't special-case any Slony objects. pgAdmin 4 will have no direct knowledge
|
||||
* Don't special-case any Slony objects. pgAdmin 4 will have no direct knowledge
|
||||
of Slony, unlike pgAdmin 3.
|
||||
|
||||
* If you copy/paste modules, please ensure any comments are properly updated.
|
||||
* If you copy/paste modules, please ensure any comments are properly updated.
|
||||
|
||||
* Read all comments, and ensure they make sense and provide useful commentary on
|
||||
the code.
|
||||
|
||||
* Ensure that field labels both use PostgreSQL parlance, but also are descriptive.
|
||||
A good example is the "Init" field on an FTS Template - Init is the PG term, but
|
||||
* Ensure that field labels both use PostgreSQL parlance, but also are descriptive.
|
||||
A good example is the "Init" field on an FTS Template - Init is the PG term, but
|
||||
adding the word "Function" after it makes it much more descriptive.
|
||||
|
||||
* Re-use code whereever possible, but factor it out into a suitably central
|
||||
location - don't copy and paste it unless modifications are required!
|
||||
|
||||
* Format code nicely to make it readable. Break up logical chunks of code with
|
||||
blank lines, and comment well to describe what different sections of code are
|
||||
* Format code nicely to make it readable. Break up logical chunks of code with
|
||||
blank lines, and comment well to describe what different sections of code are
|
||||
for or pertain to.
|
||||
|
||||
* Ensure that form validation works correctly and is consistent with other
|
||||
* Ensure that form validation works correctly and is consistent with other
|
||||
dialogues in the way errors are displayed.
|
||||
|
||||
* On dialogues with Schema or Owner fields, pre-set the default values to the
|
||||
current schema/user as appropriate. In general, if there are common or sensible
|
||||
default values available, put them in the fields for the user.
|
||||
* On dialogues with Schema or Owner fields, pre-set the default values to the
|
||||
current schema/user as appropriate. In general, if there are common or sensible
|
||||
default values available, put them in the fields for the user.
|
||||
|
||||
* 1 patch == 1 feature. If you need to fix/update existing infrastructure in
|
||||
* 1 patch == 1 feature. If you need to fix/update existing infrastructure in
|
||||
your patch, it's usually easier if it's in a separate patch. Patches containing
|
||||
multiple new features or unrelated changes are likely to be rejected.
|
||||
|
||||
* Ensure the patch is fully functional, and works! If a patch is being sent as
|
||||
a work in progress, not intended for commit, clearly state that it's a WIP,
|
||||
and note what does or does not yet work.
|
||||
* Ensure the patch is fully functional, and works! If a patch is being sent as
|
||||
a work in progress, not intended for commit, clearly state that it's a WIP,
|
||||
and note what does or does not yet work.
|
||||
@@ -4,7 +4,7 @@
|
||||
`Coding Standards`:index:
|
||||
*************************
|
||||
|
||||
pgAdmin uses multiple technologies and multiple languages, each of which have
|
||||
pgAdmin uses multiple technologies and multiple languages, each of which have
|
||||
their own coding standards.
|
||||
|
||||
General
|
||||
@@ -16,24 +16,24 @@ lines wrapped where appropriate to ensure they can be read on smaller displays
|
||||
as it's quite wasteful on modern displays). Typically lines should not be longer
|
||||
than 120 characters.
|
||||
|
||||
Comments should be included in all code where required to explain its
|
||||
Comments should be included in all code where required to explain its
|
||||
purpose or how it works if not obvious from a quick review of the code itself.
|
||||
|
||||
CSS 3
|
||||
*****
|
||||
|
||||
CSS3 is used for styling and layout throughout the application. Extensive use is
|
||||
made of the Bootstrap Framework to aid in that process, however additional
|
||||
made of the Bootstrap Framework to aid in that process, however additional
|
||||
styles must still be created from time to time.
|
||||
|
||||
Most custom styling comes from individual modules which may advertise static
|
||||
stylesheets to be included in the module that is loading them via hooks.
|
||||
|
||||
Styling overrides (for example, to alter the Bootstrap look and feel) will
|
||||
Styling overrides (for example, to alter the Bootstrap look and feel) will
|
||||
typically be found in the **overrides.css** file in the main static file
|
||||
directory for the application.
|
||||
|
||||
Styling should never be applied inline in HTML, always through an external
|
||||
Styling should never be applied inline in HTML, always through an external
|
||||
stylesheet, which should contain comments as appropriate to explain the usage
|
||||
or purpose for the style.
|
||||
|
||||
@@ -48,16 +48,16 @@ Styles should be specified clearly, one per line. For example:
|
||||
|
||||
/* Ensure the codemirror editor displays full height gutters when resized */
|
||||
.CodeMirror, .CodeMirror-gutters {
|
||||
height: 100% !important;
|
||||
}
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
All stylesheets must be CSS3 compliant.
|
||||
|
||||
HTML 5
|
||||
******
|
||||
|
||||
HTML 5 is used for page structure throughout the application, in most cases
|
||||
being rendered from templates by the Jinja2 template engine in Flask.
|
||||
HTML 5 is used for page structure throughout the application, in most cases
|
||||
being rendered from templates by the Jinja2 template engine in Flask.
|
||||
|
||||
All HTML must be HTML 5 compliant.
|
||||
|
||||
@@ -109,68 +109,20 @@ names.
|
||||
.. note:: From version 3.0 onwards, new or refactored code should be written using
|
||||
ES6 features and conventions.
|
||||
|
||||
C++
|
||||
***
|
||||
|
||||
C++ code is used in the desktop runtime for the application, primarily with the
|
||||
QT framework and an embedded Python interpreter. Note the use of hanging braces,
|
||||
which may be omitted if on a single statement is present:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Ping the application server to see if it's alive
|
||||
bool PingServer(QUrl url)
|
||||
{
|
||||
QNetworkAccessManager manager;
|
||||
QEventLoop loop;
|
||||
QNetworkReply *reply;
|
||||
QVariant redirectUrl;
|
||||
|
||||
url.setPath("/utils/ping");
|
||||
|
||||
do
|
||||
{
|
||||
reply = manager.get(QNetworkRequest(url));
|
||||
|
||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
|
||||
redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
url = redirectUrl.toUrl();
|
||||
|
||||
if (!redirectUrl.isNull())
|
||||
delete reply;
|
||||
|
||||
} while (!redirectUrl.isNull());
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
return false;
|
||||
|
||||
QString response = reply->readAll();
|
||||
|
||||
if (response != "PING")
|
||||
{
|
||||
qDebug() << "Failed to connect, server response: " << response;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Python
|
||||
******
|
||||
|
||||
Python is used for the backend web server. All code must be compatible with
|
||||
Python is used for the backend web server. All code must be compatible with
|
||||
Python 2.7 and should include PyDoc comments whilst following the official
|
||||
Python coding standards defined in
|
||||
`PEP 8 <https://www.python.org/dev/peps/pep-0008/>`_. An example function along
|
||||
Python coding standards defined in
|
||||
`PEP 8 <https://www.python.org/dev/peps/pep-0008/>`_. An example function along
|
||||
with the required file header is shown below::
|
||||
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
@@ -185,12 +137,12 @@ with the required file header is shown below::
|
||||
def get_nodes():
|
||||
"""Return a JSON document listing the server groups for the user"""
|
||||
groups = ServerGroup.query.filter_by(user_id=current_user.id)
|
||||
|
||||
|
||||
value = ''
|
||||
for group in groups:
|
||||
value += '{"id":%d,"label":"%s","icon":"icon-server-group","inode":true},' \
|
||||
% (group.id, group.name)
|
||||
|
||||
|
||||
value = value[:-1]
|
||||
|
||||
return value
|
||||
|
||||
return value
|
||||
@@ -17,11 +17,11 @@ maintenance functions to be executed. Multiple versions are included in the
|
||||
following directories to allow use with different versions of the database
|
||||
server:
|
||||
|
||||
* PostgreSQL 9.5: */usr/local/pgsql-9.5*
|
||||
* PostgreSQL 9.6: */usr/local/pgsql-9.6*
|
||||
* PostgreSQL 10: */usr/local/pgsql-10*
|
||||
* PostgreSQL 11: */usr/local/pgsql-11*
|
||||
* PostgreSQL 12: */usr/local/pgsql-12*
|
||||
* PostgreSQL 13: */usr/local/pgsql-13*
|
||||
|
||||
The most recent version of the utilities is used by default; this may be
|
||||
changed in the :ref:`preferences`.
|
||||
@@ -41,6 +41,20 @@ to login to pgAdmin. This variable is required and must be set at launch time.
|
||||
This is the password used when setting up the initial administrator account to
|
||||
login to pgAdmin. This variable is required and must be set at launch time.
|
||||
|
||||
**PGADMIN_DISABLE_POSTFIX**
|
||||
|
||||
*Default: <null>*
|
||||
|
||||
If left unset, a Postfix server will be started to deliver password reset
|
||||
emails.
|
||||
|
||||
If set to any value, the Postfix server will not be started, and pgAdmin will
|
||||
need to be configured to use an external mail server using the *PGADMIN_CONFIG_*
|
||||
options below.
|
||||
|
||||
This option is useful if you're running in an environment that prevents the use
|
||||
of sudo to start Postfix, or if you wish to use an external mail server.
|
||||
|
||||
**PGADMIN_ENABLE_TLS**
|
||||
|
||||
*Default: <null>*
|
||||
|
||||
@@ -8,13 +8,8 @@ pgAdmin may be deployed as a desktop application by configuring the application
|
||||
to run in desktop mode and then utilising the desktop runtime to host the
|
||||
program on a supported Windows, Mac OS X or Linux installation.
|
||||
|
||||
The desktop runtime is a system-tray application that when launched, runs the
|
||||
pgAdmin server and launches a web browser to render the user interface. If
|
||||
additional instances of pgAdmin are launched, a new browser tab will be opened
|
||||
and be served by the existing instance of the server in order to minimise system
|
||||
resource utilisation. Clicking the icon in the system tray will present a menu
|
||||
offering options to open a new pgAdmin window, configure the runtime, view the
|
||||
server log and shut down the server.
|
||||
The desktop runtime is a standalone application that when launched, runs the
|
||||
pgAdmin server and opens a window to render the user interface.
|
||||
|
||||
.. note:: Pre-compiled and configured installation packages are available for
|
||||
a number of platforms. These packages should be used by end-users whereever
|
||||
@@ -24,7 +19,7 @@ server log and shut down the server.
|
||||
.. seealso:: For detailed instructions on building and configuring pgAdmin from
|
||||
scratch, please see the README file in the top level directory of the source code.
|
||||
For convenience, you can find the latest version of the file
|
||||
`here <https://git.postgresql.org/gitweb/?p=pgadmin4.git;a=blob_plain;f=README>`_,
|
||||
`here <https://git.postgresql.org/gitweb/?p=pgadmin4.git;a=blob;f=README.md>`_,
|
||||
but be aware that this may differ from the version included with the source code
|
||||
for a specific version of pgAdmin.
|
||||
|
||||
@@ -38,25 +33,36 @@ settings.
|
||||
|
||||
See :ref:`config_py` for more information on configuration settings.
|
||||
|
||||
Runtime
|
||||
*******
|
||||
Desktop Runtime Standalone Application
|
||||
======================================
|
||||
|
||||
When executed, the runtime will automatically try to execute the pgAdmin Python
|
||||
application. If execution fails, it will prompt you to adjust the Python Path
|
||||
to include the directories containing the pgAdmin code as well as any additional
|
||||
Python dependencies. You can enter a list of paths by separating them with a
|
||||
semi-colon character, for example:
|
||||
The Desktop Runtime is based on `NWjs <https://nwjs.io/>`_ which integrates a
|
||||
browser and the Python server creating a standalone application.
|
||||
|
||||
.. code-block:: bash
|
||||
.. image:: images/runtime_standalone.png
|
||||
:alt: Runtime Standalone
|
||||
:align: center
|
||||
|
||||
/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/;/Users/dpage/python-libs/
|
||||
Runtime Menu
|
||||
------------
|
||||
|
||||
The configuration settings are stored using the QSettings class in Qt, which
|
||||
will use an INI file on Unix systems (~/.config/pgadmin/pgadmin4.conf),
|
||||
a plist file on Mac OS X (~/Library/Preferences/org.pgadmin.pgadmin4.plist),
|
||||
and the registry on Windows (HKEY_CURRENT_USER\\Software\\pgadmin\\pgadmin4).
|
||||
Use the *File Menu* to access the *Runtime Menu*:
|
||||
|
||||
The configuration settings:
|
||||
.. image:: images/runtime_menu.png
|
||||
:alt: Runtime Menu
|
||||
:align: center
|
||||
|
||||
Configuration Dialog
|
||||
--------------------
|
||||
|
||||
Use the *Runtime Menu* to access the *Configuration* dialog:
|
||||
|
||||
.. image:: images/runtime_configuration.png
|
||||
:alt: Runtime Configuration
|
||||
:align: center
|
||||
|
||||
Following are the details of the *Fixed port number?*, *Port Number*, and *Connection
|
||||
Timeout* configuration parameters:
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
@@ -65,18 +71,49 @@ The configuration settings:
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| Key | Type | Purpose |
|
||||
+==========================+====================+===============================================================+
|
||||
| ApplicationPath | String | The directory containing pgAdmin4.py |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| BrowserCommand | String | An alternate command to run instead of the default browser. |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| ConnectionTimeout | Integer | The number of seconds to wait for application server startup. |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| FixedPort | Boolean | Use a fixed network port number rather than a random one. |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| OpenTabAtStartup | Boolean | Open a browser tab at startup. |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| PortNumber | Integer | The port number to use, if using a fixed port. |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
| PythonPath | String | The Python module search path |
|
||||
| ConnectionTimeout | Integer | The number of seconds to wait for application server startup. |
|
||||
+--------------------------+--------------------+---------------------------------------------------------------+
|
||||
|
||||
Log dialog
|
||||
----------
|
||||
|
||||
Use the *Runtime Menu* to access the *Log* dialog:
|
||||
|
||||
.. image:: images/runtime_view_log.png
|
||||
:alt: Runtime View Log
|
||||
:align: center
|
||||
|
||||
Click on the *Reload* button at the bottom to view the latest logs of pgAdmin 4
|
||||
Server.
|
||||
|
||||
When executed, the runtime will automatically try to execute the pgAdmin Python
|
||||
application. If execution fails, it will prompt you with error message
|
||||
displaying a *Configure* button at the bottom. You can configure a fixed port
|
||||
number to avoid clashes of the default random port number with other
|
||||
applications and a connection timeout if desired.
|
||||
|
||||
.. image:: images/runtime_error.png
|
||||
:alt: Runtime Error
|
||||
:align: center
|
||||
|
||||
If the error is related to Python Path or pgAdmin Python file then you need to
|
||||
create a file named 'dev_config.json' and specify the following entries:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"pythonPath": "/path/to/python.exe",
|
||||
"pgadminFile": "/path/to/pgAdmin4.py"
|
||||
}
|
||||
|
||||
Note that the *dev_config.py* file should only be required by developers who are
|
||||
working outside of a standard installation.
|
||||
|
||||
The configuration settings are stored in *runtime_config.json* file, which
|
||||
will be available on Unix systems (~/.local/share/pgadmin/),
|
||||
on Mac OS X (~/Library/Preferences/pgadmin),
|
||||
and on Windows (%APPDATA%/pgadmin).
|
||||
@@ -15,3 +15,4 @@ PL/SQL code.
|
||||
query_tool
|
||||
editgrid
|
||||
schema_diff
|
||||
erd_tool
|
||||
@@ -0,0 +1,235 @@
|
||||
.. _erd_tool:
|
||||
|
||||
*****************
|
||||
`ERD Tool`:index:
|
||||
*****************
|
||||
|
||||
The Entity-Relationship Diagram (ERD) tool is a database design tool that provides a graphical representation of database tables, columns, and inter-relationships. ERD can give sufficient information for the database administrator to follow when developing and maintaining the database. The ERD Tool allows you to:
|
||||
|
||||
* Design and visualize the database tables and their relationships.
|
||||
* Add notes to the diagram.
|
||||
* Auto-align the tables and links for cleaner visualization.
|
||||
* Save the diagram and open it later to continue working on it.
|
||||
* Generate ready to run SQL from the database design.
|
||||
* Generate the database diagram for an existing database.
|
||||
|
||||
.. image:: images/erd_tool.png
|
||||
:alt: ERD tool window
|
||||
:align: center
|
||||
|
||||
You can open multiple copies of the ERD tool in individual tabs simultaneously. To close a copy of the ERD tool, click the *X* in the upper-right hand corner of the tab bar.
|
||||
|
||||
Toolbar
|
||||
*******
|
||||
|
||||
The *ERD Tool* toolbar uses context-sensitive icons that provide shortcuts to frequently performed tasks. The option is enabled for the highlighted icon and is disabled for the grayed-out icon.
|
||||
|
||||
.. image:: images/erd_tool_toolbar.png
|
||||
:alt: ERD tool toolbar
|
||||
:align: center
|
||||
|
||||
Hover over an icon on Toolbar to display a tooltip that describes the icon's functionality.
|
||||
|
||||
File Options
|
||||
************
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 1 4 1
|
||||
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| Icon | Behavior | Shortcut |
|
||||
+======================+===================================================================================================+================+
|
||||
| *Open File* | Click the *Open File* icon to load a previously saved diagram. | Ctrl + O |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Save* | Click the *Save* icon to perform a quick-save of a previously saved diagram, or to save the | Ctrl + S |
|
||||
| | diagram to a file. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Save as* | Click the *Save As* to open a new browser dialog and specify a new location to save the diagram. | Ctrl + Shift + |
|
||||
| | | S |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
Export Options
|
||||
**************
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 1 4 1
|
||||
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| Icon | Behavior | Shortcut |
|
||||
+======================+===================================================================================================+================+
|
||||
| *Generate SQL* | Click the *Generate SQL* icon to generate the DDL SQL for the diagram and open a query tool | Option + Ctrl +|
|
||||
| | with the generated SQL ready for execution. | S |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Download image* | Click the *Download image* icon to save the ERD diagram in a image formate | Option + Ctrl +|
|
||||
| | | I |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
Editing Options
|
||||
***************
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 1 4 1
|
||||
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| Icon | Behavior | Shortcut |
|
||||
+======================+===================================================================================================+================+
|
||||
| *Add table* | Click this button to add a new table to the diagram. On clicking, this will open a table dialog | Option/Alt + |
|
||||
| | where you can put the table details. | Ctrl + A |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Edit table* | Click this button to edit a table on the diagram. On clicking, this will open a table dialog | Option/Alt + |
|
||||
| | where you can change table details. This will enable when a table is selected. | Ctrl + E |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Clone table* | Click this button to clone the complete table structure, name it with a auto generated name and | Option/Alt + |
|
||||
| | put it in the diagram. | Ctrl + C |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Drop table/link* | You can drop a table or link using this button. You need to select a table or link and click on | Option/Alt + |
|
||||
| | this button to drop it. | Ctrl + D |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
Table Relationship Options
|
||||
**************************
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 1 4 1
|
||||
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| Icon | Behavior | Shortcut |
|
||||
+======================+===================================================================================================+================+
|
||||
| *1M* | Click this button to open a one-to-many relationship dialog to add a relationship between the | Option/Alt + |
|
||||
| | two tables. The selected table becomes the referencing table and will have the *many* endpoint of | Ctrl + O |
|
||||
| | the link. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *MM* | Click this button to open a many-to-many relationship dialog to add a relationship between the | Option/Alt + |
|
||||
| | two tables. This option will create a new table based on the selected columns for the two relating| Ctrl + M |
|
||||
| | tables and link them. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
Utility Options
|
||||
***************
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 1 4 1
|
||||
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| Icon | Behavior | Shortcut |
|
||||
+======================+===================================================================================================+================+
|
||||
| *Add/Edit note* | Click this button to make notes on tables nodes while designing the database. | Option/Alt + |
|
||||
| | | Ctrl + N |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Auto align* | Click this button to auto align all tables and links to make it look more cleaner. | Option/Alt + |
|
||||
| | | Ctrl + L |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Show details* | Click this button to toggle the column details visibility. It allows you to show few or more | Option/Alt + |
|
||||
| | column details. | Shift + D |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
Zoom Options
|
||||
************
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 1 4 1
|
||||
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| Icon | Behavior | Shortcut |
|
||||
+======================+===================================================================================================+================+
|
||||
| *Zoom to fit* | Click this button to zoom in/out automatically and fit all the tables to the view. | Option/Alt + |
|
||||
| | | Shift + F |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Zoom in* | Click this button to zoom in the diagram. | Option/Alt + |
|
||||
| | | Shift + "+" |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Zoom out* | Click this button to zoom out the diagram. | Option/Alt + |
|
||||
| | | Shift + "-" |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
Table Dialog
|
||||
************
|
||||
|
||||
.. image:: images/erd_table_dialog.png
|
||||
:alt: ERD tool table dialog
|
||||
:align: center
|
||||
|
||||
The table dialog allows you to:
|
||||
|
||||
* Change the table structure details.
|
||||
* It can be used edit an existing table or add a new one.
|
||||
* Refer :ref:`table dialog <table_dialog>` for information on different fields.
|
||||
|
||||
Table Node
|
||||
**********
|
||||
|
||||
.. image:: images/erd_table_node.png
|
||||
:alt: ERD tool table node
|
||||
:align: center
|
||||
|
||||
The table node shows table details in a graphical representation:
|
||||
|
||||
* The top bar has a *details toggle button* that is used to toggle column details visibility. There is also a *note button* that is visible only if there is some note added. you can click on this button to quickly change the note.
|
||||
* The first row shows the schema name of the table. Eg. *public* in above image.
|
||||
* The second row shows the table name. Eg. *users* in above image.
|
||||
* All other rows below the table name are the columns of the table along with data type. If the column is a primary key then it will have lock key icon eg. id is the primary key in above image. Otherwise, it will have column icon.
|
||||
* you can click on the node and drag to move on the canvas.
|
||||
* Upon double click on the table node or by clicking the edit button from the toolbar, the table dialog opens where you can change the table details. Refer :ref:`table dialog <table_dialog>` for information on different fields.
|
||||
|
||||
The One to Many Link Dialog
|
||||
***************************
|
||||
|
||||
.. image:: images/erd_1m_dialog.png
|
||||
:alt: ERD tool 1M dialog
|
||||
:align: center
|
||||
|
||||
The one to many link dialog allows you to:
|
||||
|
||||
* Add a foreign key relationship between two tables.
|
||||
* *Local Table* is the table that references a table and has the *many* end point.
|
||||
* *Local Column* the column that references.
|
||||
* *Referenced Table* is the table that is being referred and has the *one* end point.
|
||||
* *Referenced Column* the column that is being referred.
|
||||
|
||||
The Many to Many Link Dialog
|
||||
****************************
|
||||
|
||||
.. image:: images/erd_mm_dialog.png
|
||||
:alt: ERD tool MM dialog
|
||||
:align: center
|
||||
|
||||
The many to many link dialog allows you to:
|
||||
|
||||
* Add a many to many relationship between two tables.
|
||||
* It creates a relationship tables having columns derived from the two tables and link them to the tables.
|
||||
* *Left Table* is the first table that is to be linked. It will receive the *one* endpoint of the link with the new relation table.
|
||||
* *Left Column* the column of the first table, that will always be a primary key.
|
||||
* *Right Table* is the second table that is to be linked. It will receive the *one* endpoint of the link with the new relation table.
|
||||
* *Right Column* the column of the second table, that will always be a primary key.
|
||||
|
||||
The Table Link
|
||||
**************
|
||||
|
||||
.. image:: images/erd_table_link.png
|
||||
:alt: ERD tool table link
|
||||
:align: center
|
||||
|
||||
The table link shows relationship between tables:
|
||||
|
||||
* The single line endpoint of the link shows the column that is being referred.
|
||||
* The three line endpoint of the link shows the column that refers.
|
||||
* If one of the columns that is being referred or that refers is removed from the table then the link will get dropped.
|
||||
* you can click on the link and drag to move on the canvas.
|
||||
|
||||
|
||||
The Table Notes
|
||||
***************
|
||||
|
||||
.. image:: images/erd_table_note.png
|
||||
:alt: ERD tool table note
|
||||
:align: center
|
||||
|
||||
* You can use the notes popup to mark some notes while designing the database.
|
||||
* You open the pop-up using the toolbar note button.
|
||||
* If some note is added to a table then it will have notes button on the table node. You can click on the button to check/update notes.
|
||||
@@ -58,13 +58,15 @@ Click the *Columns* tab to continue.
|
||||
:alt: Exclusion constraint dialog columns tab
|
||||
:align: center
|
||||
|
||||
Use the fields in the *Columns* tab to to specify the column(s) to which the
|
||||
constraint applies. Use the drop-down listbox next to *Column* to select a
|
||||
column and click the *Add* icon (+) to provide details of the action on the
|
||||
column:
|
||||
Use the fields in the *Columns* tab to specify the column(s) or expression(s)
|
||||
to which the constraint applies. Use the *Is expression ?* switch to enable
|
||||
expression text input. Use the drop-down listbox next to *Column*
|
||||
to select a column. Once the *Column* is selected or the *Expression* is
|
||||
entered then click the *Add* icon (+) to provide details of the action on the
|
||||
column/expression:
|
||||
|
||||
* The *Column* field is populated with the selection made in the *Column*
|
||||
drop-down listbox.
|
||||
* The *Col/Exp* field is populated with the selection made in the *Column*
|
||||
drop-down listbox or the *Expression* entered.
|
||||
* If applicable, use the drop-down listbox in the *Operator class* to specify
|
||||
the operator class that will be used by the index for the column.
|
||||
* Move the *DESC* switch to *DESC* to specify a descending sort order. The
|
||||
|
||||
@@ -36,6 +36,7 @@ Mode is pre-configured for security.
|
||||
user_management
|
||||
change_user_password
|
||||
enabling_ldap_authentication
|
||||
kerberos
|
||||
|
||||
|
||||
.. note:: Pre-compiled and configured installation packages are available for
|
||||
|
||||
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 310 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 209 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 96 KiB |
@@ -103,7 +103,7 @@ The following example shows both a minimally defined and a fully defined server:
|
||||
"MaintenanceDB": "postgres"
|
||||
},
|
||||
"2": {
|
||||
"Name: "Fully Defined Server",
|
||||
"Name": "Fully Defined Server",
|
||||
"Group": "Server Group 2",
|
||||
"Host": "host.domain.com",
|
||||
"HostAddr": "192.168.1.2",
|
||||
|
||||
@@ -5,7 +5,7 @@ pgAdmin 4
|
||||
.. image:: images/logo-right-128.png
|
||||
:align: right
|
||||
:alt: pgAdmin Logo
|
||||
|
||||
|
||||
Welcome to pgAdmin 4. pgAdmin is the leading Open Source management tool for
|
||||
Postgres, the world's most advanced Open Source database. pgAdmin 4 is designed
|
||||
to meet the needs of both novice and experienced Postgres users alike, providing
|
||||
@@ -27,19 +27,3 @@ of database objects.
|
||||
contributions
|
||||
release_notes
|
||||
licence
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
.. _kerberos:
|
||||
|
||||
*******************************************************
|
||||
`Configure Kerberos Authentication for pgAdmin4`:index:
|
||||
*******************************************************
|
||||
|
||||
To configure Kerberos authentication, you must set your Kerberos Server and generate the *kinit* ticket on the client. To enable the Kerberos authentication for pgAdmin, you must configure the Kerberos settings in *config_local.py* or *config_system.py* (see the :ref:`config.py <config_py>` documentation) on the system where pgAdmin is installed in Server mode. You can copy these settings from *config.py* file and modify the values for the following parameters.
|
||||
|
||||
.. csv-table::
|
||||
:header: "**Parameter**", "**Description**"
|
||||
:class: longtable
|
||||
:widths: 35, 55
|
||||
|
||||
"AUTHENTICATION_SOURCES","The default value for this parameter is *internal*.
|
||||
To enable Kerberos authentication, you must include *kerberos* in the list of values for this parameter. you can modify the value as follows:
|
||||
|
||||
* [‘kerberos’]: pgAdmin will use only Kerberos authentication.
|
||||
|
||||
* [‘kerberos’, ‘internal’]: pgAdmin will first try to authenticate the user through kerberos. If that authentication fails, then it will return back to the login dialog where you need to provide internal pgAdmin user credentials for authentication."
|
||||
"KERBEROS_AUTO_CREATE_USER", "Specify value to *True* if you want to automatically create a pgAdmin user corresponding to the kerberos user credentials. Please note that password is not stored in the pgAdmin database."
|
||||
"KRB_APP_HOST_NAME", "Specify the name of *pgAdmin webserver hostname*. Please note that if it is not set, it will take the value of *default_server* parameter."
|
||||
|
||||
Keytab file for HTTP Service
|
||||
============================
|
||||
|
||||
* Generate the *Keytab* file for the HTTP service principal and copy it to the *pgAdmin* webserver machine. Ensure that the operating system user owning the *pgAdmin* webserver is the owner of this file and should be accessible by that user.
|
||||
|
||||
* Please note that either you should set *default_keytab_name* parameter in *krb5.conf* file or the environment variable *KRB5_KTNAME*. If not set then explicitly set *KRB_KTNAME* to the location of your *Keytab* file in the *config_local.py* or *config_system.py* file.
|
||||
|
||||
Apache HTTPD Configuration
|
||||
==========================
|
||||
|
||||
If the *pgAdmin* server is under the Apache Server, then you need to add the following parameters in *Directory* directive of :ref:`Apache HTTPD Configuration <server_deployment>`:
|
||||
|
||||
* WSGIScriptReloading On
|
||||
|
||||
* WSGIPassAuthorization On
|
||||
|
||||
|
||||
Browser settings to configure Kerberos Authentication
|
||||
=====================================================
|
||||
|
||||
You need to do the browser settings on the client machine to use the *Spnego/Kerberos*.
|
||||
|
||||
- For Mozilla Firefox
|
||||
|
||||
- Open the low level Firefox configuration page by loading the *about:config* page.
|
||||
- In the Search text box, enter: *network.negotiate-auth.trusted-uris*
|
||||
- Double-click the *network.negotiate-auth.trusted-uris* preference and enter the hostname or the domain of the web server that is protected by Kerberos HTTP SPNEGO. Separate multiple domains and hostnames with a comma.
|
||||
- Click OK.
|
||||
|
||||
- For Google Chrome
|
||||
|
||||
- For Windows:
|
||||
|
||||
* Open the Control Panel to access the Internet Options dialog.
|
||||
* Select the Security tab.
|
||||
* Select the Local Intranet zone and click the Sites button.
|
||||
* Make sure that the first two options, Include all local (intranet) sites not listed in other zones and Include all sites that bypass the proxy server are checked.
|
||||
* Click Advanced and add the names of the domains that are protected by Kerberos HTTP SPNEGO, one at a time, to the list of websites. For example, myhost.example.com. Click Close.
|
||||
* Click OK to save your configuration changes.
|
||||
|
||||
- For Linux or MacOS:
|
||||
|
||||
* Add the *--auth-server-whitelist* parameter to the google-chrome command. For example, to run Chrome from a Linux prompt, run the google-chrome command as follows:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
google-chrome --auth-server-whitelist = "hostname/domain"
|
||||
@@ -13,7 +13,7 @@ documentation is attributed to the
|
||||
|
||||
.. topic:: pgAdmin 4
|
||||
|
||||
Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose, without fee, and without a written agreement is
|
||||
@@ -29,4 +29,4 @@ documentation is attributed to the
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
|
||||
THE PGADMIN DEVELOPMENT TEAM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
|
||||
UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
@@ -35,8 +35,10 @@ node, and select *Create Cast...*
|
||||
materialized_view_dialog
|
||||
package_dialog
|
||||
procedure_dialog
|
||||
publication_dialog
|
||||
schema_dialog
|
||||
sequence_dialog
|
||||
subscription_dialog
|
||||
synonym_dialog
|
||||
trigger_function_dialog
|
||||
type_dialog
|
||||
|
||||
@@ -76,6 +76,9 @@ following options (in alphabetical order):
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| *View Data* | Click to access a context menu that provides several options for viewing data (see below). |
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Generate ERD* | Click to open the ERD tool with automatically generated diagram for the database selected. |
|
||||
| | This option is available only when a database is selected. Options are displayed on the flyout menu. |
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
The Tools Menu
|
||||
**************
|
||||
@@ -116,6 +119,12 @@ Use the *Tools* menu to access the following options (in alphabetical order):
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Storage Manager* | Click to open the :ref:`Storage Manager <storage_manager>` to upload, delete, or download the backup files. |
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *New ERD Project* | Click to open the :ref:`ERD Tool <erd_tool>` and start designing your database. |
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Schema Diff* | Click to open the :ref:`Schema Diff <schema_diff_feature>` and start comparing two database or two schema. |
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Search Objects...* | Click to open the :ref:`Search Objects... <search_objects>` and start searching any kind of objects in a database. |
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
The Help Menu
|
||||
*************
|
||||
@@ -130,6 +139,12 @@ information about the pgAdmin installation (in alphabetical order):
|
||||
+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Option | Action |
|
||||
+======================+=========================================================================================================================================+
|
||||
| *Quick Search* | Type your keywords in the Quick Search field. Typing at least three characters will display all the matching possibilities under Menu |
|
||||
| | items and the relevant documents under Help articles. Click on the options under Menu items to perform action of particular |
|
||||
| | functionality or object. Click on any of the Help articles to open the help of that topic with highlighted text in a separate window. |
|
||||
| | |
|
||||
| | **Note**:- If any of the option under Menu items is disabled, then it will provide information via info icon. |
|
||||
+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *About pgAdmin 4* | Click to open a window where you will find information about pgAdmin; this includes the current version and the current user. |
|
||||
+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Online Help* | Click to open documentation support for using pgAdmin utilities, tools and dialogs. |
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
.. _publication_dialog:
|
||||
|
||||
***************************
|
||||
`Publication Dialog`:index:
|
||||
***************************
|
||||
|
||||
`Logical replication <https://www.postgresql.org/docs/13/logical-replication.html>`_ uses a *publish* and *subscribe* model with one or more *subscribers* subscribing to one or more *publications* on a publisher node.
|
||||
|
||||
Use the *publication* dialog to create a publication. A publication is a set of changes generated from a table or a group of tables, and might also be described as a change set or replication set.
|
||||
|
||||
The *publication* dialog organizes the development of a publication through the following dialog tabs: *General* and *Definition*. The *SQL* tab displays the SQL code generated by dialog selections.
|
||||
|
||||
.. image:: images/publication_general.png
|
||||
:alt: Publication dialog general tab
|
||||
:align: center
|
||||
|
||||
Use the fields in the *General* tab to identify the publication:
|
||||
|
||||
* Use the *Name* field to add a descriptive name for the publication. The name will be displayed in the *pgAdmin* tree control.
|
||||
* The *Owner* field takes the name of the user automatically as current connected user. You can change the owner after creating publication using alter publication.
|
||||
|
||||
Click the *Definition* tab to continue.
|
||||
|
||||
.. image:: images/publication_definition.png
|
||||
:alt: Publication dialog definition tab
|
||||
:align: center
|
||||
|
||||
Use the *Definition* tab to set properties for the publication:
|
||||
|
||||
* Move the switch next to *All tables?* to *Yes* to replicate all the tables of the database, including tables created in the future.
|
||||
* Move the switch next to *Only table?* to *Yes* to replicate only the listed tables excluding all its descendant tables.
|
||||
* Specify a table or list of tables separated by a comma in *Tables* field to replicate all the listed table.
|
||||
* Use the *With* section to determine which DML operations will be published by the new publication to the subscribers. Move the switch next to *INSERT*, *UPDATE*, *DELETE*, or *TRUNCATE* to *No* if you do not want to replicate any of these DML operations from Publication to Subscription. By default, all the switches are set to *Yes* allowing all the DML operations.
|
||||
|
||||
.. note:: A published table must have a “replica identity” configured in order to be able to replicate UPDATE and DELETE operations. You can change with ALTER TABLE statement. For more information on replica identity see `Logical Replication Publication <https://www.postgresql.org/docs/13/logical-replication-publication.html>`_.
|
||||
|
||||
Click the *SQL* tab to continue.
|
||||
|
||||
Your entries in the *Publication* dialog generate a SQL command (see an example below). Use the *SQL* tab for review; revisit or switch tabs to make any changes to the SQL command.
|
||||
|
||||
**Example**
|
||||
|
||||
The following is an example of the sql command generated by user selections in
|
||||
the *Publication* dialog:
|
||||
|
||||
.. image:: images/publication_sql.png
|
||||
:alt: Publication dialog sql tab
|
||||
:align: center
|
||||
|
||||
The example creates a publication named *pub1* that is owned by *postgres*. It
|
||||
allows replication of all the DML operations.
|
||||
|
||||
* Click the *Info* button (i) to access online help.
|
||||
* Click the *Save* button to save work.
|
||||
* Click the *Cancel* button to exit without saving work.
|
||||
* Click the *Reset* button to restore all the default settings.
|
||||
@@ -122,7 +122,7 @@ You can:
|
||||
* Select and copy from the displayed result set.
|
||||
* Use the *Execute/Refresh* options to retrieve query execution information and
|
||||
set query execution options.
|
||||
* Use the *Download as CSV/TXT* icon to download the content of the *Data Output*
|
||||
* Use the *Save results to file* icon to save the content of the *Data Output*
|
||||
tab as a comma-delimited file.
|
||||
* Edit the data in the result set of a SELECT query if it is updatable.
|
||||
|
||||
@@ -186,11 +186,11 @@ under the Explain panel.
|
||||
|
||||
* Graphical
|
||||
|
||||
Please note that *EXPLAIN VERBOSE* cannot be displayed graphically. Hover over
|
||||
an icon on the *Graphical* tab to review information about that item; a popup
|
||||
window will display information about the selected object. For information on
|
||||
JIT statistics, triggers and a summary, hover over the icon on top-right
|
||||
corner; a similar popup window will be displayed when appropriate.
|
||||
Please note that *EXPLAIN VERBOSE* cannot be displayed graphically. Click on
|
||||
a node icon on the *Graphical* tab to review information about that item; a popup
|
||||
window will display on the right side with the information about the selected
|
||||
object. For information on JIT statistics, triggers and a summary, click on the
|
||||
button on top-right corner; a similar popup window will be displayed when appropriate.
|
||||
|
||||
Use the download button on top left corner of the *Explain* canvas to download
|
||||
the plan as an SVG file.
|
||||
|
||||
@@ -179,10 +179,10 @@ Query Execution
|
||||
| | | |
|
||||
| | * Select *Clear History* to erase the content of the *History* tab. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Download as CSV/TXT*| Click the *Download as CSV/TXT* icon to download the result set of the current query as a *.csv* | F8 |
|
||||
| | or as a *.txt* file. if *CSV field seperator* set to comma(,) else as a *.txt* file. | |
|
||||
| | You can specify the CSV/TXT settings through *Preferences -> SQL Editor -> CSV/TXT output* | |
|
||||
| | dialogue. | |
|
||||
| *Save results to* | Click the Save results to file icon to save the result set of the current query as a delimited | F8 |
|
||||
| *file* | text file (CSV, if the field separator is set to a comma). This button will only be enabled when | |
|
||||
| | a query has been executed and there are results in the data grid. You can specify the CSV/TXT | |
|
||||
| | settings in the Preference Dialogue under SQL Editor -> CSV/TXT output. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Macros* | Click the *Macros* icon to manage the macros. You can create, edit or clear the macros through | |
|
||||
| | the *Manage Macros* option. | |
|
||||
|
||||
@@ -11,6 +11,9 @@ notes for it.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release_notes_5_0
|
||||
release_notes_4_30
|
||||
release_notes_4_29
|
||||
release_notes_4_28
|
||||
release_notes_4_27
|
||||
release_notes_4_26
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
************
|
||||
Version 4.29
|
||||
************
|
||||
|
||||
Release date: 2020-12-10
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.28.
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #5328 <https://redmine.postgresql.org/issues/5328>`_ - Improve code coverage and API test cases for Foreign Tables.
|
||||
| `Issue #5337 <https://redmine.postgresql.org/issues/5337>`_ - Improve code coverage and API test cases for Views and Materialized Views.
|
||||
| `Issue #5343 <https://redmine.postgresql.org/issues/5343>`_ - Improve code coverage and API test cases for Debugger.
|
||||
| `Issue #6062 <https://redmine.postgresql.org/issues/6062>`_ - Ensure that code coverage should cover class and function declarations.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #5886 <https://redmine.postgresql.org/issues/5886>`_ - Fixed false error is shown while adding a new foreign key from the table dialog when a foreign key already exists with Auto FK Index set to true.
|
||||
| `Issue #5943 <https://redmine.postgresql.org/issues/5943>`_ - Ensure that folder rename should work properly in Storage Manager.
|
||||
| `Issue #5974 <https://redmine.postgresql.org/issues/5974>`_ - Fixed an issue where the debugger's custom tab title not applied when opened in the new browser tab.
|
||||
| `Issue #5978 <https://redmine.postgresql.org/issues/5978>`_ - Fixed an issue where dynamic tab title has not applied the first time for debugger panel.
|
||||
| `Issue #5982 <https://redmine.postgresql.org/issues/5982>`_ - Fixed documentation issue where JSON is not valid.
|
||||
| `Issue #5983 <https://redmine.postgresql.org/issues/5983>`_ - Added the appropriate server icon based on the server type in the new connection dialog.
|
||||
| `Issue #5985 <https://redmine.postgresql.org/issues/5985>`_ - Fixed an issue where the process watcher dialog throws an error for the database server which is already removed.
|
||||
| `Issue #5991 <https://redmine.postgresql.org/issues/5991>`_ - Ensure that dirty indicator (*) should not be visible when renaming the tabs.
|
||||
| `Issue #5992 <https://redmine.postgresql.org/issues/5992>`_ - Fixed an issue where escape character is shown when the server/database name has some special characters.
|
||||
| `Issue #5998 <https://redmine.postgresql.org/issues/5998>`_ - Fixed an issue where schema diff doesn't show the result of compare if source schema has tables with RLS.
|
||||
| `Issue #6003 <https://redmine.postgresql.org/issues/6003>`_ - Fixed an issue where an illegal argument is showing for trigger SQL when a trigger is created for View.
|
||||
| `Issue #6022 <https://redmine.postgresql.org/issues/6022>`_ - Fixed an issue where shared servers import is failing.
|
||||
| `Issue #6072 <https://redmine.postgresql.org/issues/6072>`_ - Fixed DLL load failed while importing bcrypt.
|
||||
@@ -0,0 +1,57 @@
|
||||
************
|
||||
Version 4.30
|
||||
************
|
||||
|
||||
Release date: 2021-01-28
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.29.
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #1802 <https://redmine.postgresql.org/issues/1802>`_ - Added ERD Diagram support with basic table fields, primary key, foreign key, and DDL SQL generation.
|
||||
| `Issue #5457 <https://redmine.postgresql.org/issues/5457>`_ - Added support for Kerberos authentication, using SPNEGO to forward the Kerberos tickets through a browser.
|
||||
| `Issue #6147 <https://redmine.postgresql.org/issues/6147>`_ - Documentation of Kerberos support.
|
||||
| `Issue #6152 <https://redmine.postgresql.org/issues/6152>`_ - Documentation of ERD Diagram support.
|
||||
| `Issue #6160 <https://redmine.postgresql.org/issues/6160>`_ - Add a container option (PGADMIN_DISABLE_POSTFIX) to disable the Postfix server.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #5338 <https://redmine.postgresql.org/issues/5338>`_ - Improve code coverage and API test cases for pgAgent.
|
||||
| `Issue #6052 <https://redmine.postgresql.org/issues/6052>`_ - Added connected pgAdmin user and connection name in the log file.
|
||||
| `Issue #6079 <https://redmine.postgresql.org/issues/6079>`_ - Updated mimetype from 'text/javascript' to 'application/javascript' as 'text/javascript' is obsolete.
|
||||
| `Issue #6162 <https://redmine.postgresql.org/issues/6162>`_ - Include PostgreSQL 13 utilities in the container.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #5282 <https://redmine.postgresql.org/issues/5282>`_ - Added 'Count Rows' option to the partition sub tables.
|
||||
| `Issue #5488 <https://redmine.postgresql.org/issues/5488>`_ - Improve the explain plan details by showing popup instead of tooltip on clicking of the specified node.
|
||||
| `Issue #5571 <https://redmine.postgresql.org/issues/5571>`_ - Added support for expression in exclusion constraints.
|
||||
| `Issue #5829 <https://redmine.postgresql.org/issues/5829>`_ - Fixed incorrect log information for AUTHENTICATION_SOURCES.
|
||||
| `Issue #5875 <https://redmine.postgresql.org/issues/5875>`_ - Ensure that the 'template1' database should not be visible after pg_upgrade.
|
||||
| `Issue #5905 <https://redmine.postgresql.org/issues/5905>`_ - Fixed an issue where the Save button is enabled by default in Macro.
|
||||
| `Issue #5906 <https://redmine.postgresql.org/issues/5906>`_ - Remove extra line after Manage Macros menu while clearing all macros.
|
||||
| `Issue #5907 <https://redmine.postgresql.org/issues/5907>`_ - Ensure that 'Clear All Rows' should not work if there is no existing macro available and the user does not specify any value.
|
||||
| `Issue #5929 <https://redmine.postgresql.org/issues/5929>`_ - Fixed an issue where the server is disconnected error message displayed if the user creates Macro with invalid SQL.
|
||||
| `Issue #5965 <https://redmine.postgresql.org/issues/5965>`_ - Ensure that the macro query result should be download properly.
|
||||
| `Issue #5973 <https://redmine.postgresql.org/issues/5973>`_ - Added appropriate help message and a placeholder for letting users know about the account password expiry for Login/Group Role.
|
||||
| `Issue #5997 <https://redmine.postgresql.org/issues/5997>`_ - Updated Flask-BabelEx to the latest.
|
||||
| `Issue #6046 <https://redmine.postgresql.org/issues/6046>`_ - Fixed an issue where the state of the Save File icon does not match the dirty editor indicator.
|
||||
| `Issue #6047 <https://redmine.postgresql.org/issues/6047>`_ - Fixed an issue where the dirty indicator stays active even if all changes were undone.
|
||||
| `Issue #6058 <https://redmine.postgresql.org/issues/6058>`_ - Ensure that the rename panel should be disabled when the SQL file opened in the query tool.
|
||||
| `Issue #6061 <https://redmine.postgresql.org/issues/6061>`_ - Fixed extra parentheses issue around joins for Views.
|
||||
| `Issue #6065 <https://redmine.postgresql.org/issues/6065>`_ - Fixed accessibility issues in schema diff module.
|
||||
| `Issue #6069 <https://redmine.postgresql.org/issues/6069>`_ - Fixed an issue on refreshing files in Query Tool.
|
||||
| `Issue #6075 <https://redmine.postgresql.org/issues/6075>`_ - Fixed an issue where Non-admin user is unable to view shared server created using service.
|
||||
| `Issue #6077 <https://redmine.postgresql.org/issues/6077>`_ - Fixed accessibility issues in various dialogs.
|
||||
| `Issue #6084 <https://redmine.postgresql.org/issues/6084>`_ - Fixed TypeError exception in schema diff when selected any identical object.
|
||||
| `Issue #6096 <https://redmine.postgresql.org/issues/6096>`_ - Updated deployment documentation, refer correctly to uWSGI where Gunicorn had been referenced.
|
||||
| `Issue #6098 <https://redmine.postgresql.org/issues/6098>`_ - Fixed an issue of deleting records when the user tries to delete multiple records.
|
||||
| `Issue #6120 <https://redmine.postgresql.org/issues/6120>`_ - Ensure that the user should be able to specify an older date for the account expiration of the role/user.
|
||||
| `Issue #6121 <https://redmine.postgresql.org/issues/6121>`_ - Fixed an issue where the database list in the new connection window is not visible.
|
||||
| `Issue #6122 <https://redmine.postgresql.org/issues/6122>`_ - Added informative message when there is no difference found for schema diff.
|
||||
| `Issue #6128 <https://redmine.postgresql.org/issues/6128>`_ - Fixed an issue where sequences are not created.
|
||||
| `Issue #6140 <https://redmine.postgresql.org/issues/6140>`_ - Ensure that verbose logs should be visible for Utility(Backup, Maintenance) jobs.
|
||||
| `Issue #6144 <https://redmine.postgresql.org/issues/6144>`_ - Ensure that the current value of the sequence should be ignored while comparing using schema diff.
|
||||
@@ -0,0 +1,50 @@
|
||||
************
|
||||
Version 5.0
|
||||
************
|
||||
|
||||
Release date: 2021-02-25
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.30.
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #5091 <https://redmine.postgresql.org/issues/5091>`_ - Make Statistics, Dependencies, Dependants tabs closable and the user can add them back using the 'Add panel' option.
|
||||
| `Issue #5912 <https://redmine.postgresql.org/issues/5912>`_ - Added support for Logical Replication.
|
||||
| `Issue #5967 <https://redmine.postgresql.org/issues/5967>`_ - Implemented runtime using NWjs to open pgAdmin4 in a standalone window instead of the system tray and web browser.
|
||||
| `Issue #6148 <https://redmine.postgresql.org/issues/6148>`_ - Added Quick Search functionality for menu items and help articles.
|
||||
| `Issue #6153 <https://redmine.postgresql.org/issues/6153>`_ - Added publication and subscription support in Schema Diff.
|
||||
| `Issue #6170 <https://redmine.postgresql.org/issues/6170>`_ - Ensure logs are not stored in the container, and only sent to the console.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #5017 <https://redmine.postgresql.org/issues/5017>`_ - Use cheroot as the default production server for pgAdmin4.
|
||||
| `Issue #6145 <https://redmine.postgresql.org/issues/6145>`_ - Documentation of Logical Replication.
|
||||
| `Issue #6195 <https://redmine.postgresql.org/issues/6195>`_ - Documentation of runtime with NWjs.
|
||||
| `Issue #6196 <https://redmine.postgresql.org/issues/6196>`_ - Documentation of Quick Search support.
|
||||
| `Issue #6207 <https://redmine.postgresql.org/issues/6207>`_ - Updated the JS dependencies to the latest.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #5809 <https://redmine.postgresql.org/issues/5809>`_ - Fixed an issue where the focus is not properly set on the filter text editor after closing the error dialog.
|
||||
| `Issue #5871 <https://redmine.postgresql.org/issues/5871>`_ - Ensure that username should be visible in the 'Connect to Server' popup when service and user name both specified.
|
||||
| `Issue #6045 <https://redmine.postgresql.org/issues/6045>`_ - Fixed autocomplete issue where it is not showing any suggestions if the schema name contains escape characters.
|
||||
| `Issue #6087 <https://redmine.postgresql.org/issues/6087>`_ - Fixed an issue where the dependencies tab showing multiple owners for the objects having shared dependencies.
|
||||
| `Issue #6117 <https://redmine.postgresql.org/issues/6117>`_ - Fixed an issue where the user is unable to update column-level privileges from the security tab.
|
||||
| `Issue #6143 <https://redmine.postgresql.org/issues/6143>`_ - Fixed an issue where shared server entries not getting deleted from SQLite database if the user gets deleted.
|
||||
| `Issue #6157 <https://redmine.postgresql.org/issues/6157>`_ - Fixed an issue where strike-through is not visible for rows selected for deletion after scrolling.
|
||||
| `Issue #6163 <https://redmine.postgresql.org/issues/6163>`_ - Fixed an issue where Zoom to fit button only works if the diagram is larger than the canvas.
|
||||
| `Issue #6164 <https://redmine.postgresql.org/issues/6164>`_ - Ensure that the diagram should not vanish entirely if zooming out too far in ERD.
|
||||
| `Issue #6177 <https://redmine.postgresql.org/issues/6177>`_ - Fixed an issue while downloading ERD images in Safari and Firefox.
|
||||
| `Issue #6178 <https://redmine.postgresql.org/issues/6178>`_ - Fixed an issue where the user unable to change the background color for a server.
|
||||
| `Issue #6179 <https://redmine.postgresql.org/issues/6179>`_ - Fixed an issue where Generate SQL displayed twice in the ERD tool.
|
||||
| `Issue #6180 <https://redmine.postgresql.org/issues/6180>`_ - Updated missing documentation for the 'Download Image' option in ERD.
|
||||
| `Issue #6187 <https://redmine.postgresql.org/issues/6187>`_ - Limit the upgrade check to run once per day.
|
||||
| `Issue #6193 <https://redmine.postgresql.org/issues/6193>`_ - Ensure that ERD throws a warning before closing unsaved changes if open in a new tab.
|
||||
| `Issue #6197 <https://redmine.postgresql.org/issues/6197>`_ - Fixed an issue where the ERD image is not properly downloaded.
|
||||
| `Issue #6201 <https://redmine.postgresql.org/issues/6201>`_ - Added SSL support for creating a subscription.
|
||||
| `Issue #6208 <https://redmine.postgresql.org/issues/6208>`_ - Fixed an issue where utility(Backup, Maintenance, ...) jobs are failing when the log level is set to DEBUG.
|
||||
| `Issue #6230 <https://redmine.postgresql.org/issues/6230>`_ - Fixed an issue where the user is not able to create the subscription.
|
||||
| `Issue #6250 <https://redmine.postgresql.org/issues/6250>`_ - Ensure DEB/RPM packages depend on the same version of each other.
|
||||
@@ -255,7 +255,7 @@ pgAdmin can be hosted by uWSGI, with NGINX in front of it. Note that these
|
||||
examples assume pgAdmin was installed using the Python Wheel (you may need to
|
||||
adjust the path to suit your installation).
|
||||
|
||||
To run with pgAdmin in the root directory of the server, start Gunicorn using a
|
||||
To run with pgAdmin in the root directory of the server, start uWSGI using a
|
||||
command similar to:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
.. subscription_dialog:
|
||||
|
||||
****************************
|
||||
`Subscription Dialog`:index:
|
||||
****************************
|
||||
|
||||
Use the *Subscription* dialog to create a subscription. A subscription defines the connection to another database and set of publications (one or more) to which it wants to subscribe.
|
||||
|
||||
The *subscription* dialog organizes the development of a subscription through the following dialog tabs: *General*, *Connection* and *With*. The *SQL* tab displays the SQL code generated by dialog selections.
|
||||
|
||||
.. image:: images/subscription_general.png
|
||||
:alt: Subscription dialog general tab
|
||||
:align: center
|
||||
|
||||
Use the fields in the *General* tab to identify the subscription:
|
||||
|
||||
* Use the *Name* field to add a descriptive name for the subscription. The name will be displayed in the *pgAdmin* tree control.
|
||||
* The *Owner* field takes the name of the user automatically as current connected user. You can change the owner after creating subscription using alter subscription. Please note that owner of the subscription has superuser privileges.
|
||||
|
||||
Click the *Connection* tab to continue.
|
||||
|
||||
.. image:: images/subscription_connection.png
|
||||
:alt: Subscription dialog connection tab
|
||||
:align: center
|
||||
|
||||
Use the *Connection* tab to define the connection string to the publisher:
|
||||
|
||||
* Use the *Host name/address* field to provide the valid hostname or ip address of the publication.
|
||||
* Use the *Port* field to provide port number to connect at Postgres Server in which publication is residing.
|
||||
* Use the *Username* field to provide the name of the user to connect to the publication.
|
||||
* Use the *Password* to provide the password of the user.
|
||||
* Use the *Database* field to connect to the database in which publication is residing.
|
||||
* Use the *Connection timeout* field to specify the maximum wait for connection, in seconds. Zero or not specified means wait indefinetly. It is not recommended to use a timeout of less than 2 seconds.
|
||||
* Use the *Passfile* field to specify the location of a password file (.pgpass). A .pgpass file allows a user to login without providing a password when they connect. For more information, see `Section 33.15 of the Postgres documentation <https://www.postgresql.org/docs/current/libpq-pgpass.html>`_.
|
||||
* Use the *Publication* field to specify the publication name on the publishers to subscribe to. Click on the refresh button at the end to load the names of the existing publications and then select from the list. You can also write the name of the known publication in the field.
|
||||
|
||||
Click the *SSL* tab to continue.
|
||||
|
||||
.. image:: images/subscription_ssl.png
|
||||
:alt: Subscription dialog ssl tab
|
||||
:align: center
|
||||
|
||||
Use the fields in the *SSL* tab to configure SSL:
|
||||
|
||||
* Use the drop-down list box in the *SSL* field to select the type of SSL
|
||||
connection the server should use. For more information about using SSL
|
||||
encryption, see
|
||||
`Section 33.18 of the Postgres documentation <https://www.postgresql.org/docs/current/libpq-ssl.html>`_.
|
||||
|
||||
If pgAdmin is installed in Server mode (the default mode), you can use the
|
||||
platform-specific File manager dialog to upload files that support SSL
|
||||
encryption to the server. To access the File manager dialog, click the
|
||||
icon that is located to the right of each of the following fields.
|
||||
|
||||
* Use the *Client certificate* field to specify the file containing the client
|
||||
SSL certificate. This file will replace the default
|
||||
*~/.postgresql/postgresql.crt* if pgAdmin is installed in Desktop mode, and
|
||||
*<STORAGE_DIR>/<USERNAME>/.postgresql/postgresql.crt* if pgAdmin is installed
|
||||
in Web mode. This parameter is ignored if an SSL connection is not made.
|
||||
* Use the *Client certificate key* field to specify the file containing the
|
||||
secret key used for the client certificate. This file will replace the
|
||||
default *~/.postgresql/postgresql.key* if pgAdmin is installed in Desktop
|
||||
mode, and *<STORAGE_DIR>/<USERNAME>/.postgresql/postgresql.key* if pgAdmin
|
||||
is installed in Web mode. This parameter is ignored if an SSL connection is
|
||||
not made.
|
||||
* Use the *Root certificate* field to specify the file containing the SSL
|
||||
certificate authority. This file will replace the default
|
||||
*~/.postgresql/root.crt*. This parameter is ignored if an SSL connection is
|
||||
not made.
|
||||
* Use the *Certificate revocation list* field to specify the file containing
|
||||
the SSL certificate revocation list. This list will replace the default list,
|
||||
found in *~/.postgresql/root.crl*. This parameter is ignored if an SSL
|
||||
connection is not made.
|
||||
* When *SSL compression?* is set to *True*, data sent over SSL connections will
|
||||
be compressed. The default value is *False* (compression is disabled). This
|
||||
parameter is ignored if an SSL connection is not made.
|
||||
|
||||
.. warning:: In Server mode, certificates, private keys, and the revocation list
|
||||
are stored in the per-user file storage area on the server, which is owned
|
||||
by the user account under which the pgAdmin server process is run. This
|
||||
means that administrators of the server may be able to access those files;
|
||||
appropriate caution should be taken before choosing to use this feature.
|
||||
|
||||
Click the *With* tab to continue.
|
||||
|
||||
.. image:: images/subscription_with.png
|
||||
:alt: Subscription dialog with tab
|
||||
:align: center
|
||||
|
||||
Use the *With* tab to define some parameters for a subscription:
|
||||
|
||||
* The *Copy data?* switch specifies whether the existing data in the publications that are being subscribed to should be copied once the replication starts. By default it is set to *Yes*.
|
||||
* The *Create slot?* switch specifies whether the command should create the replication slot on the publisher. By default it is set to *Yes*. Please note: if your publisher and subscriber both are inside same PostgreSQL server then is is set to *No* by default.
|
||||
* The *Enabled?* switch specifies whether the subscription should be actively replicating, or whether it should be just setup but not started yet. By default it is set to *Yes*.
|
||||
* The *Connect?* specifies whether the CREATE SUBSCRIPTION should connect to the publisher at all. By default, it is set to *Yes*. Setting this to *No* will change default values of enabled, create_slot and copy_data to *No*.
|
||||
* Use the *Slot Name* field to specify the name of the replication slot to use. By default, it uses the name of the subscription for the slot name.
|
||||
* Use the *Synchronous commit* field to override the synchronous_commit setting. By default, it is set to *off*. It is safe to use off for logical replication: If the subscriber loses transactions because of missing synchronization, the data will be sent again from the publisher.
|
||||
|
||||
Click the *SQL* tab to continue.
|
||||
|
||||
Your entries in the *Subscription* dialog generate a SQL command (see an example below). Use the *SQL* tab for review; revisit or switch tabs to make any changes to the SQL command.
|
||||
|
||||
**Example**
|
||||
|
||||
The following is an example of the sql command generated by user selections in
|
||||
the *Subscription* dialog:
|
||||
|
||||
.. image:: images/subscription_sql.png
|
||||
:alt: Subscription dialog sql tab
|
||||
:align: center
|
||||
|
||||
The example creates a subscription named *pub1_sub1* that is owned by *postgres*. It will replicate the data from the publication *pub1*.
|
||||
|
||||
* Click the *Info* button (i) to access online help.
|
||||
* Click the *Save* button to save work.
|
||||
* Click the *Cancel* button to exit without saving work.
|
||||
* Click the *Reset* button to restore all the default settings.
|
||||
@@ -1,155 +0,0 @@
|
||||
This directory contains the build runner script for creating .DEB packages for
|
||||
Debian and Ubuntu.
|
||||
|
||||
Supported platforms
|
||||
===================
|
||||
|
||||
Debian 9 & 10
|
||||
Ubuntu 16.04, 18.04, 19.04 & 19.10
|
||||
|
||||
Build configuration
|
||||
===================
|
||||
|
||||
To build Debian/Ubuntu packages, first run the setup.sh script as root to
|
||||
install the required pre-requisites, e.g.
|
||||
|
||||
# pkg/debian/setup.sh
|
||||
|
||||
Building packages
|
||||
=================
|
||||
|
||||
To build a set of packages, from the top-level source directory run:
|
||||
|
||||
$ make debian
|
||||
|
||||
or
|
||||
|
||||
$ pkg/debian/build.sh
|
||||
|
||||
Four .deb packages will be created in the dist/ directory:
|
||||
|
||||
pgadmin4_<version>_<distro>_<distro_version>_all.deb
|
||||
A convenience package that depends on all the others.
|
||||
|
||||
pgadmin4-server_<version>_<distro>_<distro_version>_<arch>.deb
|
||||
The core server, e.g. the Python and JS code and the online documentation.
|
||||
|
||||
pgadmin4-desktop_<version>_<distro>_<distro_version>_<arch>.deb
|
||||
The desktop runtime. Requires the server package.
|
||||
|
||||
pgadmin4-web_<version>_<distro>_<distro_version>_<arch>.deb
|
||||
The server mode setup script for configuring Apache HTTPD. Requires the
|
||||
server package.
|
||||
|
||||
Building a repo
|
||||
===============
|
||||
|
||||
An APT repo can be created by building DEBs for the required platforms, moving
|
||||
them into the required directory structure, and then running a number of
|
||||
commands to create the required metadata. The pgAdmin repos use the following
|
||||
structure (which doesn't entirely follow the normal structure for APT, but
|
||||
does seem to work well unlike other attempts):
|
||||
|
||||
<root>
|
||||
bionic
|
||||
dists
|
||||
pgadmin4
|
||||
InRelease
|
||||
main
|
||||
binary-all
|
||||
Packages
|
||||
Packages.gz
|
||||
pgadmin4_4.21_all.deb
|
||||
pgadmin4-web_4.21_all.deb
|
||||
binary-amd64
|
||||
Packages
|
||||
Packages.gz
|
||||
pgadmin4-desktop_4.21_amd64.deb
|
||||
pgadmin4-server_4.21_amd64.deb
|
||||
binary-i386
|
||||
Packages
|
||||
Packages.gz
|
||||
Release
|
||||
Release.gpg
|
||||
Release.gz
|
||||
buster
|
||||
disco
|
||||
eoan
|
||||
focal
|
||||
README
|
||||
stretch
|
||||
xenial
|
||||
|
||||
Note that only the first branches are shown above; other branches (e.g. for
|
||||
buster, disco etc. follow the structure shown for bionic.
|
||||
|
||||
Technically there are actually multiple repos here, one for each OS release.
|
||||
Note also that the binary-i386 directories do not contain any packages as we're
|
||||
not building 32bit packages for Linux. The directories and package indexes are
|
||||
present though, to prevent warnings being emitted on amd64 machines which are
|
||||
configured to support 32bit packages as well.
|
||||
|
||||
In order to sign the repositories you need to import your signing private key
|
||||
into the gnupg2 keystore, for example:
|
||||
|
||||
gpg --import signing_key.priv
|
||||
|
||||
Once the files are in the right structure, we need to run a number of commands
|
||||
to generate the metadata, and sign the relevant files using GPG (in APT, we
|
||||
sign the repository indexes rather than the packages themselves.
|
||||
|
||||
To create the metadata, first we create a config file for the apt-ftparchive
|
||||
program in $HOME/aptftp.conf (without the start/end markers):
|
||||
|
||||
----------
|
||||
APT::FTPArchive::Release {
|
||||
Origin "pgAdmin Development Team";
|
||||
Label "pgAdmin 4";
|
||||
Suite "pgadmin4";
|
||||
Architectures "amd64 all";
|
||||
Components "main";
|
||||
Description "pgAdmin 4 - Development Tools for PostgreSQL";
|
||||
};
|
||||
Default {
|
||||
Packages::Compress ". gzip bzip2";
|
||||
Sources::Compress ". gzip bzip2";
|
||||
Contents::Compress ". gzip bzip2";
|
||||
};
|
||||
----------
|
||||
|
||||
Next, we create the package indexes. Run the following command for each OS
|
||||
release to be included (in the example, we're using bionic):
|
||||
|
||||
for ARCH in all amd64 i386; do cd <root>/bionic && apt-ftparchive packages -c=$HOME/aptftp.conf dists/pgadmin4/main/binary-${ARCH} > dists/pgadmin4/main/binary-${ARCH}/Packages && gzip -k dists/pgadmin4/main/binary-${ARCH}/Packages; done
|
||||
|
||||
Now we need to create the release file for each OS release (again, using bionic
|
||||
in the example:
|
||||
|
||||
cd <root>/bionic/dists/pgadmin4 && apt-ftparchive release -c=$HOME/aptftp.conf . > Release && gzip -k Release
|
||||
|
||||
Finally, we can sign the release files. Replace <key name> with the email
|
||||
address on your signing key:
|
||||
|
||||
cd <root>/bionic/dists/pgadmin4 && gpg -u <key name> -bao Release.gpg Release
|
||||
cd <root>/bionic/dists/pgadmin4 && gpg -u <key name> --clear-sign --output InRelease Release
|
||||
|
||||
Note that it is important to run each command in the correct directory (hence
|
||||
the cd commands) to ensure the relative paths are created correctly in the
|
||||
indexes.
|
||||
|
||||
Repository Configuration
|
||||
========================
|
||||
|
||||
pgAdmin repo configurations live in /etc/apt/sources.list.d/pgadmin4.list. The
|
||||
file can be created with a command such as:
|
||||
|
||||
sudo sh -c 'echo "deb https://server.company.com/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list && apt update'
|
||||
|
||||
Assuming that <root> in the repository structure corresponds to
|
||||
https://server.company.com/apt/ from the client's perspective.
|
||||
|
||||
If you have signed the repository, you'll also need to import the key on the
|
||||
client. This is done as follows for the pgAdmin signing key; adjust the URL as
|
||||
needed for your own:
|
||||
|
||||
curl http://www.pgadmin.org/static/packages_pgadmin_org.pub | sudo apt-key add
|
||||
@@ -0,0 +1,154 @@
|
||||
# pgAdmin Debian/Ubuntu Builds
|
||||
|
||||
This directory contains the build runner script for creating .DEB packages for
|
||||
Debian and Ubuntu.
|
||||
|
||||
## Supported platforms
|
||||
|
||||
* Debian 9, 10 & 11 (testing)
|
||||
* Ubuntu 18.04, 20.04, 20.10
|
||||
|
||||
## Build configuration
|
||||
|
||||
To build Debian/Ubuntu packages, first run the setup.sh script as root to
|
||||
install the required pre-requisites, e.g.
|
||||
|
||||
# pkg/debian/setup.sh
|
||||
|
||||
## Building packages
|
||||
|
||||
To build a set of packages, from the top-level source directory run:
|
||||
|
||||
$ make debian
|
||||
|
||||
or:
|
||||
|
||||
$ pkg/debian/build.sh
|
||||
|
||||
Four .deb packages will be created in the dist/ directory:
|
||||
|
||||
*pgadmin4_<version>_<distro>_<distro_version>_all.deb*
|
||||
|
||||
A convenience package that depends on all the others.
|
||||
|
||||
*pgadmin4-server_<version>_<distro>_<distro_version>_<arch>.deb*
|
||||
|
||||
The core server, e.g. the Python and JS code and the online documentation.
|
||||
|
||||
*pgadmin4-desktop_<version>_<distro>_<distro_version>_<arch>.deb*
|
||||
|
||||
The desktop runtime. Requires the server package.
|
||||
|
||||
*pgadmin4-web_<version>_<distro>_<distro_version>_<arch>.deb*
|
||||
|
||||
The server mode setup script for configuring Apache HTTPD. Requires the server
|
||||
package.
|
||||
|
||||
## Building a repo
|
||||
|
||||
An APT repo can be created by building DEBs for the required platforms, moving
|
||||
them into the required directory structure, and then running a number of
|
||||
commands to create the required metadata. The pgAdmin repos use the following
|
||||
structure (which doesn't entirely follow the normal structure for APT, but
|
||||
does seem to work well unlike other attempts):
|
||||
|
||||
<root>
|
||||
bionic
|
||||
dists
|
||||
pgadmin4
|
||||
InRelease
|
||||
main
|
||||
binary-all
|
||||
Packages
|
||||
Packages.gz
|
||||
pgadmin4_4.21_all.deb
|
||||
pgadmin4-web_4.21_all.deb
|
||||
binary-amd64
|
||||
Packages
|
||||
Packages.gz
|
||||
pgadmin4-desktop_4.21_amd64.deb
|
||||
pgadmin4-server_4.21_amd64.deb
|
||||
binary-i386
|
||||
Packages
|
||||
Packages.gz
|
||||
Release
|
||||
Release.gpg
|
||||
Release.gz
|
||||
buster
|
||||
disco
|
||||
eoan
|
||||
focal
|
||||
README
|
||||
stretch
|
||||
xenial
|
||||
|
||||
Note that only the first branches are shown above; other branches (e.g. for
|
||||
buster, disco etc. follow the structure shown for bionic.
|
||||
|
||||
Technically there are actually multiple repos here, one for each OS release.
|
||||
Note also that the *binary-i386* directories do not contain any packages as we're
|
||||
not building 32bit packages for Linux. The directories and package indexes are
|
||||
present though, to prevent warnings being emitted on amd64 machines which are
|
||||
configured to support 32bit packages as well.
|
||||
|
||||
In order to sign the repositories you need to import your signing private key
|
||||
into the gnupg2 keystore, for example:
|
||||
|
||||
gpg --import signing_key.priv
|
||||
|
||||
Once the files are in the right structure, we need to run a number of commands
|
||||
to generate the metadata, and sign the relevant files using GPG (in APT, we
|
||||
sign the repository indexes rather than the packages themselves.
|
||||
|
||||
To create the metadata, first we create a config file for the *apt-ftparchive*
|
||||
program in *$HOME/aptftp.conf* (without the start/end markers):
|
||||
|
||||
APT::FTPArchive::Release {
|
||||
Origin "pgAdmin Development Team";
|
||||
Label "pgAdmin 4";
|
||||
Suite "pgadmin4";
|
||||
Architectures "amd64 all";
|
||||
Components "main";
|
||||
Description "pgAdmin 4 - Development Tools for PostgreSQL";
|
||||
};
|
||||
Default {
|
||||
Packages::Compress ". gzip bzip2";
|
||||
Sources::Compress ". gzip bzip2";
|
||||
Contents::Compress ". gzip bzip2";
|
||||
};
|
||||
|
||||
Next, we create the package indexes. Run the following command for each OS
|
||||
release to be included (in the example, we're using bionic):
|
||||
|
||||
for ARCH in all amd64 i386; do cd <root>/bionic && apt-ftparchive packages -c=$HOME/aptftp.conf dists/pgadmin4/main/binary-${ARCH} > dists/pgadmin4/main/binary-${ARCH}/Packages && gzip -k dists/pgadmin4/main/binary-${ARCH}/Packages; done
|
||||
|
||||
Now we need to create the release file for each OS release (again, using bionic
|
||||
in the example:
|
||||
|
||||
cd <root>/bionic/dists/pgadmin4 && apt-ftparchive release -c=$HOME/aptftp.conf . > Release && gzip -k Release
|
||||
|
||||
Finally, we can sign the release files. Replace <key name> with the email
|
||||
address on your signing key:
|
||||
|
||||
cd <root>/bionic/dists/pgadmin4 && gpg -u <key name> -bao Release.gpg Release
|
||||
cd <root>/bionic/dists/pgadmin4 && gpg -u <key name> --clear-sign --output InRelease Release
|
||||
|
||||
Note that it is important to run each command in the correct directory (hence
|
||||
the cd commands) to ensure the relative paths are created correctly in the
|
||||
indexes.
|
||||
|
||||
## Repository Configuration
|
||||
|
||||
pgAdmin repo configurations live in */etc/apt/sources.list.d/pgadmin4.list*. The
|
||||
file can be created with a command such as:
|
||||
|
||||
sudo sh -c 'echo "deb https://server.company.com/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list && apt update'
|
||||
|
||||
Assuming that <root> in the repository structure corresponds to
|
||||
https://server.company.com/apt/ from the client's perspective.
|
||||
|
||||
If you have signed the repository, you'll also need to import the key on the
|
||||
client. This is done as follows for the pgAdmin signing key; adjust the URL as
|
||||
needed for your own:
|
||||
|
||||
curl http://www.pgadmin.org/static/packages_pgadmin_org.pub | sudo apt-key add
|
||||
@@ -35,8 +35,8 @@ cat << EOF > "${SERVERROOT}/DEBIAN/control"
|
||||
Package: ${APP_NAME}-server
|
||||
Version: ${APP_LONG_VERSION}
|
||||
Architecture: ${OS_ARCH}
|
||||
Depends: python3, libpq5 (>= 11.0)
|
||||
Recommends: postgresql-client | postgresql-client-12 | postgresql-client-11 | postgresql-client-10
|
||||
Depends: python3, libpq5 (>= 11.0), libgssapi-krb5-2
|
||||
Recommends: postgresql-client | postgresql-client-13 | postgresql-client-12 | postgresql-client-11 | postgresql-client-10
|
||||
Maintainer: pgAdmin Development Team <pgadmin-hackers@postgresql.org>
|
||||
Description: The core server package for pgAdmin. pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
|
||||
EOF
|
||||
@@ -56,7 +56,7 @@ cat << EOF > "${DESKTOPROOT}/DEBIAN/control"
|
||||
Package: ${APP_NAME}-desktop
|
||||
Version: ${APP_LONG_VERSION}
|
||||
Architecture: ${OS_ARCH}
|
||||
Depends: ${APP_NAME}-server, libqt5gui5
|
||||
Depends: ${APP_NAME}-server (= ${APP_LONG_VERSION}), libatomic1
|
||||
Maintainer: pgAdmin Development Team <pgadmin-hackers@postgresql.org>
|
||||
Description: The desktop user interface for pgAdmin. pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
|
||||
EOF
|
||||
@@ -76,7 +76,7 @@ cat << EOF > "${WEBROOT}/DEBIAN/control"
|
||||
Package: ${APP_NAME}-web
|
||||
Version: ${APP_LONG_VERSION}
|
||||
Architecture: all
|
||||
Depends: ${APP_NAME}-server, apache2, libapache2-mod-wsgi-py3
|
||||
Depends: ${APP_NAME}-server (= ${APP_LONG_VERSION}), apache2, libapache2-mod-wsgi-py3
|
||||
Maintainer: pgAdmin Development Team <pgadmin-hackers@postgresql.org>
|
||||
Description: The web interface for pgAdmin, hosted under Apache HTTPD. pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
|
||||
EOF
|
||||
@@ -99,7 +99,7 @@ cat << EOF > "${METAROOT}/DEBIAN/control"
|
||||
Package: ${APP_NAME}
|
||||
Version: ${APP_LONG_VERSION}
|
||||
Architecture: all
|
||||
Depends: ${APP_NAME}-server, ${APP_NAME}-desktop, ${APP_NAME}-web
|
||||
Depends: ${APP_NAME}-server (= ${APP_LONG_VERSION}), ${APP_NAME}-desktop (= ${APP_LONG_VERSION}), ${APP_NAME}-web (= ${APP_LONG_VERSION})
|
||||
Maintainer: pgAdmin Development Team <pgadmin-hackers@postgresql.org>
|
||||
Description: Installs all required components to run pgAdmin in desktop and web modes. pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
|
||||
EOF
|
||||
|
||||
@@ -30,5 +30,5 @@ apt update
|
||||
|
||||
# Install pre-reqs
|
||||
echo "Installing build pre-requisites..."
|
||||
apt install -y build-essential python3-dev python3-venv python3-sphinx python3-wheel libpq-dev libffi-dev qt5-default nodejs yarn
|
||||
apt install -y build-essential python3-dev python3-venv python3-sphinx python3-wheel libpq-dev libffi-dev nodejs yarn libkrb5-dev
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
This directory contains the files required to create a docker container running
|
||||
pgAdmin.
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
From the top level directory of the pgAdmin source tree, simply run:
|
||||
|
||||
docker build .
|
||||
|
||||
You can also run 'make docker', which will call 'docker build .' but also tag
|
||||
the image like:
|
||||
|
||||
pgadmin4 pgadmin4:latest pgadmin4:4 pgadmin4:4.12
|
||||
|
||||
WARNING: The build should be run in a CLEAN source tree. Whilst some potentially
|
||||
dangerous files such as config_local.py or log files will be explicitly
|
||||
excluded from the final image, other files will not be.
|
||||
|
||||
Running
|
||||
=======
|
||||
|
||||
See the documentation at docs/en_US/container_deployment.rst for information on
|
||||
running the container.
|
||||
@@ -0,0 +1,26 @@
|
||||
# pgAdmin Docker Container Builds
|
||||
|
||||
This directory contains the files required to create a docker container running
|
||||
pgAdmin.
|
||||
|
||||
## Building
|
||||
|
||||
From the top level directory of the pgAdmin source tree, simply run:
|
||||
|
||||
docker build .
|
||||
|
||||
You can also run *make docker*, which will call *docker build .* but also tag
|
||||
the image like:
|
||||
|
||||
pgadmin4 pgadmin4:latest pgadmin4:4 pgadmin4:4.12
|
||||
|
||||
### WARNING
|
||||
|
||||
The build should be run in a CLEAN source tree. Whilst some potentially
|
||||
dangerous files such as config_local.py or log files will be explicitly
|
||||
excluded from the final image, other files will not be.
|
||||
|
||||
## Running
|
||||
|
||||
See the documentation at *docs/en_US/container_deployment.rst* for information on
|
||||
running the container.
|
||||
@@ -6,9 +6,11 @@
|
||||
# container build so it can have the required ownership.
|
||||
if [ `wc -m /pgadmin4/config_distro.py | awk '{ print $1 }'` = "0" ]; then
|
||||
cat << EOF > /pgadmin4/config_distro.py
|
||||
CA_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
||||
LOG_FILE = '/dev/null'
|
||||
HELP_PATH = '../../docs'
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg': '/usr/local/pgsql-12'
|
||||
'pg': '/usr/local/pgsql-13'
|
||||
}
|
||||
EOF
|
||||
|
||||
@@ -32,7 +34,7 @@ if [ ! -f /var/lib/pgadmin/pgadmin4.db ]; then
|
||||
|
||||
# Initialize DB before starting Gunicorn
|
||||
# Importing pgadmin4 (from this script) is enough
|
||||
python run_pgadmin.py
|
||||
/venv/bin/python3 run_pgadmin.py
|
||||
|
||||
export PGADMIN_SERVER_JSON_FILE=${PGADMIN_SERVER_JSON_FILE:-/pgadmin4/servers.json}
|
||||
# Pre-load any required servers
|
||||
@@ -40,25 +42,27 @@ if [ ! -f /var/lib/pgadmin/pgadmin4.db ]; then
|
||||
# When running in Desktop mode, no user is created
|
||||
# so we have to import servers anonymously
|
||||
if [ "${PGADMIN_CONFIG_SERVER_MODE}" = "False" ]; then
|
||||
/usr/local/bin/python /pgadmin4/setup.py --load-servers "${PGADMIN_SERVER_JSON_FILE}"
|
||||
/venv/bin/python3 /pgadmin4/setup.py --load-servers "${PGADMIN_SERVER_JSON_FILE}"
|
||||
else
|
||||
/usr/local/bin/python /pgadmin4/setup.py --load-servers "${PGADMIN_SERVER_JSON_FILE}" --user ${PGADMIN_DEFAULT_EMAIL}
|
||||
/venv/bin/python3 /pgadmin4/setup.py --load-servers "${PGADMIN_SERVER_JSON_FILE}" --user ${PGADMIN_DEFAULT_EMAIL}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start Postfix to handle password resets etc.
|
||||
sudo /usr/sbin/postfix start
|
||||
if [ -z ${PGADMIN_DISABLE_POSTFIX} ]; then
|
||||
sudo /usr/sbin/postfix start
|
||||
fi
|
||||
|
||||
# Get the session timeout from the pgAdmin config. We'll use this (in seconds)
|
||||
# to define the Gunicorn worker timeout
|
||||
TIMEOUT=$(cd /pgadmin4 && python -c 'import config; print(config.SESSION_EXPIRATION_TIME * 60 * 60 * 24)')
|
||||
TIMEOUT=$(cd /pgadmin4 && /venv/bin/python3 -c 'import config; print(config.SESSION_EXPIRATION_TIME * 60 * 60 * 24)')
|
||||
|
||||
# NOTE: currently pgadmin can run only with 1 worker due to sessions implementation
|
||||
# Using --threads to have multi-threaded single-process worker
|
||||
|
||||
if [ ! -z ${PGADMIN_ENABLE_TLS} ]; then
|
||||
exec gunicorn --timeout ${TIMEOUT} --bind ${PGADMIN_LISTEN_ADDRESS:-[::]}:${PGADMIN_LISTEN_PORT:-443} -w 1 --threads ${GUNICORN_THREADS:-25} --access-logfile ${GUNICORN_ACCESS_LOGFILE:--} --keyfile /certs/server.key --certfile /certs/server.cert -c gunicorn_config.py run_pgadmin:app
|
||||
exec /venv/bin/gunicorn --timeout ${TIMEOUT} --bind ${PGADMIN_LISTEN_ADDRESS:-[::]}:${PGADMIN_LISTEN_PORT:-443} -w 1 --threads ${GUNICORN_THREADS:-25} --access-logfile ${GUNICORN_ACCESS_LOGFILE:--} --keyfile /certs/server.key --certfile /certs/server.cert -c gunicorn_config.py run_pgadmin:app
|
||||
else
|
||||
exec gunicorn --timeout ${TIMEOUT} --bind ${PGADMIN_LISTEN_ADDRESS:-[::]}:${PGADMIN_LISTEN_PORT:-80} -w 1 --threads ${GUNICORN_THREADS:-25} --access-logfile ${GUNICORN_ACCESS_LOGFILE:--} -c gunicorn_config.py run_pgadmin:app
|
||||
exec /venv/bin/gunicorn --timeout ${TIMEOUT} --bind ${PGADMIN_LISTEN_ADDRESS:-[::]}:${PGADMIN_LISTEN_PORT:-80} -w 1 --threads ${GUNICORN_THREADS:-25} --access-logfile ${GUNICORN_ACCESS_LOGFILE:--} -c gunicorn_config.py run_pgadmin:app
|
||||
fi
|
||||
@@ -1,3 +0,0 @@
|
||||
This directory contains package build scripts and assets that are common to various Linux distributions.
|
||||
|
||||
You should not use them directly!
|
||||
@@ -0,0 +1,7 @@
|
||||
# pgAdmin Linux Build Scripts
|
||||
|
||||
This directory contains package build scripts and assets that are common to
|
||||
various Linux distributions.
|
||||
|
||||
You should not use them directly, but the functionality provided can be used to
|
||||
simplify your own build scripts (typically by sourcing *build-functions.sh*).
|
||||
@@ -53,7 +53,8 @@ _create_python_virtualenv() {
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Make sure we have the wheel package present
|
||||
# Make sure we have the wheel package present, as well as the latest pip
|
||||
pip3 install --upgrade pip
|
||||
pip3 install wheel
|
||||
|
||||
# Install the requirements
|
||||
@@ -63,7 +64,7 @@ _create_python_virtualenv() {
|
||||
# Use "python3" here as we want the venv path
|
||||
PYMODULES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
|
||||
DIR_PYMODULES_PATH=`dirname ${PYMODULES_PATH}`
|
||||
|
||||
|
||||
# Use /usr/bin/python3 here as we want the system path
|
||||
if [ $1 == "debian" ]; then
|
||||
PYSYSLIB_PATH=$(/usr/bin/python3 -c "import sys; print('%s/lib/python%d.%.d' % (sys.prefix, sys.version_info.major, sys.version_info.minor))")
|
||||
@@ -105,23 +106,60 @@ _create_python_virtualenv() {
|
||||
}
|
||||
|
||||
_build_runtime() {
|
||||
echo "Building the desktop runtime..."
|
||||
cd ${SOURCEDIR}/runtime
|
||||
if [ -f Makefile ]; then
|
||||
make clean
|
||||
fi
|
||||
if hash qmake-qt5 2>/dev/null; then
|
||||
PGADMIN_PYTHON_DIR=/usr qmake-qt5
|
||||
else
|
||||
PGADMIN_PYTHON_DIR=/usr qmake
|
||||
fi
|
||||
make
|
||||
echo "Assembling the desktop runtime..."
|
||||
|
||||
# Get a fresh copy of nwjs.
|
||||
# NOTE: The nw download servers seem to be very unreliable, so at the moment we're using wget
|
||||
# in a retry loop as Yarn/Npm don't seem to like that.
|
||||
|
||||
# YARN:
|
||||
# yarn add --cwd "${BUILDROOT}" nw
|
||||
# YARN END
|
||||
|
||||
# WGET:
|
||||
NW_VERSION=$(yarn info nw | grep latest | awk -F "'" '{ print $2}')
|
||||
pushd "${BUILDROOT}" > /dev/null
|
||||
while true;do
|
||||
wget https://dl.nwjs.io/v${NW_VERSION}/nwjs-v${NW_VERSION}-linux-x64.tar.gz && break
|
||||
rm nwjs-v${NW_VERSION}-linux-x64.tar.gz
|
||||
done
|
||||
tar -zxvf nwjs-v${NW_VERSION}-linux-x64.tar.gz
|
||||
popd > /dev/null
|
||||
# WGET END
|
||||
|
||||
# Copy nwjs into the staging directory
|
||||
mkdir -p "${DESKTOPROOT}/usr/${APP_NAME}/bin"
|
||||
cp pgAdmin4 "${DESKTOPROOT}/usr/${APP_NAME}/bin/pgadmin4"
|
||||
mkdir -p "${DESKTOPROOT}/usr/${APP_NAME}/share"
|
||||
cp pgAdmin4.ico "${DESKTOPROOT}/usr/${APP_NAME}/share/pgadmin4.ico"
|
||||
|
||||
# YARN:
|
||||
# cp -r "${BUILDROOT}/node_modules/nw/nwjs"/* "${DESKTOPROOT}/usr/${APP_NAME}/bin"
|
||||
# YARN END
|
||||
|
||||
# WGET:
|
||||
cp -r "${BUILDROOT}/nwjs-v${NW_VERSION}-linux-x64"/* "${DESKTOPROOT}/usr/${APP_NAME}/bin"
|
||||
# WGET END
|
||||
|
||||
mv "${DESKTOPROOT}/usr/${APP_NAME}/bin/nw" "${DESKTOPROOT}/usr/${APP_NAME}/bin/${APP_NAME}"
|
||||
|
||||
cp -r "${SOURCEDIR}/runtime/assets" "${DESKTOPROOT}/usr/${APP_NAME}/bin/assets"
|
||||
cp -r "${SOURCEDIR}/runtime/src" "${DESKTOPROOT}/usr/${APP_NAME}/bin/src"
|
||||
|
||||
cp "${SOURCEDIR}/runtime/package.json" "${DESKTOPROOT}/usr/${APP_NAME}/bin/"
|
||||
yarn --cwd "${DESKTOPROOT}/usr/${APP_NAME}/bin" install --production=true
|
||||
|
||||
# Create the icon
|
||||
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/128x128/apps/"
|
||||
cp "${SOURCEDIR}/pkg/linux/pgadmin4-128x128.png" "${DESKTOPROOT}/usr/share/icons/hicolor/128x128/apps/${APP_NAME}.png"
|
||||
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/64x64/apps/"
|
||||
cp "${SOURCEDIR}/pkg/linux/pgadmin4-64x64.png" "${DESKTOPROOT}/usr/share/icons/hicolor/64x64/apps/${APP_NAME}.png"
|
||||
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/48x48/apps/"
|
||||
cp "${SOURCEDIR}/pkg/linux/pgadmin4-48x48.png" "${DESKTOPROOT}/usr/share/icons/hicolor/48x48/apps/${APP_NAME}.png"
|
||||
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/32x32/apps/"
|
||||
cp "${SOURCEDIR}/pkg/linux/pgadmin4-32x32.png" "${DESKTOPROOT}/usr/share/icons/hicolor/32x32/apps/${APP_NAME}.png"
|
||||
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/16x16/apps/"
|
||||
cp "${SOURCEDIR}/pkg/linux/pgadmin4-16x16.png" "${DESKTOPROOT}/usr/share/icons/hicolor/16x16/apps/${APP_NAME}.png"
|
||||
|
||||
mkdir -p "${DESKTOPROOT}/usr/share/applications"
|
||||
cp ../pkg/linux/pgadmin4.desktop "${DESKTOPROOT}/usr/share/applications"
|
||||
cp "${SOURCEDIR}/pkg/linux/pgadmin4.desktop" "${DESKTOPROOT}/usr/share/applications"
|
||||
}
|
||||
|
||||
_build_docs() {
|
||||
|
||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
@@ -2,7 +2,7 @@
|
||||
Encoding=UTF-8
|
||||
Name=pgAdmin 4
|
||||
Exec=/usr/pgadmin4/bin/pgadmin4
|
||||
Icon=/usr/pgadmin4/share/pgadmin4.ico
|
||||
Icon=pgadmin4
|
||||
Type=Application
|
||||
Categories=Application;Development;
|
||||
MimeType=text/html
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# Global excludes across all subdirectories
|
||||
# Ignore config files
|
||||
codesign.conf
|
||||
debug.pgadmin.Info.plist
|
||||
pgadmin.Info.plist
|
||||
notarization.conf
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>__SHORT_VERSION__</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>__FULL_VERSION__</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>__FRAMEWORK_NAME__</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.pgadmin.__FRAMEWORK_NAME__</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>__SHORT_VERSION__</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>__FULL_VERSION__</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>__FRAMEWORK_NAME__</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.qt-project.Qt.__FRAMEWORK_NAME__</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>18G103</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>app.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>%APPID%</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>%APPVER%</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>%APPNAME%</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>4280.88</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>10.15</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1131</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11C505</string>
|
||||
<key>GPUEjectPolicy</key>
|
||||
<string>wait</string>
|
||||
<key>LSEnvironment</key>
|
||||
<dict>
|
||||
<key>MallocNanoZone</key>
|
||||
<string>0</string>
|
||||
<key>SYSTEM_VERSION_COMPAT</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
<key>LSFileQuarantineEnabled</key>
|
||||
<true/>
|
||||
<key>LSHasLocalizedDisplayName</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.10.0</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<true/>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>BrowserCrApplication</string>
|
||||
<key>NSRequiresAquaSystemAppearance</key>
|
||||
<false/>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>NSUserActivityTypeBrowsingWeb</string>
|
||||
</array>
|
||||
<key>NSUserNotificationAlertStyle</key>
|
||||
<string>none</string>
|
||||
<key>OSAScriptingDefinition</key>
|
||||
<string>scripting.sdef</string>
|
||||
<key>SCMRevision</key>
|
||||
<string>62f83a7521ae1f32e563795732dff0c9da1b660d-refs/heads/master@{#812354}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1 +0,0 @@
|
||||
APPL????
|
||||
@@ -1,45 +0,0 @@
|
||||
Building pgAdmin4.dmg on Mac OS X
|
||||
=================================
|
||||
|
||||
Required Packages (Either build the sources or get them from macports or
|
||||
similar):
|
||||
|
||||
1. Python installation
|
||||
- Python 3.4+ or above from https://www.python.org/
|
||||
|
||||
2. QT installation
|
||||
- Qt 5 from http://www.qt.io/
|
||||
|
||||
3. PostgreSQL installation
|
||||
- PostgreSQL 9.5 or above from http://www.postgresql.org/
|
||||
|
||||
Building:
|
||||
|
||||
1. If a value different from the default of /usr/local/python is required, set
|
||||
the PGADMIN_PYTHON_DIR environment variable to the Python root installation
|
||||
directory, e.g.
|
||||
|
||||
export PGADMIN_PYTHON_DIR=/opt/local
|
||||
|
||||
2. If a value different from the default of ~/Qt/5.13.2/clang_64, is required,
|
||||
set the PGADMIN_QT_DIR environment variable to the QT root installation
|
||||
directory, e.g.
|
||||
|
||||
export PGADMIN_QT_DIR=~/Qt/5.14.2/clang_64
|
||||
|
||||
3. If a value different from the default of /usr/local/pgsql is required, set
|
||||
the PGADMIN_POSTGRES_DIR environment variable to the PostgreSQL installation
|
||||
directory, e.g.
|
||||
|
||||
export PGADMIN_POSTGRES_DIR=/opt/local/pgsql
|
||||
|
||||
4. Copy framework.conf.in to framework.conf, and edit the values accordingly.
|
||||
|
||||
5. If you want to codesign the appbundle, copy codesign.conf.in to
|
||||
codesign.conf and set the values accordingly.
|
||||
|
||||
6. To build, go to pgAdmin4 source root directory and execute "make appbundle".
|
||||
This will create the python virtual environment and install all the required
|
||||
python modules mentioned in the requirements file using pip, build the
|
||||
runtime code and finally create the app bundle and the DMG in ./dist
|
||||
directory.
|
||||
@@ -0,0 +1,41 @@
|
||||
# pgAdmin macOS Builds
|
||||
|
||||
## Required Packages
|
||||
|
||||
Either build the sources or get them from macports or similar:
|
||||
|
||||
1. Yarn & NodeJS
|
||||
|
||||
2. PostgreSQL 12 or above from http://www.postgresql.org/
|
||||
|
||||
3. Python 3.6+ (required for building). The build environment should run this
|
||||
version of python in response to the *python* command.
|
||||
|
||||
## Building
|
||||
|
||||
1. To bundle a different version of Python from the default of 3.9.0, set the
|
||||
*PGADMIN_PYTHON_VERSION* environment variable, e.g:
|
||||
|
||||
export PGADMIN_PYTHON_VERSION=3.8.5
|
||||
|
||||
2. If a path different from the default of /usr/local/pgsql for the PostgreSQL
|
||||
installation has been used, set the *PGADMIN_POSTGRES_DIR* environment variable
|
||||
appropriately, e.g:
|
||||
|
||||
export PGADMIN_POSTGRES_DIR=/opt/local/pgsql
|
||||
|
||||
3. If you want to codesign the appbundle, copy *codesign.conf.in* to
|
||||
*codesign.conf* and set the values accordingly.
|
||||
|
||||
3. If you want to notarize the appbundle, copy *notarization.conf.in* to
|
||||
*notarization.conf* and set the values accordingly. Note that notarization
|
||||
will fail if the code isn't signed.
|
||||
|
||||
4. To build, go to pgAdmin4 source root directory and execute:
|
||||
|
||||
make appbundle
|
||||
|
||||
This will create the python virtual environment and install all the required
|
||||
python modules mentioned in the requirements file using pip, build the
|
||||
runtime code and finally create the app bundle and the DMG in *./dist*
|
||||
directory.
|
||||
@@ -9,62 +9,217 @@ _setup_env() {
|
||||
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
||||
fi
|
||||
BUNDLE_DIR="${BUILD_ROOT}/${APP_NAME}.app"
|
||||
DMG_NAME="${DIST_ROOT}/$(echo ${APP_NAME} | sed 's/ //g' | awk '{print tolower($0)}')-${APP_LONG_VERSION}.dmg"
|
||||
}
|
||||
|
||||
_cleanup() {
|
||||
echo Cleaning up the old environment and app bundle...
|
||||
rm -rf ${SOURCE_DIR}/runtime/*.app
|
||||
rm -rf ${BUILD_ROOT}
|
||||
rm -rf "${BUILD_ROOT}"
|
||||
rm -rf "${TEMP_DIR}"
|
||||
rm -f ${DIST_ROOT}/*.dmg
|
||||
}
|
||||
|
||||
_create_venv() {
|
||||
_build_runtime() {
|
||||
echo "Assembling the runtime environment..."
|
||||
test -d "${BUILD_ROOT}" || mkdir "${BUILD_ROOT}"
|
||||
|
||||
# Get a fresh copy of nwjs.
|
||||
# NOTE: The nw download servers seem to be very unreliable, so at the moment we're using wget
|
||||
# in a retry loop as Yarn/Npm don't seem to like that.
|
||||
|
||||
# YARN:
|
||||
# yarn add --cwd "${BUILDROOT}" nw
|
||||
# YARN END
|
||||
|
||||
# WGET:
|
||||
NW_VERSION=$(yarn info nw | grep latest | awk -F "'" '{ print $2}')
|
||||
pushd "${BUILD_ROOT}" > /dev/null
|
||||
while true;do
|
||||
wget https://dl.nwjs.io/v${NW_VERSION}/nwjs-v${NW_VERSION}-osx-x64.zip && break
|
||||
rm nwjs-v${NW_VERSION}-osx-x64.zip
|
||||
done
|
||||
unzip nwjs-v${NW_VERSION}-osx-x64.zip
|
||||
popd > /dev/null
|
||||
# WGET END
|
||||
|
||||
# YARN:
|
||||
# cp -R "${BUILD_ROOT}/node_modules/nw/nwjs/nwjs.app" "${BUILD_ROOT}/"
|
||||
# YARN END
|
||||
|
||||
# WGET:
|
||||
cp -R "${BUILD_ROOT}/nwjs-v${NW_VERSION}-osx-x64"/nwjs.app "${BUILD_ROOT}/"
|
||||
# WGET END
|
||||
|
||||
mv "${BUILD_ROOT}/nwjs.app" "${BUNDLE_DIR}"
|
||||
|
||||
# Copy in the runtime code
|
||||
mkdir "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
cp -R "${SOURCE_DIR}/runtime/assets" "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
cp -R "${SOURCE_DIR}/runtime/src" "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
cp "${SOURCE_DIR}/runtime/package.json" "${BUNDLE_DIR}/Contents/Resources/app.nw/"
|
||||
|
||||
# Install the runtime node_modules, then replace the package.json
|
||||
yarn --cwd "${BUNDLE_DIR}/Contents/Resources/app.nw/" install --production=true
|
||||
}
|
||||
|
||||
_create_python_env() {
|
||||
echo "Creating the Python environment..."
|
||||
PATH=${PGADMIN_POSTGRES_DIR}/bin:${PATH}
|
||||
LD_LIBRARY_PATH=${PGADMIN_POSTGRES_DIR}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
test -d ${BUILD_ROOT} || mkdir ${BUILD_ROOT}
|
||||
cd ${BUILD_ROOT}
|
||||
git clone https://github.com/gregneagle/relocatable-python.git "${BUILD_ROOT}/relocatable_python"
|
||||
PATH=$PATH:/usr/local/pgsql/bin python \
|
||||
"${BUILD_ROOT}/relocatable_python/make_relocatable_python_framework.py" \
|
||||
--upgrade-pip \
|
||||
--python-version ${PGADMIN_PYTHON_VERSION} \
|
||||
--pip-requirements "${SOURCE_DIR}/requirements.txt" \
|
||||
--destination "${BUNDLE_DIR}/Contents/Frameworks/"
|
||||
|
||||
${PYTHON_EXE} -m venv --copies venv
|
||||
# Make sure all the .so's in the Python env have the executable bit set
|
||||
# so they get properly signed later
|
||||
OLD_IFS=${IFS}
|
||||
IFS=$'\n'
|
||||
for i in $(find . -type f -name *.so -exec file "{}" \; | grep -v "(for architecture" | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle|Mach-O 64-bit dynamically linked shared library" | awk -F":" '{print $1}' | uniq)
|
||||
do
|
||||
chmod +x "${i}"
|
||||
done
|
||||
IFS=${OLD_IFS}
|
||||
|
||||
source venv/bin/activate
|
||||
pip install --no-cache-dir --no-binary psycopg2 -r ${SOURCE_DIR}/requirements.txt
|
||||
|
||||
# Figure the source path for use when completing the venv
|
||||
SOURCE_PYMODULES_PATH=$(dirname $("${PYTHON_EXE}" -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
|
||||
|
||||
# Figure the target path for use when completing the venv
|
||||
# Use "python" here as we want the venv path
|
||||
TARGET_PYMODULES_PATH=$(dirname $(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
|
||||
|
||||
# Copy in the additional system python modules
|
||||
cp -R ${SOURCE_PYMODULES_PATH}/* "${TARGET_PYMODULES_PATH}/"
|
||||
|
||||
# Link the python<version> directory to python so that the private environment path is found by the application.
|
||||
ln -s "$(basename ${TARGET_PYMODULES_PATH})" "${TARGET_PYMODULES_PATH}/../python"
|
||||
|
||||
# Remove tests
|
||||
find venv -name "test" -type d -print0 | xargs -0 rm -rf
|
||||
find venv -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||
}
|
||||
|
||||
_build_runtime() {
|
||||
cd ${SOURCE_DIR}/runtime
|
||||
if [ -f Makefile ]; then
|
||||
make clean
|
||||
fi
|
||||
${QMAKE}
|
||||
make
|
||||
cp -r pgAdmin4.app "${BUNDLE_DIR}"
|
||||
# Remove some things we don't need
|
||||
cd "${BUNDLE_DIR}/Contents/Frameworks/Python.framework"
|
||||
find . -name test -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tkinter -type d -print0 | xargs -0 rm -rf
|
||||
find . -name turtle.py -type f -print0 | xargs -0 rm -rf
|
||||
find . -name turtledemo -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tcl* -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tk* -type d -print0 | xargs -0 rm -rf
|
||||
find . -name tdbc* -type d -print0 | xargs -0 rm -rf
|
||||
find . -name itcl* -type d -print0 | xargs -0 rm -rf
|
||||
rm -f Versions/Current/lib/Tk.*
|
||||
rm -f Versions/Current/lib/libtcl*.dylib
|
||||
rm -f Versions/Current/lib/libtk*.dylib
|
||||
rm -f Versions/Current/lib/libtcl*.a
|
||||
rm -f Versions/Current/lib/libtk*.a
|
||||
rm -f Versions/Current/lib/tcl*.sh
|
||||
rm -f Versions/Current/lib/tk*.sh
|
||||
rm -rf Versions/Current/lib/pkgconfig*
|
||||
rm -rf Versions/Current/lib/sqlite*
|
||||
rm -rf Versions/Current/lib/thread*
|
||||
rm -rf Versions/Current/share
|
||||
}
|
||||
|
||||
_build_docs() {
|
||||
cd ${SOURCE_DIR}/docs/en_US
|
||||
echo "Building the docs..."
|
||||
# Create a temporary venv for the doc build, so we don't contaminate the one
|
||||
# that we're going to ship.
|
||||
"${BUNDLE_DIR}/Contents/Frameworks/Python.framework/Versions/Current/bin/python3" -m venv "${BUILD_ROOT}/venv"
|
||||
source "${BUILD_ROOT}/venv/bin/activate"
|
||||
pip3 install --upgrade pip
|
||||
pip3 install -r "${SOURCE_DIR}/requirements.txt"
|
||||
pip3 install sphinx
|
||||
|
||||
cd "${SOURCE_DIR}"
|
||||
make docs
|
||||
|
||||
cd "${SOURCE_DIR}/docs/en_US"
|
||||
test -d "${BUNDLE_DIR}/Contents/Resources/docs/en_US" || mkdir -p "${BUNDLE_DIR}/Contents/Resources/docs/en_US"
|
||||
cp -r _build/html "${BUNDLE_DIR}/Contents/Resources/docs/en_US/"
|
||||
|
||||
# Remove some things we don't need
|
||||
rm -rf "${BUNDLE_DIR}/Contents/Resources/docs/en_US/html/_sources"
|
||||
rm -f "${BUNDLE_DIR}/Contents/Resources/docs/en_US/html/_static"/*.png
|
||||
}
|
||||
|
||||
_fixup_imports() {
|
||||
local TODO TODO_OLD FW_RELPATH LIB LIB_BN
|
||||
|
||||
echo "Fixing imports on the core appbundle..."
|
||||
pushd "$1" > /dev/null
|
||||
|
||||
# Find all the files that may need tweaks
|
||||
TODO=$(file `find . -perm +0111 -type f` | \
|
||||
grep -v "Frameworks/Python.framework" | \
|
||||
grep -v "Frameworks/nwjs" | \
|
||||
grep -E "Mach-O 64-bit" | \
|
||||
awk -F ':| ' '{ORS=" "; print $1}' | \
|
||||
uniq)
|
||||
|
||||
# Add anything in the site-packages Python directory
|
||||
TODO+=$(file `find ./Contents/Frameworks/Python.framework/Versions/Current/lib/python*/site-packages -perm +0111 -type f` | \
|
||||
grep -E "Mach-O 64-bit" | \
|
||||
awk -F ':| ' '{ORS=" "; print $1}' | \
|
||||
uniq)
|
||||
|
||||
echo "Found executables: ${TODO}"
|
||||
while test "${TODO}" != ""; do
|
||||
TODO_OLD=${TODO} ;
|
||||
TODO="" ;
|
||||
for TODO_OBJ in ${TODO_OLD}; do
|
||||
echo "Post-processing: ${TODO_OBJ}"
|
||||
|
||||
# The Rust interface in the Python Cryptography module contains
|
||||
# a reference to a .so that won't exist. See:
|
||||
# https://github.com/PyO3/setuptools-rust/issues/106
|
||||
if [[ "${TODO_OBJ}" =~ cryptography/hazmat/bindings/\_rust\.abi3\.so$ ]]; then
|
||||
echo "Skipping because of https://github.com/PyO3/setuptools-rust/issues/106."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Figure out the relative path from ${TODO_OBJ} to Contents/Frameworks
|
||||
FW_RELPATH=$(echo "${TODO_OBJ}" | \
|
||||
sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | \
|
||||
sed -n 's|[^/][^/]*/|../|gp' \
|
||||
)"Contents/Frameworks"
|
||||
|
||||
# Find all libraries ${TODO_OBJ} depends on, but skip system libraries
|
||||
for LIB in $(
|
||||
otool -L ${TODO_OBJ} | \
|
||||
sed -n 's|^.*[[:space:]]\([^[:space:]]*\.dylib\).*$|\1|p' | \
|
||||
egrep -v '^(/usr/lib)|(/System)|@executable_path' \
|
||||
); do
|
||||
# Copy in any required dependencies
|
||||
LIB_BN="$(basename "${LIB}")" ;
|
||||
if ! test -f "Contents/Frameworks/${LIB_BN}"; then
|
||||
TARGET_FILE=""
|
||||
TARGET_PATH=""
|
||||
echo "Adding symlink: ${LIB_BN} (because of: ${TODO_OBJ})"
|
||||
cp -R "${LIB}" "Contents/Frameworks/${LIB_BN}"
|
||||
if ! test -L "Contents/Frameworks/${LIB_BN}"; then
|
||||
chmod 755 "Contents/Frameworks/${LIB_BN}"
|
||||
else
|
||||
TARGET_FILE=$(readlink "${LIB}")
|
||||
TARGET_PATH=$(dirname "${LIB}")/${TARGET_FILE}
|
||||
echo "Adding symlink target: ${TARGET_PATH}"
|
||||
cp "${TARGET_PATH}" "Contents/Frameworks/${TARGET_FILE}"
|
||||
chmod 755 "Contents/Frameworks/${TARGET_FILE}"
|
||||
fi
|
||||
echo "Rewriting ID in Contents/Frameworks/${LIB_BN} to ${LIB_BN}"
|
||||
install_name_tool \
|
||||
-id "${LIB_BN}" \
|
||||
"Contents/Frameworks/${LIB_BN}" || exit 1
|
||||
TODO="${TODO} ./Contents/Frameworks/${LIB_BN}"
|
||||
fi
|
||||
|
||||
# Rewrite the dependency paths
|
||||
echo "Rewriting library ${LIB} to @loader_path/${FW_RELPATH}/${LIB_BN} in ${TODO_OBJ}"
|
||||
install_name_tool -change \
|
||||
"${LIB}" \
|
||||
"@loader_path/${FW_RELPATH}/${LIB_BN}" \
|
||||
"${TODO_OBJ}" || exit 1
|
||||
install_name_tool -change \
|
||||
"${TARGET_PATH}" \
|
||||
"@loader_path/${FW_RELPATH}/${TARGET_FILE}" \
|
||||
"${TODO_OBJ}" || exit 1
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
echo "Imports updated on the core appbundle."
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
_complete_bundle() {
|
||||
echo "Completing the appbundle..."
|
||||
cd ${SCRIPT_DIR}
|
||||
|
||||
# Copy the binary utilities into place
|
||||
@@ -73,137 +228,43 @@ _complete_bundle() {
|
||||
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_dumpall" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_restore" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
cp "${PGADMIN_POSTGRES_DIR}/bin/psql" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
|
||||
# Replace the place holders with the current version
|
||||
sed -e "s/PGADMIN_LONG_VERSION/${APP_LONG_VERSION}/g" -e "s/PGADMIN_SHORT_VERSION/${APP_SHORT_VERSION}/g" pgadmin.Info.plist.in > pgadmin.Info.plist
|
||||
|
||||
# copy Python private environment to app bundle
|
||||
cp -PR ${BUILD_ROOT}/venv "${BUNDLE_DIR}/Contents/Resources/"
|
||||
# Update the plist
|
||||
cp Info.plist.in "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
sed -i '' "s/%APPNAME%/${APP_NAME}/g" "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
sed -i '' "s/%APPVER%/${APP_LONG_VERSION}/g" "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
sed -i '' "s/%APPID%/org.pgadmin.pgadmin4/g" "${BUNDLE_DIR}/Contents/Info.plist"
|
||||
for FILE in "${BUNDLE_DIR}"/Contents/Resources/*.lproj/InfoPlist.strings; do
|
||||
sed -i '' 's/CFBundleGetInfoString =.*/CFBundleGetInfoString = "Copyright (C) 2013 - 2021, The pgAdmin Development Team";/g' "${FILE}"
|
||||
sed -i '' 's/NSHumanReadableCopyright =.*/NSHumanReadableCopyright = "Copyright (C) 2013 - 2021, The pgAdmin Development Team";/g' "${FILE}"
|
||||
echo CFBundleDisplayName = \"${APP_NAME}\"\; >> "${FILE}"
|
||||
done
|
||||
|
||||
# Remove any TCL-related files that may cause us problems
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name "_tkinter*" -print0 | xargs -0 rm -f
|
||||
# PkgInfo
|
||||
echo APPLPGA4 > "${BUNDLE_DIR}/Contents/PkgInfo"
|
||||
|
||||
test -d "${BUNDLE_DIR}/Contents/Resources" || mkdir -p "${BUNDLE_DIR}/Contents/Resources"
|
||||
# Create qt.conf so that app knows where the Plugins are present
|
||||
cat >> "${BUNDLE_DIR}/Contents/Resources/qt.conf" << EOF
|
||||
[Paths]
|
||||
Plugins = PlugIns
|
||||
EOF
|
||||
# Icon
|
||||
cp pgAdmin4.icns "${BUNDLE_DIR}/Contents/Resources/app.icns"
|
||||
|
||||
test -d "${BUNDLE_DIR}/Contents/Frameworks" || mkdir -p "${BUNDLE_DIR}/Contents/Frameworks"
|
||||
test -d "${BUNDLE_DIR}/Contents/PlugIns/platforms" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/platforms"
|
||||
test -d "${BUNDLE_DIR}/Contents/PlugIns/imageformats" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
|
||||
cp -f ${PGADMIN_QT_DIR}/plugins/platforms/libqcocoa.dylib "${BUNDLE_DIR}/Contents/PlugIns/platforms"
|
||||
cp -f ${PGADMIN_QT_DIR}/plugins/imageformats/libqsvg.dylib "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
|
||||
cp -f ${PGADMIN_POSTGRES_DIR}/lib/libpq.5.dylib "${BUNDLE_DIR}/Contents/Frameworks"
|
||||
# Rename the executable
|
||||
mv "${BUNDLE_DIR}/Contents/MacOS/nwjs" "${BUNDLE_DIR}/Contents/MacOS/${APP_NAME}"
|
||||
|
||||
local todo todo_old fw_relpath lib lib_bn
|
||||
# Rename the app in package.json so the menu looks as it should
|
||||
sed -i '' "s/\"name\": \"pgadmin4\"/\"name\": \"${APP_NAME}\"/g" "${BUNDLE_DIR}/Contents/Resources/app.nw/package.json"
|
||||
|
||||
pushd "${BUNDLE_DIR}" > /dev/null
|
||||
# Import the dependencies, and rewrite any library references
|
||||
_fixup_imports "${BUNDLE_DIR}"
|
||||
|
||||
# We skip nested apps here - those are treated specially
|
||||
todo=$(file `find ./ -perm +0111 ! -type d ! -path "*.app/*" ! -name "*.app"` | grep -E "Mach-O 64-bit" | awk -F ':| ' '{ORS=" "; print $1}')
|
||||
|
||||
echo "Found executables: ${todo}"
|
||||
while test "${todo}" != ""; do
|
||||
todo_old=${todo} ;
|
||||
todo="" ;
|
||||
for todo_obj in ${todo_old}; do
|
||||
echo "Post-processing: ${todo_obj}"
|
||||
|
||||
# Figure out the relative path from todo_obj to Contents/Frameworks
|
||||
fw_relpath=$(echo "${todo_obj}" | sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | sed -n 's|[^/][^/]*/|../|gp')"Contents/Frameworks"
|
||||
fw_relpath_old=${fw_relpath}
|
||||
|
||||
# Find all libraries $todo_obj depends on, but skip system libraries
|
||||
for lib in $(otool -L ${todo_obj} | grep "Qt\|dylib\|Frameworks\|PlugIns" | grep -v ":" | sed 's/(.*//' | egrep -v '(/usr/lib)|(/System)|@executable_path@'); do
|
||||
if echo ${lib} | grep "PlugIns\|libqcocoa" > /dev/null; then
|
||||
lib_loc="Contents/PlugIns/platforms"
|
||||
elif echo ${lib} | grep "PlugIns\|libqsvg" > /dev/null; then
|
||||
lib_loc="Contents/PlugIns/imageformats"
|
||||
elif echo ${lib} | grep "Qt" > /dev/null; then
|
||||
qtfw_path="$(dirname ${lib} | sed 's|.*\(Qt.*framework\)|\1|')"
|
||||
lib_loc="Contents/Frameworks/${qtfw_path}"
|
||||
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
|
||||
lib_loc="$(dirname ${todo_obj})"
|
||||
qtfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
|
||||
fi
|
||||
elif echo ${lib} | grep "Python" > /dev/null; then
|
||||
pyfw_path="$(dirname ${lib} | sed 's|.*\(Python.*framework\)|\1|')"
|
||||
lib_loc="Contents/Frameworks/${pyfw_path}"
|
||||
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
|
||||
lib_loc="$(dirname ${todo_obj})"
|
||||
pyfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
|
||||
fi
|
||||
else
|
||||
lib_loc="Contents/Frameworks"
|
||||
fi
|
||||
lib_bn="$(basename "${lib}")" ;
|
||||
if ! test -f "${lib_loc}/${lib_bn}"; then
|
||||
target_file=""
|
||||
target_path=""
|
||||
echo "Adding symlink: ${lib_bn} (because of: ${todo_obj})"
|
||||
|
||||
# Copy the QT and Python framework
|
||||
if echo ${lib} | grep Qt > /dev/null ; then
|
||||
test -d ${lib_loc} || mkdir -p ${lib_loc}
|
||||
echo Copying -R ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} to ${lib_loc}/
|
||||
cp ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} ${lib_loc}/
|
||||
elif echo ${lib} | grep Python > /dev/null ; then
|
||||
test -d ${lib_loc} || mkdir -p ${lib_loc}
|
||||
cp -R "${lib}" "${lib_loc}/${lib_bn}"
|
||||
else
|
||||
cp -R "${lib}" "${lib_loc}/${lib_bn}"
|
||||
fi
|
||||
if ! test -L "${lib_loc}/${lib_bn}"; then
|
||||
chmod 755 "${lib_loc}/${lib_bn}"
|
||||
else
|
||||
target_file=$(readlink "${lib}")
|
||||
target_path=$(dirname "${lib}")/${target_file}
|
||||
|
||||
echo "Adding symlink target: ${target_path}"
|
||||
cp "${target_path}" "${lib_loc}/${target_file}"
|
||||
chmod 755 "${lib_loc}/${target_file}"
|
||||
fi
|
||||
echo "Rewriting ID in ${lib_loc}/${lib_bn} to ${lib_bn}"
|
||||
install_name_tool -id "${lib_bn}" "${lib_loc}/${lib_bn}"
|
||||
|
||||
todo="${todo} ./${lib_loc}/${lib_bn}"
|
||||
fi
|
||||
if echo ${lib} | grep Qt > /dev/null ; then
|
||||
fw_relpath="${fw_relpath}/${qtfw_path}"
|
||||
fi
|
||||
if echo ${lib} | grep Python > /dev/null ; then
|
||||
fw_relpath="${fw_relpath}/${pyfw_path}"
|
||||
fi
|
||||
chmod +w ${todo_obj}
|
||||
echo "Rewriting library ${lib} to @loader_path/${fw_relpath}/${lib_bn} in ${todo_obj}"
|
||||
|
||||
install_name_tool -change "${lib}" "@loader_path/${fw_relpath}/${lib_bn}" "${todo_obj}"
|
||||
install_name_tool -change "${target_path}" "@loader_path/${fw_relpath}/${target_file}" "${todo_obj}"
|
||||
|
||||
fw_relpath="${fw_relpath_old}"
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
# Fix the rpaths for psycopg module
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libpq.5.dylib @loader_path/../../../../../../Frameworks/libpq.5.dylib
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libssl.1.0.0.dylib @loader_path/../../../../../../Frameworks/libssl.1.0.0.dylib
|
||||
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libcrypto.1.0.0.dylib @loader_path/../../../../../../Frameworks/libcrypto.1.0.0.dylib
|
||||
|
||||
echo "App completed: ${BUNDLE_DIR}"
|
||||
popd > /dev/null
|
||||
|
||||
pushd ${SOURCE_DIR}/web > /dev/null
|
||||
# Build node modules
|
||||
pushd "${SOURCE_DIR}/web" > /dev/null
|
||||
yarn install
|
||||
yarn run bundle
|
||||
|
||||
curl https://curl.haxx.se/ca/cacert.pem -o cacert.pem -s
|
||||
curl https://curl.se/ca/cacert.pem -o cacert.pem -s
|
||||
popd > /dev/null
|
||||
|
||||
# copy the web directory to the bundle as it is required by runtime
|
||||
cp -r ${SOURCE_DIR}/web "${BUNDLE_DIR}/Contents/Resources/"
|
||||
cp -r "${SOURCE_DIR}/web" "${BUNDLE_DIR}/Contents/Resources/"
|
||||
cd "${BUNDLE_DIR}/Contents/Resources/web"
|
||||
rm -f pgadmin4.db config_local.*
|
||||
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
||||
@@ -226,66 +287,6 @@ EOF
|
||||
find "${BUNDLE_DIR}" -name "*.pyc" -print0 | xargs -0 rm -f
|
||||
}
|
||||
|
||||
_framework_config() {
|
||||
# Get the config
|
||||
source ${SCRIPT_DIR}/framework.conf
|
||||
|
||||
echo Reorganising the framework structure...
|
||||
|
||||
# Create "Current" and "Current/Resources" inside each of the framework dirs
|
||||
find "${BUNDLE_DIR}/Contents/Frameworks"/*framework -type d -name "Versions" | while read -r framework_dir; do
|
||||
pushd "${framework_dir}" > /dev/null
|
||||
|
||||
# Create framework 'Current' soft link
|
||||
VERSION_NUMBER=`ls -1`
|
||||
ln -s ${VERSION_NUMBER} Current
|
||||
|
||||
# Create "Resources" subdirectory
|
||||
if [ ! -d Current/Resources ]; then
|
||||
mkdir Current/Resources
|
||||
fi
|
||||
|
||||
popd > /dev/null
|
||||
done
|
||||
|
||||
# Stuff for Qt framework files only
|
||||
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "Qt*framework" | while read -r framework_dir; do
|
||||
pushd "${framework_dir}" > /dev/null
|
||||
|
||||
# Create soft link to the framework binary
|
||||
ln -s Versions/Current/Qt*
|
||||
|
||||
# Create soft link to the framework Resources dir
|
||||
ln -s Versions/Current/Resources
|
||||
|
||||
# Create the Info.plist files
|
||||
MYNAME=`ls -1 Qt*`
|
||||
if [ -f Resources/Info.plist ]; then
|
||||
chmod +w Resources/Info.plist
|
||||
fi
|
||||
sed 's/__SHORT_VERSION__/${QT_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Qt5" | sed 's/__FULL_VERSION__/${QT_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
|
||||
|
||||
popd > /dev/null
|
||||
done
|
||||
|
||||
# Same thing, but specific to the Python framework dir
|
||||
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "P*framework" | while read -r framework_dir; do
|
||||
pushd "${framework_dir}" > /dev/null
|
||||
|
||||
# Create soft link to the framework binary
|
||||
ln -s Versions/Current/Py*
|
||||
|
||||
# Create soft link to the framework Resources dir
|
||||
ln -s Versions/Current/Resources
|
||||
|
||||
# Create the Info.plist file
|
||||
MYNAME=`ls -1 Py*`
|
||||
sed 's/__SHORT_VERSION__/${PYTHON_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Python" | sed 's/__FULL_VERSION__/${PYTHON_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
|
||||
|
||||
popd > /dev/null
|
||||
done
|
||||
}
|
||||
|
||||
_codesign_binaries() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
return
|
||||
@@ -296,21 +297,36 @@ _codesign_binaries() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${DEVELOPER_BUNDLE_ID}" ]; then
|
||||
echo "Developer Bundle Identifier not found in codesign.conf" >&2
|
||||
fi
|
||||
# Create the entitlements file
|
||||
cp "${SCRIPT_DIR}/entitlements.plist.in" "${BUILD_ROOT}/entitlements.plist"
|
||||
TEAM_ID=$(echo ${DEVELOPER_ID} | awk -F"[()]" '{print $2}')
|
||||
sed -i '' "s/%TEAMID%/${TEAM_ID}/g" "${BUILD_ROOT}/entitlements.plist"
|
||||
|
||||
echo Signing ${BUNDLE_DIR} binaries...
|
||||
IFS=$'\n'
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle" | awk -F":| \\\(" '{print $1}' | uniq)
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | \
|
||||
grep -v "(for architecture" | \
|
||||
grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle|Mach-O 64-bit dynamically linked shared library" | \
|
||||
awk -F":" '{print $1}' | \
|
||||
uniq)
|
||||
do
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||
codesign --deep --force --verify --verbose --timestamp \
|
||||
--options runtime \
|
||||
--entitlements "${BUILD_ROOT}/entitlements.plist" \
|
||||
-i org.pgadmin.pgadmin4 \
|
||||
--sign "${DEVELOPER_ID}" \
|
||||
"$i"
|
||||
done
|
||||
|
||||
echo Signing ${BUNDLE_DIR} libraries...
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -name "*.dylib*")
|
||||
do
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||
codesign --deep --force --verify --verbose --timestamp \
|
||||
--options runtime \
|
||||
--entitlements "${BUILD_ROOT}/entitlements.plist" \
|
||||
-i org.pgadmin.pgadmin4 \
|
||||
--sign "${DEVELOPER_ID}" \
|
||||
"$i"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -321,44 +337,37 @@ _codesign_bundle() {
|
||||
|
||||
# Sign the .app
|
||||
echo Signing ${BUNDLE_DIR}...
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE_DIR}"
|
||||
|
||||
# Verify it worked
|
||||
echo Verifying the signature...
|
||||
codesign --verify --verbose --deep --force "${BUNDLE_DIR}"
|
||||
echo ${BUNDLE_DIR} successfully signed.
|
||||
codesign --deep --force --verify --verbose --timestamp \
|
||||
--options runtime \
|
||||
--entitlements "${BUILD_ROOT}/entitlements.plist" \
|
||||
-i org.pgadmin.pgadmin4 \
|
||||
--sign "${DEVELOPER_ID}" \
|
||||
"${BUNDLE_DIR}"
|
||||
}
|
||||
|
||||
_create_dmg() {
|
||||
# move to the directory where we want to create the DMG
|
||||
test -d ${DIST_ROOT} || mkdir ${DIST_ROOT}
|
||||
cd ${DIST_ROOT}
|
||||
|
||||
DMG_LICENCE=./../pkg/mac/licence.rtf
|
||||
DMG_VOLUME_NAME=${APP_NAME}
|
||||
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
DMG_IMAGE=${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
||||
echo "Checking out create-dmg..."
|
||||
git clone https://github.com/create-dmg/create-dmg.git "${BUILD_ROOT}/create-dmg"
|
||||
|
||||
DMG_DIR=./${DMG_IMAGE}.src
|
||||
|
||||
if test -e "${DMG_DIR}"; then
|
||||
echo "Directory ${DMG_DIR} already exists. Please delete it manually." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Cleaning up"
|
||||
rm -f "${DMG_IMAGE}"
|
||||
mkdir "${DMG_DIR}"
|
||||
|
||||
echo "Copying data into temporary directory"
|
||||
cp -R "${BUNDLE_DIR}" "${DMG_DIR}"
|
||||
|
||||
echo "Creating image"
|
||||
hdiutil create -quiet -srcfolder "$DMG_DIR" -fs HFS+ -format UDZO -volname "${DMG_VOLUME_NAME}" -ov "${DMG_IMAGE}"
|
||||
rm -rf "${DMG_DIR}"
|
||||
|
||||
echo Attaching License to image...
|
||||
python ${SCRIPT_DIR}/dmg-license.py "${DMG_IMAGE}" "${DMG_LICENCE}" -c bz2
|
||||
"${BUILD_ROOT}/create-dmg/create-dmg" \
|
||||
--volname "${APP_NAME}" \
|
||||
--volicon "${SCRIPT_DIR}/dmg-icon.icns" \
|
||||
--eula "${SCRIPT_DIR}/licence.rtf" \
|
||||
--background "${SCRIPT_DIR}/dmg-background.png" \
|
||||
--app-drop-link 600 220 \
|
||||
--icon "${APP_NAME}.app" 200 220 \
|
||||
--window-pos 200 120 \
|
||||
--window-size 800 400 \
|
||||
--hide-extension "${APP_NAME}.app" \
|
||||
--add-file .DS_Store "${SCRIPT_DIR}/dmg.DS_Store" 5 5 \
|
||||
--format UDBZ \
|
||||
--skip-jenkins \
|
||||
--no-internet-enable \
|
||||
"${DMG_NAME}" \
|
||||
"${BUNDLE_DIR}"
|
||||
}
|
||||
|
||||
_codesign_dmg() {
|
||||
@@ -366,21 +375,85 @@ _codesign_dmg() {
|
||||
return
|
||||
fi
|
||||
|
||||
DMG_VOLUME_NAME=${APP_NAME}
|
||||
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
DMG_IMAGE=${DIST_ROOT}/${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
||||
# Sign the .app
|
||||
echo Signing disk image...
|
||||
codesign --force --verify --verbose --timestamp \
|
||||
--options runtime \
|
||||
-i org.pgadmin.pgadmin4 \
|
||||
--sign "${DEVELOPER_ID}" \
|
||||
"${DMG_NAME}"
|
||||
}
|
||||
|
||||
if ! test -f "${DMG_IMAGE}" ; then
|
||||
echo "${DMG_IMAGE} is no disk image!" >&2
|
||||
|
||||
_notarize_pkg() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Notarize the package. Try three times, to allow for upload issues
|
||||
cmd_status=0
|
||||
for i in {1..3}; do
|
||||
echo "Uploading DMG for notarisation (attempt ${i} of 3)..."
|
||||
STATUS=$(xcrun altool --notarize-app \
|
||||
-f "${DMG_NAME}" \
|
||||
--asc-provider ${DEVELOPER_NAME} \
|
||||
--primary-bundle-id org.pgadmin.pgadmin4 \
|
||||
-u ${DEVELOPER_USER} \
|
||||
-p ${DEVELOPER_ASP} 2>&1)
|
||||
RETVAL=$?
|
||||
|
||||
if [ ${RETVAL} != 0 ]; then
|
||||
echo "Attempt ${i} failure: ${STATUS}"
|
||||
else
|
||||
# Success!
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
# print error if above command fails
|
||||
if [ ${RETVAL} != 0 ]; then
|
||||
echo "Notarization failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sign the .app
|
||||
echo Signing ${DMG_IMAGE}...
|
||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DMG_IMAGE}"
|
||||
# Get the request ID
|
||||
REQUEST_UUID=$(echo ${STATUS} | awk '/RequestUUID/ { print $NF; }')
|
||||
echo "Notarization request ID: ${REQUEST_UUID}"
|
||||
|
||||
# Verify it worked
|
||||
echo Verifying the signature...
|
||||
codesign --verify --verbose --force "${DMG_IMAGE}"
|
||||
echo ${DMG_IMAGE} successfully signed.
|
||||
# Now we need to wait for the results. Try 60 times.
|
||||
for i in {1..60}; do
|
||||
echo "Waiting 30 seconds..."
|
||||
sleep 30
|
||||
|
||||
echo "Requesting notarisation result (attempt ${i} of 60)..."
|
||||
REQUEST_STATUS=$(xcrun altool --notarization-info ${REQUEST_UUID} \
|
||||
--username ${DEVELOPER_USER} \
|
||||
--password ${DEVELOPER_ASP} 2>&1 | \
|
||||
awk -F ': ' '/Status:/ { print $2; }' )
|
||||
|
||||
if [[ "${REQUEST_STATUS}" == "success" ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Print status information
|
||||
xcrun altool --notarization-info ${REQUEST_UUID} \
|
||||
--username ${DEVELOPER_USER} \
|
||||
--password ${DEVELOPER_ASP}
|
||||
|
||||
if [[ "${REQUEST_STATUS}" != "success" ]]; then
|
||||
echo "Notarization failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Staple the notarization
|
||||
echo "Stapling the notarization to the pgAdmin DMG..."
|
||||
xcrun stapler staple "${DMG_NAME}"
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Stapling failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Notarization completed successfully."
|
||||
}
|
||||
@@ -12,57 +12,33 @@ trap 'if [ $? -ne 0 ]; then echo "\"${last_command}\" command filed with exit co
|
||||
SCRIPT_DIR=$(cd `dirname $0` && pwd)
|
||||
SOURCE_DIR=$(realpath ${SCRIPT_DIR}/../..)
|
||||
BUILD_ROOT=$(realpath ${SCRIPT_DIR}/../..)/mac-build
|
||||
TEMP_DIR=$(realpath ${SCRIPT_DIR}/../..)/mac-temp
|
||||
DIST_ROOT=$(realpath ${SCRIPT_DIR}/../..)/dist
|
||||
|
||||
if [ ! -f ${SCRIPT_DIR}/framework.conf ]; then
|
||||
echo
|
||||
echo "Error: pkg/mac/framework.conf not found!"
|
||||
echo "Copy pkg/mac/framework.conf.in to pkg/mac/framework.conf and edit as required for the current system."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CODESIGN=1
|
||||
if [ ! -f ${SCRIPT_DIR}/codesign.conf ]; then
|
||||
echo
|
||||
echo "******************************************************************"
|
||||
echo "* ${SCRIPT_DIR}/codesign.conf not found. NOT signing the binaries."
|
||||
echo "* pkg/mac/codesign.conf not found. NOT signing the binaries."
|
||||
echo "******************************************************************"
|
||||
echo
|
||||
CODESIGN=0
|
||||
sleep 5
|
||||
sleep 2
|
||||
else
|
||||
source ${SCRIPT_DIR}/codesign.conf
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_PYTHON_DIR}" == "x" ]; then
|
||||
echo "PGADMIN_PYTHON_DIR not set. Setting it to the default: /usr/local/python"
|
||||
export PGADMIN_PYTHON_DIR=/usr/local/python
|
||||
fi
|
||||
PYTHON_EXE=${PGADMIN_PYTHON_DIR}/bin/python3
|
||||
|
||||
# Check if Python is working and calculate PYTHON_VERSION
|
||||
if ${PYTHON_EXE} -V > /dev/null 2>&1; then
|
||||
PYTHON_VERSION=`${PYTHON_EXE} -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
|
||||
NOTARIZE=1
|
||||
if [ ! -f ${SCRIPT_DIR}/notarization.conf ]; then
|
||||
echo
|
||||
echo "******************************************************************"
|
||||
echo "* pkg/mac/notarization.conf not found. NOT notarizing the package."
|
||||
echo "******************************************************************"
|
||||
echo
|
||||
NOTARIZE=0
|
||||
sleep 2
|
||||
else
|
||||
echo "Error: Python installation missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${PYTHON_VERSION}" -gt "38" ] && [ "${PYTHON_VERSION}" -lt "34" ]; then
|
||||
echo "Python version not supported."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_QT_DIR}" == "x" ]; then
|
||||
echo "PGADMIN_QT_DIR not set. Setting it to the default: ~/Qt/5.13.2/clang_64"
|
||||
export PGADMIN_QT_DIR=~/Qt/5.13.2/clang_64
|
||||
fi
|
||||
|
||||
QMAKE=${PGADMIN_QT_DIR}/bin/qmake
|
||||
if ! ${QMAKE} --version > /dev/null 2>&1; then
|
||||
echo "Error: qmake not found. QT installation is not present or incomplete."
|
||||
exit 1
|
||||
source ${SCRIPT_DIR}/notarization.conf
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_POSTGRES_DIR}" == "x" ]; then
|
||||
@@ -70,16 +46,21 @@ if [ "x${PGADMIN_POSTGRES_DIR}" == "x" ]; then
|
||||
export PGADMIN_POSTGRES_DIR=/usr/local/pgsql
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_PYTHON_VERSION}" == "x" ]; then
|
||||
echo "PGADMIN_PYTHON_VERSION not set. Setting it to the default: 3.9.1"
|
||||
export PGADMIN_PYTHON_VERSION=3.9.1
|
||||
fi
|
||||
|
||||
source ${SCRIPT_DIR}/build-functions.sh
|
||||
|
||||
_setup_env
|
||||
_cleanup
|
||||
_create_venv
|
||||
_build_runtime
|
||||
_create_python_env
|
||||
_build_docs
|
||||
_complete_bundle
|
||||
_framework_config
|
||||
_codesign_binaries
|
||||
_codesign_bundle
|
||||
_create_dmg
|
||||
_codesign_dmg
|
||||
_notarize_pkg
|
||||
@@ -2,4 +2,4 @@
|
||||
# codesign.conf, and edit the values below to reflect your developer ID.
|
||||
|
||||
DEVELOPER_ID="Developer ID Application: My Name (12345ABCD)"
|
||||
DEVELOPER_BUNDLE_ID="Developer Bundle Identifier (pgadmin4-4)"
|
||||
|
||||
|
After Width: | Height: | Size: 701 KiB |
@@ -1,166 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
"""
|
||||
This script adds a license file to a DMG. Requires Xcode and a plain ascii text
|
||||
license file.
|
||||
Obviously only runs on a Mac.
|
||||
|
||||
Copyright (C) 2011-2013 Jared Hobbs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import optparse
|
||||
|
||||
|
||||
class Path(str):
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
os.unlink(self)
|
||||
|
||||
|
||||
def mktemp(dir=None, suffix=''):
|
||||
(fd, filename) = tempfile.mkstemp(dir=dir, suffix=suffix)
|
||||
os.close(fd)
|
||||
return Path(filename)
|
||||
|
||||
|
||||
def main(options, args):
|
||||
dmg_file, license_file = args
|
||||
with mktemp('.') as tmp_file:
|
||||
with open(tmp_file, 'w') as f:
|
||||
f.write("""data 'TMPL' (128, "LPic") {
|
||||
$"1344 6566 6175 6C74 204C 616E 6775 6167"
|
||||
$"6520 4944 4457 5244 0543 6F75 6E74 4F43"
|
||||
$"4E54 042A 2A2A 2A4C 5354 430B 7379 7320"
|
||||
$"6C61 6E67 2049 4444 5752 441E 6C6F 6361"
|
||||
$"6C20 7265 7320 4944 2028 6F66 6673 6574"
|
||||
$"2066 726F 6D20 3530 3030 4457 5244 1032"
|
||||
$"2D62 7974 6520 6C61 6E67 7561 6765 3F44"
|
||||
$"5752 4404 2A2A 2A2A 4C53 5445"
|
||||
};
|
||||
|
||||
data 'LPic' (5000) {
|
||||
$"0000 0002 0000 0000 0000 0000 0004 0000"
|
||||
};
|
||||
|
||||
data 'STR#' (5000, "English buttons") {
|
||||
$"0006 0D45 6E67 6C69 7368 2074 6573 7431"
|
||||
$"0541 6772 6565 0844 6973 6167 7265 6505"
|
||||
$"5072 696E 7407 5361 7665 2E2E 2E7A 4966"
|
||||
$"2079 6F75 2061 6772 6565 2077 6974 6820"
|
||||
$"7468 6520 7465 726D 7320 6F66 2074 6869"
|
||||
$"7320 6C69 6365 6E73 652C 2063 6C69 636B"
|
||||
$"2022 4167 7265 6522 2074 6F20 6163 6365"
|
||||
$"7373 2074 6865 2073 6F66 7477 6172 652E"
|
||||
$"2020 4966 2079 6F75 2064 6F20 6E6F 7420"
|
||||
$"6167 7265 652C 2070 7265 7373 2022 4469"
|
||||
$"7361 6772 6565 2E22"
|
||||
};
|
||||
|
||||
data 'STR#' (5002, "English") {
|
||||
$"0006 0745 6E67 6C69 7368 0541 6772 6565"
|
||||
$"0844 6973 6167 7265 6505 5072 696E 7407"
|
||||
$"5361 7665 2E2E 2E7B 4966 2079 6F75 2061"
|
||||
$"6772 6565 2077 6974 6820 7468 6520 7465"
|
||||
$"726D 7320 6F66 2074 6869 7320 6C69 6365"
|
||||
$"6E73 652C 2070 7265 7373 2022 4167 7265"
|
||||
$"6522 2074 6F20 696E 7374 616C 6C20 7468"
|
||||
$"6520 736F 6674 7761 7265 2E20 2049 6620"
|
||||
$"796F 7520 646F 206E 6F74 2061 6772 6565"
|
||||
$"2C20 7072 6573 7320 2244 6973 6167 7265"
|
||||
$"6522 2E"
|
||||
};\n\n""")
|
||||
with open(license_file, 'r') as lines:
|
||||
kind = 'RTF ' if license_file.lower().endswith('.rtf') \
|
||||
else 'TEXT'
|
||||
f.write('data \'%s\' (5000, "English") {\n' % kind)
|
||||
|
||||
def escape(s):
|
||||
return s.strip().replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
for line in lines:
|
||||
if len(line) < 1000:
|
||||
f.write(' "' + escape(line) + '\\n"\n')
|
||||
else:
|
||||
for liner in line.split('.'):
|
||||
f.write(' "' + escape(liner) + '. \\n"\n')
|
||||
f.write('};\n\n')
|
||||
f.write("""data 'styl' (5000, "English") {
|
||||
$"0003 0000 0000 000C 0009 0014 0000 0000"
|
||||
$"0000 0000 0000 0000 0027 000C 0009 0014"
|
||||
$"0100 0000 0000 0000 0000 0000 002A 000C"
|
||||
$"0009 0014 0000 0000 0000 0000 0000"
|
||||
};\n""")
|
||||
os.system('hdiutil unflatten -quiet "%s"' % dmg_file)
|
||||
ret = os.system('%s -a %s -o "%s"' %
|
||||
(options.rez, tmp_file, dmg_file))
|
||||
os.system('hdiutil flatten -quiet "%s"' % dmg_file)
|
||||
if options.compression is not None:
|
||||
os.system('cp %s %s.temp.dmg' % (dmg_file, dmg_file))
|
||||
os.remove(dmg_file)
|
||||
if options.compression == "bz2":
|
||||
os.system('hdiutil convert %s.temp.dmg -format UDBZ -o %s' %
|
||||
(dmg_file, dmg_file))
|
||||
elif options.compression == "gz":
|
||||
os.system('hdiutil convert %s.temp.dmg -format ' % dmg_file +
|
||||
'UDZO -imagekey zlib-devel=9 -o %s' % dmg_file)
|
||||
os.remove('%s.temp.dmg' % dmg_file)
|
||||
if ret == 0:
|
||||
print("Successfully added license to '%s'" % dmg_file)
|
||||
else:
|
||||
print("Failed to add license to '%s'" % dmg_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser()
|
||||
parser.set_usage("""%prog <dmgFile> <licenseFile> [OPTIONS]
|
||||
This program adds a software license agreement to a DMG file.
|
||||
It requires Xcode and either a plain ascii text <licenseFile>
|
||||
or a <licenseFile.rtf> with the RTF contents.
|
||||
|
||||
See --help for more details.""")
|
||||
parser.add_option(
|
||||
'--rez',
|
||||
'-r',
|
||||
action='store',
|
||||
default='/Applications/Xcode.app/Contents/Developer/Tools/Rez',
|
||||
help='The path to the Rez tool. Defaults to %default'
|
||||
)
|
||||
parser.add_option(
|
||||
'--compression',
|
||||
'-c',
|
||||
action='store',
|
||||
choices=['bz2', 'gz'],
|
||||
default=None,
|
||||
help='Optionally compress dmg using specified compression type. '
|
||||
'Choices are bz2 and gz.'
|
||||
)
|
||||
options, args = parser.parse_args()
|
||||
cond = len(args) != 2
|
||||
if not os.path.exists(options.rez):
|
||||
print('Failed to find Rez at "%s"!\n' % options.rez)
|
||||
cond = True
|
||||
if cond:
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
main(options, args)
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<string>%TEAMID%.org.pgadmin.pgadmin4</string>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,10 +0,0 @@
|
||||
# Copy this file to framework.conf, and edit the values below to reflect your
|
||||
# environment (versions of Python/Qt used)
|
||||
|
||||
PYTHON_SHORT_VERSION=3.8
|
||||
PYTHON_FULL_VERSION=3.8.2
|
||||
|
||||
QT_SHORT_VERSION=5.14
|
||||
QT_FULL_VERSION=5.14.2
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
\fs22 \
|
||||
\
|
||||
|
||||
\f1\i Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
\f1\i Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
\f0\i0 \
|
||||
\
|
||||
Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.\
|
||||
\
|
||||
IN NO EVENT SHALL THE PGADMIN DEVELOPMENT TEAM BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE PGADMIN DEVELOPMENT TEAM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\
|
||||
\
|
||||
THE PGADMIN DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE PGADMIN DEVELOPMENT TEAM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.}
|
||||
THE PGADMIN DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE PGADMIN DEVELOPMENT TEAM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.}
|
||||
@@ -0,0 +1,12 @@
|
||||
# In order to enable notarization of the Mac Appbundle, copy this file to
|
||||
# notarization.conf, and edit the values below to reflect your Apple
|
||||
# Developer User ID, app-specific password and Provider Shortname.
|
||||
#
|
||||
# You can use the following command to see the available shortnames for your
|
||||
# Apple Developer ID (substituting the appropriate username/password):
|
||||
#
|
||||
# xcrun altool --list-providers -u "APPLE_DEVELOPER_USERNAME" -p "APP_SPECIFIC_PASSWORD"
|
||||
|
||||
DEVELOPER_USER=user@example.com
|
||||
DEVELOPER_ASP=1234-abcd-5678-efgh
|
||||
DEVELOPER_NAME=MyCompany
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>pgAdmin4</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>pgAdmin4 PGADMIN_LONG_VERSION</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>pgAdmin4.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.postgresql.pgadmin</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>PGADMIN_SHORT_VERSION</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>PGADMIN_LONG_VERSION</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2020, The pgAdmin Development Team
|
||||
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
@@ -32,18 +32,26 @@ builtins.SERVER_MODE = None
|
||||
req_file = '../requirements.txt'
|
||||
|
||||
with open(req_file, 'r') as req_lines:
|
||||
requires = req_lines.read().splitlines()
|
||||
all_requires = req_lines.read().splitlines()
|
||||
|
||||
requires = []
|
||||
extras_require = {}
|
||||
# Remove any requirements with environment specifiers. These
|
||||
# must be explicitly listed in extras_require below.
|
||||
for index, req in enumerate(requires):
|
||||
for index, req in enumerate(all_requires):
|
||||
if ";" in req or req.startswith("#") or req == "":
|
||||
requires.remove(req)
|
||||
# Add the pkgs to extras_require
|
||||
if ";" in req:
|
||||
pkg, env_spec = req.split(";")
|
||||
extras_require[env_spec] = extras_require.get(env_spec, [])
|
||||
extras_require[env_spec].append(pkg)
|
||||
continue
|
||||
|
||||
# Ensure the Wheel will use psycopg2-binary, not the source distro
|
||||
if 'psycopg2' in req:
|
||||
requires[index] = req.replace('psycopg2', 'psycopg2-binary')
|
||||
req = req.replace('psycopg2', 'psycopg2-binary')
|
||||
|
||||
requires.append(req)
|
||||
|
||||
# Get the version
|
||||
config = load_source('APP_VERSION', '../web/config.py')
|
||||
@@ -84,6 +92,8 @@ setup(
|
||||
|
||||
install_requires=requires,
|
||||
|
||||
extras_require=extras_require,
|
||||
|
||||
entry_points={
|
||||
'console_scripts': ['pgadmin4=pgadmin4.pgAdmin4:main'],
|
||||
},
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
This directory contains the build runner script for creating .RPM packages for
|
||||
Redhat distributions.
|
||||
|
||||
Supported platforms
|
||||
===================
|
||||
|
||||
Fedora 30, 31 & 32
|
||||
RHEL/CentOS 7 & 8
|
||||
|
||||
Build configuration
|
||||
===================
|
||||
|
||||
To build RPM packages, first run the setup.sh script as root to install the
|
||||
required pre-requisites, e.g.
|
||||
|
||||
# pkg/redhat/setup.sh
|
||||
|
||||
Building packages
|
||||
=================
|
||||
|
||||
To build a set of packages, from the top-level source directory run:
|
||||
|
||||
$ make redhat
|
||||
|
||||
or
|
||||
|
||||
$ pkg/redhat/build.sh
|
||||
|
||||
Four .rpm packages will be created in the dist/ directory:
|
||||
|
||||
pgadmin4-<version>.<distro>_noarch.rpm
|
||||
A convenience package that depends on all the others.
|
||||
|
||||
pgadmin4-server-<version>.<distro>.<arch>.rpm
|
||||
The core server, e.g. the Python and JS code and the online documentation.
|
||||
|
||||
pgadmin4-desktop-<version>.<distro>.<arch>.rpm
|
||||
The desktop runtime. Requires the server package.
|
||||
|
||||
pgadmin4-web-<version>.<distro>.<arch>.rpm
|
||||
The server mode setup script for configuring Apache HTTPD. Requires the
|
||||
server package.
|
||||
|
||||
pgadmin4-python3-mod_wsgi-4.7.1-2.el7.<arch>.rpm
|
||||
The Python 3 build of mod_wsgi for the Apache HTTPD server. Only built
|
||||
on RHEL/CentOS 7.
|
||||
|
||||
Signing Packages
|
||||
================
|
||||
|
||||
It is good practice to sign RPMs to prove their provenance. The build scripts
|
||||
included in this directory do NOT do that; doing so is done using a Jenkins
|
||||
task in the pgAdmin buildfarm.
|
||||
|
||||
If you want to sign your own RPMs, you'll first need to ensure that the
|
||||
gnupg2 and rpmsign tools are available on your system.
|
||||
|
||||
Then, create a .rpmmacros file in the home directory of the user account that
|
||||
will be doing the signing. On Fedora 30 and later, and RHEL/CentOS 8 and later,
|
||||
that should contain the following contents (without the start/end markers).
|
||||
Replace <your signing key> with the email address in your key:
|
||||
|
||||
---------
|
||||
%_signature gpg
|
||||
%_gpg_path ~/.gnupg
|
||||
%_gpg_name <your signing key>
|
||||
%_gpgbin /usr/bin/gpg2
|
||||
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename
|
||||
} --digest-algo sha256 %{__plaintext_filename}
|
||||
---------
|
||||
|
||||
On RHEL/CentOS 7, the .rpmmacros file should look like this:
|
||||
|
||||
---------
|
||||
%_signature gpg
|
||||
%_gpg_path ~/.gnupg
|
||||
%_gpg_name Package Manager
|
||||
%_gpgbin /usr/bin/gpg2
|
||||
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" -sbo %{__
|
||||
signature_filename} --digest-algo sha256 %{__plaintext_filename}
|
||||
---------
|
||||
|
||||
Note that these configurations are designed for automated signing in a CI/CD
|
||||
system. You may need to adjust them to handle passphrases on keys in your own
|
||||
environment.
|
||||
|
||||
You also need to import your signing private key into the gnupg2 keystore, for
|
||||
example:
|
||||
|
||||
gpg --import signing_key.priv
|
||||
|
||||
Once everything is setup, RPMs can be signed easily; for example:
|
||||
|
||||
rpmsign --addsign dist/*.rpm
|
||||
|
||||
Building a repo
|
||||
===============
|
||||
|
||||
A Yum repo can be created by building RPMs for the required platforms, moving
|
||||
them into the required directory structure, and then running the createrepo tool
|
||||
over that directory. The pgAdmin repos use the following structure:
|
||||
|
||||
<root>
|
||||
redhat/
|
||||
rhel-7-x86_64/
|
||||
pgadmin4-4.21-1.el7.noarch.rpm
|
||||
pgadmin4-desktop-4.21-1.el7.x86_64.rpm
|
||||
pgadmin4-python3-mod_wsgi-4.7.1-2.el7.x86_64.rpm
|
||||
pgadmin4-server-4.21-1.el7.x86_64.rpm
|
||||
pgadmin4-web-4.21-1.el7.noarch.rpm
|
||||
rhel-8-x86_64/
|
||||
<...>
|
||||
fedora/
|
||||
<...>
|
||||
pgadmin4-fedora-repo-1-1.noarch.rpm
|
||||
pgadmin4-redhat-repo-1-1.noarch.rpm
|
||||
README
|
||||
|
||||
Note that only the first branches are shown above; other branches (e.g. for
|
||||
Fedora and RHEL 8 follow the structure shown for RHEL 7.
|
||||
|
||||
Technically there are multiple different repos, one for each platform and
|
||||
architecture. The metadata can be created for each as follows:
|
||||
|
||||
/usr/bin/createrepo <root>/redhat/rhel-7-x86_64
|
||||
/usr/bin/createrepo <root>/redhat/rhel-8-x86_64
|
||||
...
|
||||
|
||||
Repository RPMs
|
||||
===============
|
||||
|
||||
A script is provided for the creation of repo RPMs. It will create RPMs that
|
||||
install the required Yum configuration file and the public signing key for
|
||||
pgAdmin (you may want to replace the contents of PGADMIN_PKG_KEY with your own
|
||||
public key):
|
||||
|
||||
./repo-rpms.sh
|
||||
|
||||
Set the PGADMIN_REPO_DIR environment variable to define the repository root
|
||||
from the client's perspective. Given the example above, you might do:
|
||||
|
||||
PGADMIN_REPO_DIR=https://yum.company.com/repos/<root> ./repo-rpms.sh
|
||||
@@ -0,0 +1,138 @@
|
||||
# pgAdmin Redhat Builds
|
||||
|
||||
This directory contains the build runner script for creating .RPM packages for
|
||||
Redhat distributions.
|
||||
|
||||
## Supported platforms
|
||||
|
||||
* Fedora 30, 31 & 32
|
||||
* RHEL/CentOS 7 & 8
|
||||
|
||||
## Build configuration
|
||||
|
||||
To build RPM packages, first run the setup.sh script as root to install the
|
||||
required pre-requisites, e.g.
|
||||
|
||||
# pkg/redhat/setup.sh
|
||||
|
||||
# Building packages
|
||||
|
||||
To build a set of packages, from the top-level source directory run:
|
||||
|
||||
$ make redhat
|
||||
|
||||
or
|
||||
|
||||
$ pkg/redhat/build.sh
|
||||
|
||||
Four (or five) .rpm packages will be created in the dist/ directory:
|
||||
|
||||
*pgadmin4-<version>.<distro>_noarch.rpm*
|
||||
|
||||
A convenience package that depends on all the others.
|
||||
|
||||
*pgadmin4-server-<version>.<distro>.<arch>.rpm*
|
||||
|
||||
The core server, e.g. the Python and JS code and the online documentation.
|
||||
|
||||
*pgadmin4-desktop-<version>.<distro>.<arch>.rpm*
|
||||
|
||||
The desktop runtime. Requires the server package.
|
||||
|
||||
*pgadmin4-web-<version>.<distro>.<arch>.rpm*
|
||||
|
||||
The server mode setup script for configuring Apache HTTPD. Requires the server
|
||||
package.
|
||||
|
||||
*pgadmin4-python3-mod_wsgi-4.7.1-2.el7.<arch>.rpm*
|
||||
|
||||
The Python 3 build of mod_wsgi for the Apache HTTPD server. Only built on
|
||||
RHEL/CentOS 7.
|
||||
|
||||
## Signing Packages
|
||||
|
||||
It is good practice to sign RPMs to prove their provenance. The build scripts
|
||||
included in this directory do NOT do that; doing so is done using a Jenkins
|
||||
task in the pgAdmin buildfarm.
|
||||
|
||||
If you want to sign your own RPMs, you'll first need to ensure that the
|
||||
*gnupg2* and *rpmsign* tools are available on your system.
|
||||
|
||||
Then, create a *.rpmmacros* file in the home directory of the user account that
|
||||
will be doing the signing. On Fedora 30 and later, and RHEL/CentOS 8 and later,
|
||||
that should contain the following contents (without the start/end markers).
|
||||
Replace <your signing key> with the email address in your key:
|
||||
|
||||
%_signature gpg
|
||||
%_gpg_path ~/.gnupg
|
||||
%_gpg_name <your signing key>
|
||||
%_gpgbin /usr/bin/gpg2
|
||||
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename} --digest-algo sha256 %{__plaintext_filename}
|
||||
|
||||
On RHEL/CentOS 7, the .rpmmacros file should look like this:
|
||||
|
||||
%_signature gpg
|
||||
%_gpg_path ~/.gnupg
|
||||
%_gpg_name Package Manager
|
||||
%_gpgbin /usr/bin/gpg2
|
||||
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" -sbo %{__
|
||||
signature_filename} --digest-algo sha256 %{__plaintext_filename}
|
||||
|
||||
Note that these configurations are designed for automated signing in a CI/CD
|
||||
system. You may need to adjust them to handle passphrases on keys in your own
|
||||
environment.
|
||||
|
||||
You also need to import your signing private key into the gnupg2 keystore, for
|
||||
example:
|
||||
|
||||
gpg --import signing_key.priv
|
||||
|
||||
Once everything is setup, RPMs can be signed easily; for example:
|
||||
|
||||
rpmsign --addsign dist/*.rpm
|
||||
|
||||
## Building a repo
|
||||
|
||||
A Yum repo can be created by building RPMs for the required platforms, moving
|
||||
them into the required directory structure, and then running the *createrepo*
|
||||
tool over that directory. The pgAdmin repos use the following structure:
|
||||
|
||||
<root>
|
||||
redhat/
|
||||
rhel-7-x86_64/
|
||||
pgadmin4-4.21-1.el7.noarch.rpm
|
||||
pgadmin4-desktop-4.21-1.el7.x86_64.rpm
|
||||
pgadmin4-python3-mod_wsgi-4.7.1-2.el7.x86_64.rpm
|
||||
pgadmin4-server-4.21-1.el7.x86_64.rpm
|
||||
pgadmin4-web-4.21-1.el7.noarch.rpm
|
||||
rhel-8-x86_64/
|
||||
<...>
|
||||
fedora/
|
||||
<...>
|
||||
pgadmin4-fedora-repo-1-1.noarch.rpm
|
||||
pgadmin4-redhat-repo-1-1.noarch.rpm
|
||||
README
|
||||
|
||||
Note that only the first branches are shown above; other branches (e.g. for
|
||||
Fedora and RHEL 8 follow the structure shown for RHEL 7.
|
||||
|
||||
Technically there are multiple different repos, one for each platform and
|
||||
architecture. The metadata can be created for each as follows:
|
||||
|
||||
/usr/bin/createrepo <root>/redhat/rhel-7-x86_64
|
||||
/usr/bin/createrepo <root>/redhat/rhel-8-x86_64
|
||||
...
|
||||
|
||||
## Repository RPMs
|
||||
|
||||
A script is provided for the creation of repo RPMs. It will create RPMs that
|
||||
install the required Yum configuration file and the public signing key for
|
||||
pgAdmin (you may want to replace the contents of *PGADMIN_PKG_KEY* with your own
|
||||
public key):
|
||||
|
||||
./repo-rpms.sh
|
||||
|
||||
Set the *PGADMIN_REPO_DIR* environment variable to define the repository root
|
||||
from the client's perspective. Given the example above, you might do:
|
||||
|
||||
PGADMIN_REPO_DIR=https://yum.company.com/repos/<root> ./repo-rpms.sh
|
||||