Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d9dfe7d04 | ||
|
|
2b00480605 | ||
|
|
a2a18d4b4a | ||
|
|
e2b00dda1b | ||
|
|
bfabcea6e9 | ||
|
|
05d3633cdf | ||
|
|
5a5da5f720 | ||
|
|
a87c07df93 | ||
|
|
d38d0ce805 | ||
|
|
04b1e26041 | ||
|
|
769f58970e | ||
|
|
9ac233f244 | ||
|
|
985546fff6 | ||
|
|
01a9a41bd9 | ||
|
|
0cb00c7b4f | ||
|
|
40e0175ee5 | ||
|
|
16bcb7d4a2 | ||
|
|
2de965d710 | ||
|
|
ab5d53f3b1 | ||
|
|
eb60b3892d | ||
|
|
703cefd9ae | ||
|
|
1bff94d0ea | ||
|
|
93f5fbc797 | ||
|
|
76a6feb2e7 | ||
|
|
ca8b5c68fd | ||
|
|
b128ba2f57 | ||
|
|
43022b7aa2 | ||
|
|
cbf5886430 | ||
|
|
d967d5046d | ||
|
|
3b95a416ca | ||
|
|
ec47a2aa66 | ||
|
|
b73aa6d000 | ||
|
|
b8f63adf41 | ||
|
|
7086719640 | ||
|
|
603ce21d24 | ||
|
|
0c9c57e608 | ||
|
|
18b77f15dd | ||
|
|
e1942d8c9e | ||
|
|
ad59380676 | ||
|
|
0f46f070ed | ||
|
|
1d0ac0f7dc | ||
|
|
71c962f51c | ||
|
|
7c729d5f0e | ||
|
|
317a17337d | ||
|
|
9a317f3ba6 | ||
|
|
5625fe0969 | ||
|
|
72f819ec67 | ||
|
|
e58b9c767b | ||
|
|
71a4b20d90 | ||
|
|
af1e9210b9 | ||
|
|
fe0577be5f | ||
|
|
37082a955b | ||
|
|
92741680b5 | ||
|
|
bbef9acaf6 | ||
|
|
f48a3c7dcb | ||
|
|
a84118823e | ||
|
|
78757564c8 | ||
|
|
41a3345101 | ||
|
|
6b6efd1c4d | ||
|
|
d53f2b69f2 | ||
|
|
5c04f1aa2e | ||
|
|
2de89dcaaf | ||
|
|
f2cc897f2f | ||
|
|
56e2c9db97 | ||
|
|
8ca8cb9409 | ||
|
|
0d518a5cb6 | ||
|
|
0f53fc8511 | ||
|
|
d7307fd334 | ||
|
|
ee1f97d124 | ||
|
|
09e2c0eac0 | ||
|
|
f873ab5374 | ||
|
|
8bcd1e4e60 | ||
|
|
e455114441 | ||
|
|
306b184e11 | ||
|
|
c8ef4733d0 | ||
|
|
71647c886d | ||
|
|
3583b094d0 | ||
|
|
da927f4897 | ||
|
|
f771d3a4bb | ||
|
|
d4fdd4601e | ||
|
|
b12c1f8740 | ||
|
|
ef91207669 | ||
|
|
d45072fae5 | ||
|
|
ff4c5392d6 | ||
|
|
485265979e | ||
|
|
88a443f73d | ||
|
|
2d27a97b8c | ||
|
|
06d454473c | ||
|
|
ae5254e8a9 | ||
|
|
1e94c3bd81 | ||
|
|
6179b216c5 | ||
|
|
76f581289c | ||
|
|
7bd0d55c83 | ||
|
|
084203debc | ||
|
|
b34078c6d2 | ||
|
|
b6765e00eb | ||
|
|
2567ed5784 | ||
|
|
3cffcc8f5b | ||
|
|
b4e5717bde | ||
|
|
9a7859c5cb | ||
|
|
e1fa1b0396 | ||
|
|
c2b23465cc | ||
|
|
271b6d91fc | ||
|
|
3766fa7f0b | ||
|
|
626681c5ba | ||
|
|
9c9fb293da | ||
|
|
2bc60c9142 | ||
|
|
0f11033989 | ||
|
|
c0c4524ec3 | ||
|
|
8b7ce2c276 | ||
|
|
5e4d3cc535 | ||
|
|
f6e7221359 | ||
|
|
d7ad375232 | ||
|
|
9c418188ee | ||
|
|
b69af1341b | ||
|
|
233652c3f1 | ||
|
|
923f2fc7c4 | ||
|
|
f5793e9a7a | ||
|
|
f96653e9af | ||
|
|
8c24d28740 | ||
|
|
d1c94ac73d | ||
|
|
fa6b77b42c | ||
|
|
4c6e7d4f4f | ||
|
|
53887c32bf | ||
|
|
060d7ba46b | ||
|
|
5877b49f64 | ||
|
|
352eb15dc7 | ||
|
|
66a1123268 | ||
|
|
95312f2d14 | ||
|
|
6145dc76fc | ||
|
|
526ee51485 | ||
|
|
1dab98c6a0 | ||
|
|
7e46e46080 | ||
|
|
81b0d1138b | ||
|
|
81f52a82c8 |
No files matched your search
@@ -23,18 +23,18 @@ Python Dependencies
|
||||
|
||||
Name Version Licence URL
|
||||
---- ------- ------- ---
|
||||
Flask 2.1.1 BSD-3-Clause https://palletsprojects.com/p/flask
|
||||
Flask 2.1.3 BSD-3-Clause https://palletsprojects.com/p/flask
|
||||
Flask-Gravatar 0.5.0 BSD https://github.com/zzzsochi/Flask-Gravatar/
|
||||
Flask-Login 0.6.0 MIT https://github.com/maxcountryman/flask-login
|
||||
Flask-Login 0.6.2 MIT https://github.com/maxcountryman/flask-login
|
||||
Flask-Mail 0.9.1 BSD https://github.com/rduplain/flask-mail
|
||||
Flask-Migrate 3.1.0 UNKNOWN https://github.com/miguelgrinberg/flask-migrate
|
||||
Flask-SQLAlchemy 2.5.1 BSD-3-Clause https://github.com/pallets/flask-sqlalchemy
|
||||
Flask-WTF 1.0.1 BSD-3-Clause https://github.com/wtforms/flask-wtf/
|
||||
Flask-Compress 1.11 MIT https://github.com/colour-science/flask-compress
|
||||
Flask-Compress 1.12 MIT https://github.com/colour-science/flask-compress
|
||||
Flask-Paranoid 0.3.0 UNKNOWN https://github.com/miguelgrinberg/flask-paranoid
|
||||
Flask-Babel 2.0.0 BSD http://github.com/python-babel/flask-babel
|
||||
Flask-Security-Too 4.1.4 MIT https://github.com/Flask-Middleware/flask-security
|
||||
Flask-SocketIO 5.1.1 UNKNOWN https://github.com/miguelgrinberg/flask-socketio
|
||||
Flask-Security-Too 4.1.5 MIT https://github.com/Flask-Middleware/flask-security
|
||||
Flask-SocketIO 5.2.0 Unknown https://github.com/miguelgrinberg/flask-socketio
|
||||
WTForms 3.0.1 BSD-3-Clause https://wtforms.readthedocs.io/
|
||||
passlib 1.7.4 BSD https://passlib.readthedocs.io
|
||||
pytz 2021.3 MIT http://pythonhosted.org/pytz
|
||||
@@ -42,28 +42,28 @@ simplejson 3.17.6
|
||||
six 1.16.0 MIT https://github.com/benjaminp/six
|
||||
speaklater3 1.4 UNKNOWN https://github.com/ThomasWaldmann/speaklater
|
||||
sqlparse 0.4.2 BSD-3-Clause https://github.com/andialbrecht/sqlparse
|
||||
psutil 5.9.0 BSD https://github.com/giampaolo/psutil
|
||||
psutil 5.9.1 BSD https://github.com/giampaolo/psutil
|
||||
psycopg2 2.9.3 LGPL with exceptions https://psycopg.org/
|
||||
python-dateutil 2.8.2 Dual License https://github.com/dateutil/dateutil
|
||||
SQLAlchemy 1.4.35 MIT https://www.sqlalchemy.org
|
||||
bcrypt 3.2.0 Apache License, Version 2.0 https://github.com/pyca/bcrypt/
|
||||
SQLAlchemy 1.4.40 MIT https://www.sqlalchemy.org
|
||||
bcrypt 3.2.2 Apache License, Version 2.0 https://github.com/pyca/bcrypt/
|
||||
cryptography 3.4.8 BSD or Apache License, Version 2.0 https://github.com/pyca/cryptography
|
||||
sshtunnel 0.4.0 MIT https://github.com/pahaz/sshtunnel
|
||||
ldap3 2.9.1 LGPL v3 https://github.com/cannatag/ldap3
|
||||
gssapi 1.7.3 LICENSE.txt https://github.com/pythongssapi/python-gssapi
|
||||
eventlet 0.33.0 UNKNOWN http://eventlet.net
|
||||
httpagentparser 1.9.2 http://www.opensource.org/licenses/mit-license.php https://github.com/shon/httpagentparser
|
||||
httpagentparser 1.9.3 http://www.opensource.org/licenses/mit-license.php https://github.com/shon/httpagentparser
|
||||
user-agents 2.2.0 MIT https://github.com/selwin/python-user-agents
|
||||
pywinpty 1.1.* Unknown Unknown
|
||||
Authlib 0.15.5 BSD-3-Clause https://authlib.org/
|
||||
requests 2.25.1 Apache 2.0 https://requests.readthedocs.io
|
||||
pyotp 2.6.0 MIT License https://github.com/pyotp/pyotp
|
||||
qrcode 7.3.1 BSD https://github.com/lincolnloop/python-qrcode
|
||||
Pillow 9.1.0 HPND https://python-pillow.org
|
||||
Pillow 9.2.0 HPND https://python-pillow.org
|
||||
boto3 1.20.54 Apache License 2.0 https://github.com/boto/boto3
|
||||
botocore 1.23.54 Apache License 2.0 https://github.com/boto/botocore
|
||||
urllib3 1.26.9 MIT https://urllib3.readthedocs.io/
|
||||
Werkzeug 2.0.3 BSD-3-Clause https://palletsprojects.com/p/werkzeug/
|
||||
urllib3 1.26.11 MIT https://urllib3.readthedocs.io/
|
||||
Werkzeug 2.1.2 BSD-3-Clause https://palletsprojects.com/p/werkzeug/
|
||||
azure-mgmt-rdbms 10.1.0 MIT License https://github.com/Azure/azure-sdk-for-python
|
||||
azure-mgmt-resource 21.0.0 MIT License https://github.com/Azure/azure-sdk-for-python
|
||||
azure-mgmt-subscription 3.0.0 MIT License https://github.com/Azure/azure-sdk-for-python
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# and clean up the web/ source code
|
||||
#########################################################################
|
||||
|
||||
FROM alpine:3.15 AS app-builder
|
||||
FROM alpine:3.16 AS app-builder
|
||||
|
||||
RUN apk add --no-cache \
|
||||
autoconf \
|
||||
@@ -60,7 +60,7 @@ RUN export CPPFLAGS="-DPNG_ARM_NEON_OPT=0" && \
|
||||
# Next, create the base environment for Python
|
||||
#########################################################################
|
||||
|
||||
FROM alpine:3.15 as env-builder
|
||||
FROM alpine:3.16 as env-builder
|
||||
|
||||
# Install dependencies
|
||||
COPY requirements.txt /
|
||||
@@ -117,7 +117,7 @@ FROM postgres:12-alpine as pg12-builder
|
||||
FROM postgres:13-alpine as pg13-builder
|
||||
FROM postgres:14-alpine as pg14-builder
|
||||
|
||||
FROM alpine:3.15 as tool-builder
|
||||
FROM alpine:3.16 as tool-builder
|
||||
|
||||
# Copy the PG binaries
|
||||
COPY --from=pg10-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-10/
|
||||
@@ -149,7 +149,7 @@ COPY --from=pg14-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-14/
|
||||
# Assemble everything into the final container.
|
||||
#########################################################################
|
||||
|
||||
FROM alpine:3.15
|
||||
FROM alpine:3.16
|
||||
|
||||
# Copy in the Python packages
|
||||
COPY --from=env-builder /venv /venv
|
||||
@@ -196,7 +196,7 @@ RUN apk add \
|
||||
chown pgadmin:root /pgadmin4/config_distro.py && \
|
||||
chmod g=u /pgadmin4/config_distro.py && \
|
||||
chmod g=u /etc/passwd && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/python3.9 && \
|
||||
setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/python3.10 && \
|
||||
echo "pgadmin ALL = NOPASSWD: /usr/sbin/postfix start" > /etc/sudoers.d/postfix && \
|
||||
echo "pgadminr ALL = NOPASSWD: /usr/sbin/postfix start" >> /etc/sudoers.d/postfix
|
||||
|
||||
|
||||
@@ -263,15 +263,12 @@ See https://www.pgadmin.org/support/ for support options.
|
||||
|
||||
# Project info
|
||||
|
||||
The source code repository can be found here:
|
||||
A GitHub project for pgAdmin 4 can be found at the address below:
|
||||
|
||||
http://git.postgresql.org/gitweb/?p=pgadmin4.git;a=summary
|
||||
https://github.com/pgadmin-org/pgadmin4
|
||||
|
||||
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
|
||||
**NOTE:** The repository on GitHub is a clone of the main project repository.
|
||||
Please do not submit pull requests!
|
||||
|
||||
If you wish to discuss pgAdmin 4, or contribute to the project, please use the
|
||||
pgAdmin Hackers mailing list:
|
||||
|
||||
@@ -203,21 +203,6 @@ command:
|
||||
|
||||
* Click the *Cancel* button to exit without saving work.
|
||||
|
||||
.. image:: images/backup_messages.png
|
||||
:alt: Backup success notification popup
|
||||
:align: center
|
||||
|
||||
Use the **Stop Process** button to stop the Backup process.
|
||||
|
||||
If the backup is successful, a popup window will confirm success. Click *More details* on the popup window to launch the *Process Watcher*. The *Process Watcher* logs all the activity associated with the backup and provides additional information for troubleshooting.
|
||||
|
||||
.. image:: images/backup_process_watcher.png
|
||||
:alt: Backup process watcher
|
||||
:align: center
|
||||
|
||||
If the backup is unsuccessful, you can review the error messages returned by the
|
||||
backup command on the *Process Watcher*.
|
||||
|
||||
.. note:: If you are running *pgAdmin* in *Server Mode* you can click on the |sm_icon| icon in the process watcher window to open the file location in the Storage Manager. You can use the :ref:`Storage Manager <storage_manager>` to download the backup file on the client machine .
|
||||
|
||||
.. |sm_icon| image:: images/sm_icon.png
|
||||
pgAdmin will run the backup process in background. You can view all the background
|
||||
process with there running status and logs on the :ref:`Processes <processes>`
|
||||
tab
|
||||
@@ -34,24 +34,6 @@ statements that should be included in the backup.
|
||||
Click the *Backup* button to build and execute a command based on your
|
||||
selections; click the *Cancel* button to exit without saving work.
|
||||
|
||||
.. image:: images/backup_globals_messages.png
|
||||
:alt: Backup globals success notification popup
|
||||
:align: center
|
||||
|
||||
Use the **Stop Process** button to stop the Backup process.
|
||||
|
||||
If the backup is successful, a popup window will confirm success. Click *Click
|
||||
here for details* on the popup window to launch the *Process Watcher*. The
|
||||
*Process Watcher* logs all the activity associated with the backup and provides
|
||||
additional information for troubleshooting.
|
||||
|
||||
.. image:: images/backup_globals_process_watcher.png
|
||||
:alt: Backup globals process watcher
|
||||
:align: center
|
||||
|
||||
If the backup is unsuccessful, review the error message returned by the
|
||||
*Process Watcher* to resolve any issue.
|
||||
|
||||
.. note:: If you are running *pgAdmin* in *Server Mode* you can click on the |sm_icon| icon in the process watcher window to open the file location in the Storage Manager. You can use the :ref:`Storage Manager <storage_manager>` to download the backup file on the client machine .
|
||||
|
||||
.. |sm_icon| image:: images/sm_icon.png
|
||||
pgAdmin will run the backup process in background. You can view all the background
|
||||
process with there running status and logs on the :ref:`Processes <processes>`
|
||||
tab
|
||||
@@ -122,24 +122,6 @@ tab to provide options related to data or pgAdmin objects that correspond to *pg
|
||||
Click the *Backup* button to build and execute a command based on your
|
||||
selections; click the *Cancel* button to exit without saving work.
|
||||
|
||||
.. image:: images/backup_server_messages.png
|
||||
:alt: Backup server success notification popup
|
||||
:align: center
|
||||
|
||||
Use the **Stop Process** button to stop the Backup process.
|
||||
|
||||
If the backup is successful, a popup window will confirm success. Click *Click
|
||||
here for details* on the popup window to launch the *Process Watcher*. The
|
||||
*Process Watcher* logs all the activity associated with the backup and provides
|
||||
additional information for troubleshooting.
|
||||
|
||||
.. image:: images/backup_server_process_watcher.png
|
||||
:alt: Backup server process watcher
|
||||
:align: center
|
||||
|
||||
If the backup is unsuccessful, review the error message returned by the
|
||||
*Process Watcher* to resolve any issue.
|
||||
|
||||
.. note:: If you are running *pgAdmin* in *Server Mode* you can click on the |sm_icon| icon in the process watcher window to open the file location in the Storage Manager. You can use the :ref:`Storage Manager <storage_manager>` to download the backup file on the client machine .
|
||||
|
||||
.. |sm_icon| image:: images/sm_icon.png
|
||||
pgAdmin will run the backup process in background. You can view all the background
|
||||
process with there running status and logs on the :ref:`Processes <processes>`
|
||||
tab
|
||||
@@ -0,0 +1,27 @@
|
||||
.. _change_ownership:
|
||||
|
||||
************************************
|
||||
`Change Ownership Dialog`:index:
|
||||
************************************
|
||||
|
||||
Use the *Change Ownership* dialog to change the ownership of the shared servers.
|
||||
This dialog will appear if a user has been deleted from
|
||||
:ref:`User Management <user_management>` and owned some shared servers.
|
||||
|
||||
Choose the user who will own the shared servers from the drop-down.
|
||||
|
||||
.. image:: images/change_ownership.png
|
||||
:alt: Change ownership dialog
|
||||
:align: center
|
||||
|
||||
Click the *Change* button to change the ownership.
|
||||
|
||||
The shared servers owned by the user will be deleted if the user is not
|
||||
selected from the drop-down.
|
||||
|
||||
.. image:: images/change_ownership_info.png
|
||||
:alt: Change ownership dialog
|
||||
:align: center
|
||||
|
||||
Click the *Change* button to change the ownership; click *Close* to
|
||||
exit the dialog.
|
||||
@@ -89,5 +89,8 @@ button to deploy the instance on Amazon RDS.
|
||||
|
||||
Once you click on the finish, one background process will start which will
|
||||
deploy the instance in the cloud and monitor the progress of the deployment.
|
||||
You can view all the background process with there running status and logs
|
||||
on the :ref:`Processes <processes>` tab
|
||||
|
||||
The Server will be added to the tree with the cloud deployment icon. Once the
|
||||
deployment is done, the server details will be updated.
|
||||
@@ -107,6 +107,8 @@ button to deploy the instance on Azure PostgreSQL.
|
||||
|
||||
Once you click on the finish, one background process will start which will
|
||||
deploy the instance in the cloud and monitor the progress of the deployment.
|
||||
You can view all the background process with there running status and logs
|
||||
on the :ref:`Processes <processes>` tab
|
||||
|
||||
.. image:: images/cloud_azure_bg_process_watcher.png
|
||||
:alt: Cloud Deployment
|
||||
|
||||
@@ -36,7 +36,8 @@ details.
|
||||
|
||||
* Use the *Region* field to select the region.
|
||||
|
||||
* Use the *Database version* field to specify the PostgreSQL version to deploy.
|
||||
* Use the *Public IP range* field to specify the IP Address range for permitting the
|
||||
inbound traffic. Leave it blank for 0.0.0.0/0
|
||||
|
||||
* Use the *Instance type* field to select the instance type.
|
||||
|
||||
@@ -49,10 +50,7 @@ details.
|
||||
|
||||
* Use the *Volume properties* field to specify the storage capacity.
|
||||
|
||||
* Use the *Cloud type* field to specify the private or public network.
|
||||
|
||||
* Use the *Public IP range* field to specify the IP Address range for permitting the
|
||||
inbound traffic. Leave it blank for 0.0.0.0/0
|
||||
|
||||
.. image:: images/cloud_biganimal_database.png
|
||||
:alt: Cloud Deployment Provider
|
||||
@@ -74,6 +72,12 @@ Use the fields from the Database Details tab to specify the Instance details.
|
||||
|
||||
* Use the *Confirm password* field to repeat the password.
|
||||
|
||||
* Use the *High Availability* field to create the cluster with high availability, which creates a cluster
|
||||
with one primary and up to two standby replicas in different availability zones.
|
||||
|
||||
* Use the *Number of standby replicas* field to specify the standby replicas.
|
||||
|
||||
|
||||
.. image:: images/cloud_biganimal_review.png
|
||||
:alt: Cloud Deployment Provider
|
||||
:align: center
|
||||
@@ -87,5 +91,8 @@ button to deploy the instance on EDB BigAnimal.
|
||||
|
||||
Once you click on the finish, one background process will start which will
|
||||
deploy the instance in the cloud and monitor the progress of the deployment.
|
||||
You can view all the background process with there running status and logs
|
||||
on the :ref:`Processes <processes>` tab
|
||||
|
||||
The Server will be added to the tree with the cloud deployment icon. Once the
|
||||
deployment is done, the server details will be updated.
|
||||
@@ -208,7 +208,7 @@ Front End
|
||||
pgAdmin uses javascript extensively for the front-end implementation. It uses
|
||||
require.js to allow the lazy loading (or, say load only when required),
|
||||
bootstrap for UI look and feel, Backbone for data manipulation of a node,
|
||||
Backform for generating properties/create dialog for selected node. We have
|
||||
React for generating properties/create dialog for selected node. We have
|
||||
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
|
||||
|
||||
@@ -45,9 +45,10 @@ The configuration files are as follows:
|
||||
macOS,/Library/Preferences/pgadmin/config_system.py
|
||||
Windows,%CommonProgramFiles%\\pgadmin\\config_system.py
|
||||
|
||||
.. note:: If the SERVER_MODE setting is changed in ``config_distro.py``,
|
||||
``config_local.py``, or ``config_system.py`` you will most likely need to
|
||||
re-set the LOG_FILE, SQLITE_PATH, SESSION_DB_PATH and STORAGE_DIR values
|
||||
.. note:: If the SERVER_MODE or DATA_DIR settings are changed in
|
||||
``config_distro.py``, ``config_local.py``, or ``config_system.py`` you
|
||||
will most likely need to re-set the LOG_FILE, SQLITE_PATH, SESSION_DB_PATH,
|
||||
STORAGE_DIR, KERBEROS_CCACHE_DIR, and AZURE_CREDENTIAL_CACHE_DIR values
|
||||
as well as they will have been set based on the default configuration or
|
||||
overridden by the runtime.
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ Mode is pre-configured for security.
|
||||
login
|
||||
mfa
|
||||
user_management
|
||||
change_ownership
|
||||
change_user_password
|
||||
restore_locked_user
|
||||
ldap
|
||||
|
||||
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 218 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 310 KiB After Width: | Height: | Size: 348 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 431 KiB After Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 336 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 247 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 130 KiB |
@@ -23,6 +23,7 @@ of database objects.
|
||||
management_basics
|
||||
backup_and_restore
|
||||
developer_tools
|
||||
processes
|
||||
pgagent
|
||||
contributions
|
||||
release_notes
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
***************************
|
||||
`Keyboard Shortcuts`:index:
|
||||
***************************
|
||||
****************************
|
||||
`Keyboard Shortcuts`:index::
|
||||
****************************
|
||||
|
||||
Keyboard shortcuts are provided in pgAdmin to allow easy access to specific
|
||||
functions. Alternate shortcuts can be configured through File > Preferences if
|
||||
desired.˝
|
||||
desired.
|
||||
|
||||
Main Browser Window
|
||||
*******************
|
||||
@@ -18,33 +18,49 @@ When using main browser window, the following keyboard shortcuts are available:
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shortcut for all platforms | Function |
|
||||
+============================+=======================================================+
|
||||
| Alt+Shift+F | Open the File menu |
|
||||
| Shift+Ctrl+a | Add grid row |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+O | Open the Object menu |
|
||||
| Shift+Alt+b | Browser tree |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+L | Open the Tools menu |
|
||||
| Shift+Alt+n | Create object |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+H | Open the Help menu |
|
||||
| Shift+Alt+d | Delete object |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+B | Focus the browser tree |
|
||||
| Shift+Alt+m | Delete/Drop multiple objects |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+[ | Move tabbed panel backward |
|
||||
| Shift+Ctrl+[ | Dialog tab backward |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+] | Move tabbed panel forward |
|
||||
| Shift+Ctrl+] | Dialog tab forward |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+Q | Open the Query Tool in the current database |
|
||||
| Shift+Alt+g | Direct debugging |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+V | View Data in the selected table/view |
|
||||
| Shift+Alt+u | Drop Cascade multiple objects |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+C | Open the context menu |
|
||||
| Shift+Alt+e | Edit object properties |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+N | Create an object |
|
||||
| Shift+Alt+f | File main menu |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+E | Edit object properties |
|
||||
| Shift+Alt+h | Help main menu |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+D | Delete the object |
|
||||
| Shift+Alt+o | Object main menu |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Alt+Shift+G | Direct debugging |
|
||||
| Shift+Alt+c | Open context menu |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Alt+q | Open query tool |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Ctrl+f | Quick Search |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| F5 | Refresh browser tree |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Alt+s | Search objects |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Alt+[ | Tabbed panel backward |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Alt+] | Tabbed panel forward |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Alt+l | Tools main menu |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
| Shift+Alt+v | View data |
|
||||
+----------------------------+-------------------------------------------------------+
|
||||
|
||||
Dialog Tabs
|
||||
@@ -152,43 +168,51 @@ When using the Query Tool, the following shortcuts are available:
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shortcut (Windows/Linux) | Shortcut (Mac) | Function |
|
||||
+==========================+====================+===================================+
|
||||
| F5 | F5 | Execute query |
|
||||
| <accesskey> + q | <accesskey> + q | Cancel query |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F6 | F6 | Save data changes |
|
||||
| <accesskey> + t | <accesskey> + t | Connection status |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F7 | F7 | EXPLAIN query |
|
||||
| <accesskey> + d | <accesskey> + d | Delete rows |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + F7 | Shift + F7 | EXPLAIN ANALYZE query |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F8 | F8 | Execute query to CSV file |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + o | <accesskey> + o | Open file |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + s | <accesskey> + s | Save file |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + n | <accesskey> + n | Find option drop down |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + c | <accesskey> + c | Copy row(s) |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + p | <accesskey> + p | Paste row(s) |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + d | <accesskey> + d | Delete row(s) |
|
||||
| <accesskey> + x | <accesskey> + x | Execute options |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + f | <accesskey> + f | Filter dialog |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + i | <accesskey> + i | Filter options drop down |
|
||||
| <accesskey> + i | <accesskey> + i | Filter options |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + r | <accesskey> + r | Row limit |
|
||||
| <accesskey> + n | <accesskey> + n | Find options |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + q | <accesskey> + q | Cancel query |
|
||||
| <accesskey> + o | <accesskey> + o | Open file |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + l | <accesskey> + l | Clear option drop down |
|
||||
| <accesskey> + p | <accesskey> + p | Paste rows |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + x | <accesskey> + x | Execute option drop down |
|
||||
| <accesskey> + r | <accesskey> + r | Rows limit |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + t | <accesskey> + t | Display connection status |
|
||||
| <accesskey> + s | <accesskey> + s | Save file |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + y | <accesskey> + y | Copy SQL on history panel |
|
||||
| Ctrl + Alt + L | Ctrl + option + L | Clear query |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Ctrl + m | Shift + Ctrl + m | Commit |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F8 | F8 | Download Results |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + F7 | Shift + F7 | EXPLAIN ANALYZE query |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F7 | F7 | EXPLAIN query |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F5 | F5 | Execute query |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + ] | Shift + option + ] | Next tab |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + [ | Shift + option + [ | Previous tab |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Ctrl + r | Shift + Ctrl + r | Rollback |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| F6 | F6 | Save data changes |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + Tab | Shift + option +Tab| Switch Panel |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Ctrl + u | Shift + Ctrl + u | Toggle case of selected text |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
|
||||
Debugger
|
||||
@@ -203,19 +227,72 @@ When using the Debugger, the following shortcuts are available:
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shortcut (Windows/Linux) | Shortcut (Mac) | Function |
|
||||
+==========================+====================+===================================+
|
||||
| <accesskey> + i | <accesskey> + i | Step in |
|
||||
| <accesskey> + x | <accesskey> + x | Clear all breakpoints |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + c | <accesskey> + c | Continue/Start |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + i | <accesskey> + i | Step into |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + o | <accesskey> + o | Step over |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + c | <accesskey> + c | Continue/Restart |
|
||||
| <accesskey> + s | <accesskey> + s | Stop |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + t | <accesskey> + t | Toggle breakpoint |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + x | <accesskey> + x | Clear all breakpoints |
|
||||
| Shift + Alt + q | Shift + option + q | Edit grid values |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| <accesskey> + s | <accesskey> + s | Stop |
|
||||
| Shift + Alt + ] | Shift + option + ] | Next tab |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Alt + Shift + q | Option + Shift + q | Enter or Edit values in Grid |
|
||||
| Shift + Alt + [ | Shift + option + ] | Previous tab |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + Tab | Shift + option +Tab| Switch Panel |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
|
||||
ERD Tool
|
||||
********
|
||||
|
||||
When using the ERD Tool, the following shortcuts are available:
|
||||
|
||||
.. table::
|
||||
:class: longtable
|
||||
:widths: 2 2 3
|
||||
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shortcut (Windows/Linux) | Shortcut (Mac) | Function |
|
||||
+==========================+====================+===================================+
|
||||
| Ctrl + Alt + a | Ctrl + option + a | Add table |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + n | Ctrl + option + n | Add/Edit note |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + l | Ctrl + option + l | Auto align |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + c | Ctrl + option + c | Clone table |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + i | Ctrl + option + i | Download image |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + d | Ctrl + option + d | Drop table |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + e | Ctrl + option + e | Edit table |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + s | Ctrl + option + s | Generate SQL |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + m | Ctrl + option + m | Many to many link |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + o | Ctrl + option + o | One to many link |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + o | Ctrl + o | Open project |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + s | Ctrl + s | Save project |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Ctrl + s | Shift + Ctrl + s | Save project as |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Ctrl + Alt + t | Ctrl + option + t | Show more/fewer details |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + + | Shift + option + + | Zoom in |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + - | Shift + option + - | Zoom out |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
| Shift + Alt + f | Shift + option + f | Zoom to fit |
|
||||
+--------------------------+--------------------+-----------------------------------+
|
||||
|
||||
Inner Tab and Panel Navigation
|
||||
@@ -224,7 +301,7 @@ Inner Tab and Panel Navigation
|
||||
When using the Query Tool and Debugger, the following shortcuts are available
|
||||
for inner panel navigation:
|
||||
|
||||
.. table::
|
||||
.. table::I
|
||||
:class: longtable
|
||||
:widths: 2 2 3
|
||||
|
||||
@@ -251,7 +328,7 @@ default access keys for supported browsers.
|
||||
+-------------------+-------------+-------------+---------------+
|
||||
| | Windows | Linux | Mac |
|
||||
+===================+=============+=============+===============+
|
||||
| Internet Explorer | Alt | Alt | |
|
||||
| Edge | Alt | | |
|
||||
+-------------------+-------------+-------------+---------------+
|
||||
| Chrome | Alt | Alt | Ctrl + Option |
|
||||
+-------------------+-------------+-------------+---------------+
|
||||
|
||||
@@ -45,18 +45,6 @@ switch to the *No* position; by default, status messages are included.
|
||||
When you've completed the dialog, click *OK* to start the background process;
|
||||
to exit the dialog without performing maintenance operations, click *Cancel*.
|
||||
|
||||
pgAdmin will inform you when the background process completes:
|
||||
|
||||
.. image:: images/maintenance_complete.png
|
||||
:alt: Maintenance completion notification
|
||||
:align: center
|
||||
|
||||
Use the **Stop Process** button to stop the Maintenance process.
|
||||
|
||||
Use the *Click here for details* link on the notification to open the *Process
|
||||
Watcher* and review detailed information about the execution of the command that
|
||||
performed the import or export:
|
||||
|
||||
.. image:: images/maintenance_pw.png
|
||||
:alt: Maintenance process watcher
|
||||
:align: center
|
||||
pgAdmin will run the maintenance process in background. You can view all the background
|
||||
process with there running status and logs on the :ref:`Processes <processes>`
|
||||
tab
|
||||
@@ -43,13 +43,6 @@ Use the fields on the *Display* panel to specify general display preferences:
|
||||
attempt to catch browser close or refresh events and prompt before allowing
|
||||
them to continue.
|
||||
|
||||
* When the *Enable browser tree animation?* switch is set to *True*, the client
|
||||
will display the animated tree control otherwise it will be unanimated.
|
||||
|
||||
* When the *Enable dialogue/notification animation?* switch is set to *True*,
|
||||
the client will display the animated dialogues/notifications otherwise it
|
||||
will be unanimated.
|
||||
|
||||
* When the *Hide shared servers?* switch is set to *True*, the client will hide
|
||||
all the shared servers from the browser tree.
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
.. _processes:
|
||||
|
||||
***********************
|
||||
`Processes`:index:
|
||||
***********************
|
||||
|
||||
There are certain tasks which pgAdmin runs in the background. The processes
|
||||
running in the background can be viewed in the processes tab. It shows the
|
||||
process details of Backup, Restore, Maintenance, Import/Export and Cloud instance
|
||||
creation.
|
||||
|
||||
.. image:: images/processes_main.png
|
||||
:alt: Processes Tab
|
||||
:align: center
|
||||
|
||||
The columns of the processes table shows:
|
||||
|
||||
* The *PID* of the forked OS process.
|
||||
* The *Type* of the task being performed.
|
||||
* The *Server* name for which the task is.
|
||||
* The *Object* can be a database, table, mview or anything which gives more info.
|
||||
* The *Start Time* of the process, sorted descending by default.
|
||||
* The current *Status* of the process. It can be Running, Finished, Failed, Terminated.
|
||||
* The *Time Taken* to complete. It will keep updating if it is running.
|
||||
|
||||
There are two action buttons on each row:
|
||||
|
||||
* The *Stop Process* button allows you to kill a running process.
|
||||
* The *More details* button allows you to open the process watcher which shows the
|
||||
process logs and other details.
|
||||
|
||||
You can also select the checkboxes and click on *Delete and Acknowledge* button
|
||||
on the top to clear the process info and logs.
|
||||
|
||||
Process Watcher
|
||||
*********************
|
||||
|
||||
.. image:: images/processes_details.png
|
||||
:alt: Process Watcher
|
||||
:align: center
|
||||
|
||||
|
||||
The Process Watcher logs all the activity associated with the process/task and provides
|
||||
additional information for troubleshooting
|
||||
Use the **Stop Process** button to stop the Backup process.
|
||||
|
||||
.. note:: If you are running *pgAdmin* in *Server Mode* you can click on the |sm_icon| icon in the process watcher window to open the file location in the Storage Manager. You can use the :ref:`Storage Manager <storage_manager>` to download the backup file on the client machine .
|
||||
|
||||
.. |sm_icon| image:: images/sm_icon.png
|
||||
@@ -11,6 +11,8 @@ notes for it.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release_notes_6_14
|
||||
release_notes_6_13
|
||||
release_notes_6_12
|
||||
release_notes_6_11
|
||||
release_notes_6_10
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
************
|
||||
Version 6.13
|
||||
************
|
||||
|
||||
Release date: 2022-08-25
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v6.12.
|
||||
|
||||
Supported Database Servers
|
||||
**************************
|
||||
**PostgreSQL**: 10, 11, 12, 13 and 14
|
||||
|
||||
**EDB Advanced Server**: 10, 11, 12, 13 and 14
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #3709 <https://redmine.postgresql.org/issues/3709>`_ - Added support to show all background processes in separate panel.
|
||||
| `Issue #7387 <https://redmine.postgresql.org/issues/7387>`_ - Added support to create triggers from existing trigger functions in EPAS.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #7344 <https://redmine.postgresql.org/issues/7344>`_ - Port Role Reassign dialog to React.
|
||||
| `Issue #7345 <https://redmine.postgresql.org/issues/7345>`_ - Port User Management dialog to React.
|
||||
| `Issue #7404 <https://redmine.postgresql.org/issues/7404>`_ - Port process watcher to React.
|
||||
| `Issue #7462 <https://redmine.postgresql.org/issues/7462>`_ - Remove the SQL files for the unsupported versions of the database server.
|
||||
| `Issue #7567 <https://redmine.postgresql.org/issues/7567>`_ - Port About dialog to React.
|
||||
| `Issue #7568 <https://redmine.postgresql.org/issues/7568>`_ - Port change user password and 2FA dialog to React.
|
||||
| `Issue #7590 <https://redmine.postgresql.org/issues/7590>`_ - Port change ownership dialog to React.
|
||||
| `Issue #7595 <https://redmine.postgresql.org/issues/7595>`_ - Update the container base image to Alpine 3.16 (with Python 3.10.5).
|
||||
| `Issue #7602 <https://redmine.postgresql.org/issues/7602>`_ - Fixed improper parsing of HTTP requests in Pallets Werkzeug v2.1.0 and below (CVE-2022-29361).
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #7452 <https://redmine.postgresql.org/issues/7452>`_ - Ensure that an error is thrown if clipboard access is not provided and change the copy rows shortcut.
|
||||
| `Issue #7468 <https://redmine.postgresql.org/issues/7468>`_ - Fixed an issue where the History tab is getting blank and showing an error after some queries are executed.
|
||||
| `Issue #7481 <https://redmine.postgresql.org/issues/7481>`_ - Fixed an issue where OWNED BY was incorrectly set to NONE when adding user privileges on the sequence.
|
||||
| `Issue #7497 <https://redmine.postgresql.org/issues/7497>`_ - Fixed an issue with the error message being displayed at the right place for Azure deployments.
|
||||
| `Issue #7521 <https://redmine.postgresql.org/issues/7521>`_ - Fixed an issue where the Query Editor loses focus when saving a query (Alt+s).
|
||||
| `Issue #7527 <https://redmine.postgresql.org/issues/7527>`_ - Fixed API test cases for Postgres 14.4.
|
||||
| `Issue #7540 <https://redmine.postgresql.org/issues/7540>`_ - Ensure that rename panel should work on view/edit panels.
|
||||
| `Issue #7563 <https://redmine.postgresql.org/issues/7563>`_ - Fixed an issue where autocomplete is not working after clearing the query editor.
|
||||
| `Issue #7573 <https://redmine.postgresql.org/issues/7573>`_ - Ensure that autocomplete does not appear when navigating code using arrow keys.
|
||||
| `Issue #7575 <https://redmine.postgresql.org/issues/7575>`_ - Fixed an issue where Alt-Shift-Q didn't work after creating a new query.
|
||||
| `Issue #7579 <https://redmine.postgresql.org/issues/7579>`_ - Fixed an issue where copy and pasting a row in the results grid doesn't set the default for boolean.
|
||||
| `Issue #7586 <https://redmine.postgresql.org/issues/7586>`_ - Fixed an issue with rendering geometry when selecting a complete column.
|
||||
| `Issue #7587 <https://redmine.postgresql.org/issues/7587>`_ - Ensure that the children of information_schema and pg_catalog node should be displayed.
|
||||
| `Issue #7591 <https://redmine.postgresql.org/issues/7591>`_ - Fixed column "none" does not exist issue, while comparing schema objects.
|
||||
| `Issue #7596 <https://redmine.postgresql.org/issues/7596>`_ - Fixed an issue where schema diff did not pick up the change in RLS policy.
|
||||
| `Issue #7608 <https://redmine.postgresql.org/issues/7608>`_ - Fixed an issue where the cloud deployment wizard creates the cluster with the High Availability even if that option is not selected.
|
||||
| `Issue #7611 <https://redmine.postgresql.org/issues/7611>`_ - Ensure that schema diff maintains view ownership when view definitions are modified.
|
||||
| `Issue #7614 <https://redmine.postgresql.org/issues/7614>`_ - Fixed crypt key is missing issue when logout from the pgAdmin.
|
||||
| `Issue #7616 <https://redmine.postgresql.org/issues/7616>`_ - Ensure that the next button should be disabled if the password did not match for Azure deployment.
|
||||
| `Issue #7617 <https://redmine.postgresql.org/issues/7617>`_ - Fixed an issue where Azure cloud deployment failed.
|
||||
| `Issue #7625 <https://redmine.postgresql.org/issues/7625>`_ - Fixed Spanish translations typo.
|
||||
| `Issue #7630 <https://redmine.postgresql.org/issues/7630>`_ - Ensure that If the trigger function definition is changed, drop and recreate the trigger in the schema diff.
|
||||
| `Issue #7632 <https://redmine.postgresql.org/issues/7632>`_ - Fixed an issue where a user could not authenticate using Azure CLI on OSX.
|
||||
| `Issue #7633 <https://redmine.postgresql.org/issues/7633>`_ - Ensure that the autofocus is on the input control for the master password and server password dialogs.
|
||||
| `Issue #7641 <https://redmine.postgresql.org/issues/7641>`_ - Pin Flask-SocketIO <= v5.2.0. The latest version does not support Werkzeug in production environments.
|
||||
@@ -0,0 +1,48 @@
|
||||
************
|
||||
Version 6.14
|
||||
************
|
||||
|
||||
Release date: 2022-09-22
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v6.13.
|
||||
|
||||
Supported Database Servers
|
||||
**************************
|
||||
**PostgreSQL**: 10, 11, 12, 13 and 14
|
||||
|
||||
**EDB Advanced Server**: 10, 11, 12, 13 and 14
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #4059 <https://github.com/postgres/pgadmin4/issues/4059>`_ - Port schema diff to React. (RM #6133)
|
||||
| `Issue #4060 <https://github.com/postgres/pgadmin4/issues/4060>`_ - Remove Backgrid and Backform. (RM #6134)
|
||||
| `Issue #5035 <https://github.com/postgres/pgadmin4/issues/5035>`_ - Port the remaining components of the ERD Tool to React. (RM #7343)
|
||||
| `Issue #5120 <https://github.com/postgres/pgadmin4/issues/5120>`_ - Updated keyboard shortcut documentation. (RM #7446)
|
||||
| `Issue #5260 <https://github.com/postgres/pgadmin4/issues/5260>`_ - Remove Alertify from pgAdmin completely. (RM #7619)
|
||||
| `Issue #5263 <https://github.com/postgres/pgadmin4/issues/5263>`_ - Port search object dialog to React. (RM #7622)
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #5144 <https://github.com/postgres/pgadmin4/issues/5144>`_ - Ensure that if big animal authentication is aborted, API calls should be stopped. (RM #7472)
|
||||
| `Issue #5209 <https://github.com/postgres/pgadmin4/issues/5209>`_ - Fixed an issue where pgAdmin failed to start due to bin path migration. (RM #7557)
|
||||
| `Issue #5230 <https://github.com/postgres/pgadmin4/issues/5230>`_ - Fixed an issue where backup does not work due to parameter 'preexec_fn' no longer being supported. (RM #7580)
|
||||
| `Issue #5250 <https://github.com/postgres/pgadmin4/issues/5250>`_ - Ensure that the browser tree should be refreshed after changing the ownership. (RM #7607)
|
||||
| `Issue #5274 <https://github.com/postgres/pgadmin4/issues/5274>`_ - Fixed the error message displayed when clicking the cloud server for which deployment is in progress. (RM #7636)
|
||||
| `Issue #5275 <https://github.com/postgres/pgadmin4/issues/5275>`_ - Fixed an issue where the wrong SQL displayed in difference if the user create an RLS policy on the table without a column. (RM #7637)
|
||||
| `Issue #5282 <https://github.com/postgres/pgadmin4/issues/5282>`_ - Ensure that the dump servers functionality works from setup.py. (RM #7644)
|
||||
| `Issue #5284 <https://github.com/postgres/pgadmin4/issues/5284>`_ - Ensure that the Import/Export server menu option is visible. (RM #7646)
|
||||
| `Issue #5286 <https://github.com/postgres/pgadmin4/issues/5286>`_ - Fixed API test case for change password in the server mode. (RM #7648)
|
||||
| `Issue #5287 <https://github.com/postgres/pgadmin4/issues/5287>`_ - Fixed an issue with the non-visibility of columns added prior to import/export data. (RM #7649)
|
||||
| `Issue #5292 <https://github.com/postgres/pgadmin4/issues/5292>`_ - Fixed an issue where textarea of the JSON Editor does not resize with dialog. (RM #7656)
|
||||
| `Issue #5299 <https://github.com/postgres/pgadmin4/issues/5299>`_ - Fixed ModuleNotFoundError when running setup.py to load/dump servers. (RM #7663)
|
||||
| `Issue #5323 <https://github.com/postgres/pgadmin4/issues/5323>`_ - Replace the language selection 'Brazilian' with 'Portuguese (Brazilian). (RM #7693)
|
||||
| `Issue #5325 <https://github.com/postgres/pgadmin4/issues/5325>`_ - Fixed an issue where server names with special characters are not displayed correctly in the process tab. (RM #7695)
|
||||
| `Issue #5333 <https://github.com/postgres/pgadmin4/issues/5333>`_ - Fixed an issue where ERD throws an error if variable is added to the column. (RM #7709)
|
||||
| `Issue #5342 <https://github.com/postgres/pgadmin4/issues/5342>`_ - Fixed an error while saving changes to the ERD table.
|
||||
| `Issue #5343 <https://github.com/postgres/pgadmin4/issues/5343>`_ - Fixes a redirect vulnerability when the user opens the pgAdmin URL.
|
||||
@@ -143,17 +143,6 @@ command, click the *Restore* button to start the process, or click the *Cancel*
|
||||
button to exit without saving your work. A popup will confirm if the restore is
|
||||
successful.
|
||||
|
||||
.. image:: images/restore_messages.png
|
||||
:alt: Restore dialog notifications
|
||||
:align: center
|
||||
|
||||
Use the **Stop Process** button to stop the Restore process.
|
||||
|
||||
Click *Click here for details* on the popup to launch the *Process Watcher*. The
|
||||
*Process Watcher* logs all the activity associated with the restore, and
|
||||
provides additional information for troubleshooting should the restore command
|
||||
encounter problems.
|
||||
|
||||
.. image:: images/restore_process_watcher.png
|
||||
:alt: Restore dialog process watcher
|
||||
:align: center
|
||||
pgAdmin will run the restore process in background. You can view all the background
|
||||
process with there running status and logs on the :ref:`Processes <processes>`
|
||||
tab
|
||||
@@ -99,6 +99,8 @@ following comparison criteria:
|
||||
Click on any of the database objects in the object comparison panel to
|
||||
display the DDL Statements of that object in the DDL Comparison panel.
|
||||
|
||||
Click the *Help* icon to open Schema Diff documentation.
|
||||
|
||||
|
||||
Schema Diff DDL Comparison Panel
|
||||
================================
|
||||
|
||||
@@ -35,12 +35,13 @@ To add a user, click the Add (+) button at the top right corner.
|
||||
Provide information about the new pgAdmin role in the row:
|
||||
|
||||
* Use the drop-down list box next to *Authentication source* field to select the
|
||||
type of authentication that should be used for the user. If LDAP
|
||||
authentication is not enabled for pgAdmin, then *Authentication source* field
|
||||
is disabled.
|
||||
type of authentication that should be used for the user. If authentication
|
||||
source is only 'internal' then *Authentication source* field
|
||||
is disabled. Supported *Authentication source* are internal, ldap, kerberos,
|
||||
oauth2 and webserver.
|
||||
* Click in the *Username* field, and provide a username for the user. This field
|
||||
is enabled only if you select *ldap* as authentication source. If you select
|
||||
*internal* as authentication source, your email address is displayed in the
|
||||
is enabled only when you select authentication source except *internal*. If you
|
||||
select *internal* as authentication source, your email address is displayed in the
|
||||
username field.
|
||||
* Click in the *Email* field, and provide an email address for the user.
|
||||
* Use the drop-down list box next to *Role* to select whether a user is an
|
||||
@@ -54,15 +55,19 @@ Provide information about the new pgAdmin role in the row:
|
||||
active; the default is *Yes*. Use this switch to disable account activity
|
||||
without deleting an account.
|
||||
* Use the *New password* field to provide the password associated with the user
|
||||
specified in the *Email* field. This field is disabled if you select *ldap*
|
||||
as authentication source since LDAP password is not stored in the pgAdmin database.
|
||||
specified in the *Email* field. This field is disabled if you select any
|
||||
authentication source except *internal*.
|
||||
* Re-enter the password in the *Confirm password* field. This field is disabled
|
||||
if you select *ldap* as authentication source.
|
||||
* Move the *Locked* switch to the *True* position if you want to lock the account;
|
||||
the default is *False*. This functionality is useful when a user is locked by trying unsuccessful login attempts.
|
||||
* *Locked* switch is disabled by default when set to *False*. It is only enabled
|
||||
when the user is locked by trying unsuccessful login attempts. Move the switch
|
||||
to the *False* position if you want to unlock the account.
|
||||
|
||||
To discard a user, and revoke access to pgAdmin, click the trash icon to the
|
||||
left of the row and confirm deletion in the *Delete user?* dialog.
|
||||
left of the row and confirm deletion in the *Delete user?* dialog. If the user
|
||||
has created some shared servers, then the :ref:`Change Ownership <change_ownership>`
|
||||
dialog will appear to change the ownership of a shared server.
|
||||
|
||||
|
||||
Users with the *Administrator* role are able to add, edit and remove pgAdmin
|
||||
users, but otherwise have the same capabilities as those with the *User* role.
|
||||
|
||||
@@ -6,8 +6,7 @@ set -e
|
||||
# Debugging shizz
|
||||
trap 'ERRCODE=$? && if [ ${ERRCODE} -ne 0 ]; then echo "The command \"${BASH_COMMAND}\" failed in \"${FUNCNAME}\" with exit code ${ERRCODE}."; fi' EXIT
|
||||
|
||||
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_NAME=$(cat /etc/os-release | grep "^ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_VERSION=$(grep "^VERSION_ID=" /etc/os-release | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_ARCH=$(dpkg-architecture -qDEB_HOST_ARCH)
|
||||
|
||||
# Stop creating pyc files.
|
||||
@@ -17,7 +16,7 @@ export PYTHONDONTWRITEBYTECODE=1
|
||||
source pkg/linux/build-functions.sh
|
||||
|
||||
# Assemble the "standard" installation footprint
|
||||
_setup_env $0 "debian"
|
||||
_setup_env "$0" "debian"
|
||||
_cleanup "deb"
|
||||
_setup_dirs
|
||||
_create_python_virtualenv "debian"
|
||||
@@ -122,7 +121,7 @@ EOF
|
||||
fakeroot dpkg-deb --build "${METAROOT}" "${DISTROOT}/${APP_NAME}_${APP_LONG_VERSION}_all.deb"
|
||||
|
||||
# Get the libpq package
|
||||
pushd ${DISTROOT} 1> /dev/null
|
||||
pushd "${DISTROOT}" 1> /dev/null
|
||||
apt-get download libpq5
|
||||
popd 1> /dev/null
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)
|
||||
|
||||
# Node repo
|
||||
echo "Setting up the NodeJS repo..."
|
||||
curl -sL https://deb.nodesource.com/setup_12.x | bash -
|
||||
curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
||||
|
||||
# Yarn repo
|
||||
echo "Setting up the Yarn repo..."
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Fixup the passwd file, in case we're on OpenShift
|
||||
if ! whoami &> /dev/null; then
|
||||
if [ $(id -u) -ne 5050 ]; then
|
||||
if ! whoami > /dev/null 2>&1; then
|
||||
if [ "$(id -u)" -ne 5050 ]; then
|
||||
if [ -w /etc/passwd ]; then
|
||||
echo "${USER_NAME:-pgadminr}:x:$(id -u):0:${USER_NAME:-pgadminr} user:${HOME}:/sbin/nologin" >> /etc/passwd
|
||||
fi
|
||||
@@ -13,7 +13,7 @@ fi
|
||||
# provided by the user through the PGADMIN_CONFIG_* environment variables.
|
||||
# Only update the file on first launch. The empty file is created during the
|
||||
# container build so it can have the required ownership.
|
||||
if [ `wc -m /pgadmin4/config_distro.py | awk '{ print $1 }'` = "0" ]; then
|
||||
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'
|
||||
@@ -31,37 +31,40 @@ EOF
|
||||
# This is a bit kludgy, but necessary as the container uses BusyBox/ash as
|
||||
# it's shell and not bash which would allow a much cleaner implementation
|
||||
for var in $(env | grep PGADMIN_CONFIG_ | cut -d "=" -f 1); do
|
||||
# shellcheck disable=SC2086
|
||||
# shellcheck disable=SC2046
|
||||
echo ${var#PGADMIN_CONFIG_} = $(eval "echo \$$var") >> /pgadmin4/config_distro.py
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -f /var/lib/pgadmin/pgadmin4.db ]; then
|
||||
if ([ -z "${PGADMIN_DEFAULT_EMAIL}" ]) || ( [ -z "${PGADMIN_DEFAULT_PASSWORD}" ] && [ ! -n "${PGADMIN_DEFAULT_PASSWORD_FILE}" ] ); then
|
||||
if [ -z "${PGADMIN_DEFAULT_EMAIL}" ] || { [ -z "${PGADMIN_DEFAULT_PASSWORD}" ] && [ -z "${PGADMIN_DEFAULT_PASSWORD_FILE}" ]; }; then
|
||||
echo 'You need to define the PGADMIN_DEFAULT_EMAIL and PGADMIN_DEFAULT_PASSWORD or PGADMIN_DEFAULT_PASSWORD_FILE environment variables.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ${PGADMIN_DEFAULT_EMAIL} | grep -E "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$" > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
if ! echo "${PGADMIN_DEFAULT_EMAIL}" | grep -E "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$" > /dev/null; then
|
||||
echo "'${PGADMIN_DEFAULT_EMAIL}' does not appear to be a valid email address. Please reset the PGADMIN_DEFAULT_EMAIL environment variable and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Read secret contents
|
||||
if [ -n "${PGADMIN_DEFAULT_PASSWORD_FILE}" ]; then
|
||||
export PGADMIN_DEFAULT_PASSWORD=$(cat ${PGADMIN_DEFAULT_PASSWORD_FILE})
|
||||
PGADMIN_DEFAULT_PASSWORD=$(cat "${PGADMIN_DEFAULT_PASSWORD_FILE}")
|
||||
export PGADMIN_DEFAULT_PASSWORD
|
||||
fi
|
||||
|
||||
# Set the default username and password in a
|
||||
# backwards compatible way
|
||||
export PGADMIN_SETUP_EMAIL=${PGADMIN_DEFAULT_EMAIL}
|
||||
export PGADMIN_SETUP_PASSWORD=${PGADMIN_DEFAULT_PASSWORD}
|
||||
export PGADMIN_SETUP_EMAIL="${PGADMIN_DEFAULT_EMAIL}"
|
||||
export PGADMIN_SETUP_PASSWORD="${PGADMIN_DEFAULT_PASSWORD}"
|
||||
|
||||
# Initialize DB before starting Gunicorn
|
||||
# Importing pgadmin4 (from this script) is enough
|
||||
/venv/bin/python3 run_pgadmin.py
|
||||
|
||||
export PGADMIN_SERVER_JSON_FILE=${PGADMIN_SERVER_JSON_FILE:-/pgadmin4/servers.json}
|
||||
export PGADMIN_SERVER_JSON_FILE="${PGADMIN_SERVER_JSON_FILE:-/pgadmin4/servers.json}"
|
||||
|
||||
# Pre-load any required servers
|
||||
if [ -f "${PGADMIN_SERVER_JSON_FILE}" ]; then
|
||||
# When running in Desktop mode, no user is created
|
||||
@@ -69,13 +72,13 @@ if [ ! -f /var/lib/pgadmin/pgadmin4.db ]; then
|
||||
if [ "${PGADMIN_CONFIG_SERVER_MODE}" = "False" ]; then
|
||||
/venv/bin/python3 /pgadmin4/setup.py --load-servers "${PGADMIN_SERVER_JSON_FILE}"
|
||||
else
|
||||
/venv/bin/python3 /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.
|
||||
if [ -z ${PGADMIN_DISABLE_POSTFIX} ]; then
|
||||
if [ -z "${PGADMIN_DISABLE_POSTFIX}" ]; then
|
||||
sudo /usr/sbin/postfix start
|
||||
fi
|
||||
|
||||
@@ -86,8 +89,8 @@ TIMEOUT=$(cd /pgadmin4 && /venv/bin/python3 -c 'import config; print(config.SESS
|
||||
# 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 /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
|
||||
if [ -n "${PGADMIN_ENABLE_TLS}" ]; then
|
||||
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 /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
|
||||
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,6 +1,8 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
_setup_env() {
|
||||
echo "Setting up the environment..."
|
||||
WD=$(cd `dirname "$1"` && pwd)
|
||||
WD=$(cd "$(dirname "$1")" && pwd)
|
||||
SOURCEDIR=$(realpath "${WD}/../..")
|
||||
BUILDROOT=$(realpath "${WD}/../../$2-build")
|
||||
DESKTOPROOT=${BUILDROOT}/desktop
|
||||
@@ -8,49 +10,49 @@ _setup_env() {
|
||||
SERVERROOT=${BUILDROOT}/server
|
||||
WEBROOT=${BUILDROOT}/web
|
||||
DISTROOT=$(realpath "${WD}/../../dist")
|
||||
APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //' | sed 's/ //g' | tr '[:upper:]' '[:lower:]'`
|
||||
APP_RELEASE=$(grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_REVISION=$(grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_NAME=$(grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //' | sed 's/ //g' | tr '[:upper:]' '[:lower:]')
|
||||
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
|
||||
APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
|
||||
APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
|
||||
if [ ! -z ${APP_SUFFIX} ]; then
|
||||
APP_SUFFIX=$(grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
|
||||
if [ -n "${APP_SUFFIX}" ]; then
|
||||
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
||||
fi
|
||||
}
|
||||
|
||||
_cleanup() {
|
||||
echo "Cleaning up the old environment and app..."
|
||||
if test -f ${SOURCEDIR}/runtime/pgAdmin4; then
|
||||
rm -rf ${SOURCEDIR}/runtime/pgAdmin4
|
||||
if test -f "${SOURCEDIR}/runtime/pgAdmin4"; then
|
||||
rm -rf "${SOURCEDIR}/runtime/pgAdmin4"
|
||||
fi
|
||||
if test -d ${BUILDROOT}; then
|
||||
rm -rf ${BUILDROOT}
|
||||
if test -d "${BUILDROOT}"; then
|
||||
rm -rf "${BUILDROOT}"
|
||||
fi
|
||||
rm -f ${DISTROOT}/pgadmin4*.$1
|
||||
rm -f "${DISTROOT}/pgadmin4"*".$1"
|
||||
}
|
||||
|
||||
_setup_dirs() {
|
||||
echo "Creating output directories..."
|
||||
test -d ${BUILDROOT} || mkdir ${BUILDROOT}
|
||||
test -d ${DESKTOPROOT} || mkdir ${DESKTOPROOT}
|
||||
test -d ${METAROOT} || mkdir ${METAROOT}
|
||||
test -d ${SERVERROOT} || mkdir ${SERVERROOT}
|
||||
test -d ${WEBROOT} || mkdir ${WEBROOT}
|
||||
test -d ${DISTROOT} || mkdir ${DISTROOT}
|
||||
test -d "${BUILDROOT}" || mkdir "${BUILDROOT}"
|
||||
test -d "${DESKTOPROOT}" || mkdir "${DESKTOPROOT}"
|
||||
test -d "${METAROOT}" || mkdir "${METAROOT}"
|
||||
test -d "${SERVERROOT}" || mkdir "${SERVERROOT}"
|
||||
test -d "${WEBROOT}" || mkdir "${WEBROOT}"
|
||||
test -d "${DISTROOT}" || mkdir "${DISTROOT}"
|
||||
}
|
||||
|
||||
_create_python_virtualenv() {
|
||||
echo "Creating the virtual environment..."
|
||||
|
||||
cd ${SERVERROOT}
|
||||
cd "${SERVERROOT}" || exit
|
||||
|
||||
# Create the required directories
|
||||
mkdir -p "usr/${APP_NAME}"
|
||||
cd "usr/${APP_NAME}"
|
||||
cd "usr/${APP_NAME}" || exit
|
||||
|
||||
# Create the blank venv
|
||||
python3 -m venv venv
|
||||
# shellcheck disable=SC1091
|
||||
source venv/bin/activate
|
||||
|
||||
# Make sure we have the wheel package present, as well as the latest pip
|
||||
@@ -58,7 +60,7 @@ _create_python_virtualenv() {
|
||||
pip3 install wheel
|
||||
|
||||
# Install the requirements
|
||||
pip3 install --no-cache-dir --no-binary psycopg2 -r ${SOURCEDIR}/requirements.txt
|
||||
pip3 install --no-cache-dir --no-binary psycopg2 -r "${SOURCEDIR}/requirements.txt"
|
||||
|
||||
# Fixup the paths in the venv activation scripts
|
||||
sed -i 's/VIRTUAL_ENV=.*/VIRTUAL_ENV="\/usr\/pgadmin4\/venv"/g' venv/bin/activate
|
||||
@@ -74,10 +76,10 @@ _create_python_virtualenv() {
|
||||
# Figure out some paths for use when completing the venv
|
||||
# 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}`
|
||||
DIR_PYMODULES_PATH=$(dirname "${PYMODULES_PATH}")
|
||||
|
||||
# Use /usr/bin/python3 here as we want the system path
|
||||
if [ $1 == "debian" ]; then
|
||||
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))")
|
||||
else
|
||||
PYSYSLIB_PATH=$(/usr/bin/python3 -c "import sys; print('%s/lib64/python%d.%.d' % (sys.prefix, sys.version_info.major, sys.version_info.minor))")
|
||||
@@ -86,33 +88,33 @@ _create_python_virtualenv() {
|
||||
# Symlink in the rest of the Python libs. This is required because the runtime
|
||||
# will clear PYTHONHOME for safety, which has the side-effect of preventing
|
||||
# it from finding modules that are not explicitly included in the venv
|
||||
cd ${DIR_PYMODULES_PATH}
|
||||
cd "${DIR_PYMODULES_PATH}" || exit
|
||||
|
||||
# Files
|
||||
for FULLPATH in ${PYSYSLIB_PATH}/*.py; do
|
||||
for FULLPATH in "${PYSYSLIB_PATH}"/*.py; do
|
||||
FILE=${FULLPATH##*/}
|
||||
if [ ! -e ${FILE} ]; then
|
||||
ln -s ${FULLPATH} ${FILE}
|
||||
if [ ! -e "${FILE}" ]; then
|
||||
ln -s "${FULLPATH}" "${FILE}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Paths
|
||||
for FULLPATH in ${PYSYSLIB_PATH}/*/; do
|
||||
for FULLPATH in "${PYSYSLIB_PATH}"/*/; do
|
||||
FULLPATH=${FULLPATH%*/}
|
||||
FILE=${FULLPATH##*/}
|
||||
if [ ! -e ${FILE} ]; then
|
||||
ln -s ${FULLPATH} ${FILE}
|
||||
if [ ! -e "${FILE}" ]; then
|
||||
ln -s "${FULLPATH}" "${FILE}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove tests
|
||||
cd site-packages
|
||||
cd site-packages || exit
|
||||
find . -name "test" -type d -print0 | xargs -0 rm -rf
|
||||
find . -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||
|
||||
# Link the python<version> directory to python so that the private environment path is found by the application.
|
||||
if test -d ${DIR_PYMODULES_PATH}; then
|
||||
ln -s $(basename ${DIR_PYMODULES_PATH}) ${DIR_PYMODULES_PATH}/../python
|
||||
if test -d "${DIR_PYMODULES_PATH}"; then
|
||||
ln -s "$(basename "${DIR_PYMODULES_PATH}")" "${DIR_PYMODULES_PATH}/../python"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -134,13 +136,13 @@ _build_runtime() {
|
||||
# NW_VERSION=$(yarn info nw | grep latest | awk -F "'" '{ print $2}')
|
||||
NW_VERSION="0.62.2"
|
||||
|
||||
pushd "${BUILDROOT}" > /dev/null
|
||||
pushd "${BUILDROOT}" > /dev/null || exit
|
||||
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
|
||||
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
|
||||
tar -zxvf "nwjs-v${NW_VERSION}-linux-x64.tar.gz"
|
||||
popd > /dev/null || exit
|
||||
# WGET END
|
||||
|
||||
# Copy nwjs into the staging directory
|
||||
@@ -188,10 +190,11 @@ _build_runtime() {
|
||||
_build_docs() {
|
||||
echo "Building the documentation..."
|
||||
cd "${SERVERROOT}" && mkdir -p "usr/${APP_NAME}/share/docs/en_US/html"
|
||||
cd "${SOURCEDIR}/docs/en_US"
|
||||
cd "${SOURCEDIR}/docs/en_US" || exit
|
||||
python3 build_code_snippet.py
|
||||
SYS_PYTHONPATH=$(/usr/bin/python3 -c "import sys; print(':'.join([p for p in sys.path if p]))")
|
||||
if [ $1 == "redhat" -a "${OS_VERSION}" == "7" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
if [ "$1" == "redhat" ] && [ "${OS_VERSION}" == "7" ]; then
|
||||
PYTHONPATH=$PYTHONPATH:${SYS_PYTHONPATH} python3 /usr/local/bin/sphinx-build . "${SERVERROOT}/usr/${APP_NAME}/share/docs/en_US/html"
|
||||
else
|
||||
PYTHONPATH=$PYTHONPATH:${SYS_PYTHONPATH} python3 -msphinx . "${SERVERROOT}/usr/${APP_NAME}/share/docs/en_US/html"
|
||||
@@ -204,15 +207,15 @@ _copy_code() {
|
||||
# Remove any TCL-related files that may cause us problems
|
||||
find "${SERVERROOT}/usr/${APP_NAME}/venv/" -name "_tkinter*" -print0 | xargs -0 rm -rf
|
||||
|
||||
pushd ${SOURCEDIR}/web > /dev/null
|
||||
pushd "${SOURCEDIR}/web" > /dev/null || exit
|
||||
yarn install
|
||||
yarn run bundle
|
||||
popd > /dev/null
|
||||
popd > /dev/null || exit
|
||||
|
||||
# copy the web directory to the bundle as it is required by runtime
|
||||
cp -r "${SOURCEDIR}/web" "${SERVERROOT}/usr/${APP_NAME}/web/"
|
||||
cp "${SOURCEDIR}/pkg/linux/config_distro.py" "${SERVERROOT}/usr/${APP_NAME}/web/"
|
||||
cd "${SERVERROOT}/usr/${APP_NAME}/web/"
|
||||
cd "${SERVERROOT}/usr/${APP_NAME}/web/" || exit
|
||||
rm -f pgadmin4.db config_local.*
|
||||
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
||||
find . -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||
@@ -230,11 +233,11 @@ _copy_code() {
|
||||
# Ensure our venv will use the correct Python interpreter, even if the
|
||||
# user has configured an alternative default.
|
||||
# DO THIS LAST!
|
||||
cd "${SERVERROOT}/usr/${APP_NAME}/venv/bin"
|
||||
cd "${SERVERROOT}/usr/${APP_NAME}/venv/bin" || exit
|
||||
PYTHON_INTERPRETER=$(/usr/bin/python3 -c "import os, sys; print(os.path.realpath(sys.executable))")
|
||||
PYTHON_VERSION=$(/usr/bin/python3 -c "import sys; print('%d.%d' % (sys.version_info.major, sys.version_info.minor))")
|
||||
rm python && ln -s python3 python
|
||||
rm python${PYTHON_VERSION} && ln -s python3 python${PYTHON_VERSION}
|
||||
rm "python${PYTHON_VERSION}" && ln -s python3 "python${PYTHON_VERSION}"
|
||||
rm python3 && ln -s "${PYTHON_INTERPRETER}" python3
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ if [ "$EUID" -ne 0 ]
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$#" -ne 0 ]] && ([[ "$#" -eq 1 ]] && [[ "$1" != "--yes" ]]); then
|
||||
if [[ "$#" -gt 1 ]] || { [[ "$#" -eq 1 ]] && [[ "$1" != "--yes" ]]; }; then
|
||||
echo "Usage: $0 [--yes]"
|
||||
exit 1
|
||||
fi
|
||||
@@ -20,7 +20,7 @@ IS_SUSE=0
|
||||
UNAME=$(uname -a)
|
||||
|
||||
# Get the distro from the environment
|
||||
if [ "x${PGADMIN_PLATFORM_TYPE}" == "x" ]; then
|
||||
if [ "${PGADMIN_PLATFORM_TYPE}" == "" ]; then
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
PLATFORM_TYPE=redhat
|
||||
elif [[ ${UNAME} =~ "Ubuntu" ]] || [[ ${UNAME} =~ "Debian" ]] || [ -f /etc/apt/sources.list ]; then
|
||||
@@ -72,9 +72,7 @@ fi
|
||||
|
||||
# Run setup script first:
|
||||
echo "Creating configuration database..."
|
||||
/usr/pgadmin4/venv/bin/python3 /usr/pgadmin4/web/setup.py
|
||||
|
||||
if [ $? != 0 ]
|
||||
if ! /usr/pgadmin4/venv/bin/python3 /usr/pgadmin4/web/setup.py;
|
||||
then
|
||||
echo "Error setting up server mode. Please examine the output above."
|
||||
exit 1
|
||||
@@ -108,7 +106,7 @@ if [ ${IS_DEBIAN} == 1 ]; then
|
||||
if [ ${AUTOMATED} == 1 ]; then
|
||||
RESPONSE=Y
|
||||
else
|
||||
read -p "We can now configure the Apache Web server for you. This involves enabling the wsgi module and configuring the pgAdmin 4 application to mount at /pgadmin4. Do you wish to continue (y/n)? " RESPONSE
|
||||
read -r -p "We can now configure the Apache Web server for you. This involves enabling the wsgi module and configuring the pgAdmin 4 application to mount at /pgadmin4. Do you wish to continue (y/n)? " RESPONSE
|
||||
fi
|
||||
|
||||
case ${RESPONSE} in
|
||||
@@ -121,18 +119,16 @@ if [ ${IS_DEBIAN} == 1 ]; then
|
||||
esac
|
||||
fi
|
||||
|
||||
APACHE_STATUS=`ps cax | grep ${APACHE}`
|
||||
if [ $? -eq 0 ]; then
|
||||
if pgrep ${APACHE} > /dev/null; then
|
||||
if [ ${AUTOMATED} == 1 ]; then
|
||||
RESPONSE=Y
|
||||
else
|
||||
read -p "The Apache web server is running and must be restarted for the pgAdmin 4 installation to complete. Continue (y/n)? " RESPONSE
|
||||
read -r -p "The Apache web server is running and must be restarted for the pgAdmin 4 installation to complete. Continue (y/n)? " RESPONSE
|
||||
fi
|
||||
|
||||
case ${RESPONSE} in
|
||||
y|Y )
|
||||
systemctl restart ${APACHE}
|
||||
if [ $? != 0 ]; then
|
||||
if ! systemctl restart ${APACHE}; then
|
||||
echo "Error restarting ${APACHE}. Please check the systemd logs"
|
||||
else
|
||||
echo "Apache successfully restarted. You can now start using pgAdmin 4 in web mode at http://127.0.0.1/pgadmin4"
|
||||
@@ -144,20 +140,18 @@ else
|
||||
if [ ${AUTOMATED} == 1 ]; then
|
||||
RESPONSE=Y
|
||||
else
|
||||
read -p "The Apache web server is not running. We can enable and start the web server for you to finish pgAdmin 4 installation. Continue (y/n)? " RESPONSE
|
||||
read -r -p "The Apache web server is not running. We can enable and start the web server for you to finish pgAdmin 4 installation. Continue (y/n)? " RESPONSE
|
||||
fi
|
||||
|
||||
case ${RESPONSE} in
|
||||
y|Y )
|
||||
systemctl enable ${APACHE}
|
||||
if [ $? != 0 ]; then
|
||||
if ! systemctl enable ${APACHE}; then
|
||||
echo "Error enabling ${APACHE}. Please check the systemd logs"
|
||||
else
|
||||
echo "Apache successfully enabled."
|
||||
fi
|
||||
|
||||
systemctl start ${APACHE}
|
||||
if [ $? != 0 ]; then
|
||||
if ! systemctl start ${APACHE}; then
|
||||
echo "Error starting ${APACHE}. Please check the systemd logs"
|
||||
else
|
||||
echo "Apache successfully started."
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
_setup_env() {
|
||||
FUNCS_DIR=$(cd `dirname $0` && pwd)/../..
|
||||
APP_RELEASE=`grep "^APP_RELEASE" ${FUNCS_DIR}/web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_REVISION=`grep "^APP_REVISION" ${FUNCS_DIR}/web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_NAME=`grep "^APP_NAME" ${FUNCS_DIR}/web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
|
||||
FUNCS_DIR=$(cd "$(dirname "$0")" && pwd)/../..
|
||||
APP_RELEASE=$(grep "^APP_RELEASE" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_REVISION=$(grep "^APP_REVISION" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_NAME=$(grep "^APP_NAME" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
|
||||
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
|
||||
APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
|
||||
APP_SUFFIX=`grep "^APP_SUFFIX" ${FUNCS_DIR}/web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
|
||||
if [ ! -z ${APP_SUFFIX} ]; then
|
||||
APP_SUFFIX=$(grep "^APP_SUFFIX" "${FUNCS_DIR}/web/config.py" | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
|
||||
if [ -n "${APP_SUFFIX}" ]; then
|
||||
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"
|
||||
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 "${BUILD_ROOT}"
|
||||
rm -rf "${TEMP_DIR}"
|
||||
rm -f ${DIST_ROOT}/*.dmg
|
||||
rm -f "${DIST_ROOT}"/*.dmg
|
||||
}
|
||||
|
||||
_build_runtime() {
|
||||
@@ -39,13 +40,13 @@ _build_runtime() {
|
||||
# NW_VERSION=$(yarn info nw | grep latest | awk -F "'" '{ print $2}')
|
||||
NW_VERSION="0.62.2"
|
||||
|
||||
pushd "${BUILD_ROOT}" > /dev/null
|
||||
pushd "${BUILD_ROOT}" > /dev/null || exit
|
||||
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
|
||||
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
|
||||
unzip "nwjs-v${NW_VERSION}-osx-x64.zip"
|
||||
popd > /dev/null || exit
|
||||
# WGET END
|
||||
|
||||
# YARN:
|
||||
@@ -77,7 +78,7 @@ _create_python_env() {
|
||||
PATH=$PATH:/usr/local/pgsql/bin python \
|
||||
"${BUILD_ROOT}/relocatable_python/make_relocatable_python_framework.py" \
|
||||
--upgrade-pip \
|
||||
--python-version ${PGADMIN_PYTHON_VERSION} \
|
||||
--python-version "${PGADMIN_PYTHON_VERSION}" \
|
||||
--pip-requirements "${SOURCE_DIR}/requirements.txt" \
|
||||
--destination "${BUNDLE_DIR}/Contents/Frameworks/"
|
||||
|
||||
@@ -85,26 +86,27 @@ _create_python_env() {
|
||||
# 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)
|
||||
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}
|
||||
|
||||
# Fixup shebangs
|
||||
cd "${BUNDLE_DIR}/Contents/Frameworks/Python.framework/Versions/Current/bin"
|
||||
grep -RiIl 'mac-build' * | xargs sed -i '' 's/\/.*\/python3\./\$(dirname \"$0\")\/python3./g'
|
||||
cd "${BUNDLE_DIR}/Contents/Frameworks/Python.framework/Versions/Current/bin" || exit
|
||||
# shellcheck disable=SC2016
|
||||
grep -RiIl 'mac-build' ./* | xargs sed -i '' 's/\/.*\/python3\./\$(dirname \"$0\")\/python3./g'
|
||||
|
||||
# Remove some things we don't need
|
||||
cd "${BUNDLE_DIR}/Contents/Frameworks/Python.framework"
|
||||
cd "${BUNDLE_DIR}/Contents/Frameworks/Python.framework" || exit
|
||||
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
|
||||
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
|
||||
@@ -123,15 +125,16 @@ _build_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"
|
||||
# shellcheck disable=SC1091
|
||||
source "${BUILD_ROOT}/venv/bin/activate"
|
||||
pip3 install --upgrade pip
|
||||
pip3 install -r "${SOURCE_DIR}/requirements.txt"
|
||||
pip3 install sphinx
|
||||
|
||||
cd "${SOURCE_DIR}"
|
||||
cd "${SOURCE_DIR}" || exit
|
||||
make docs
|
||||
|
||||
cd "${SOURCE_DIR}/docs/en_US"
|
||||
cd "${SOURCE_DIR}/docs/en_US" || exit
|
||||
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/"
|
||||
|
||||
@@ -144,10 +147,10 @@ _fixup_imports() {
|
||||
local TODO TODO_OLD FW_RELPATH LIB LIB_BN
|
||||
|
||||
echo "Fixing imports on the core appbundle..."
|
||||
pushd "$1" > /dev/null
|
||||
pushd "$1" > /dev/null || exit
|
||||
|
||||
# Find all the files that may need tweaks
|
||||
TODO=$(file `find . -perm +0111 -type f` | \
|
||||
TODO=$(find . -perm +0111 -type f -exec file "{}" \; | \
|
||||
grep -v "Frameworks/Python.framework" | \
|
||||
grep -v "Frameworks/nwjs" | \
|
||||
grep -E "Mach-O 64-bit" | \
|
||||
@@ -155,7 +158,7 @@ _fixup_imports() {
|
||||
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` | \
|
||||
TODO+=$(find ./Contents/Frameworks/Python.framework/Versions/Current/lib/python*/site-packages -perm +0111 -type f -exec file "{}" \; | \
|
||||
grep -E "Mach-O 64-bit" | \
|
||||
awk -F ':| ' '{ORS=" "; print $1}' | \
|
||||
uniq)
|
||||
@@ -183,9 +186,9 @@ _fixup_imports() {
|
||||
|
||||
# Find all libraries ${TODO_OBJ} depends on, but skip system libraries
|
||||
for LIB in $(
|
||||
otool -L ${TODO_OBJ} | \
|
||||
otool -L "${TODO_OBJ}" | \
|
||||
sed -n 's|^.*[[:space:]]\([^[:space:]]*\.dylib\).*$|\1|p' | \
|
||||
egrep -v '^(/usr/lib)|(/System)|@executable_path|@loader_path|/DLC/PIL/' \
|
||||
grep -E -v '^(/usr/lib)|(/System)|@executable_path|@loader_path|/DLC/PIL/' \
|
||||
); do
|
||||
# Copy in any required dependencies
|
||||
LIB_BN="$(basename "${LIB}")" ;
|
||||
@@ -225,12 +228,12 @@ _fixup_imports() {
|
||||
done
|
||||
|
||||
echo "Imports updated on the core appbundle."
|
||||
popd > /dev/null
|
||||
popd > /dev/null || exit
|
||||
}
|
||||
|
||||
_complete_bundle() {
|
||||
echo "Completing the appbundle..."
|
||||
cd ${SCRIPT_DIR}
|
||||
cd "${SCRIPT_DIR}" || exit
|
||||
|
||||
# Copy the binary utilities into place
|
||||
mkdir -p "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||
@@ -247,7 +250,7 @@ _complete_bundle() {
|
||||
for FILE in "${BUNDLE_DIR}"/Contents/Resources/*.lproj/InfoPlist.strings; do
|
||||
sed -i '' 's/CFBundleGetInfoString =.*/CFBundleGetInfoString = "Copyright (C) 2013 - 2022, The pgAdmin Development Team";/g' "${FILE}"
|
||||
sed -i '' 's/NSHumanReadableCopyright =.*/NSHumanReadableCopyright = "Copyright (C) 2013 - 2022, The pgAdmin Development Team";/g' "${FILE}"
|
||||
echo CFBundleDisplayName = \"${APP_NAME}\"\; >> "${FILE}"
|
||||
echo CFBundleDisplayName = \""${APP_NAME}"\"\; >> "${FILE}"
|
||||
done
|
||||
|
||||
# PkgInfo
|
||||
@@ -266,39 +269,41 @@ _complete_bundle() {
|
||||
_fixup_imports "${BUNDLE_DIR}"
|
||||
|
||||
# Build node modules
|
||||
pushd "${SOURCE_DIR}/web" > /dev/null
|
||||
pushd "${SOURCE_DIR}/web" > /dev/null || exit
|
||||
yarn install
|
||||
yarn run bundle
|
||||
|
||||
curl https://curl.se/ca/cacert.pem -o cacert.pem -s
|
||||
popd > /dev/null
|
||||
popd > /dev/null || exit
|
||||
|
||||
# copy the web directory to the bundle as it is required by runtime
|
||||
cp -r "${SOURCE_DIR}/web" "${BUNDLE_DIR}/Contents/Resources/"
|
||||
cd "${BUNDLE_DIR}/Contents/Resources/web"
|
||||
cd "${BUNDLE_DIR}/Contents/Resources/web" || exit
|
||||
rm -f pgadmin4.db config_local.*
|
||||
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
||||
find . -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
|
||||
find . -name ".DS_Store" -print0 | xargs -0 rm -f
|
||||
|
||||
echo "SERVER_MODE = False" > config_distro.py
|
||||
echo "HELP_PATH = '../../../docs/en_US/html/'" >> config_distro.py
|
||||
echo "DEFAULT_BINARY_PATHS = {" >> config_distro.py
|
||||
echo " 'pg': '\$DIR/../../SharedSupport'," >> config_distro.py
|
||||
echo " 'ppas': ''" >> config_distro.py
|
||||
echo "}" >> config_distro.py
|
||||
{
|
||||
echo "SERVER_MODE = False"
|
||||
echo "HELP_PATH = '../../../docs/en_US/html/'"
|
||||
echo "DEFAULT_BINARY_PATHS = {"
|
||||
echo " 'pg': '\$DIR/../../SharedSupport',"
|
||||
echo " 'ppas': ''"
|
||||
echo "}"
|
||||
} > config_distro.py
|
||||
|
||||
# License files
|
||||
cp -r ${SOURCE_DIR}/LICENSE "${BUNDLE_DIR}/Contents/"
|
||||
cp -r ${SOURCE_DIR}/DEPENDENCIES "${BUNDLE_DIR}/Contents/"
|
||||
cp -r "${SOURCE_DIR}/LICENSE" "${BUNDLE_DIR}/Contents/"
|
||||
cp -r "${SOURCE_DIR}/DEPENDENCIES" "${BUNDLE_DIR}/Contents/"
|
||||
|
||||
# Remove the .pyc files if any
|
||||
find "${BUNDLE_DIR}" -name "*.pyc" -print0 | xargs -0 rm -f
|
||||
}
|
||||
|
||||
_codesign_binaries() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
if [ "${CODESIGN}" -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -309,13 +314,14 @@ _codesign_binaries() {
|
||||
|
||||
# Create the entitlements file
|
||||
cp "${SCRIPT_DIR}/entitlements.plist.in" "${BUILD_ROOT}/entitlements.plist"
|
||||
TEAM_ID=$(echo ${DEVELOPER_ID} | awk -F"[()]" '{print $2}')
|
||||
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...
|
||||
echo Signing "${BUNDLE_DIR}" binaries...
|
||||
IFS=$'\n'
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | \
|
||||
grep -v "(for architecture" | \
|
||||
grep -v -E "^- Mach-O" | \
|
||||
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)
|
||||
@@ -328,25 +334,23 @@ _codesign_binaries() {
|
||||
"$i"
|
||||
done
|
||||
|
||||
echo Signing ${BUNDLE_DIR} libraries...
|
||||
for i in $(find "${BUNDLE_DIR}" -type f -name "*.dylib*")
|
||||
do
|
||||
echo Signing "${BUNDLE_DIR}" libraries...
|
||||
find "${BUNDLE_DIR}" -type f -name "*.dylib*" -exec \
|
||||
codesign --deep --force --verify --verbose --timestamp \
|
||||
--options runtime \
|
||||
--entitlements "${BUILD_ROOT}/entitlements.plist" \
|
||||
-i org.pgadmin.pgadmin4 \
|
||||
--sign "${DEVELOPER_ID}" \
|
||||
"$i"
|
||||
done
|
||||
{} \;
|
||||
}
|
||||
|
||||
_codesign_bundle() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
if [ "${CODESIGN}" -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Sign the .app
|
||||
echo Signing ${BUNDLE_DIR}...
|
||||
echo Signing "${BUNDLE_DIR}"...
|
||||
codesign --deep --force --verify --verbose --timestamp \
|
||||
--options runtime \
|
||||
--entitlements "${BUILD_ROOT}/entitlements.plist" \
|
||||
@@ -357,7 +361,7 @@ _codesign_bundle() {
|
||||
|
||||
_create_dmg() {
|
||||
# move to the directory where we want to create the DMG
|
||||
test -d ${DIST_ROOT} || mkdir ${DIST_ROOT}
|
||||
test -d "${DIST_ROOT}" || mkdir "${DIST_ROOT}"
|
||||
|
||||
echo "Checking out create-dmg..."
|
||||
git clone https://github.com/create-dmg/create-dmg.git "${BUILD_ROOT}/create-dmg"
|
||||
@@ -381,7 +385,7 @@ _create_dmg() {
|
||||
}
|
||||
|
||||
_codesign_dmg() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
if [ "${CODESIGN}" -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -396,20 +400,19 @@ _codesign_dmg() {
|
||||
|
||||
|
||||
_notarize_pkg() {
|
||||
if [ ${CODESIGN} -eq 0 ]; then
|
||||
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} \
|
||||
--asc-provider "${DEVELOPER_NAME}" \
|
||||
--primary-bundle-id org.pgadmin.pgadmin4 \
|
||||
-u ${DEVELOPER_USER} \
|
||||
-p ${DEVELOPER_ASP} 2>&1)
|
||||
-u "${DEVELOPER_USER}" \
|
||||
-p "${DEVELOPER_ASP}" 2>&1)
|
||||
RETVAL=$?
|
||||
|
||||
if [ ${RETVAL} != 0 ]; then
|
||||
@@ -427,7 +430,7 @@ _notarize_pkg() {
|
||||
fi
|
||||
|
||||
# Get the request ID
|
||||
REQUEST_UUID=$(echo ${STATUS} | awk '/RequestUUID/ { print $NF; }')
|
||||
REQUEST_UUID=$(echo "${STATUS}" | awk '/RequestUUID/ { print $NF; }')
|
||||
echo "Notarization request ID: ${REQUEST_UUID}"
|
||||
|
||||
# Now we need to wait for the results. Try 60 times.
|
||||
@@ -436,9 +439,9 @@ _notarize_pkg() {
|
||||
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 | \
|
||||
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
|
||||
@@ -447,9 +450,9 @@ _notarize_pkg() {
|
||||
done
|
||||
|
||||
# Print status information
|
||||
xcrun altool --notarization-info ${REQUEST_UUID} \
|
||||
--username ${DEVELOPER_USER} \
|
||||
--password ${DEVELOPER_ASP}
|
||||
xcrun altool --notarization-info "${REQUEST_UUID}" \
|
||||
--username "${DEVELOPER_USER}" \
|
||||
--password "${DEVELOPER_ASP}"
|
||||
|
||||
if [[ "${REQUEST_STATUS}" != "success" ]]; then
|
||||
echo "Notarization failed."
|
||||
@@ -458,10 +461,8 @@ _notarize_pkg() {
|
||||
|
||||
# Staple the notarization
|
||||
echo "Stapling the notarization to the pgAdmin DMG..."
|
||||
xcrun stapler staple "${DMG_NAME}"
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Stapling failed."
|
||||
if ! xcrun stapler staple "${DMG_NAME}"; then
|
||||
echo "Stapling failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -8,49 +8,57 @@ set -e -E
|
||||
# Debugging shizz
|
||||
trap 'ERRCODE=$? && if [ ${ERRCODE} -ne 0 ]; then echo "The command \"${BASH_COMMAND}\" failed in \"${FUNCNAME}\" with exit code ${ERRCODE}."; fi' EXIT
|
||||
|
||||
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
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
export SCRIPT_DIR
|
||||
SOURCE_DIR=$(realpath "${SCRIPT_DIR}"/../..)
|
||||
export SOURCE_DIR
|
||||
BUILD_ROOT=$(realpath "${SCRIPT_DIR}"/../..)/mac-build
|
||||
export BUILD_ROOT
|
||||
TEMP_DIR=$(realpath "${SCRIPT_DIR}"/../..)/mac-temp
|
||||
export TEMP_DIR
|
||||
DIST_ROOT=$(realpath "${SCRIPT_DIR}"/../..)/dist
|
||||
export DIST_ROOT
|
||||
|
||||
CODESIGN=1
|
||||
if [ ! -f ${SCRIPT_DIR}/codesign.conf ]; then
|
||||
export CODESIGN=1
|
||||
if [ ! -f "${SCRIPT_DIR}/codesign.conf" ]; then
|
||||
echo
|
||||
echo "******************************************************************"
|
||||
echo "* pkg/mac/codesign.conf not found. NOT signing the binaries."
|
||||
echo "******************************************************************"
|
||||
echo
|
||||
CODESIGN=0
|
||||
export CODESIGN=0
|
||||
sleep 2
|
||||
else
|
||||
source ${SCRIPT_DIR}/codesign.conf
|
||||
# shellcheck disable=SC1091
|
||||
source "${SCRIPT_DIR}/codesign.conf"
|
||||
fi
|
||||
|
||||
NOTARIZE=1
|
||||
if [ ! -f ${SCRIPT_DIR}/notarization.conf ]; then
|
||||
export 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
|
||||
export NOTARIZE=0
|
||||
sleep 2
|
||||
else
|
||||
source ${SCRIPT_DIR}/notarization.conf
|
||||
# shellcheck disable=SC1091
|
||||
source "${SCRIPT_DIR}/notarization.conf"
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_POSTGRES_DIR}" == "x" ]; then
|
||||
if [ "${PGADMIN_POSTGRES_DIR}" == "" ]; then
|
||||
echo "PGADMIN_POSTGRES_DIR not set. Setting it to the default: /usr/local/pgsql"
|
||||
export PGADMIN_POSTGRES_DIR=/usr/local/pgsql
|
||||
fi
|
||||
|
||||
if [ "x${PGADMIN_PYTHON_VERSION}" == "x" ]; then
|
||||
if [ "${PGADMIN_PYTHON_VERSION}" == "" ]; then
|
||||
echo "PGADMIN_PYTHON_VERSION not set. Setting it to the default: 3.9.9"
|
||||
export PGADMIN_PYTHON_VERSION=3.9.9
|
||||
fi
|
||||
|
||||
source ${SCRIPT_DIR}/build-functions.sh
|
||||
# shellcheck disable=SC1091
|
||||
source "${SCRIPT_DIR}/build-functions.sh"
|
||||
|
||||
_setup_env
|
||||
_cleanup
|
||||
|
||||
@@ -10,30 +10,28 @@
|
||||
#########################################################################
|
||||
|
||||
# Runtime checks
|
||||
if [ ! -d runtime -a ! -d web ]; then
|
||||
if [ ! -d runtime ] && [ ! -d web ]; then
|
||||
echo This script must be run from the top-level directory of the source tree.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d .git -a ! -f .git/config ]; then
|
||||
if [ ! -d .git ] && [ ! -f .git/config ]; then
|
||||
echo This script must be run from a git checkout of the source tree.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the required package info
|
||||
APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
|
||||
APP_RELEASE=$(grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_REVISION=$(grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_NAME=$(grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
|
||||
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
|
||||
APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
|
||||
APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
|
||||
if [ ! -z ${APP_SUFFIX} ]; then
|
||||
APP_SUFFIX=$(grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
|
||||
if [ -n "${APP_SUFFIX}" ]; then
|
||||
export APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
||||
fi
|
||||
TARBALL_NAME=`echo ${APP_NAME}-${APP_LONG_VERSION} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
|
||||
# Output basic details to show we're working
|
||||
echo Building tarballs for ${APP_NAME} version ${APP_LONG_VERSION}...
|
||||
echo Building tarballs for "${APP_NAME}" version "${APP_LONG_VERSION}"...
|
||||
|
||||
# Create/clearout the build directory
|
||||
echo Creating/cleaning required directories...
|
||||
@@ -49,36 +47,39 @@ mkdir pip-build/pgadmin4
|
||||
mkdir pip-build/pgadmin4/docs
|
||||
|
||||
# Build the clean tree
|
||||
cd web
|
||||
for FILE in `git ls-files`
|
||||
cd web || exit
|
||||
for FILE in $(git ls-files)
|
||||
do
|
||||
echo Adding ${FILE}
|
||||
echo Adding "${FILE}"
|
||||
# We use tar here to preserve the path, as Mac (for example) doesn't support cp --parents
|
||||
tar cf - ${FILE} | (cd ../pip-build/pgadmin4; tar xf -)
|
||||
# shellcheck disable=SC2164
|
||||
tar cf - "${FILE}" | (cd ../pip-build/pgadmin4; tar xf -)
|
||||
done
|
||||
|
||||
yarn install
|
||||
yarn run bundle
|
||||
|
||||
for FILE in `ls -d pgadmin/static/js/generated/*`
|
||||
for FILE in pgadmin/static/js/generated/*
|
||||
do
|
||||
echo Adding ${FILE}
|
||||
tar cf - ${FILE} | (cd ../pip-build/pgadmin4; tar xf -)
|
||||
echo Adding "${FILE}"
|
||||
# shellcheck disable=SC2164
|
||||
tar cf - "${FILE}" | (cd ../pip-build/pgadmin4; tar xf -)
|
||||
done
|
||||
|
||||
cd ../docs
|
||||
for FILE in `git ls-files`
|
||||
cd ../docs || exit
|
||||
for FILE in $(git ls-files)
|
||||
do
|
||||
echo Adding ${FILE}
|
||||
echo Adding "${FILE}"
|
||||
# We use tar here to preserve the path, as Mac (for example) doesn't support cp --parents
|
||||
tar cf - ${FILE} | (cd ../pip-build/pgadmin4/docs; tar xf -)
|
||||
# shellcheck disable=SC2164
|
||||
tar cf - "${FILE}" | (cd ../pip-build/pgadmin4/docs; tar xf -)
|
||||
done
|
||||
|
||||
for DIR in `ls -d ??_??/`
|
||||
for DIR in ./??_??/
|
||||
do
|
||||
if [ -d ${DIR}/_build/html ]; then
|
||||
mkdir -p ../pip-build/pgadmin4/docs/${DIR}/_build
|
||||
cp -R ${DIR}/_build/html ../pip-build/pgadmin4/docs/${DIR}/_build
|
||||
if [ -d "${DIR}"/_build/html ]; then
|
||||
mkdir -p "../pip-build/pgadmin4/docs/${DIR}/_build"
|
||||
cp -R "${DIR}/_build/html" "../pip-build/pgadmin4/docs/${DIR}/_build"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -87,6 +88,7 @@ for FILE in LICENSE DEPENDENCIES README.md
|
||||
do
|
||||
echo Adding ${FILE}
|
||||
# We use tar here to preserve the path, as Mac (for example) doesn't support cp --parents
|
||||
# shellcheck disable=SC2164
|
||||
tar cf - ${FILE} | (cd pip-build/pgadmin4; tar xf -)
|
||||
done
|
||||
|
||||
@@ -101,7 +103,7 @@ echo recursive-include pgadmin4 \* > pip-build/MANIFEST.in
|
||||
|
||||
# Run the build
|
||||
echo Building wheel...
|
||||
cd pip-build
|
||||
cd pip-build || exit
|
||||
python ../pkg/pip/setup_pip.py bdist_wheel
|
||||
cd ../
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ set -e
|
||||
# Debugging shizz
|
||||
trap 'ERRCODE=$? && if [ ${ERRCODE} -ne 0 ]; then echo "The command \"${BASH_COMMAND}\" failed in \"${FUNCNAME}\" with exit code ${ERRCODE}."; fi' EXIT
|
||||
|
||||
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_NAME=$(cat /etc/os-release | grep "^ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_VERSION=$(grep "^VERSION_ID=" /etc/os-release | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_ARCH=$(arch)
|
||||
|
||||
# Make sure we get the right libpq
|
||||
@@ -17,10 +16,11 @@ export PATH=/usr/pgsql-14/bin:$PATH
|
||||
export PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# Common Linux build functions
|
||||
# shellcheck disable=SC1091
|
||||
source pkg/linux/build-functions.sh
|
||||
|
||||
# Assemble the "standard" installation footprint
|
||||
_setup_env $0 "redhat"
|
||||
_setup_env "$0" "redhat"
|
||||
_cleanup "rpm"
|
||||
_setup_dirs
|
||||
_create_python_virtualenv "redhat"
|
||||
@@ -30,7 +30,7 @@ _copy_code
|
||||
|
||||
# Get an RPM-compatible version number
|
||||
RPM_VERSION=${APP_RELEASE}.${APP_REVISION}
|
||||
if [ ! -z ${APP_SUFFIX} ]; then
|
||||
if [ -n "${APP_SUFFIX}" ]; then
|
||||
RPM_VERSION=${RPM_VERSION}_${APP_SUFFIX}
|
||||
fi
|
||||
|
||||
@@ -222,23 +222,23 @@ rpmbuild --define "pga_build_root ${BUILDROOT}" -bb "${BUILDROOT}/meta.spec"
|
||||
#
|
||||
# mod_wsgi for CentOS 7
|
||||
#
|
||||
if [ ${OS_VERSION} == 7 ]; then
|
||||
cp "${SOURCEDIR}/pkg/redhat/pgadmin4-python3-mod_wsgi-exports.patch" ${HOME}/rpmbuild/SOURCES
|
||||
cp "${SOURCEDIR}/pkg/redhat/pgadmin4-python3-mod_wsgi.conf" ${HOME}/rpmbuild/SOURCES
|
||||
curl -o ${HOME}/rpmbuild/SOURCES/mod_wsgi-4.9.0.tar.gz https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.9.0
|
||||
if [ "${OS_VERSION}" == 7 ]; then
|
||||
cp "${SOURCEDIR}/pkg/redhat/pgadmin4-python3-mod_wsgi-exports.patch" "${HOME}/rpmbuild/SOURCES"
|
||||
cp "${SOURCEDIR}/pkg/redhat/pgadmin4-python3-mod_wsgi.conf" "${HOME}/rpmbuild/SOURCES"
|
||||
curl -o "${HOME}/rpmbuild/SOURCES/mod_wsgi-4.9.0.tar.gz" https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.9.0
|
||||
rpmbuild -bb "${SOURCEDIR}/pkg/redhat/pgadmin4-python-mod_wsgi.spec"
|
||||
fi
|
||||
|
||||
# Get the libpq we need
|
||||
yumdownloader -y --downloadonly --destdir=$DISTROOT postgresql14-libs
|
||||
yumdownloader -y --downloadonly --destdir="${DISTROOT}" postgresql14-libs
|
||||
|
||||
#
|
||||
# Get the results!
|
||||
#
|
||||
cp ${HOME}/rpmbuild/RPMS/${OS_ARCH}/${APP_NAME}-*${RPM_VERSION}-*.${OS_ARCH}.rpm "${DISTROOT}/"
|
||||
cp ${HOME}/rpmbuild/RPMS/noarch/${APP_NAME}-*${RPM_VERSION}-*.noarch.rpm "${DISTROOT}/"
|
||||
if [ ${OS_VERSION} == 7 ]; then
|
||||
cp ${HOME}/rpmbuild/RPMS/${OS_ARCH}/pgadmin4-python3-mod_wsgi-4.9.0-1.el7.x86_64.rpm "${DISTROOT}/"
|
||||
cp "${HOME}/rpmbuild/RPMS/${OS_ARCH}/${APP_NAME}-"*"${RPM_VERSION}-"*".${OS_ARCH}.rpm" "${DISTROOT}/"
|
||||
cp "${HOME}/rpmbuild/RPMS/noarch/${APP_NAME}-"*"${RPM_VERSION}-"*".noarch.rpm" "${DISTROOT}/"
|
||||
if [ "${OS_VERSION}" == 7 ]; then
|
||||
cp "${HOME}/rpmbuild/RPMS/${OS_ARCH}/pgadmin4-python3-mod_wsgi-4.9.0-1.el7.x86_64.rpm" "${DISTROOT}/"
|
||||
fi
|
||||
|
||||
echo "Completed. RPMs created in ${DISTROOT}."
|
||||
@@ -5,7 +5,7 @@ REPO_RPM_VERSION=2
|
||||
REPO_RPM_BUILD=1
|
||||
|
||||
# Set the repo base directory
|
||||
if [ "x${PGADMIN_REPO_DIR}" == "x" ]; then
|
||||
if [ "${PGADMIN_REPO_DIR}" == "" ]; then
|
||||
echo "PGADMIN_REPO_DIR not set. Setting it to the default: https://ftp.postgresql.org/pub/pgadmin/pgadmin4/repos/yum"
|
||||
export PGADMIN_REPO_DIR=https://ftp.postgresql.org/pub/pgadmin/pgadmin4/repos/yum
|
||||
fi
|
||||
@@ -14,14 +14,10 @@ fi
|
||||
set -e
|
||||
|
||||
# Debugging shizz
|
||||
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
|
||||
trap 'if [ $? -ne 0 ]; then echo "\"${last_command}\" command filed with exit code $?."; fi' EXIT
|
||||
|
||||
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_NAME=$(cat /etc/os-release | grep "^ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
|
||||
OS_ARCH=$(arch)
|
||||
trap 'ERRCODE=$? && if [ ${ERRCODE} -ne 0 ]; then echo "The command \"${BASH_COMMAND}\" failed in \"${FUNCNAME}\" with exit code ${ERRCODE}."; fi' EXIT
|
||||
|
||||
# Common Linux build functions
|
||||
# shellcheck disable=SC1091
|
||||
source pkg/linux/build-functions.sh
|
||||
|
||||
# Are we installing a package key?
|
||||
@@ -38,14 +34,14 @@ fi
|
||||
# Create the Redhat packaging stuffs for the repo
|
||||
_create_repo_rpm() {
|
||||
DISTRO=$1
|
||||
if [ ${DISTRO} == "redhat" ]; then
|
||||
if [ "${DISTRO}" == "redhat" ]; then
|
||||
PLATFORM="rhel"
|
||||
else
|
||||
PLATFORM=${DISTRO}
|
||||
fi
|
||||
|
||||
echo "Creating the repo package for ${DISTRO}..."
|
||||
test -d ${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d || mkdir -p ${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d
|
||||
test -d "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d" || mkdir -p "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d"
|
||||
|
||||
cat << EOF > "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
|
||||
[pgAdmin4]
|
||||
@@ -55,9 +51,11 @@ enabled=1
|
||||
EOF
|
||||
|
||||
if [ ${INCLUDE_KEY} -eq 1 ]; then
|
||||
echo repo_gpgcheck=1 >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
|
||||
echo gpgcheck=1 >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
|
||||
echo gpgkey=file:///etc/pki/rpm-gpg/PGADMIN_PKG_KEY >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
|
||||
{
|
||||
echo repo_gpgcheck=1
|
||||
echo gpgcheck=1
|
||||
echo gpgkey=file:///etc/pki/rpm-gpg/PGADMIN_PKG_KEY
|
||||
} >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
|
||||
else
|
||||
echo gpgcheck=0 >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
|
||||
fi
|
||||
@@ -88,11 +86,11 @@ cp -rfa %{pga_build_root}/${DISTRO}-repo/* \${RPM_BUILD_ROOT}
|
||||
EOF
|
||||
|
||||
if [ ${INCLUDE_KEY} -eq 1 ]; then
|
||||
cat << EOF >> ${BUILDROOT}/${DISTRO}-repo.spec
|
||||
cat << EOF >> "${BUILDROOT}/${DISTRO}-repo.spec"
|
||||
/etc/pki/rpm-gpg/PGADMIN_PKG_KEY
|
||||
EOF
|
||||
test -d ${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg || mkdir -p ${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg
|
||||
cp pkg/redhat/PGADMIN_PKG_KEY ${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg/
|
||||
test -d "${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg" || mkdir -p "${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg"
|
||||
cp pkg/redhat/PGADMIN_PKG_KEY "${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg/"
|
||||
fi
|
||||
|
||||
# Build the package
|
||||
@@ -100,7 +98,7 @@ EOF
|
||||
rpmbuild --define "pga_build_root ${BUILDROOT}" -bb "${BUILDROOT}/${DISTRO}-repo.spec"
|
||||
}
|
||||
|
||||
_setup_env $0 "redhat"
|
||||
_setup_env "$0" "redhat"
|
||||
_create_repo_rpm redhat
|
||||
_create_repo_rpm fedora
|
||||
|
||||
@@ -108,4 +106,4 @@ _create_repo_rpm fedora
|
||||
# Get the results!
|
||||
#
|
||||
test -d "${DISTROOT}/" || mkdir -p "${DISTROOT}/"
|
||||
cp ${HOME}/rpmbuild/RPMS/noarch/${APP_NAME}-*-repo-${REPO_RPM_VERSION}-${REPO_RPM_BUILD}.noarch.rpm "${DISTROOT}/"
|
||||
cp "${HOME}/rpmbuild/RPMS/noarch/${APP_NAME}-"*"-repo-${REPO_RPM_VERSION}-${REPO_RPM_BUILD}.noarch.rpm" "${DISTROOT}/"
|
||||
@@ -5,24 +5,24 @@ if [ "$EUID" -ne 0 ]
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g' | awk -F "." '{ print $1 }')
|
||||
OS_VERSION=$(grep "^VERSION_ID=" /etc/os-release | awk -F "=" '{ print $2 }' | sed 's/"//g' | awk -F "." '{ print $1 }')
|
||||
|
||||
# EPEL & other repos
|
||||
if [ ${OS_VERSION} != 9 ]; then
|
||||
if [ "${OS_VERSION}" != 9 ]; then
|
||||
yum -y install centos-release-scl
|
||||
fi
|
||||
|
||||
yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${OS_VERSION}.noarch.rpm
|
||||
if [ ${OS_VERSION} == 8 ] || [ ${OS_VERSION} == 9 ]; then
|
||||
yum config-manager --enable PowerTools AppStream BaseOS *epel
|
||||
yum install -y "https://dl.fedoraproject.org/pub/epel/epel-release-latest-${OS_VERSION}.noarch.rpm"
|
||||
if [ "${OS_VERSION}" == 8 ] || [ "${OS_VERSION}" == 9 ]; then
|
||||
yum config-manager --enable PowerTools AppStream BaseOS "*epel"
|
||||
dnf -qy module disable postgresql
|
||||
fi
|
||||
|
||||
# PostgreSQL repo
|
||||
if [ ${OS_VERSION} == 7 ] || [ ${OS_VERSION} == 8 ] || [ ${OS_VERSION} == 9 ]; then
|
||||
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-${OS_VERSION}-x86_64/pgdg-redhat-repo-latest.noarch.rpm
|
||||
if [ "${OS_VERSION}" == 7 ] || [ "${OS_VERSION}" == 8 ] || [ "${OS_VERSION}" == 9 ]; then
|
||||
yum install -y "https://download.postgresql.org/pub/repos/yum/reporpms/EL-${OS_VERSION}-x86_64/pgdg-redhat-repo-latest.noarch.rpm"
|
||||
else
|
||||
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/F-${OS_VERSION}-x86_64/pgdg-fedora-repo-latest.noarch.rpm
|
||||
yum install -y "https://download.postgresql.org/pub/repos/yum/reporpms/F-${OS_VERSION}-x86_64/pgdg-fedora-repo-latest.noarch.rpm"
|
||||
fi
|
||||
|
||||
# Node repo
|
||||
@@ -37,20 +37,21 @@ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yu
|
||||
echo "Installing build pre-requisites..."
|
||||
yum groupinstall -y "Development Tools"
|
||||
|
||||
if [ ${OS_VERSION} == 7 ]; then
|
||||
if [ "${OS_VERSION}" == 7 ]; then
|
||||
yum install -y expect fakeroot httpd-devel postgresql14-devel python3-devel nodejs yarn rpm-build rpm-sign yum-utils krb5-devel
|
||||
pip3 install sphinx
|
||||
elif [ ${OS_VERSION} == 9 ]; then
|
||||
elif [ "${OS_VERSION}" == 9 ]; then
|
||||
yum install -y expect postgresql14-devel python3-devel nodejs yarn rpm-build rpm-sign yum-utils krb5-devel
|
||||
pip3 install sphinx
|
||||
else
|
||||
yum install -y expect fakeroot postgresql14-devel python3-devel python3-sphinx nodejs yarn rpm-build rpm-sign yum-utils krb5-devel
|
||||
yum install -y expect fakeroot postgresql14-devel python3-devel nodejs yarn rpm-build rpm-sign yum-utils krb5-devel
|
||||
pip3 install sphinx
|
||||
fi
|
||||
|
||||
# Setup RPM macros for signing
|
||||
echo "Please add the following macros to ~/.rpmmacros for the user that will sign the RPMs if required:"
|
||||
echo
|
||||
if [ ${OS_VERSION} == 7 ]; then
|
||||
if [ "${OS_VERSION}" == 7 ]; then
|
||||
cat << EOF
|
||||
# Macros for signing RPMs.
|
||||
|
||||
|
||||
@@ -10,31 +10,30 @@
|
||||
#########################################################################
|
||||
|
||||
# Runtime checks
|
||||
if [ ! -d runtime -a ! -d web ]; then
|
||||
if [ ! -d runtime ] && [ ! -d web ]; then
|
||||
echo This script must be run from the top-level directory of the source tree.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d .git -a ! -f .git/config ]; then
|
||||
if [ ! -d .git ] && [ ! -f .git/config ]; then
|
||||
echo This script must be run from a git checkout of the source tree.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the required package info
|
||||
APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||
APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
|
||||
APP_RELEASE=$(grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_REVISION=$(grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g')
|
||||
APP_NAME=$(grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //')
|
||||
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
|
||||
APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
|
||||
APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
|
||||
if [ ! -z ${APP_SUFFIX} ]; then
|
||||
APP_SUFFIX=$(grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
|
||||
if [ -n "${APP_SUFFIX}" ]; then
|
||||
export APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
||||
fi
|
||||
TARBALL_NAME=`echo ${APP_NAME}-${APP_LONG_VERSION} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
DOC_TARBALL_NAME=`echo ${APP_NAME}-${APP_LONG_VERSION}-docs | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||
TARBALL_NAME=$(echo "${APP_NAME}-${APP_LONG_VERSION}" | sed 's/ //g' | awk '{print tolower($0)}')
|
||||
DOC_TARBALL_NAME=$(echo "${APP_NAME}-${APP_LONG_VERSION}-docs" | sed 's/ //g' | awk '{print tolower($0)}')
|
||||
|
||||
# Output basic details to show we're working
|
||||
echo Building tarballs for ${APP_NAME} version ${APP_LONG_VERSION}...
|
||||
echo "Building tarballs for ${APP_NAME} version ${APP_LONG_VERSION}..."
|
||||
|
||||
# Create/clearout the build directory
|
||||
echo Creating/cleaning required directories...
|
||||
@@ -42,58 +41,60 @@ if [ ! -d src-build ]; then
|
||||
mkdir src-build
|
||||
fi
|
||||
|
||||
if [ -d src-build/${TARBALL_NAME} ]; then
|
||||
rm -rf src-build/${TARBALL_NAME}
|
||||
if [ -d "src-build/${TARBALL_NAME}" ]; then
|
||||
rm -rf "src-build/${TARBALL_NAME}"
|
||||
fi
|
||||
|
||||
mkdir src-build/${TARBALL_NAME}
|
||||
mkdir "src-build/${TARBALL_NAME}"
|
||||
|
||||
# Create the output directory if not present
|
||||
if [ ! -d dist ]; then
|
||||
mkdir dist
|
||||
fi
|
||||
|
||||
if [ -f dist/${TARBALL_NAME}.tar.gz ]; then
|
||||
rm -f dist/${TARBALL_NAME}.tar.gz
|
||||
if [ -f "dist/${TARBALL_NAME}.tar.gz" ]; then
|
||||
rm -f "dist/${TARBALL_NAME}.tar.gz"
|
||||
fi
|
||||
|
||||
if [ -f dist/${DOC_TARBALL_NAME}.tar.gz ]; then
|
||||
rm -f dist/${DOC_TARBALL_NAME}.tar.gz
|
||||
if [ -f "dist/${DOC_TARBALL_NAME}.tar.gz" ]; then
|
||||
rm -f "dist/${DOC_TARBALL_NAME}.tar.gz"
|
||||
fi
|
||||
|
||||
# Build the clean tree
|
||||
for FILE in `git ls-files`
|
||||
for FILE in $(git ls-files)
|
||||
do
|
||||
echo Adding ${FILE}
|
||||
echo Adding "${FILE}"
|
||||
# We use tar here to preserve the path, as Mac (for example) doesn't support cp --parents
|
||||
tar cf - ${FILE} | (cd src-build/${TARBALL_NAME}; tar xf -)
|
||||
# shellcheck disable=SC2164
|
||||
tar cf - "${FILE}" | (cd "src-build/${TARBALL_NAME}"; tar xf -)
|
||||
done
|
||||
|
||||
pushd web > /dev/null
|
||||
pushd web > /dev/null || exit
|
||||
yarn install
|
||||
yarn run bundle
|
||||
|
||||
for FILE in `ls -d pgadmin/static/js/generated/*`
|
||||
for FILE in pgadmin/static/js/generated/*
|
||||
do
|
||||
echo Adding ${FILE}
|
||||
tar cf - ${FILE} | (cd ../src-build/${TARBALL_NAME}/web; tar xf -)
|
||||
echo Adding "${FILE}"
|
||||
# shellcheck disable=SC2164
|
||||
tar cf - "${FILE}" | (cd "../src-build/${TARBALL_NAME}/web"; tar xf -)
|
||||
done
|
||||
popd > /dev/null
|
||||
popd > /dev/null || exit
|
||||
|
||||
# Create the tarball
|
||||
echo Creating tarball...
|
||||
cd src-build
|
||||
tar zcvf ../dist/${TARBALL_NAME}.tar.gz ${TARBALL_NAME}
|
||||
cd src-build || exit
|
||||
tar zcvf "../dist/${TARBALL_NAME}.tar.gz" "${TARBALL_NAME}"
|
||||
cd ..
|
||||
|
||||
# Create the docs
|
||||
echo Creating docs...
|
||||
cd src-build/${TARBALL_NAME}/docs/en_US
|
||||
cd "src-build/${TARBALL_NAME}/docs/en_US" || exit
|
||||
make -f Makefile.sphinx html
|
||||
cd _build
|
||||
mv html ${DOC_TARBALL_NAME}
|
||||
tar zcvf ../../../../../dist/${DOC_TARBALL_NAME}.tar.gz ${DOC_TARBALL_NAME}
|
||||
cd _build || exit
|
||||
mv html "${DOC_TARBALL_NAME}"
|
||||
tar zcvf "../../../../../dist/${DOC_TARBALL_NAME}.tar.gz" "${DOC_TARBALL_NAME}"
|
||||
cd ../../../../../
|
||||
|
||||
# Fin!
|
||||
echo Created tarball dist/${TARBALL_NAME}.tar.gz and dist/${DOC_TARBALL_NAME}.tar.gz
|
||||
echo "Created tarball dist/${TARBALL_NAME}.tar.gz and dist/${DOC_TARBALL_NAME}.tar.gz"
|
||||
@@ -8,7 +8,8 @@
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
Flask==2.*
|
||||
Flask==2.0.3; python_version <= '3.6'
|
||||
Flask==2.1.*; python_version >= '3.7'
|
||||
Flask-Gravatar==0.*
|
||||
Flask-Login==0.*
|
||||
Flask-Mail==0.*
|
||||
@@ -19,7 +20,7 @@ Flask-Compress==1.*
|
||||
Flask-Paranoid==0.*
|
||||
Flask-Babel==2.*
|
||||
Flask-Security-Too==4.1.*
|
||||
Flask-SocketIO>=5.0.1
|
||||
Flask-SocketIO<=5.2.0
|
||||
WTForms==3.*
|
||||
passlib==1.*
|
||||
pytz==2021.*
|
||||
@@ -49,7 +50,8 @@ Pillow==9.*; python_version >= '3.7'
|
||||
boto3==1.20.*
|
||||
botocore==1.23.*
|
||||
urllib3==1.26.*
|
||||
Werkzeug==2.0.3
|
||||
Werkzeug==2.0.3; python_version <= '3.6'
|
||||
Werkzeug==2.1.2; python_version >= '3.7'
|
||||
azure-mgmt-rdbms==10.1.0
|
||||
azure-mgmt-resource==21.0.0
|
||||
azure-mgmt-subscription==3.0.0
|
||||
|
||||
@@ -335,7 +335,7 @@ const toggleFullScreen = () => {
|
||||
pgAdminWindowObject.toggleFullscreen();
|
||||
|
||||
// Change the menu label.
|
||||
var menu_label = pgAdminWindowObject.window.document.querySelector('#mnu_toggle_fullscreen_runtime span').innerHTML;
|
||||
let menu_label = pgAdminWindowObject.window.document.querySelector('#mnu_toggle_fullscreen_runtime span').innerHTML;
|
||||
if (menu_label.indexOf('Enter Full Screen') >= 0) {
|
||||
pgAdminWindowObject.window.document.querySelector('#mnu_toggle_fullscreen_runtime span').innerHTML = menu_label.replace('Enter', 'Exit');
|
||||
} else if (menu_label.indexOf('Exit Full Screen') >= 0) {
|
||||
|
||||
@@ -38,16 +38,6 @@ if (fs.existsSync('dev_config.json')) {
|
||||
}
|
||||
}
|
||||
|
||||
// This function is used to create UUID
|
||||
function createUUID() {
|
||||
let dt = new Date().getTime();
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
let r = (dt + Math.random()*16)%16 | 0;
|
||||
dt = Math.floor(dt/16);
|
||||
return (c==='x' ? r :(r&0x3|0x8)).toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
// This functions is used to start the pgAdmin4 server by spawning a
|
||||
// separate process.
|
||||
function startDesktopMode() {
|
||||
@@ -56,7 +46,7 @@ function startDesktopMode() {
|
||||
if (pgadminServerProcess != null)
|
||||
return;
|
||||
|
||||
let UUID = createUUID();
|
||||
let UUID = crypto.randomUUID();
|
||||
// Set the environment variables so that pgAdmin 4 server
|
||||
// starts listening on the appropriate port.
|
||||
process.env.PGADMIN_INT_PORT = serverPort;
|
||||
@@ -80,6 +70,13 @@ function startDesktopMode() {
|
||||
misc.writeServerLog('pgAdmin Command: "' + command + '"');
|
||||
misc.writeServerLog('Environment: ');
|
||||
Object.keys(process.env).forEach(function(key) {
|
||||
// Below code is included only for Mac OS as default path for azure CLI
|
||||
// installation path is not included in PATH variable while spawning
|
||||
// runtime environment.
|
||||
if (platform() === 'darwin' && key === 'PATH') {
|
||||
let updated_path = process.env[key] + ':/usr/local/bin';
|
||||
process.env[key] = updated_path;
|
||||
}
|
||||
misc.writeServerLog(' - ' + key + ': ' + process.env[key]);
|
||||
});
|
||||
misc.writeServerLog('--------------------------------------------------------\n');
|
||||
|
||||
@@ -43,7 +43,7 @@ APP_ICON = 'pg-icon'
|
||||
|
||||
# Application version number components
|
||||
APP_RELEASE = 6
|
||||
APP_REVISION = 12
|
||||
APP_REVISION = 14
|
||||
|
||||
# Application version suffix, e.g. 'beta1', 'dev'. Usually an empty string
|
||||
# for GA releases.
|
||||
@@ -52,7 +52,7 @@ APP_SUFFIX = ''
|
||||
# Numeric application version for upgrade checks. Should be in the format:
|
||||
# [X]XYYZZ, where X is the release version, Y is the revision, with a leading
|
||||
# zero if needed, and Z represents the suffix, with a leading zero if needed
|
||||
APP_VERSION_INT = 61200
|
||||
APP_VERSION_INT = 61400
|
||||
|
||||
# DO NOT CHANGE!
|
||||
# The application version string, constructed from the components
|
||||
@@ -82,6 +82,7 @@ LANGUAGES = {
|
||||
'ja': 'Japanese',
|
||||
'ko': 'Korean',
|
||||
'pl': 'Polish',
|
||||
'pt_BR': 'Portuguese (Brazilian)',
|
||||
'ru': 'Russian',
|
||||
'es': 'Spanish',
|
||||
}
|
||||
@@ -107,10 +108,11 @@ NODE_BLACKLIST = []
|
||||
# We only set SERVER_MODE if it's not already set. That's to allow the
|
||||
# runtime to force it to False.
|
||||
#
|
||||
# NOTE: If you change the value of SERVER_MODE in an included config file,
|
||||
# you may also need to redefine any values below that are derived
|
||||
# from it, notably various paths such as LOG_FILE and anything
|
||||
# using DATA_DIR.
|
||||
# NOTE: If you change the value of SERVER_MODE or DATA_DIR in an included
|
||||
# config file, you may also need to redefine any values below that are
|
||||
# derived from it, notably various paths such as LOG_FILE, SQLITE_PATH,
|
||||
# SESSION_DB_PATH, STORAGE_DIR, KERBEROS_CCACHE_DIR, and
|
||||
# AZURE_CREDENTIAL_CACHE_DIR
|
||||
|
||||
if (not hasattr(builtins, 'SERVER_MODE')) or builtins.SERVER_MODE is None:
|
||||
SERVER_MODE = True
|
||||
|
||||
@@ -33,7 +33,6 @@ module.exports = function (config) {
|
||||
}),
|
||||
],
|
||||
files: [
|
||||
'pgadmin/static/bundle/slickgrid.js',
|
||||
{pattern: 'pgadmin/static/**/*.js', included: false, watched: true},
|
||||
{pattern: 'pgadmin/browser/static/js/**/*.js', included: false, watched: true},
|
||||
{pattern: 'regression/javascript/**/*.js', watched: true},
|
||||
@@ -50,7 +49,6 @@ module.exports = function (config) {
|
||||
preprocessors: {
|
||||
'pgadmin/**/js/**/*.js?': ['sourcemap'],
|
||||
'regression/javascript/**/*.js': ['webpack', 'sourcemap'],
|
||||
'pgadmin/static/bundle/slickgrid.js': ['webpack', 'sourcemap'],
|
||||
},
|
||||
|
||||
// optionally, configure the reporter
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
"exports-loader": "^2.0.0",
|
||||
"html-react-parser": "^1.2.7",
|
||||
"image-minimizer-webpack-plugin": "^2.2.0",
|
||||
"imagemin-mozjpeg": "^10.0.0",
|
||||
"imagemin-optipng": "^8.0.0",
|
||||
"imagemin-pngquant": "^9.0.2",
|
||||
"is-docker": "^2.1.1",
|
||||
"istanbul-instrumenter-loader": "^3.0.1",
|
||||
"jasmine-core": "^3.6.0",
|
||||
@@ -85,20 +88,15 @@
|
||||
"@projectstorm/react-diagrams": "^6.6.1",
|
||||
"@simonwep/pickr": "^1.5.1",
|
||||
"@szhsin/react-menu": "^2.2.0",
|
||||
"@tippyjs/react": "^4.2.0",
|
||||
"@types/classnames": "^2.2.6",
|
||||
"@types/react": "^16.7.18",
|
||||
"@types/react-dom": "^16.0.11",
|
||||
"ajv": "^8.8.2",
|
||||
"alertifyjs": "git+https://github.com/EnterpriseDB/AlertifyJS/#72c1d794f5b6d4ec13a68d123c08f19021afe263",
|
||||
"anti-trojan-source": "^1.4.0",
|
||||
"aspen-decorations": "^1.0.2",
|
||||
"axios": "^0.21.1",
|
||||
"babelify": "~10.0.0",
|
||||
"backbone": "1.4.0",
|
||||
"backform": "^0.2.0",
|
||||
"backgrid-filter": "^0.3.7",
|
||||
"backgrid-select-all": "^0.3.5",
|
||||
"bignumber.js": "^9.0.1",
|
||||
"bootstrap": "^4.3.1",
|
||||
"bootstrap-datepicker": "^1.8.0",
|
||||
@@ -147,7 +145,7 @@
|
||||
"react": "^17.0.1",
|
||||
"react-aspen": "^1.1.0",
|
||||
"react-checkbox-tree": "^1.7.2",
|
||||
"react-data-grid": "git+https://github.com/adityatoshniwal/react-data-grid.git/#8d9bc16ddd7c419acfbbd1c1cc2b70eb9f5b453c",
|
||||
"react-data-grid": "git+https://github.com/EnterpriseDB/react-data-grid.git/#200d2f5e02de694e3e9ffbe177c279bc40240fb8",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-draggable": "^4.4.4",
|
||||
"react-dropzone": "^14.2.1",
|
||||
@@ -161,7 +159,6 @@
|
||||
"react-window": "^1.8.5",
|
||||
"select2": "^4.0.13",
|
||||
"shim-loader": "^1.0.1",
|
||||
"slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16",
|
||||
"snapsvg-cjs": "^0.0.6",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"split.js": "^1.5.10",
|
||||
|
||||
@@ -239,11 +239,11 @@ class AzureProvider(AbsProvider):
|
||||
except ResourceNotFoundError:
|
||||
pass
|
||||
except Exception as e:
|
||||
error(args, e)
|
||||
error(str(e))
|
||||
|
||||
if svr is not None:
|
||||
error(args, 'Azure Database for PostgreSQL instance {} already '
|
||||
'exists.'.format(args.name))
|
||||
error('Azure Database for PostgreSQL instance {} already '
|
||||
'exists.'.format(args.name))
|
||||
|
||||
db_password = self._database_pass if self._database_pass is not None \
|
||||
else args.db_password
|
||||
@@ -273,7 +273,7 @@ class AzureProvider(AbsProvider):
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
error(e)
|
||||
error(str(e))
|
||||
|
||||
server = poller.result()
|
||||
|
||||
@@ -313,7 +313,7 @@ class AzureProvider(AbsProvider):
|
||||
firewall_rules.append(firewall_rule.__dict__)
|
||||
return firewall_rules
|
||||
|
||||
def _delete_azure_instance(self, args, name):
|
||||
def _delete_azure_instance(self, args):
|
||||
""" Delete an Azure instance """
|
||||
# Obtain the management client object
|
||||
postgresql_client = self._get_azure_client('postgresql')
|
||||
@@ -326,7 +326,7 @@ class AzureProvider(AbsProvider):
|
||||
args.name
|
||||
)
|
||||
except Exception as e:
|
||||
error(args, e)
|
||||
error(str(e))
|
||||
|
||||
poller.result()
|
||||
|
||||
@@ -353,7 +353,7 @@ class AzureProvider(AbsProvider):
|
||||
|
||||
def cmd_delete_instance(self, args):
|
||||
""" Delete an Azure instance """
|
||||
self._delete_azure_instance(args, args.name)
|
||||
self._delete_azure_instance(args)
|
||||
|
||||
|
||||
def load():
|
||||
|
||||
@@ -70,23 +70,24 @@ class BigAnimalProvider(AbsProvider):
|
||||
parser_create_instance.add_argument('--public-ip', default='',
|
||||
help='Public IP '
|
||||
'(default: 127.0.0.1)')
|
||||
parser_create_instance.add_argument('--high-availability',
|
||||
parser_create_instance.add_argument('--cluster-arch',
|
||||
required=True,
|
||||
help='High Availability')
|
||||
help='Cluster Architecture')
|
||||
parser_create_instance.add_argument('--nodes',
|
||||
required=True,
|
||||
help='No of Nodes')
|
||||
|
||||
def cmd_create_instance(self, args):
|
||||
""" Create a biganimal cluster """
|
||||
|
||||
try:
|
||||
private_network = True if args.private_network == '1' else False
|
||||
high_availability = True if args.high_availability == '1' else\
|
||||
False
|
||||
ip = args.public_ip if args.public_ip else '0.0.0.0/0'
|
||||
IpRanges = []
|
||||
ip_ranges = []
|
||||
|
||||
ip = ip.split(',')
|
||||
for i in ip:
|
||||
IpRanges.append([i, 'pgcloud client {}'.format(i)])
|
||||
ip_ranges.append([i, 'pgcloud client {}'.format(i)])
|
||||
|
||||
debug('Creating BigAnimal cluster: {}...'.format(args.name))
|
||||
|
||||
@@ -107,12 +108,13 @@ class BigAnimalProvider(AbsProvider):
|
||||
'replicas': 3,
|
||||
'volumePropertiesId': args.volume_properties,
|
||||
'volumeTypeId': args.volume_type,
|
||||
'zoneRedundantHa': high_availability,
|
||||
'clusterArch': {'id': args.cluster_arch, 'nodes': int(
|
||||
args.nodes)},
|
||||
'pgConfigMap': [],
|
||||
}
|
||||
|
||||
if not private_network:
|
||||
_data['allowIpRangeMap'] = IpRanges
|
||||
_data['allowIpRangeMap'] = ip_ranges
|
||||
|
||||
cluster_resp = requests.post(_url,
|
||||
headers=_headers,
|
||||
|
||||
@@ -162,11 +162,11 @@ class RdsProvider(AbsProvider):
|
||||
ip = args.public_ip if args.public_ip else\
|
||||
'{}/32'.format(get_my_ip())
|
||||
port = args.db_port or 5432
|
||||
IpRanges = []
|
||||
ip_ranges = []
|
||||
|
||||
ip = ip.split(',')
|
||||
for i in ip:
|
||||
IpRanges.append({
|
||||
ip_ranges.append({
|
||||
'CidrIp': i,
|
||||
'Description': 'pgcloud client {}'.format(i)
|
||||
})
|
||||
@@ -180,7 +180,7 @@ class RdsProvider(AbsProvider):
|
||||
'FromPort': port,
|
||||
'ToPort': port,
|
||||
'IpProtocol': 'tcp',
|
||||
'IpRanges': IpRanges
|
||||
'IpRanges': ip_ranges
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
import datetime
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def debug(message):
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import random
|
||||
import secrets
|
||||
import string
|
||||
import urllib3
|
||||
import ipaddress
|
||||
@@ -39,4 +39,4 @@ def get_my_ip():
|
||||
def get_random_id():
|
||||
""" Return a random 10 byte string """
|
||||
letters = string.ascii_letters + string.digits
|
||||
return(''.join(random.choice(letters) for _ in range(10)))
|
||||
return ''.join(secrets.choice(letters) for _ in range(10))
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"dark": {
|
||||
"disp_name": "dark_(Beta)",
|
||||
"cssfile": "pgadmin.theme.dark",
|
||||
|
||||
@@ -222,7 +222,7 @@ def create_app(app_name=None):
|
||||
|
||||
config.SECURITY_RECOVERABLE = True
|
||||
config.SECURITY_CHANGEABLE = True
|
||||
# Now we'll open change password page in alertify dialog
|
||||
# Now we'll open change password page in dialog
|
||||
# we don't want it to redirect to main page after password
|
||||
# change operation so we will open the same password change page again.
|
||||
config.SECURITY_POST_CHANGE_VIEW = 'browser.change_password'
|
||||
@@ -444,7 +444,7 @@ def create_app(app_name=None):
|
||||
# Don't bother paths when running in cli mode
|
||||
if not cli_mode:
|
||||
import pgadmin.utils.paths as paths
|
||||
paths.init_app(app)
|
||||
paths.init_app()
|
||||
|
||||
# Setup Flask-Security
|
||||
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||
@@ -578,7 +578,7 @@ def create_app(app_name=None):
|
||||
maintenance_db='postgres',
|
||||
username=superuser,
|
||||
ssl_mode='prefer',
|
||||
comment=svr_comment,
|
||||
comment=comment,
|
||||
discovery_id=discovery_id)
|
||||
|
||||
db.session.add(svr)
|
||||
@@ -700,16 +700,16 @@ def create_app(app_name=None):
|
||||
|
||||
for mdl in current_app.logout_hooks:
|
||||
try:
|
||||
mdl.on_logout(user)
|
||||
mdl.on_logout()
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
|
||||
# remove key
|
||||
current_app.keyManager.reset()
|
||||
|
||||
_driver = get_driver(PG_DEFAULT_DRIVER)
|
||||
_driver.gc_own()
|
||||
|
||||
# remove key
|
||||
current_app.keyManager.reset()
|
||||
|
||||
##########################################################################
|
||||
# Load plugin modules
|
||||
##########################################################################
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
|
||||
"""A blueprint module implementing the about box."""
|
||||
|
||||
from flask import Response, render_template, url_for, request
|
||||
from flask import Response, render_template, request
|
||||
from flask_babel import gettext
|
||||
from flask_security import current_user, login_required
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.menu import MenuItem
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
||||
from pgadmin.utils.ajax import make_json_response
|
||||
import config
|
||||
import httpagentparser
|
||||
from pgadmin.model import User
|
||||
@@ -66,6 +67,7 @@ def index():
|
||||
info['os_details'] = os_details
|
||||
info['config_db'] = config.SQLITE_PATH
|
||||
info['log_file'] = config.LOG_FILE
|
||||
info['version'] = config.APP_VERSION
|
||||
|
||||
if config.SERVER_MODE:
|
||||
info['app_mode'] = gettext('Server')
|
||||
@@ -98,8 +100,9 @@ def index():
|
||||
|
||||
info['settings'] = settings
|
||||
|
||||
return render_template(
|
||||
MODULE_NAME + '/index.html', info=info, _=gettext
|
||||
return make_json_response(
|
||||
data=info,
|
||||
status=200
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
import url_for from 'sources/url_for';
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { Box, Grid, InputLabel } from '@material-ui/core';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DefaultButton } from '../../../static/js/components/Buttons';
|
||||
import { makeStyles } from '@material-ui/styles';
|
||||
import { InputText } from '../../../static/js/components/FormComponents';
|
||||
import getApiInstance from '../../../static/js/api_instance';
|
||||
import { copyToClipboard } from '../../../static/js/clipboard';
|
||||
import Notify from '../../../static/js/helpers/Notifier';
|
||||
import { useDelayedCaller } from '../../../static/js/custom_hooks';
|
||||
|
||||
|
||||
const useStyles = makeStyles((theme)=>({
|
||||
container: {
|
||||
padding: '16px',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
copyBtn: {
|
||||
marginRight: '1px',
|
||||
float: 'right',
|
||||
borderColor: theme.otherVars.borderColor,
|
||||
fontSize: '13px',
|
||||
},
|
||||
}));
|
||||
|
||||
export default function AboutComponent() {
|
||||
const classes = useStyles();
|
||||
const containerRef = useRef();
|
||||
const [aboutData, setAboutData] = useState([]);
|
||||
const [copyText, setCopyText] = useState(gettext('Copy'));
|
||||
const revertCopiedText = useDelayedCaller(()=>{
|
||||
setCopyText(gettext('Copy'));
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const about_url = url_for('about.index');
|
||||
const api = getApiInstance();
|
||||
|
||||
api.get(about_url).then((res)=>{
|
||||
setAboutData(res.data.data);
|
||||
}).catch((err)=>{
|
||||
Notify.error(err);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box className={classes.container} ref={containerRef}>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('Version')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.version}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('Application Mode')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.app_mode}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('Current User')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.current_user}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{ aboutData.nwjs &&
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('NW.js Version')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.nwjs}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
}
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('Browser')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.browser_details}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('Operating System')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.os_details}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('pgAdmin Database File')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.config_db}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item lg={3} md={3} sm={3} xs={12}>
|
||||
<InputLabel style={{fontWeight: 'bold'}}>{gettext('Log File')}</InputLabel>
|
||||
</Grid>
|
||||
<Grid item lg={9} md={9} sm={9} xs={12}>
|
||||
<InputLabel>{aboutData.log_file}</InputLabel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{ (aboutData.app_mode == 'Desktop' || (aboutData.app_mode == 'Server' && aboutData.admin)) &&
|
||||
<>
|
||||
<Box flexGrow="1" display="flex" flexDirection="column">
|
||||
<Box>
|
||||
<span style={{fontWeight: 'bold'}}>{gettext('Server Configuration')}</span>
|
||||
<DefaultButton className={classes.copyBtn} onClick={()=>{
|
||||
copyToClipboard(aboutData.settings);
|
||||
setCopyText(gettext('Copied!'));
|
||||
revertCopiedText(1500);
|
||||
}}>{copyText}</DefaultButton>
|
||||
</Box>
|
||||
<Box flexGrow="1" paddingTop="1px">
|
||||
<InputText style={{height: '100%'}} controlProps={{multiline: true}} inputStyle={{resize: 'none'}}
|
||||
value={aboutData.settings}/>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
AboutComponent.propTypes = {
|
||||
closeModal: PropTypes.func
|
||||
};
|
||||
@@ -7,85 +7,50 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
define(
|
||||
['jquery', 'alertify', 'sources/pgadmin', 'sources/gettext',
|
||||
'sources/url_for','sources/utils','pgadmin.user_management.current_user',
|
||||
],
|
||||
function($, alertify, pgAdmin, gettext, url_for, commonUtils, current_user) {
|
||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||
import React from 'react';
|
||||
import gettext from 'sources/gettext';
|
||||
import Notify from '../../../static/js/helpers/Notifier';
|
||||
import pgAdmin from 'sources/pgadmin';
|
||||
import AboutComponent from './AboutComponent';
|
||||
import current_user from 'pgadmin.user_management.current_user';
|
||||
|
||||
/* Return back, this has been called more than once */
|
||||
if (pgAdmin.About)
|
||||
class About {
|
||||
static instance;
|
||||
|
||||
static getInstance(...args) {
|
||||
if (!About.instance) {
|
||||
About.instance = new About(...args);
|
||||
}
|
||||
return About.instance;
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.initialized)
|
||||
return;
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
pgAdmin.About = {
|
||||
about_show: function() {
|
||||
if (!alertify.aboutDialog) {
|
||||
alertify.dialog('aboutDialog', function factory() {
|
||||
return {
|
||||
main: function(title, message) {
|
||||
this.set('title', title);
|
||||
this.message = message;
|
||||
},
|
||||
setup: function() {
|
||||
return {
|
||||
buttons:[{ text: gettext('OK'), key: 27,
|
||||
className: 'btn btn-primary fa fa-lg fa-check pg-alertify-button' }],
|
||||
options: {
|
||||
modal: false,
|
||||
resizable: true,
|
||||
maximizable: true,
|
||||
pinnable: false,
|
||||
closableByDimmer: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
build: function() {
|
||||
alertify.pgDialogBuild.apply(this);
|
||||
},
|
||||
hooks:{
|
||||
onshow:function(){
|
||||
var self = this;
|
||||
var container = $(this.elements.footer).find('button:not([disabled])');
|
||||
commonUtils.findAndSetFocus(container);
|
||||
$('#copy_textarea').on('click', function(){
|
||||
//Copy the server configuration details
|
||||
let textarea = document.getElementById('about-textarea');
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
$('#copy_textarea').text('Copied');
|
||||
});
|
||||
// This is a callback function to show about dialog.
|
||||
about_show() {
|
||||
let dlgHeight = 470,
|
||||
dlgWidth = 750;
|
||||
|
||||
$(this.elements.resizeHandle).on('click', function(){
|
||||
// Set the height of the Textarea
|
||||
var height = self.elements.dialog.scrollHeight - 300;
|
||||
if (height < 0)
|
||||
height = self.elements.dialog.scrollHeight - 150;
|
||||
$('#about-textarea').css({'height':height});
|
||||
});
|
||||
},
|
||||
},
|
||||
prepare:function() {
|
||||
this.setContent(this.message);
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
if(!current_user.is_admin && pgAdmin.server_mode) {
|
||||
dlgWidth = pgAdmin.Browser.stdW.md;
|
||||
dlgHeight = 300;
|
||||
}
|
||||
|
||||
$.get(url_for('about.index'),
|
||||
function(data) {
|
||||
if(!current_user.is_admin && pgAdmin.server_mode){
|
||||
alertify.aboutDialog(
|
||||
gettext('About %s', pgAdmin.Browser.utils.app_name), data
|
||||
).resizeTo(pgAdmin.Browser.stdW.md, 300);
|
||||
}else{
|
||||
alertify.aboutDialog(
|
||||
gettext('About %s', pgAdmin.Browser.utils.app_name), data
|
||||
).resizeTo(750, 470);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
// Render About component
|
||||
Notify.showModal(gettext('About %s', pgAdmin.Browser.utils.app_name), () => {
|
||||
return <AboutComponent />;
|
||||
}, { isFullScreen: false, isResizeable: true, showFullScreen: true,
|
||||
isFullWidth: true, dialogWidth: dlgWidth, dialogHeight: dlgHeight, minHeight: dlgHeight
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return pgAdmin.About;
|
||||
});
|
||||
pgAdmin.About = About.getInstance();
|
||||
|
||||
module.exports = {
|
||||
About: About,
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
<div class="container-fluid enable-selection">
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Version') }}</strong></div>
|
||||
<div class="col-sm-9">{{ config.APP_VERSION }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Application Mode') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.app_mode }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Current User') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.current_user }}</div>
|
||||
</div>
|
||||
{% if info.nwjs %}
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('NW.js Version') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.nwjs }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Browser') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.browser_details }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Operating System') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.os_details }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('pgAdmin Database File') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.config_db }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Log File') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.log_file }}</div>
|
||||
</div>
|
||||
{%if (info.app_mode == 'Desktop') or (info.app_mode == 'Server' and info.admin)%}
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><b>{{ _('Server Configuration') }}</b></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<textarea id="about-textarea" rows="7" cols="150" style="position: relative;width:105%; white-space: pre-wrap;" readonly>{{ info.settings|safe }}</textarea>
|
||||
<button class="btn btn-secondary about-copy" id="copy_textarea" style="position:absolute;top:0;right:0;z-index:20;">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -16,11 +16,10 @@ from flask import current_app, flash, Response, request, url_for, \
|
||||
session, redirect
|
||||
from flask_babel import gettext
|
||||
from flask_security.views import _security
|
||||
from flask_security.utils import get_post_logout_redirect, \
|
||||
get_post_login_redirect, logout_user
|
||||
from flask_security.utils import get_post_logout_redirect, logout_user
|
||||
|
||||
from pgadmin.model import db, User
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils import PgAdminModule, get_safe_post_login_redirect
|
||||
from pgadmin.utils.constants import KERBEROS, INTERNAL, OAUTH2, LDAP
|
||||
from pgadmin.authenticate.registry import AuthSourceRegistry
|
||||
|
||||
@@ -145,7 +144,7 @@ def login():
|
||||
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
return redirect(get_post_login_redirect())
|
||||
return redirect(get_safe_post_login_redirect())
|
||||
|
||||
elif isinstance(msg, Response):
|
||||
return msg
|
||||
|
||||
@@ -178,9 +178,10 @@ class KerberosAuthentication(BaseAuthentication):
|
||||
headers = Headers()
|
||||
authorization = request.headers.get("Authorization", None)
|
||||
form_class = _security.login_form
|
||||
req_json = request.get_json(silent=True)
|
||||
|
||||
if request.json:
|
||||
form = form_class(MultiDict(request.json))
|
||||
if req_json:
|
||||
form = form_class(MultiDict(req_json))
|
||||
else:
|
||||
form = form_class()
|
||||
|
||||
@@ -263,7 +264,7 @@ class KerberosAuthentication(BaseAuthentication):
|
||||
del_creds = getattr(context, 'delegated_creds', None)
|
||||
if del_creds:
|
||||
deleg_creds = context.delegated_creds
|
||||
del(deleg_creds)
|
||||
del deleg_creds
|
||||
|
||||
def __auto_create_user(self, username):
|
||||
"""Add the kerberos user to the internal SQLite database."""
|
||||
|
||||
@@ -28,12 +28,11 @@ def __generate_otp() -> str:
|
||||
str: A six-digits OTP for the current user
|
||||
"""
|
||||
import time
|
||||
import base64
|
||||
import codecs
|
||||
import random
|
||||
import secrets
|
||||
|
||||
code = codecs.encode("{}{}{}".format(
|
||||
time.time(), current_user.username, random.randint(1000, 9999)
|
||||
time.time(), current_user.username, secrets.choice(range(1000, 9999))
|
||||
).encode(), "hex")
|
||||
|
||||
res = 0
|
||||
|
||||