You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-15 01:04:37 +02:00
Add TLS Server.
The TLS server is an alternative to using SSH for protocol connections to remote hosts. This command is currently experimental and intended only for trial and testing. As such, the new commands and options will not show up in the command-line help unless directly requested.
This commit is contained in:
@ -130,6 +130,21 @@
|
|||||||
<p>Add hints to standby replay timeout message.</p>
|
<p>Add hints to standby replay timeout message.</p>
|
||||||
</release-item>
|
</release-item>
|
||||||
</release-improvement-list>
|
</release-improvement-list>
|
||||||
|
|
||||||
|
<release-development-list>
|
||||||
|
<release-item>
|
||||||
|
<github-pull-request id="1504"/>
|
||||||
|
|
||||||
|
<release-item-contributor-list>
|
||||||
|
<release-item-contributor id="david.steele"/>
|
||||||
|
<release-item-reviewer id="stephen.frost"/>
|
||||||
|
<!-- Actually tester, but we don't have a tag for that yet -->
|
||||||
|
<release-item-reviewer id="andrew.lecuyer"/>
|
||||||
|
</release-item-contributor-list>
|
||||||
|
|
||||||
|
<p><proper>Add TLS</proper> server.</p>
|
||||||
|
</release-item>
|
||||||
|
</release-development-list>
|
||||||
</release-core-list>
|
</release-core-list>
|
||||||
</release>
|
</release>
|
||||||
|
|
||||||
|
@ -78,6 +78,8 @@ SRCS = \
|
|||||||
command/restore/protocol.c \
|
command/restore/protocol.c \
|
||||||
command/restore/restore.c \
|
command/restore/restore.c \
|
||||||
command/remote/remote.c \
|
command/remote/remote.c \
|
||||||
|
command/server/ping.c \
|
||||||
|
command/server/server.c \
|
||||||
command/stanza/common.c \
|
command/stanza/common.c \
|
||||||
command/stanza/create.c \
|
command/stanza/create.c \
|
||||||
command/stanza/delete.c \
|
command/stanza/delete.c \
|
||||||
@ -116,11 +118,15 @@ SRCS = \
|
|||||||
common/io/http/response.c \
|
common/io/http/response.c \
|
||||||
common/io/http/session.c \
|
common/io/http/session.c \
|
||||||
common/io/http/url.c \
|
common/io/http/url.c \
|
||||||
|
common/io/server.c \
|
||||||
common/io/session.c \
|
common/io/session.c \
|
||||||
common/io/socket/client.c \
|
common/io/socket/client.c \
|
||||||
common/io/socket/common.c \
|
common/io/socket/common.c \
|
||||||
|
common/io/socket/server.c \
|
||||||
common/io/socket/session.c \
|
common/io/socket/session.c \
|
||||||
common/io/tls/client.c \
|
common/io/tls/client.c \
|
||||||
|
common/io/tls/common.c \
|
||||||
|
common/io/tls/server.c \
|
||||||
common/io/tls/session.c \
|
common/io/tls/session.c \
|
||||||
common/lock.c \
|
common/lock.c \
|
||||||
common/stat.c \
|
common/stat.c \
|
||||||
|
@ -119,6 +119,14 @@ command:
|
|||||||
local: {}
|
local: {}
|
||||||
remote: {}
|
remote: {}
|
||||||
|
|
||||||
|
server-ping:
|
||||||
|
internal: true
|
||||||
|
log-file: false
|
||||||
|
parameter-allowed: true
|
||||||
|
|
||||||
|
server-start:
|
||||||
|
internal: true
|
||||||
|
|
||||||
stanza-create:
|
stanza-create:
|
||||||
command-role:
|
command-role:
|
||||||
remote: {}
|
remote: {}
|
||||||
@ -599,6 +607,8 @@ option:
|
|||||||
repo-put: {}
|
repo-put: {}
|
||||||
repo-rm: {}
|
repo-rm: {}
|
||||||
restore: {}
|
restore: {}
|
||||||
|
server-ping: {}
|
||||||
|
server-start: {}
|
||||||
stanza-create: {}
|
stanza-create: {}
|
||||||
stanza-delete: {}
|
stanza-delete: {}
|
||||||
stanza-upgrade: {}
|
stanza-upgrade: {}
|
||||||
@ -822,6 +832,7 @@ option:
|
|||||||
repo-put: {}
|
repo-put: {}
|
||||||
repo-rm: {}
|
repo-rm: {}
|
||||||
restore: {}
|
restore: {}
|
||||||
|
server-start: {}
|
||||||
stanza-create: {}
|
stanza-create: {}
|
||||||
stanza-delete: {}
|
stanza-delete: {}
|
||||||
stanza-upgrade: {}
|
stanza-upgrade: {}
|
||||||
@ -889,6 +900,61 @@ option:
|
|||||||
command: buffer-size
|
command: buffer-size
|
||||||
depend: tcp-keep-alive-count
|
depend: tcp-keep-alive-count
|
||||||
|
|
||||||
|
tls-server-ca-file:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
type: path
|
||||||
|
command:
|
||||||
|
server-start:
|
||||||
|
internal: false
|
||||||
|
|
||||||
|
tls-server-cert-file:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
type: path
|
||||||
|
command:
|
||||||
|
server-start:
|
||||||
|
internal: false
|
||||||
|
|
||||||
|
tls-server-key-file:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
type: path
|
||||||
|
command:
|
||||||
|
server-start:
|
||||||
|
internal: false
|
||||||
|
|
||||||
|
tls-server-auth:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
type: hash
|
||||||
|
command:
|
||||||
|
server-start:
|
||||||
|
internal: false
|
||||||
|
|
||||||
|
tls-server-address:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
type: string
|
||||||
|
default: localhost
|
||||||
|
command:
|
||||||
|
server-ping:
|
||||||
|
internal: false
|
||||||
|
server-start:
|
||||||
|
internal: false
|
||||||
|
|
||||||
|
tls-server-port:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
type: integer
|
||||||
|
default: 8432
|
||||||
|
allow-range: [1, 65535]
|
||||||
|
command:
|
||||||
|
server-ping:
|
||||||
|
internal: false
|
||||||
|
server-start:
|
||||||
|
internal: false
|
||||||
|
|
||||||
# Logging options
|
# Logging options
|
||||||
#---------------------------------------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------------------------------------
|
||||||
log-level-console:
|
log-level-console:
|
||||||
@ -1265,6 +1331,32 @@ option:
|
|||||||
db-host: {}
|
db-host: {}
|
||||||
db?-host: {}
|
db?-host: {}
|
||||||
|
|
||||||
|
pg-host-cert-file:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
group: pg
|
||||||
|
type: string
|
||||||
|
command: pg-local
|
||||||
|
command-role:
|
||||||
|
async: {}
|
||||||
|
main: {}
|
||||||
|
local: {}
|
||||||
|
depend:
|
||||||
|
option: pg-host-type
|
||||||
|
list:
|
||||||
|
- tls
|
||||||
|
|
||||||
|
pg-host-key-file:
|
||||||
|
inherit: pg-host-cert-file
|
||||||
|
|
||||||
|
pg-host-ca-file:
|
||||||
|
inherit: pg-host-cert-file
|
||||||
|
required: false
|
||||||
|
|
||||||
|
pg-host-ca-path:
|
||||||
|
inherit: pg-host-cert-file
|
||||||
|
required: false
|
||||||
|
|
||||||
pg-host-cmd:
|
pg-host-cmd:
|
||||||
section: stanza
|
section: stanza
|
||||||
group: pg
|
group: pg
|
||||||
@ -1324,6 +1416,25 @@ option:
|
|||||||
db-user: {}
|
db-user: {}
|
||||||
db?-user: {}
|
db?-user: {}
|
||||||
|
|
||||||
|
pg-host-type:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
group: pg
|
||||||
|
type: string
|
||||||
|
default: ssh
|
||||||
|
allow-list:
|
||||||
|
- ssh
|
||||||
|
- tls
|
||||||
|
command: pg-local
|
||||||
|
command-role:
|
||||||
|
async: {}
|
||||||
|
main: {}
|
||||||
|
local: {}
|
||||||
|
depend:
|
||||||
|
option: pg-local
|
||||||
|
list:
|
||||||
|
- false
|
||||||
|
|
||||||
pg-path:
|
pg-path:
|
||||||
section: stanza
|
section: stanza
|
||||||
group: pg
|
group: pg
|
||||||
@ -1699,6 +1810,25 @@ option:
|
|||||||
deprecate:
|
deprecate:
|
||||||
hardlink: {}
|
hardlink: {}
|
||||||
|
|
||||||
|
repo-host-type:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
group: repo
|
||||||
|
type: string
|
||||||
|
default: ssh
|
||||||
|
allow-list:
|
||||||
|
- ssh
|
||||||
|
- tls
|
||||||
|
command: repo-local
|
||||||
|
command-role:
|
||||||
|
async: {}
|
||||||
|
main: {}
|
||||||
|
local: {}
|
||||||
|
depend:
|
||||||
|
option: repo-local
|
||||||
|
list:
|
||||||
|
- false
|
||||||
|
|
||||||
repo-host:
|
repo-host:
|
||||||
section: global
|
section: global
|
||||||
group: repo
|
group: repo
|
||||||
@ -1709,13 +1839,36 @@ option:
|
|||||||
async: {}
|
async: {}
|
||||||
main: {}
|
main: {}
|
||||||
local: {}
|
local: {}
|
||||||
depend:
|
depend: repo-host-type
|
||||||
option: repo-local
|
|
||||||
list:
|
|
||||||
- false
|
|
||||||
deprecate:
|
deprecate:
|
||||||
backup-host: {}
|
backup-host: {}
|
||||||
|
|
||||||
|
repo-host-cert-file:
|
||||||
|
internal: true
|
||||||
|
section: global
|
||||||
|
group: repo
|
||||||
|
type: string
|
||||||
|
command: repo-local
|
||||||
|
command-role:
|
||||||
|
async: {}
|
||||||
|
main: {}
|
||||||
|
local: {}
|
||||||
|
depend:
|
||||||
|
option: repo-host-type
|
||||||
|
list:
|
||||||
|
- tls
|
||||||
|
|
||||||
|
repo-host-key-file:
|
||||||
|
inherit: repo-host-cert-file
|
||||||
|
|
||||||
|
repo-host-ca-file:
|
||||||
|
inherit: repo-host-cert-file
|
||||||
|
required: false
|
||||||
|
|
||||||
|
repo-host-ca-path:
|
||||||
|
inherit: repo-host-cert-file
|
||||||
|
required: false
|
||||||
|
|
||||||
repo-host-cmd:
|
repo-host-cmd:
|
||||||
section: global
|
section: global
|
||||||
group: repo
|
group: repo
|
||||||
@ -1724,6 +1877,7 @@ option:
|
|||||||
command:
|
command:
|
||||||
archive-get: {}
|
archive-get: {}
|
||||||
archive-push: {}
|
archive-push: {}
|
||||||
|
backup: {}
|
||||||
check: {}
|
check: {}
|
||||||
info: {}
|
info: {}
|
||||||
repo-create: {}
|
repo-create: {}
|
||||||
|
@ -102,6 +102,9 @@ repo-invalid: 103
|
|||||||
# The command encountered one or more errors
|
# The command encountered one or more errors
|
||||||
command: 104
|
command: 104
|
||||||
|
|
||||||
|
# Unable to authenticate or authorize
|
||||||
|
access: 105
|
||||||
|
|
||||||
# This error should not be thrown directly -- it serves as a parent for the C errors
|
# This error should not be thrown directly -- it serves as a parent for the C errors
|
||||||
runtime: 122
|
runtime: 122
|
||||||
|
|
||||||
|
@ -550,6 +550,22 @@
|
|||||||
<example>none</example>
|
<example>none</example>
|
||||||
</config-key>
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="repo-host-type" name="Repository Host Protocol Type">
|
||||||
|
<summary>Repository host protocol type.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>The following protocol types are supported:</p>
|
||||||
|
|
||||||
|
<list>
|
||||||
|
<list-item><id>ssh</id> - Secure Shell.</list-item>
|
||||||
|
<list-item><id>tls</id> - <backrest/> TLS server.</list-item>
|
||||||
|
</list>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>tls</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
<!-- CONFIG - REPO SECTION - REPO-HOST KEY -->
|
<!-- CONFIG - REPO SECTION - REPO-HOST KEY -->
|
||||||
<config-key id="repo-host" name="Repository Host">
|
<config-key id="repo-host" name="Repository Host">
|
||||||
<summary>Repository host when operating remotely via SSH.</summary>
|
<summary>Repository host when operating remotely via SSH.</summary>
|
||||||
@ -563,6 +579,50 @@
|
|||||||
<example>repo1.domain.com</example>
|
<example>repo1.domain.com</example>
|
||||||
</config-key>
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="repo-host-ca-file" name="Repository Host Certificate Authority File">
|
||||||
|
<summary>Repository host certificate authority file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Use a CA file other than the system default for connecting to the repository host.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/etc/pki/tls/certs/ca-bundle.crt</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="repo-host-ca-path" name="Repository Host Certificate Authority Path">
|
||||||
|
<summary>Repository host certificate authority path.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Use a CA path other than the system default for connecting to the repository host.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/etc/pki/tls/certs</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="repo-host-cert-file" name="Repository Host Certificate File">
|
||||||
|
<summary>Repository host certificate file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Sent to repository host to prove client indentity.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/client.crt</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="repo-host-key-file" name="Repository Host Key File">
|
||||||
|
<summary>Repository host key file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Proves client certificate was sent by owner.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/client.key</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
<!-- CONFIG - REPO SECTION - REPO-HOST-CMD KEY -->
|
<!-- CONFIG - REPO SECTION - REPO-HOST-CMD KEY -->
|
||||||
<config-key id="repo-host-cmd" name="Repository Host Command">
|
<config-key id="repo-host-cmd" name="Repository Host Command">
|
||||||
<summary><backrest/> exe path on the repository host.</summary>
|
<summary><backrest/> exe path on the repository host.</summary>
|
||||||
@ -1326,6 +1386,75 @@
|
|||||||
|
|
||||||
<example>/data/tablespace</example>
|
<example>/data/tablespace</example>
|
||||||
</config-key>
|
</config-key>
|
||||||
|
|
||||||
|
<!-- For now the server options must be here so they do not show up in the documentation -->
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="tls-server-auth" name="TLS Server Authorized Clients">
|
||||||
|
<summary>TLS server authorized clients.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Clients are authorized on the server by verifying their certificate and checking the certificate CN (Common name) against a list on the server configured with the <br-option>tls-server-auth</br-option>.</p>
|
||||||
|
|
||||||
|
<p>A CN can be authorized for as many stanzas as needed by repeating the <br-option>tls-server-auth</br-option> option, or for all stanzas by specifying <br-option>tls-server-auth=*</br-option>.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>stanza1</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="tls-server-ca-file" name="TLS Server Certificate Authorities">
|
||||||
|
<summary>TLS server certificate authorities.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Checks that client certificates are signed by a trusted certificate authority.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/server.ca</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="tls-server-cert-file" name="TLS Server Certificate">
|
||||||
|
<summary>TLS server certificate file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Sent to the client to show the server identity.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/server.crt</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="tls-server-key-file" name="TLS Server Key">
|
||||||
|
<summary>TLS server key file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Proves server certificate was sent by the owner.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/server.key</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="tls-server-address" name="TLS Server Address">
|
||||||
|
<summary>TLS server address.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>IP address the server will listen on for client requests.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>::*</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="tls-server-port" name="TLS Server Port">
|
||||||
|
<summary>TLS server port.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Port the server will listen on for client requests.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>8000</example>
|
||||||
|
</config-key>
|
||||||
</config-key-list>
|
</config-key-list>
|
||||||
</config-section>
|
</config-section>
|
||||||
|
|
||||||
@ -1394,6 +1523,66 @@
|
|||||||
<example>db.domain.com</example>
|
<example>db.domain.com</example>
|
||||||
</config-key>
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="pg-host-ca-file" name="PostgreSQL Host Certificate Authority File">
|
||||||
|
<summary><postgres/> host certificate authority file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Use a CA file other than the system default for connecting to the <postgres/> host.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/etc/pki/tls/certs/ca-bundle.crt</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="pg-host-ca-path" name="PostgreSQL Host Certificate Authority Path">
|
||||||
|
<summary><postgres/> host certificate authority path.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Use a CA path other than the system default for connecting to the <postgres/> host.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/etc/pki/tls/certs</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="pg-host-cert-file" name="PostgreSQL Host Certificate File">
|
||||||
|
<summary><postgres/> host certificate file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Sent to <postgres/> host to prove client indentity.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/client.crt</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="pg-host-key-file" name="PostgreSQL Host Key File">
|
||||||
|
<summary><postgres/> host key file.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Proves client certificate was sent by owner.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>/path/to/client.key</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
|
<!-- ======================================================================================================= -->
|
||||||
|
<config-key id="pg-host-type" name="PostgreSQL Host Protocol Type">
|
||||||
|
<summary><postgres/> host protocol type.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>The following protocol types are supported:</p>
|
||||||
|
|
||||||
|
<list>
|
||||||
|
<list-item><id>ssh</id> - Secure Shell.</list-item>
|
||||||
|
<list-item><id>tls</id> - <backrest/> TLS server.</list-item>
|
||||||
|
</list>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>tls</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
<!-- CONFIG - STANZA SECTION - PG-HOST-USER KEY -->
|
<!-- CONFIG - STANZA SECTION - PG-HOST-USER KEY -->
|
||||||
<config-key id="pg-host-user" name="PostgreSQL Host User">
|
<config-key id="pg-host-user" name="PostgreSQL Host User">
|
||||||
<summary><postgres/> host logon user when <setting>pg-host</setting> is set.</summary>
|
<summary><postgres/> host logon user when <setting>pg-host</setting> is set.</summary>
|
||||||
@ -2065,6 +2254,26 @@
|
|||||||
</text>
|
</text>
|
||||||
</command>
|
</command>
|
||||||
|
|
||||||
|
<!-- =============================================================================================================== -->
|
||||||
|
<command id="server-start" name="Server Start">
|
||||||
|
<summary>Start <backrest/> server.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>The <backrest/> server allows access to remote hosts without using the <proper>SSH</proper> protocol.</p>
|
||||||
|
</text>
|
||||||
|
</command>
|
||||||
|
|
||||||
|
<!-- =============================================================================================================== -->
|
||||||
|
<command id="server-ping" name="Server Ping">
|
||||||
|
<summary>Ping <backrest/> server.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Ping a <backrest/> <proper>TLS</proper> server to ensure it is accepting connections. This serves as an aliveness check only since no authentication is attempted.</p>
|
||||||
|
|
||||||
|
<p>If no host is specified on the command-line then the <br-option>tls-server-host</br-option> option will be used.</p>
|
||||||
|
</text>
|
||||||
|
</command>
|
||||||
|
|
||||||
<!-- OPERATION - START COMMAND -->
|
<!-- OPERATION - START COMMAND -->
|
||||||
<command id="start" name="Start">
|
<command id="start" name="Start">
|
||||||
<summary>Allow <backrest/> processes to run.</summary>
|
<summary>Allow <backrest/> processes to run.</summary>
|
||||||
|
49
src/command/server/ping.c
Normal file
49
src/command/server/ping.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Server Ping Command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include "command/server/ping.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/io/tls/client.h"
|
||||||
|
#include "common/io/socket/client.h"
|
||||||
|
#include "config/config.h"
|
||||||
|
#include "protocol/client.h"
|
||||||
|
#include "protocol/helper.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
cmdServerPing(void)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_VOID(logLevelDebug);
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Check for user-specified host
|
||||||
|
const String *host = cfgOptionStr(cfgOptTlsServerAddress);
|
||||||
|
const StringList *commandParam = cfgCommandParam();
|
||||||
|
|
||||||
|
if (strLstSize(commandParam) == 1)
|
||||||
|
host = strLstGet(commandParam, 0);
|
||||||
|
else if (strLstSize(commandParam) > 1)
|
||||||
|
THROW(ParamInvalidError, "extra parameters found");
|
||||||
|
|
||||||
|
// Connect to server without any verification
|
||||||
|
const TimeMSec timeout = cfgOptionUInt64(cfgOptIoTimeout);
|
||||||
|
|
||||||
|
IoClient *const tlsClient = tlsClientNew(
|
||||||
|
sckClientNew(host, cfgOptionUInt(cfgOptTlsServerPort), timeout, timeout), host, timeout, timeout, false, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
IoSession *const tlsSession = ioClientOpen(tlsClient);
|
||||||
|
|
||||||
|
// Send ping
|
||||||
|
ProtocolClient *const protocolClient = protocolClientNew(
|
||||||
|
strNewFmt(PROTOCOL_SERVICE_REMOTE " socket protocol on '%s'", strZ(host)), PROTOCOL_SERVICE_REMOTE_STR,
|
||||||
|
ioSessionIoRead(tlsSession), ioSessionIoWrite(tlsSession));
|
||||||
|
protocolClientNoExit(protocolClient);
|
||||||
|
protocolClientNoOp(protocolClient);
|
||||||
|
protocolClientFree(protocolClient);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
|
}
|
12
src/command/server/ping.h
Normal file
12
src/command/server/ping.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Server Ping Command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMAND_SERVER_PING_H
|
||||||
|
#define COMMAND_SERVER_PING_H
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void cmdServerPing(void);
|
||||||
|
|
||||||
|
#endif
|
81
src/command/server/server.c
Normal file
81
src/command/server/server.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Server Command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "command/remote/remote.h"
|
||||||
|
#include "command/server/server.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/fork.h"
|
||||||
|
#include "common/io/socket/server.h"
|
||||||
|
#include "common/io/tls/server.h"
|
||||||
|
#include "config/config.h"
|
||||||
|
#include "protocol/helper.h"
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
void
|
||||||
|
cmdServer(uint64_t connectionMax)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_VOID(logLevelDebug);
|
||||||
|
|
||||||
|
ASSERT(connectionMax > 0);
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
IoServer *const tlsServer = tlsServerNew(
|
||||||
|
cfgOptionStr(cfgOptTlsServerAddress), cfgOptionStr(cfgOptTlsServerCaFile), cfgOptionStr(cfgOptTlsServerKeyFile),
|
||||||
|
cfgOptionStr(cfgOptTlsServerCertFile), cfgOptionUInt64(cfgOptProtocolTimeout));
|
||||||
|
IoServer *const socketServer = sckServerNew(
|
||||||
|
cfgOptionStr(cfgOptTlsServerAddress), cfgOptionUInt(cfgOptTlsServerPort), cfgOptionUInt64(cfgOptProtocolTimeout));
|
||||||
|
|
||||||
|
// Accept connections until connection max is reached
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Accept a new connection
|
||||||
|
IoSession *const socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
// Fork off the child process
|
||||||
|
pid_t pid = forkSafe();
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
// Close the server socket so we don't hold the port open if the parent exits first
|
||||||
|
ioServerFree(socketServer);
|
||||||
|
|
||||||
|
// Disable logging and close log file
|
||||||
|
logClose();
|
||||||
|
|
||||||
|
// Detach from parent process
|
||||||
|
forkDetach();
|
||||||
|
|
||||||
|
// Start standard remote processing if a server is returned
|
||||||
|
ProtocolServer *server = protocolServer(tlsServer, socketSession);
|
||||||
|
|
||||||
|
if (server != NULL)
|
||||||
|
cmdRemote(server);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Wait for first fork to exit
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The process that was just forked should return immediately
|
||||||
|
int processStatus;
|
||||||
|
|
||||||
|
THROW_ON_SYS_ERROR(waitpid(pid, &processStatus, 0) == -1, ExecuteError, "unable to wait for forked process");
|
||||||
|
|
||||||
|
// The first fork should exit with success. If not, something went wrong during the second fork.
|
||||||
|
CHECK(WIFEXITED(processStatus) && WEXITSTATUS(processStatus) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the socket since the child is now using it
|
||||||
|
ioSessionFree(socketSession);
|
||||||
|
}
|
||||||
|
while (--connectionMax > 0);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
|
}
|
14
src/command/server/server.h
Normal file
14
src/command/server/server.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Server Command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMAND_SERVER_SERVER_H
|
||||||
|
#define COMMAND_SERVER_SERVER_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void cmdServer(uint64_t connectionMax);
|
||||||
|
|
||||||
|
#endif
|
@ -85,6 +85,7 @@ ERROR_DEFINE(101, ServiceError, RuntimeError);
|
|||||||
ERROR_DEFINE(102, ExecuteError, RuntimeError);
|
ERROR_DEFINE(102, ExecuteError, RuntimeError);
|
||||||
ERROR_DEFINE(103, RepoInvalidError, RuntimeError);
|
ERROR_DEFINE(103, RepoInvalidError, RuntimeError);
|
||||||
ERROR_DEFINE(104, CommandError, RuntimeError);
|
ERROR_DEFINE(104, CommandError, RuntimeError);
|
||||||
|
ERROR_DEFINE(105, AccessError, RuntimeError);
|
||||||
ERROR_DEFINE(122, RuntimeError, RuntimeError);
|
ERROR_DEFINE(122, RuntimeError, RuntimeError);
|
||||||
ERROR_DEFINE(123, InvalidError, RuntimeError);
|
ERROR_DEFINE(123, InvalidError, RuntimeError);
|
||||||
ERROR_DEFINE(124, UnhandledError, RuntimeError);
|
ERROR_DEFINE(124, UnhandledError, RuntimeError);
|
||||||
@ -173,6 +174,7 @@ static const ErrorType *errorTypeList[] =
|
|||||||
&ExecuteError,
|
&ExecuteError,
|
||||||
&RepoInvalidError,
|
&RepoInvalidError,
|
||||||
&CommandError,
|
&CommandError,
|
||||||
|
&AccessError,
|
||||||
&RuntimeError,
|
&RuntimeError,
|
||||||
&InvalidError,
|
&InvalidError,
|
||||||
&UnhandledError,
|
&UnhandledError,
|
||||||
|
@ -87,6 +87,7 @@ ERROR_DECLARE(ServiceError);
|
|||||||
ERROR_DECLARE(ExecuteError);
|
ERROR_DECLARE(ExecuteError);
|
||||||
ERROR_DECLARE(RepoInvalidError);
|
ERROR_DECLARE(RepoInvalidError);
|
||||||
ERROR_DECLARE(CommandError);
|
ERROR_DECLARE(CommandError);
|
||||||
|
ERROR_DECLARE(AccessError);
|
||||||
ERROR_DECLARE(RuntimeError);
|
ERROR_DECLARE(RuntimeError);
|
||||||
ERROR_DECLARE(InvalidError);
|
ERROR_DECLARE(InvalidError);
|
||||||
ERROR_DECLARE(UnhandledError);
|
ERROR_DECLARE(UnhandledError);
|
||||||
|
56
src/common/io/server.c
Normal file
56
src/common/io/server.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Io Server Interface
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/io/server.h"
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/memContext.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Object type
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
struct IoServer
|
||||||
|
{
|
||||||
|
IoServerPub pub; // Publicly accessible variables
|
||||||
|
};
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
IoServer *
|
||||||
|
ioServerNew(void *const driver, const IoServerInterface *const interface)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace)
|
||||||
|
FUNCTION_LOG_PARAM_P(VOID, driver);
|
||||||
|
FUNCTION_LOG_PARAM(IO_SERVER_INTERFACE, interface);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(driver != NULL);
|
||||||
|
ASSERT(interface != NULL);
|
||||||
|
ASSERT(interface->type != 0);
|
||||||
|
ASSERT(interface->name != NULL);
|
||||||
|
ASSERT(interface->accept != NULL);
|
||||||
|
ASSERT(interface->toLog != NULL);
|
||||||
|
|
||||||
|
IoServer *this = memNew(sizeof(IoServer));
|
||||||
|
|
||||||
|
*this = (IoServer)
|
||||||
|
{
|
||||||
|
.pub =
|
||||||
|
{
|
||||||
|
.memContext = memContextCurrent(),
|
||||||
|
.driver = driver,
|
||||||
|
.interface = interface,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(IO_SERVER, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
String *
|
||||||
|
ioServerToLog(const IoServer *const this)
|
||||||
|
{
|
||||||
|
return strNewFmt(
|
||||||
|
"{type: %s, driver: %s}", strZ(strIdToStr(this->pub.interface->type)), strZ(this->pub.interface->toLog(this->pub.driver)));
|
||||||
|
}
|
72
src/common/io/server.h
Normal file
72
src/common/io/server.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Io Server Interface
|
||||||
|
|
||||||
|
Create sessions for protocol servers. For example, a TLS server can be created with tlsServerNew() and then new TLS sessions can be
|
||||||
|
accepted with ioServerAccept().
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMON_IO_SERVER_H
|
||||||
|
#define COMMON_IO_SERVER_H
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Object type
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct IoServer IoServer;
|
||||||
|
|
||||||
|
#include "common/io/server.intern.h"
|
||||||
|
#include "common/io/session.h"
|
||||||
|
#include "common/type/object.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Getters/Setters
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct IoServerPub
|
||||||
|
{
|
||||||
|
MemContext *memContext; // Mem context
|
||||||
|
void *driver; // Driver object
|
||||||
|
const IoServerInterface *interface; // Driver interface
|
||||||
|
} IoServerPub;
|
||||||
|
|
||||||
|
// Name that identifies the server
|
||||||
|
__attribute__((always_inline)) static inline const String *
|
||||||
|
ioServerName(const IoServer *const this)
|
||||||
|
{
|
||||||
|
return THIS_PUB(IoServer)->interface->name(THIS_PUB(IoServer)->driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Move to a new parent mem context
|
||||||
|
__attribute__((always_inline)) static inline IoServer *
|
||||||
|
ioServerMove(IoServer *const this, MemContext *const parentNew)
|
||||||
|
{
|
||||||
|
return objMoveContext(this, parentNew);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open session
|
||||||
|
__attribute__((always_inline)) static inline IoSession *
|
||||||
|
ioServerAccept(IoServer *const this, IoSession *const session)
|
||||||
|
{
|
||||||
|
return THIS_PUB(IoServer)->interface->accept(THIS_PUB(IoServer)->driver, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Destructor
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
__attribute__((always_inline)) static inline void
|
||||||
|
ioServerFree(IoServer *const this)
|
||||||
|
{
|
||||||
|
objFreeContext(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Macros for function logging
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
String *ioServerToLog(const IoServer *this);
|
||||||
|
|
||||||
|
#define FUNCTION_LOG_IO_SERVER_TYPE \
|
||||||
|
IoServer *
|
||||||
|
#define FUNCTION_LOG_IO_SERVER_FORMAT(value, buffer, bufferSize) \
|
||||||
|
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, ioServerToLog, buffer, bufferSize)
|
||||||
|
|
||||||
|
#endif
|
42
src/common/io/server.intern.h
Normal file
42
src/common/io/server.intern.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Io Server Interface Internal
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMON_IO_SERVER_INTERN_H
|
||||||
|
#define COMMON_IO_SERVER_INTERN_H
|
||||||
|
|
||||||
|
#include "common/io/server.h"
|
||||||
|
#include "common/io/session.h"
|
||||||
|
#include "common/type/string.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Interface
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct IoServerInterface
|
||||||
|
{
|
||||||
|
// Type used to identify the server
|
||||||
|
StringId type;
|
||||||
|
|
||||||
|
// Server name, usually address:port or some other unique indentifier
|
||||||
|
const String *(*name)(void *driver);
|
||||||
|
|
||||||
|
// Accept a session
|
||||||
|
IoSession *(*accept)(void *driver, IoSession *session);
|
||||||
|
|
||||||
|
// Driver log function
|
||||||
|
String *(*toLog)(const void *driver);
|
||||||
|
} IoServerInterface;
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Constructors
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
IoServer *ioServerNew(void *driver, const IoServerInterface *interface);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Macros for function logging
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define FUNCTION_LOG_IO_SERVER_INTERFACE_TYPE \
|
||||||
|
IoServerInterface *
|
||||||
|
#define FUNCTION_LOG_IO_SERVER_INTERFACE_FORMAT(value, buffer, bufferSize) \
|
||||||
|
objToLog(&value, "IoServerInterface", buffer, bufferSize)
|
||||||
|
|
||||||
|
#endif
|
@ -48,6 +48,20 @@ ioSessionNew(void *driver, const IoSessionInterface *interface)
|
|||||||
FUNCTION_LOG_RETURN(IO_SESSION, this);
|
FUNCTION_LOG_RETURN(IO_SESSION, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
void
|
||||||
|
ioSessionAuthenticatedSet(IoSession *const this, const bool authenticated)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM(IO_SESSION, this);
|
||||||
|
FUNCTION_TEST_PARAM(BOOL, authenticated);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
this->pub.authenticated = authenticated;
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
int
|
int
|
||||||
ioSessionFd(IoSession *this)
|
ioSessionFd(IoSession *this)
|
||||||
@ -61,6 +75,24 @@ ioSessionFd(IoSession *this)
|
|||||||
FUNCTION_TEST_RETURN(this->pub.interface->fd == NULL ? -1 : this->pub.interface->fd(this->pub.driver));
|
FUNCTION_TEST_RETURN(this->pub.interface->fd == NULL ? -1 : this->pub.interface->fd(this->pub.driver));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
void
|
||||||
|
ioSessionPeerNameSet(IoSession *const this, const String *const peerName) // {vm_covered}
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN(); // {vm_covered}
|
||||||
|
FUNCTION_TEST_PARAM(IO_SESSION, this); // {vm_covered}
|
||||||
|
FUNCTION_TEST_PARAM(STRING, peerName); // {vm_covered}
|
||||||
|
FUNCTION_TEST_END(); // {vm_covered}
|
||||||
|
|
||||||
|
MEM_CONTEXT_BEGIN(this->pub.memContext) // {vm_covered}
|
||||||
|
{
|
||||||
|
this->pub.peerName = strDup(peerName); // {vm_covered}
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END(); // {vm_covered}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID(); // {vm_covered}
|
||||||
|
} // {vm_covered}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
String *
|
String *
|
||||||
ioSessionToLog(const IoSession *this)
|
ioSessionToLog(const IoSession *this)
|
||||||
|
@ -36,8 +36,17 @@ typedef struct IoSessionPub
|
|||||||
MemContext *memContext; // Mem context
|
MemContext *memContext; // Mem context
|
||||||
void *driver; // Driver object
|
void *driver; // Driver object
|
||||||
const IoSessionInterface *interface; // Driver interface
|
const IoSessionInterface *interface; // Driver interface
|
||||||
|
const String *peerName; // Name of peer (exact meaning depends on driver)
|
||||||
|
bool authenticated; // Is the session authenticated?
|
||||||
} IoSessionPub;
|
} IoSessionPub;
|
||||||
|
|
||||||
|
// Is the session authenticated? The exact meaning of "authenticated" will vary by driver type.
|
||||||
|
__attribute__((always_inline)) static inline bool
|
||||||
|
ioSessionAuthenticated(const IoSession *const this)
|
||||||
|
{
|
||||||
|
return THIS_PUB(IoSession)->authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
// Session file descriptor, -1 if none
|
// Session file descriptor, -1 if none
|
||||||
int ioSessionFd(IoSession *this);
|
int ioSessionFd(IoSession *this);
|
||||||
|
|
||||||
@ -55,6 +64,14 @@ ioSessionIoWrite(IoSession *const this)
|
|||||||
return THIS_PUB(IoSession)->interface->ioWrite(THIS_PUB(IoSession)->driver);
|
return THIS_PUB(IoSession)->interface->ioWrite(THIS_PUB(IoSession)->driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The peer name, if any. The exact meaning will vary by driver type, for example the peer name will be the client CN for the
|
||||||
|
// TlsSession driver.
|
||||||
|
__attribute__((always_inline)) static inline const String *
|
||||||
|
ioSessionPeerName(const IoSession *const this)
|
||||||
|
{
|
||||||
|
return THIS_PUB(IoSession)->peerName;
|
||||||
|
}
|
||||||
|
|
||||||
// Session role
|
// Session role
|
||||||
__attribute__((always_inline)) static inline IoSessionRole
|
__attribute__((always_inline)) static inline IoSessionRole
|
||||||
ioSessionRole(const IoSession *const this)
|
ioSessionRole(const IoSession *const this)
|
||||||
|
@ -39,6 +39,15 @@ Constructors
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
IoSession *ioSessionNew(void *driver, const IoSessionInterface *interface);
|
IoSession *ioSessionNew(void *driver, const IoSessionInterface *interface);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Getters/Setters
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Has the session been authenticated?
|
||||||
|
void ioSessionAuthenticatedSet(IoSession *this, bool authenticated);
|
||||||
|
|
||||||
|
// Set the peer name
|
||||||
|
void ioSessionPeerNameSet(IoSession *this, const String *peerName);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Macros for function logging
|
Macros for function logging
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
@ -33,7 +33,8 @@ typedef struct SocketClient
|
|||||||
String *host; // Hostname or IP address
|
String *host; // Hostname or IP address
|
||||||
unsigned int port; // Port to connect to host on
|
unsigned int port; // Port to connect to host on
|
||||||
String *name; // Socket name (host:port)
|
String *name; // Socket name (host:port)
|
||||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
TimeMSec timeoutConnect; // Timeout for connection
|
||||||
|
TimeMSec timeoutSession; // Timeout passed to session
|
||||||
} SocketClient;
|
} SocketClient;
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
@ -44,7 +45,9 @@ sckClientToLog(const THIS_VOID)
|
|||||||
{
|
{
|
||||||
THIS(const SocketClient);
|
THIS(const SocketClient);
|
||||||
|
|
||||||
return strNewFmt("{host: %s, port: %u, timeout: %" PRIu64 "}", strZ(this->host), this->port, this->timeout);
|
return strNewFmt(
|
||||||
|
"{host: %s, port: %u, timeoutConnect: %" PRIu64 ", timeoutSession: %" PRIu64 "}", strZ(this->host), this->port,
|
||||||
|
this->timeoutConnect, this->timeoutSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FUNCTION_LOG_SOCKET_CLIENT_TYPE \
|
#define FUNCTION_LOG_SOCKET_CLIENT_TYPE \
|
||||||
@ -69,7 +72,7 @@ sckClientOpen(THIS_VOID)
|
|||||||
MEM_CONTEXT_TEMP_BEGIN()
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
{
|
{
|
||||||
bool retry;
|
bool retry;
|
||||||
Wait *wait = waitNew(this->timeout);
|
Wait *wait = waitNew(this->timeoutConnect);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -79,48 +82,28 @@ sckClientOpen(THIS_VOID)
|
|||||||
|
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
// Set hints that narrow the type of address we are looking for -- we'll take ipv4 or ipv6
|
// Get an address for the host. We are only going to try the first address returned.
|
||||||
struct addrinfo hints = (struct addrinfo)
|
struct addrinfo *addressFound = sckHostLookup(this->host, this->port);
|
||||||
{
|
|
||||||
.ai_family = AF_UNSPEC,
|
|
||||||
.ai_socktype = SOCK_STREAM,
|
|
||||||
.ai_protocol = IPPROTO_TCP,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert the port to a zero-terminated string for use with getaddrinfo()
|
|
||||||
char port[CVT_BASE10_BUFFER_SIZE];
|
|
||||||
cvtUIntToZ(this->port, port, sizeof(port));
|
|
||||||
|
|
||||||
// Get an address for the host. We are only going to try the first address returned.
|
|
||||||
struct addrinfo *hostAddress;
|
|
||||||
int resultAddr;
|
|
||||||
|
|
||||||
if ((resultAddr = getaddrinfo(strZ(this->host), port, &hints, &hostAddress)) != 0)
|
|
||||||
{
|
|
||||||
THROW_FMT(
|
|
||||||
HostConnectError, "unable to get address for '%s': [%d] %s", strZ(this->host), resultAddr,
|
|
||||||
gai_strerror(resultAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to the host
|
// Connect to the host
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
fd = socket(hostAddress->ai_family, hostAddress->ai_socktype, hostAddress->ai_protocol);
|
fd = socket(addressFound->ai_family, addressFound->ai_socktype, addressFound->ai_protocol);
|
||||||
THROW_ON_SYS_ERROR(fd == -1, HostConnectError, "unable to create socket");
|
THROW_ON_SYS_ERROR(fd == -1, HostConnectError, "unable to create socket");
|
||||||
|
|
||||||
sckOptionSet(fd);
|
sckOptionSet(fd);
|
||||||
sckConnect(fd, this->host, this->port, hostAddress, waitRemaining(wait));
|
sckConnect(fd, this->host, this->port, addressFound, waitRemaining(wait));
|
||||||
}
|
}
|
||||||
FINALLY()
|
FINALLY()
|
||||||
{
|
{
|
||||||
freeaddrinfo(hostAddress);
|
freeaddrinfo(addressFound);
|
||||||
}
|
}
|
||||||
TRY_END();
|
TRY_END();
|
||||||
|
|
||||||
// Create the session
|
// Create the session
|
||||||
MEM_CONTEXT_PRIOR_BEGIN()
|
MEM_CONTEXT_PRIOR_BEGIN()
|
||||||
{
|
{
|
||||||
result = sckSessionNew(ioSessionRoleClient, fd, this->host, this->port, this->timeout);
|
result = sckSessionNew(ioSessionRoleClient, fd, this->host, this->port, this->timeoutSession);
|
||||||
}
|
}
|
||||||
MEM_CONTEXT_PRIOR_END();
|
MEM_CONTEXT_PRIOR_END();
|
||||||
}
|
}
|
||||||
@ -176,12 +159,13 @@ static const IoClientInterface sckClientInterface =
|
|||||||
};
|
};
|
||||||
|
|
||||||
IoClient *
|
IoClient *
|
||||||
sckClientNew(const String *host, unsigned int port, TimeMSec timeout)
|
sckClientNew(const String *const host, const unsigned int port, const TimeMSec timeoutConnect, const TimeMSec timeoutSession)
|
||||||
{
|
{
|
||||||
FUNCTION_LOG_BEGIN(logLevelDebug)
|
FUNCTION_LOG_BEGIN(logLevelDebug)
|
||||||
FUNCTION_LOG_PARAM(STRING, host);
|
FUNCTION_LOG_PARAM(STRING, host);
|
||||||
FUNCTION_LOG_PARAM(UINT, port);
|
FUNCTION_LOG_PARAM(UINT, port);
|
||||||
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
FUNCTION_LOG_PARAM(TIME_MSEC, timeoutConnect);
|
||||||
|
FUNCTION_LOG_PARAM(TIME_MSEC, timeoutSession);
|
||||||
FUNCTION_LOG_END();
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
ASSERT(host != NULL);
|
ASSERT(host != NULL);
|
||||||
@ -197,7 +181,8 @@ sckClientNew(const String *host, unsigned int port, TimeMSec timeout)
|
|||||||
.host = strDup(host),
|
.host = strDup(host),
|
||||||
.port = port,
|
.port = port,
|
||||||
.name = strNewFmt("%s:%u", strZ(host), port),
|
.name = strNewFmt("%s:%u", strZ(host), port),
|
||||||
.timeout = timeout,
|
.timeoutConnect = timeoutConnect,
|
||||||
|
.timeoutSession = timeoutSession,
|
||||||
};
|
};
|
||||||
|
|
||||||
statInc(SOCKET_STAT_CLIENT_STR);
|
statInc(SOCKET_STAT_CLIENT_STR);
|
||||||
|
@ -27,6 +27,6 @@ Statistics constants
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Constructors
|
Constructors
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
IoClient *sckClientNew(const String *host, unsigned int port, TimeMSec timeout);
|
IoClient *sckClientNew(const String *host, unsigned int port, TimeMSec timeoutConnect, TimeMSec timeoutSession);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,6 +55,41 @@ sckInit(bool block, bool keepAlive, int tcpKeepAliveCount, int tcpKeepAliveIdle,
|
|||||||
FUNCTION_LOG_RETURN_VOID();
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
struct addrinfo *
|
||||||
|
sckHostLookup(const String *const host, unsigned int port)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, host);
|
||||||
|
FUNCTION_LOG_PARAM(UINT, port);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(host != NULL);
|
||||||
|
ASSERT(port != 0);
|
||||||
|
|
||||||
|
// Set hints that narrow the type of address we are looking for -- we'll take ipv4 or ipv6
|
||||||
|
struct addrinfo hints = (struct addrinfo)
|
||||||
|
{
|
||||||
|
.ai_family = AF_UNSPEC,
|
||||||
|
.ai_flags = AI_PASSIVE,
|
||||||
|
.ai_socktype = SOCK_STREAM,
|
||||||
|
.ai_protocol = IPPROTO_TCP,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert the port to a zero-terminated string for use with getaddrinfo()
|
||||||
|
char portZ[CVT_BASE10_BUFFER_SIZE];
|
||||||
|
cvtUIntToZ(port, portZ, sizeof(portZ));
|
||||||
|
|
||||||
|
// Do the lookup
|
||||||
|
struct addrinfo *result;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if ((error = getaddrinfo(strZ(host), portZ, &hints, &result)) != 0)
|
||||||
|
THROW_FMT(HostConnectError, "unable to get address for '%s': [%d] %s", strZ(host), error, gai_strerror(error));
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_P(VOID, result);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
void
|
void
|
||||||
sckOptionSet(int fd)
|
sckOptionSet(int fd)
|
||||||
|
@ -15,6 +15,9 @@ Functions
|
|||||||
// Initialize settings for socket connections (some are used only for TCP)
|
// Initialize settings for socket connections (some are used only for TCP)
|
||||||
void sckInit(bool block, bool keepAlive, int tcpKeepAliveCount, int tcpKeepAliveIdle, int tcpKeepAliveInterval);
|
void sckInit(bool block, bool keepAlive, int tcpKeepAliveCount, int tcpKeepAliveIdle, int tcpKeepAliveInterval);
|
||||||
|
|
||||||
|
// Get address info for a host/address. The caller is reponsible for freeing addrinfo.
|
||||||
|
struct addrinfo *sckHostLookup(const String *const host, unsigned int port);
|
||||||
|
|
||||||
// Set options on a socket
|
// Set options on a socket
|
||||||
void sckOptionSet(int fd);
|
void sckOptionSet(int fd);
|
||||||
|
|
||||||
|
205
src/common/io/socket/server.c
Normal file
205
src/common/io/socket/server.c
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Socket Server
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/io/server.h"
|
||||||
|
#include "common/io/socket/server.h"
|
||||||
|
#include "common/io/socket/common.h"
|
||||||
|
#include "common/io/socket/session.h"
|
||||||
|
#include "common/memContext.h"
|
||||||
|
#include "common/stat.h"
|
||||||
|
#include "common/type/object.h"
|
||||||
|
#include "common/wait.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Statistics constants
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
STRING_EXTERN(SOCKET_STAT_SERVER_STR, SOCKET_STAT_SERVER);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Object type
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct SocketServer
|
||||||
|
{
|
||||||
|
MemContext *memContext; // Mem context
|
||||||
|
String *address; // Address to listen on
|
||||||
|
unsigned int port; // Port to listen on
|
||||||
|
int socket; // Socket used to listen for new connections
|
||||||
|
String *name; // Socket name (address:port)
|
||||||
|
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
||||||
|
} SocketServer;
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Macros for function logging
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static String *
|
||||||
|
sckServerToLog(const THIS_VOID)
|
||||||
|
{
|
||||||
|
THIS(const SocketServer);
|
||||||
|
|
||||||
|
return strNewFmt("{address: %s, port: %u, timeout: %" PRIu64 "}", strZ(this->address), this->port, this->timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FUNCTION_LOG_SOCKET_SERVER_TYPE \
|
||||||
|
SocketServer *
|
||||||
|
#define FUNCTION_LOG_SOCKET_SERVER_FORMAT(value, buffer, bufferSize) \
|
||||||
|
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, sckServerToLog, buffer, bufferSize)
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Free connection
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
sckServerFreeResource(THIS_VOID)
|
||||||
|
{
|
||||||
|
THIS(SocketServer);
|
||||||
|
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
|
FUNCTION_LOG_PARAM(SOCKET_SERVER, this);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
|
close(this->socket);
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
static IoSession *
|
||||||
|
sckServerAccept(THIS_VOID, IoSession *const session)
|
||||||
|
{
|
||||||
|
THIS(SocketServer);
|
||||||
|
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
|
FUNCTION_LOG_PARAM(SOCKET_SERVER, this);
|
||||||
|
(void)session; // Not used by this server
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(this != NULL);
|
||||||
|
ASSERT(session == NULL);
|
||||||
|
|
||||||
|
IoSession *result = NULL;
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Accept the socket connection
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
unsigned int len = sizeof(addr);
|
||||||
|
|
||||||
|
int serverSocket = accept(this->socket, (struct sockaddr *)&addr, &len);
|
||||||
|
|
||||||
|
THROW_ON_SYS_ERROR(serverSocket == -1, FileOpenError, "unable to accept socket");
|
||||||
|
|
||||||
|
// Create socket session
|
||||||
|
sckOptionSet(serverSocket);
|
||||||
|
|
||||||
|
MEM_CONTEXT_PRIOR_BEGIN()
|
||||||
|
{
|
||||||
|
result = sckSessionNew(ioSessionRoleServer, serverSocket, this->address, this->port, this->timeout);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_PRIOR_END();
|
||||||
|
|
||||||
|
statInc(SOCKET_STAT_SESSION_STR);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(IO_SESSION, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
static const String *
|
||||||
|
sckServerName(THIS_VOID) // {vm_covered}
|
||||||
|
{
|
||||||
|
THIS(SocketServer); // {vm_covered}
|
||||||
|
|
||||||
|
FUNCTION_TEST_BEGIN(); // {vm_covered}
|
||||||
|
FUNCTION_TEST_PARAM(SOCKET_SERVER, this); // {vm_covered}
|
||||||
|
FUNCTION_TEST_END(); // {vm_covered}
|
||||||
|
|
||||||
|
ASSERT(this != NULL); // {vm_covered}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN(this->name); // {vm_covered}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
static const IoServerInterface sckServerInterface =
|
||||||
|
{
|
||||||
|
.type = IO_SERVER_SOCKET_TYPE,
|
||||||
|
.name = sckServerName,
|
||||||
|
.accept = sckServerAccept,
|
||||||
|
.toLog = sckServerToLog,
|
||||||
|
};
|
||||||
|
|
||||||
|
IoServer *
|
||||||
|
sckServerNew(const String *const address, const unsigned int port, const TimeMSec timeout)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelDebug)
|
||||||
|
FUNCTION_LOG_PARAM(STRING, address);
|
||||||
|
FUNCTION_LOG_PARAM(UINT, port);
|
||||||
|
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(address != NULL);
|
||||||
|
ASSERT(port > 0);
|
||||||
|
|
||||||
|
IoServer *this = NULL;
|
||||||
|
|
||||||
|
MEM_CONTEXT_NEW_BEGIN("SocketServer")
|
||||||
|
{
|
||||||
|
SocketServer *driver = memNew(sizeof(SocketServer));
|
||||||
|
|
||||||
|
*driver = (SocketServer)
|
||||||
|
{
|
||||||
|
.memContext = MEM_CONTEXT_NEW(),
|
||||||
|
.address = strDup(address),
|
||||||
|
.port = port,
|
||||||
|
.name = strNewFmt("%s:%u", strZ(address), port),
|
||||||
|
.timeout = timeout,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Lookup address
|
||||||
|
struct addrinfo *addressFound = sckHostLookup(driver->address, driver->port);
|
||||||
|
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
// Create socket
|
||||||
|
THROW_ON_SYS_ERROR(
|
||||||
|
(driver->socket = socket(addressFound->ai_family, SOCK_STREAM, 0)) == -1, FileOpenError, "unable to create socket");
|
||||||
|
|
||||||
|
// Set the address as reusable so we can bind again quickly after a restart or crash
|
||||||
|
int reuseAddr = 1;
|
||||||
|
setsockopt(driver->socket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr));
|
||||||
|
|
||||||
|
// Ensure file descriptor is closed
|
||||||
|
memContextCallbackSet(driver->memContext, sckServerFreeResource, driver);
|
||||||
|
|
||||||
|
// Bind the address
|
||||||
|
THROW_ON_SYS_ERROR(
|
||||||
|
bind(driver->socket, addressFound->ai_addr, addressFound->ai_addrlen) == -1, FileOpenError,
|
||||||
|
"unable to bind socket");
|
||||||
|
}
|
||||||
|
FINALLY()
|
||||||
|
{
|
||||||
|
freeaddrinfo(addressFound);
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
|
// Listen for client connections. It might be a good idea to make the backlog configurable but this value seems OK for now.
|
||||||
|
THROW_ON_SYS_ERROR(listen(driver->socket, 100) == -1, FileOpenError, "unable to listen on socket");
|
||||||
|
|
||||||
|
statInc(SOCKET_STAT_SERVER_STR);
|
||||||
|
|
||||||
|
this = ioServerNew(driver, &sckServerInterface);
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_NEW_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(IO_SERVER, this);
|
||||||
|
}
|
29
src/common/io/socket/server.h
Normal file
29
src/common/io/socket/server.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Socket Server
|
||||||
|
|
||||||
|
A simple socket server intended to expose services by accepting a socket.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMON_IO_SOCKET_SERVER_H
|
||||||
|
#define COMMON_IO_SOCKET_SERVER_H
|
||||||
|
|
||||||
|
#include "common/io/server.h"
|
||||||
|
#include "common/io/socket/client.h"
|
||||||
|
#include "common/time.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Io server type
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define IO_SERVER_SOCKET_TYPE IO_CLIENT_SOCKET_TYPE
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Statistics constants
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define SOCKET_STAT_SERVER "socket.server" // Servers created
|
||||||
|
STRING_DECLARE(SOCKET_STAT_SERVER_STR);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Constructors
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
IoServer *sckServerNew(const String *address, unsigned int port, TimeMSec timeout);
|
||||||
|
|
||||||
|
#endif
|
@ -22,7 +22,7 @@ typedef struct SocketSession
|
|||||||
int fd; // File descriptor
|
int fd; // File descriptor
|
||||||
String *host; // Hostname or IP address
|
String *host; // Hostname or IP address
|
||||||
unsigned int port; // Port to connect to host on
|
unsigned int port; // Port to connect to host on
|
||||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
TimeMSec timeout; // Timeout for any i/o operation (read, write, etc.)
|
||||||
|
|
||||||
IoRead *read; // IoRead interface to the file descriptor
|
IoRead *read; // IoRead interface to the file descriptor
|
||||||
IoWrite *write; // IoWrite interface to the file descriptor
|
IoWrite *write; // IoWrite interface to the file descriptor
|
||||||
|
@ -3,17 +3,15 @@ TLS Client
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#include "build.auto.h"
|
#include "build.auto.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include <openssl/x509v3.h>
|
|
||||||
|
|
||||||
#include "common/crypto/common.h"
|
#include "common/crypto/common.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/io/client.h"
|
#include "common/io/client.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
#include "common/io/tls/client.h"
|
#include "common/io/tls/client.h"
|
||||||
|
#include "common/io/tls/common.h"
|
||||||
#include "common/io/tls/session.h"
|
#include "common/io/tls/session.h"
|
||||||
#include "common/stat.h"
|
#include "common/stat.h"
|
||||||
#include "common/type/object.h"
|
#include "common/type/object.h"
|
||||||
@ -32,7 +30,8 @@ Object type
|
|||||||
typedef struct TlsClient
|
typedef struct TlsClient
|
||||||
{
|
{
|
||||||
const String *host; // Host to use for peer verification
|
const String *host; // Host to use for peer verification
|
||||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
TimeMSec timeoutConnect; // Timeout for connection
|
||||||
|
TimeMSec timeoutSession; // Timeout passed to session
|
||||||
bool verifyPeer; // Should the peer (server) certificate be verified?
|
bool verifyPeer; // Should the peer (server) certificate be verified?
|
||||||
IoClient *ioClient; // Underlying client (usually a SocketClient)
|
IoClient *ioClient; // Underlying client (usually a SocketClient)
|
||||||
|
|
||||||
@ -48,8 +47,8 @@ tlsClientToLog(const THIS_VOID)
|
|||||||
THIS(const TlsClient);
|
THIS(const TlsClient);
|
||||||
|
|
||||||
return strNewFmt(
|
return strNewFmt(
|
||||||
"{ioClient: %s, timeout: %" PRIu64", verifyPeer: %s}",
|
"{ioClient: %s, timeoutConnect: %" PRIu64 ", timeoutSession: %" PRIu64 ", verifyPeer: %s}",
|
||||||
objMemContextFreeing(this) ? NULL_Z : strZ(ioClientToLog(this->ioClient)), this->timeout,
|
objMemContextFreeing(this) ? NULL_Z : strZ(ioClientToLog(this->ioClient)), this->timeoutConnect, this->timeoutSession,
|
||||||
cvtBoolToConstZ(this->verifyPeer));
|
cvtBoolToConstZ(this->verifyPeer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,30 +76,6 @@ tlsClientFreeResource(THIS_VOID)
|
|||||||
FUNCTION_LOG_RETURN_VOID();
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
|
||||||
Convert an ASN1 string used in certificates to a String
|
|
||||||
***********************************************************************************************************************************/
|
|
||||||
static String *
|
|
||||||
asn1ToStr(ASN1_STRING *nameAsn1)
|
|
||||||
{
|
|
||||||
FUNCTION_TEST_BEGIN();
|
|
||||||
FUNCTION_TEST_PARAM_P(VOID, nameAsn1);
|
|
||||||
FUNCTION_TEST_END();
|
|
||||||
|
|
||||||
// The name should not be null
|
|
||||||
if (nameAsn1 == NULL) // {vm_covered}
|
|
||||||
THROW(CryptoError, "TLS certificate name entry is missing");
|
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN( // {vm_covered}
|
|
||||||
strNewZN(
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
(const char *)ASN1_STRING_data(nameAsn1),
|
|
||||||
#else
|
|
||||||
(const char *)ASN1_STRING_get0_data(nameAsn1),
|
|
||||||
#endif
|
|
||||||
(size_t)ASN1_STRING_length(nameAsn1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Check if a name from the server certificate matches the hostname
|
Check if a name from the server certificate matches the hostname
|
||||||
|
|
||||||
@ -117,9 +92,8 @@ tlsClientHostVerifyName(const String *host, const String *name)
|
|||||||
ASSERT(host != NULL);
|
ASSERT(host != NULL);
|
||||||
ASSERT(name != NULL);
|
ASSERT(name != NULL);
|
||||||
|
|
||||||
// Reject embedded nulls in certificate common or alternative name to prevent attacks like CVE-2009-4034
|
// Check for NULLs in the name
|
||||||
if (strlen(strZ(name)) != strSize(name))
|
tlsCertNameVerify(name);
|
||||||
THROW(CryptoError, "TLS certificate name contains embedded null");
|
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
@ -185,7 +159,7 @@ tlsClientHostVerify(const String *host, X509 *certificate)
|
|||||||
altNameFound = true; // {vm_covered}
|
altNameFound = true; // {vm_covered}
|
||||||
|
|
||||||
if (name->type == GEN_DNS) // {vm_covered}
|
if (name->type == GEN_DNS) // {vm_covered}
|
||||||
result = tlsClientHostVerifyName(host, asn1ToStr(name->d.dNSName)); // {vm_covered}
|
result = tlsClientHostVerifyName(host, tlsAsn1ToStr(name->d.dNSName)); // {vm_covered}
|
||||||
|
|
||||||
if (result != false) // {vm_covered}
|
if (result != false) // {vm_covered}
|
||||||
break; // {vm_covered}
|
break; // {vm_covered}
|
||||||
@ -197,17 +171,7 @@ tlsClientHostVerify(const String *host, X509 *certificate)
|
|||||||
// If no subject alternative name was found then check the common name. Per RFC 2818 and RFC 6125, if the subjectAltName
|
// If no subject alternative name was found then check the common name. Per RFC 2818 and RFC 6125, if the subjectAltName
|
||||||
// extension of type dNSName is present the CN must be ignored.
|
// extension of type dNSName is present the CN must be ignored.
|
||||||
if (!altNameFound) // {vm_covered}
|
if (!altNameFound) // {vm_covered}
|
||||||
{
|
result = tlsClientHostVerifyName(host, tlsCertCommonName(certificate)); // {vm_covered}
|
||||||
X509_NAME *subjectName = X509_get_subject_name(certificate); // {vm_covered}
|
|
||||||
CHECK(subjectName != NULL); // {vm_covered}
|
|
||||||
|
|
||||||
int commonNameIndex = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); // {vm_covered}
|
|
||||||
CHECK(commonNameIndex >= 0); // {vm_covered}
|
|
||||||
|
|
||||||
result = tlsClientHostVerifyName( // {vm_covered}
|
|
||||||
host, // {vm_covered}
|
|
||||||
asn1ToStr(X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subjectName, commonNameIndex)))); // {vm_covered}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
MEM_CONTEXT_TEMP_END(); // {vm_covered}
|
MEM_CONTEXT_TEMP_END(); // {vm_covered}
|
||||||
|
|
||||||
@ -215,46 +179,110 @@ tlsClientHostVerify(const String *host, X509 *certificate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Open connection if this is a new client or if the connection was closed by the server
|
Authenticate server
|
||||||
|
|
||||||
|
Adapted from PostgreSQL open_client_SSL() in src/interfaces/libpq/fe-secure-openssl.c.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static bool
|
||||||
|
tlsClientAuth(const TlsClient *const this, SSL *const tlsSession)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
|
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||||
|
FUNCTION_LOG_PARAM_P(VOID, tlsSession);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Verify that the certificate presented by the server is valid
|
||||||
|
if (this->verifyPeer) // {vm_covered}
|
||||||
|
{
|
||||||
|
// Verify that the chain of trust leads to a valid CA
|
||||||
|
long int verifyResult = SSL_get_verify_result(tlsSession); // {vm_covered}
|
||||||
|
|
||||||
|
if (verifyResult != X509_V_OK) // {vm_covered}
|
||||||
|
{
|
||||||
|
THROW_FMT( // {vm_covered}
|
||||||
|
CryptoError, "unable to verify certificate presented by '%s': [%ld] %s", // {vm_covered}
|
||||||
|
strZ(ioClientName(this->ioClient)), verifyResult, // {vm_covered}
|
||||||
|
X509_verify_cert_error_string(verifyResult)); // {vm_covered}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the hostname appears in the certificate
|
||||||
|
X509 *certificate = SSL_get_peer_certificate(tlsSession); // {vm_covered}
|
||||||
|
bool nameResult = tlsClientHostVerify(this->host, certificate); // {vm_covered}
|
||||||
|
X509_free(certificate); // {vm_covered}
|
||||||
|
|
||||||
|
if (!nameResult) // {vm_covered}
|
||||||
|
{
|
||||||
|
THROW_FMT( // {vm_covered}
|
||||||
|
CryptoError, // {vm_covered}
|
||||||
|
"unable to find hostname '%s' in certificate common name or subject alternative names", // {vm_covered}
|
||||||
|
strZ(this->host)); // {vm_covered}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(BOOL, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Open TLS session on a socket
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
static IoSession *
|
static IoSession *
|
||||||
tlsClientOpen(THIS_VOID)
|
tlsClientOpen(THIS_VOID)
|
||||||
{
|
{
|
||||||
THIS(TlsClient);
|
THIS(TlsClient);
|
||||||
|
|
||||||
FUNCTION_LOG_BEGIN(logLevelTrace)
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
FUNCTION_LOG_PARAM(TLS_CLIENT, this);
|
||||||
FUNCTION_LOG_END();
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
ASSERT(this != NULL);
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
IoSession *result = NULL;
|
IoSession *result = NULL;
|
||||||
SSL *session = NULL;
|
|
||||||
|
|
||||||
MEM_CONTEXT_TEMP_BEGIN()
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
{
|
{
|
||||||
bool retry;
|
bool retry;
|
||||||
Wait *wait = waitNew(this->timeout);
|
Wait *wait = waitNew(this->timeoutConnect);
|
||||||
|
SSL *tlsSession = NULL;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Assume there will be no retry
|
// Assume there will be no retry
|
||||||
retry = false;
|
retry = false;
|
||||||
|
|
||||||
|
// Create the TLS session
|
||||||
|
tlsSession = SSL_new(this->context);
|
||||||
|
cryptoError(tlsSession == NULL, "unable to create TLS session");
|
||||||
|
|
||||||
|
// Set server host name used for validation
|
||||||
|
cryptoError(SSL_set_tlsext_host_name(tlsSession, strZ(this->host)) != 1, "unable to set TLS host name");
|
||||||
|
|
||||||
|
// Open TLS session
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
// Open the underlying session first since this is mostly likely to fail
|
// Open the underlying session first since this is mostly likely to fail
|
||||||
IoSession *ioSession = ioClientOpen(this->ioClient);
|
IoSession *ioSession = NULL;
|
||||||
|
|
||||||
// Create internal TLS session. If there is a failure before the TlsSession object is created there may be a leak
|
TRY_BEGIN()
|
||||||
// of the TLS session but this is likely to result in program termination so it doesn't seem worth coding for.
|
{
|
||||||
cryptoError((session = SSL_new(this->context)) == NULL, "unable to create TLS session");
|
ioSession = ioClientOpen(this->ioClient);
|
||||||
|
}
|
||||||
|
CATCH_ANY()
|
||||||
|
{
|
||||||
|
SSL_free(tlsSession);
|
||||||
|
RETHROW();
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
// Set server host name used for validation
|
// Open session
|
||||||
cryptoError(SSL_set_tlsext_host_name(session, strZ(this->host)) != 1, "unable to set TLS host name");
|
result = tlsSessionNew(tlsSession, ioSession, this->timeoutSession);
|
||||||
|
|
||||||
// Create the TLS session
|
|
||||||
result = tlsSessionNew(session, ioSession, this->timeout);
|
|
||||||
}
|
}
|
||||||
CATCH_ANY()
|
CATCH_ANY()
|
||||||
{
|
{
|
||||||
@ -275,39 +303,16 @@ tlsClientOpen(THIS_VOID)
|
|||||||
}
|
}
|
||||||
while (retry);
|
while (retry);
|
||||||
|
|
||||||
|
// Authenticate TLS session
|
||||||
|
ioSessionAuthenticatedSet(result, tlsClientAuth(this, tlsSession));
|
||||||
|
|
||||||
|
// Move session
|
||||||
ioSessionMove(result, memContextPrior());
|
ioSessionMove(result, memContextPrior());
|
||||||
}
|
}
|
||||||
MEM_CONTEXT_TEMP_END();
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
statInc(TLS_STAT_SESSION_STR);
|
statInc(TLS_STAT_SESSION_STR);
|
||||||
|
|
||||||
// Verify that the certificate presented by the server is valid
|
|
||||||
if (this->verifyPeer) // {vm_covered}
|
|
||||||
{
|
|
||||||
// Verify that the chain of trust leads to a valid CA
|
|
||||||
long int verifyResult = SSL_get_verify_result(session); // {vm_covered}
|
|
||||||
|
|
||||||
if (verifyResult != X509_V_OK) // {vm_covered}
|
|
||||||
{
|
|
||||||
THROW_FMT( // {vm_covered}
|
|
||||||
CryptoError, "unable to verify certificate presented by '%s': [%ld] %s", // {vm_covered}
|
|
||||||
strZ(ioClientName(this->ioClient)), verifyResult, X509_verify_cert_error_string(verifyResult)); // {vm_covered}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the hostname appears in the certificate
|
|
||||||
X509 *certificate = SSL_get_peer_certificate(session); // {vm_covered}
|
|
||||||
bool nameResult = tlsClientHostVerify(this->host, certificate); // {vm_covered}
|
|
||||||
X509_free(certificate); // {vm_covered}
|
|
||||||
|
|
||||||
if (!nameResult) // {vm_covered}
|
|
||||||
{
|
|
||||||
THROW_FMT( // {vm_covered}
|
|
||||||
CryptoError, // {vm_covered}
|
|
||||||
"unable to find hostname '%s' in certificate common name or subject alternative names", // {vm_covered}
|
|
||||||
strZ(this->host)); // {vm_covered}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNCTION_LOG_RETURN(IO_SESSION, result);
|
FUNCTION_LOG_RETURN(IO_SESSION, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +331,11 @@ tlsClientName(THIS_VOID)
|
|||||||
FUNCTION_TEST_RETURN(ioClientName(this->ioClient));
|
FUNCTION_TEST_RETURN(ioClientName(this->ioClient));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/***********************************************************************************************************************************
|
||||||
|
Initialize TLS session with all required security features
|
||||||
|
|
||||||
|
Adapted from PostgreSQL initialize_SSL() in src/interfaces/libpq/fe-secure-openssl.c.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
static const IoClientInterface tlsClientInterface =
|
static const IoClientInterface tlsClientInterface =
|
||||||
{
|
{
|
||||||
.type = IO_CLIENT_TLS_TYPE,
|
.type = IO_CLIENT_TLS_TYPE,
|
||||||
@ -336,15 +345,21 @@ static const IoClientInterface tlsClientInterface =
|
|||||||
};
|
};
|
||||||
|
|
||||||
IoClient *
|
IoClient *
|
||||||
tlsClientNew(IoClient *ioClient, const String *host, TimeMSec timeout, bool verifyPeer, const String *caFile, const String *caPath)
|
tlsClientNew(
|
||||||
|
IoClient *const ioClient, const String *const host, const TimeMSec timeoutConnect, const TimeMSec timeoutSession,
|
||||||
|
const bool verifyPeer, const String *const caFile, const String *const caPath, const String *const certFile,
|
||||||
|
const String *const keyFile)
|
||||||
{
|
{
|
||||||
FUNCTION_LOG_BEGIN(logLevelDebug)
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
FUNCTION_LOG_PARAM(IO_CLIENT, ioClient);
|
FUNCTION_LOG_PARAM(IO_CLIENT, ioClient);
|
||||||
FUNCTION_LOG_PARAM(STRING, host);
|
FUNCTION_LOG_PARAM(STRING, host);
|
||||||
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
FUNCTION_LOG_PARAM(TIME_MSEC, timeoutConnect);
|
||||||
|
FUNCTION_LOG_PARAM(TIME_MSEC, timeoutSession);
|
||||||
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
|
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
|
||||||
FUNCTION_LOG_PARAM(STRING, caFile);
|
FUNCTION_LOG_PARAM(STRING, caFile);
|
||||||
FUNCTION_LOG_PARAM(STRING, caPath);
|
FUNCTION_LOG_PARAM(STRING, caPath);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, certFile);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, keyFile);
|
||||||
FUNCTION_LOG_END();
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
ASSERT(ioClient != NULL);
|
ASSERT(ioClient != NULL);
|
||||||
@ -359,33 +374,19 @@ tlsClientNew(IoClient *ioClient, const String *host, TimeMSec timeout, bool veri
|
|||||||
{
|
{
|
||||||
.ioClient = ioClientMove(ioClient, MEM_CONTEXT_NEW()),
|
.ioClient = ioClientMove(ioClient, MEM_CONTEXT_NEW()),
|
||||||
.host = strDup(host),
|
.host = strDup(host),
|
||||||
.timeout = timeout,
|
.timeoutConnect = timeoutConnect,
|
||||||
|
.timeoutSession = timeoutSession,
|
||||||
.verifyPeer = verifyPeer,
|
.verifyPeer = verifyPeer,
|
||||||
|
.context = tlsContext(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup TLS context
|
// Set callback to free context
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
cryptoInit();
|
|
||||||
|
|
||||||
// Select the TLS method to use. To maintain compatibility with older versions of OpenSSL we need to use an SSL method,
|
|
||||||
// but SSL versions will be excluded in SSL_CTX_set_options().
|
|
||||||
const SSL_METHOD *method = SSLv23_method();
|
|
||||||
cryptoError(method == NULL, "unable to load TLS method");
|
|
||||||
|
|
||||||
// Create the TLS context
|
|
||||||
driver->context = SSL_CTX_new(method);
|
|
||||||
cryptoError(driver->context == NULL, "unable to create TLS context");
|
|
||||||
|
|
||||||
memContextCallbackSet(objMemContext(driver), tlsClientFreeResource, driver);
|
memContextCallbackSet(objMemContext(driver), tlsClientFreeResource, driver);
|
||||||
|
|
||||||
// Exclude SSL versions to only allow TLS and also disable compression
|
// Enable safe compatibility options
|
||||||
SSL_CTX_set_options(driver->context, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION);
|
SSL_CTX_set_options(driver->context, SSL_OP_ALL);
|
||||||
|
|
||||||
// Disable auto-retry to prevent SSL_read() from hanging
|
|
||||||
SSL_CTX_clear_mode(driver->context, SSL_MODE_AUTO_RETRY);
|
|
||||||
|
|
||||||
// Set location of CA certificates if the server certificate will be verified
|
// Set location of CA certificates if the server certificate will be verified
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
|
||||||
if (driver->verifyPeer)
|
if (driver->verifyPeer)
|
||||||
{
|
{
|
||||||
// If the user specified a location
|
// If the user specified a location
|
||||||
@ -403,6 +404,10 @@ tlsClientNew(IoClient *ioClient, const String *host, TimeMSec timeout, bool veri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load certificate and key, if specified
|
||||||
|
tlsCertKeyLoad(driver->context, certFile, keyFile);
|
||||||
|
|
||||||
|
// Increment stat
|
||||||
statInc(TLS_STAT_CLIENT_STR);
|
statInc(TLS_STAT_CLIENT_STR);
|
||||||
|
|
||||||
// Create client interface
|
// Create client interface
|
||||||
|
@ -31,7 +31,8 @@ Statistics constants
|
|||||||
Constructors
|
Constructors
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
IoClient *tlsClientNew(
|
IoClient *tlsClientNew(
|
||||||
IoClient *ioClient, const String *host, TimeMSec timeout, bool verifyPeer, const String *caFile, const String *caPath);
|
IoClient *ioClient, const String *host, TimeMSec timeoutConnect, TimeMSec timeoutSession, bool verifyPeer, const String *caFile,
|
||||||
|
const String *caPath, const String *certFile, const String *keyFile);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Functions
|
Functions
|
||||||
|
186
src/common/io/tls/common.c
Normal file
186
src/common/io/tls/common.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
TLS Common
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
#include "common/crypto/common.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/io/tls/common.h"
|
||||||
|
#include "common/user.h"
|
||||||
|
#include "storage/posix/storage.h"
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
String *
|
||||||
|
tlsAsn1ToStr(ASN1_STRING *const nameAsn1)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, nameAsn1);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
// The name should not be null
|
||||||
|
if (nameAsn1 == NULL) // {vm_covered}
|
||||||
|
THROW(CryptoError, "TLS certificate name entry is missing");
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN( // {vm_covered}
|
||||||
|
strNewZN(
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
(const char *)ASN1_STRING_data(nameAsn1),
|
||||||
|
#else
|
||||||
|
(const char *)ASN1_STRING_get0_data(nameAsn1),
|
||||||
|
#endif
|
||||||
|
(size_t)ASN1_STRING_length(nameAsn1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
void
|
||||||
|
tlsCertNameVerify(const String *const name)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM(STRING, name);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
// Check for embedded NULLs
|
||||||
|
if (strlen(strZ(name)) != strSize(name))
|
||||||
|
THROW(CryptoError, "TLS certificate name contains embedded null");
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
String *
|
||||||
|
tlsCertCommonName(X509 *const certificate) // {vm_covered}
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN(); // {vm_covered}
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, certificate); // {vm_covered}
|
||||||
|
FUNCTION_TEST_END(); // {vm_covered}
|
||||||
|
|
||||||
|
X509_NAME *const subjectName = X509_get_subject_name(certificate); // {vm_covered}
|
||||||
|
CHECK(subjectName != NULL); // {vm_covered}
|
||||||
|
|
||||||
|
const int commonNameIndex = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); // {vm_covered}
|
||||||
|
CHECK(commonNameIndex >= 0); // {vm_covered}
|
||||||
|
|
||||||
|
String *result = tlsAsn1ToStr(X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subjectName, commonNameIndex))); // {vm_covered}
|
||||||
|
|
||||||
|
// Check for NULLs in the name
|
||||||
|
tlsCertNameVerify(result); // {vm_covered}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN(result); // {vm_covered}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
// Callback to process cert passwords
|
||||||
|
static int
|
||||||
|
tlsCertPwd(char *buffer, const int size, const int rwFlag, void *const userData)
|
||||||
|
{
|
||||||
|
CHECK(size > 0);
|
||||||
|
(void)rwFlag; (void)userData;
|
||||||
|
|
||||||
|
// No password is currently supplied
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tlsCertKeyLoad(SSL_CTX *const context, const String *const certFile, const String *const keyFile)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, context);
|
||||||
|
FUNCTION_TEST_PARAM(STRING, certFile);
|
||||||
|
FUNCTION_TEST_PARAM(STRING, keyFile);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
ASSERT(context != NULL);
|
||||||
|
ASSERT((certFile == NULL && keyFile == NULL) || (certFile != NULL && keyFile != NULL));
|
||||||
|
|
||||||
|
if (certFile != NULL)
|
||||||
|
{
|
||||||
|
userInit();
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Set cert password callback
|
||||||
|
SSL_CTX_set_default_passwd_cb(context, tlsCertPwd);
|
||||||
|
|
||||||
|
// Load certificate
|
||||||
|
cryptoError(
|
||||||
|
SSL_CTX_use_certificate_chain_file(context, strZ(certFile)) != 1,
|
||||||
|
strZ(strNewFmt("unable to load cert file '%s'", strZ(certFile))));
|
||||||
|
|
||||||
|
// Check that key has the correct permissions
|
||||||
|
const StorageInfo keyInfo = storageInfoP(
|
||||||
|
storagePosixNewP(FSLASH_STR), keyFile, .ignoreMissing = true, .followLink = true);
|
||||||
|
|
||||||
|
if (keyInfo.exists)
|
||||||
|
{
|
||||||
|
if (keyInfo.userId != userId() && keyInfo.userId != 0) // {vm_covered}
|
||||||
|
{
|
||||||
|
THROW_FMT( // {vm_covered}
|
||||||
|
FileReadError, "key file '%s' must be owned by the '%s' user or root", strZ(keyFile), strZ(userName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((keyInfo.userId == userId() && keyInfo.mode & (S_IRWXG | S_IRWXO)) || // {vm_covered}
|
||||||
|
(keyInfo.userId == 0 && keyInfo.mode & (S_IWGRP | S_IXGRP | S_IRWXO))) // {vm_covered}
|
||||||
|
{
|
||||||
|
THROW_FMT(
|
||||||
|
FileReadError,
|
||||||
|
"key file '%s' has group or other permissions\n"
|
||||||
|
"HINT: file must have permissions u=rw (0600) or less if owned by the '%s' user\n"
|
||||||
|
"HINT: file must have permissions u=rw, g=r (0640) or less if owned by root\n",
|
||||||
|
strZ(keyFile), strZ(userName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load key and verify that the key and cert go together
|
||||||
|
cryptoError(
|
||||||
|
SSL_CTX_use_PrivateKey_file(context, strZ(keyFile), SSL_FILETYPE_PEM) != 1,
|
||||||
|
strZ(strNewFmt("unable to load key file '%s'", strZ(keyFile))));
|
||||||
|
|
||||||
|
// Verify again that the cert and key go together. It is not clear why this is needed since the key has already been
|
||||||
|
// verified in SSL_CTX_use_PrivateKey_file(), but it may be that older versions of OpenSSL need it.
|
||||||
|
cryptoError(
|
||||||
|
SSL_CTX_check_private_key(context) != 1,
|
||||||
|
strZ(strNewFmt("cert '%s' and key '%s' do not match", strZ(certFile), strZ(keyFile))));
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
SSL_CTX *
|
||||||
|
tlsContext(void)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_VOID();
|
||||||
|
|
||||||
|
cryptoInit();
|
||||||
|
|
||||||
|
// Select the TLS method to use. To maintain compatibility with older versions of OpenSSL we need to use an SSL method, but
|
||||||
|
// SSL versions will be excluded in SSL_CTX_set_options().
|
||||||
|
const SSL_METHOD *const method = SSLv23_method();
|
||||||
|
cryptoError(method == NULL, "unable to load TLS method");
|
||||||
|
|
||||||
|
// Create TLS context
|
||||||
|
SSL_CTX *const result = SSL_CTX_new(method);
|
||||||
|
cryptoError(result == NULL, "unable to create TLS context");
|
||||||
|
|
||||||
|
// Set options
|
||||||
|
SSL_CTX_set_options(
|
||||||
|
result,
|
||||||
|
// Disable SSL
|
||||||
|
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
|
||||||
|
// Disable compression
|
||||||
|
SSL_OP_NO_COMPRESSION);
|
||||||
|
|
||||||
|
// Disable auto-retry to prevent SSL_read() from hanging
|
||||||
|
SSL_CTX_clear_mode(result, SSL_MODE_AUTO_RETRY);
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN(result);
|
||||||
|
}
|
29
src/common/io/tls/common.h
Normal file
29
src/common/io/tls/common.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
TLS Common
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMON_IO_TLS_COMMON_H
|
||||||
|
#define COMMON_IO_TLS_COMMON_H
|
||||||
|
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
|
||||||
|
#include "common/type/string.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Convert an ASN1 string used in certificates to a String
|
||||||
|
String *tlsAsn1ToStr(ASN1_STRING *nameAsn1);
|
||||||
|
|
||||||
|
// Get common name from a certificate
|
||||||
|
String *tlsCertCommonName(X509 *certificate);
|
||||||
|
|
||||||
|
// Reject embedded nulls in certificate common or alternative name to prevent attacks like CVE-2009-4034
|
||||||
|
void tlsCertNameVerify(const String *name);
|
||||||
|
|
||||||
|
// Load certificate and key and check that they match
|
||||||
|
void tlsCertKeyLoad(SSL_CTX *context, const String *certFile, const String *keyFile);
|
||||||
|
|
||||||
|
// Create TLS context
|
||||||
|
SSL_CTX *tlsContext(void);
|
||||||
|
|
||||||
|
#endif
|
357
src/common/io/tls/server.c
Normal file
357
src/common/io/tls/server.c
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
TLS Server
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#include "common/crypto/common.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/io/server.h"
|
||||||
|
#include "common/io/tls/common.h"
|
||||||
|
#include "common/io/tls/server.h"
|
||||||
|
#include "common/io/tls/session.h"
|
||||||
|
#include "common/stat.h"
|
||||||
|
#include "common/type/object.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Statistics constants
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
STRING_EXTERN(TLS_STAT_SERVER_STR, TLS_STAT_SERVER);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Object type
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
typedef struct TlsServer
|
||||||
|
{
|
||||||
|
String *host; // Host
|
||||||
|
SSL_CTX *context; // TLS context
|
||||||
|
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
||||||
|
bool verifyPeer; // Will the client cert be verified?
|
||||||
|
} TlsServer;
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Macros for function logging
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static String *
|
||||||
|
tlsServerToLog(const THIS_VOID)
|
||||||
|
{
|
||||||
|
THIS(const TlsServer);
|
||||||
|
|
||||||
|
return strNewFmt("{host: %s, timeout: %" PRIu64 "}", strZ(this->host), this->timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FUNCTION_LOG_TLS_SERVER_TYPE \
|
||||||
|
TlsServer *
|
||||||
|
#define FUNCTION_LOG_TLS_SERVER_FORMAT(value, buffer, bufferSize) \
|
||||||
|
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, tlsServerToLog, buffer, bufferSize)
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Free context
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
tlsServerFreeResource(THIS_VOID)
|
||||||
|
{
|
||||||
|
THIS(TlsServer);
|
||||||
|
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
|
FUNCTION_LOG_PARAM(TLS_SERVER, this);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(this != NULL);
|
||||||
|
|
||||||
|
SSL_CTX_free(this->context);
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Set DH parameters for generating ephemeral DH keys. The DH parameters can take a long time to compute, so they must be precomputed
|
||||||
|
using parameters provided by the OpenSSL project.
|
||||||
|
|
||||||
|
These values can be static since the OpenSSL library can efficiently generate random keys from the information provided.
|
||||||
|
|
||||||
|
Adapted from PostgreSQL initialize_dh() in src/backend/libpq/be-secure-openssl.c. Also see https://weakdh.org and
|
||||||
|
https://en.wikipedia.org/wiki/Logjam_(computer_security).
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Hardcoded DH parameters, used in ephemeral DH keying. This is the 2048-bit DH parameter from RFC 3526. The generation of the
|
||||||
|
// prime is specified in RFC 2412 Appendix E, which also discusses the design choice of the generator. Note that when loaded with
|
||||||
|
// OpenSSL this causes DH_check() to fail on DH_NOT_SUITABLE_GENERATOR, where leaking a bit is preferred.
|
||||||
|
#define DH_2048 \
|
||||||
|
"-----BEGIN DH PARAMETERS-----\n" \
|
||||||
|
"MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n" \
|
||||||
|
"IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n" \
|
||||||
|
"awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n" \
|
||||||
|
"mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n" \
|
||||||
|
"fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n" \
|
||||||
|
"5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n" \
|
||||||
|
"-----END DH PARAMETERS-----"
|
||||||
|
|
||||||
|
static void
|
||||||
|
tlsServerDh(SSL_CTX *const context)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, context);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
|
||||||
|
|
||||||
|
BIO *const bio = BIO_new_mem_buf(DH_2048, sizeof(DH_2048));
|
||||||
|
cryptoError(bio == NULL, "unable create buffer for DH parameters");
|
||||||
|
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
DH *const dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
cryptoError(SSL_CTX_set_tmp_dh(context, dh) != 1, "unable to set temp dh parameters");
|
||||||
|
}
|
||||||
|
FINALLY()
|
||||||
|
{
|
||||||
|
DH_free(dh);
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
}
|
||||||
|
FINALLY()
|
||||||
|
{
|
||||||
|
BIO_free(bio);
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Set ECDH parameters for generating ephemeral Elliptic Curve DH keys.
|
||||||
|
|
||||||
|
Adapted from PostgreSQL initialize_ecdh() in src/backend/libpq/be-secure-openssl.c.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define ECHD_CURVE "prime256v1"
|
||||||
|
|
||||||
|
static void
|
||||||
|
tlsServerEcdh(SSL_CTX *const context)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM_P(VOID, context);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
const int nid = OBJ_sn2nid(ECHD_CURVE);
|
||||||
|
cryptoError(nid == NID_undef, "unrecognized ECDH curve " ECHD_CURVE);
|
||||||
|
|
||||||
|
EC_KEY *const ecdh = EC_KEY_new_by_curve_name(nid);
|
||||||
|
cryptoError(ecdh == NULL, "could not create ecdh key");
|
||||||
|
|
||||||
|
SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
|
||||||
|
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
cryptoError(SSL_CTX_set_tmp_ecdh(context, ecdh) != 1, "unable to set temp ecdh key");
|
||||||
|
}
|
||||||
|
FINALLY()
|
||||||
|
{
|
||||||
|
EC_KEY_free(ecdh);
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Authenticate client
|
||||||
|
|
||||||
|
Adapted from PostgreSQL be_tls_open_server() in src/backend/libpq/be-secure-openssl.c.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
tlsServerAuth(const TlsServer *const this, IoSession *const ioSession, SSL *const tlsSession)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
|
FUNCTION_LOG_PARAM(TLS_SERVER, this);
|
||||||
|
FUNCTION_LOG_PARAM(IO_SESSION, ioSession);
|
||||||
|
FUNCTION_LOG_PARAM_P(VOID, tlsSession);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// If peer verification requested
|
||||||
|
if (this->verifyPeer) // {vm_covered}
|
||||||
|
{
|
||||||
|
// If the client cert was presented then the session is authenticated. An error will be thrown automatically if the
|
||||||
|
// client cert is not valid.
|
||||||
|
X509 *const clientCert = SSL_get_peer_certificate(tlsSession); // {vm_covered}
|
||||||
|
ioSessionAuthenticatedSet(ioSession, clientCert != NULL); // {vm_covered}
|
||||||
|
|
||||||
|
// Set the peer name to the client cert common name
|
||||||
|
if (clientCert != NULL) // {vm_covered}
|
||||||
|
ioSessionPeerNameSet(ioSession, tlsCertCommonName(clientCert)); // {vm_covered}
|
||||||
|
|
||||||
|
// Free the cert
|
||||||
|
X509_free(clientCert); // {vm_covered}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
static IoSession *
|
||||||
|
tlsServerAccept(THIS_VOID, IoSession *const ioSession)
|
||||||
|
{
|
||||||
|
THIS(TlsServer);
|
||||||
|
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
|
FUNCTION_LOG_PARAM(TLS_SERVER, this);
|
||||||
|
FUNCTION_LOG_PARAM(IO_SESSION, ioSession);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(this != NULL);
|
||||||
|
ASSERT(ioSession != NULL);
|
||||||
|
|
||||||
|
IoSession *result = NULL;
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Open TLS session
|
||||||
|
SSL *tlsSession = SSL_new(this->context);
|
||||||
|
result = tlsSessionNew(tlsSession, ioSession, this->timeout);
|
||||||
|
|
||||||
|
// Authenticate TLS session
|
||||||
|
tlsServerAuth(this, result, tlsSession);
|
||||||
|
|
||||||
|
// Move session
|
||||||
|
ioSessionMove(result, memContextPrior());
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
statInc(TLS_STAT_SESSION_STR);
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(IO_SESSION, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
static const String *
|
||||||
|
tlsServerName(THIS_VOID) // {vm_covered}
|
||||||
|
{
|
||||||
|
THIS(TlsServer); // {vm_covered}
|
||||||
|
|
||||||
|
FUNCTION_TEST_BEGIN(); // {vm_covered}
|
||||||
|
FUNCTION_TEST_PARAM(TLS_SERVER, this); // {vm_covered}
|
||||||
|
FUNCTION_TEST_END(); // {vm_covered}
|
||||||
|
|
||||||
|
ASSERT(this != NULL); // {vm_covered}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN(this->host); // {vm_covered}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Initialize TLS context with all required security features
|
||||||
|
|
||||||
|
Adapted from PostgreSQL be_tls_init() in src/backend/libpq/be-secure-openssl.c.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static const IoServerInterface tlsServerInterface =
|
||||||
|
{
|
||||||
|
.type = IO_SERVER_TLS_TYPE,
|
||||||
|
.name = tlsServerName,
|
||||||
|
.accept = tlsServerAccept,
|
||||||
|
.toLog = tlsServerToLog,
|
||||||
|
};
|
||||||
|
|
||||||
|
IoServer *
|
||||||
|
tlsServerNew(
|
||||||
|
const String *const host, const String *const caFile, const String *const keyFile, const String *const certFile,
|
||||||
|
const TimeMSec timeout)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, host);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, caFile);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, keyFile);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, certFile);
|
||||||
|
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(host != NULL);
|
||||||
|
ASSERT(keyFile != NULL);
|
||||||
|
ASSERT(certFile != NULL);
|
||||||
|
|
||||||
|
IoServer *this = NULL;
|
||||||
|
|
||||||
|
OBJ_NEW_BEGIN(TlsServer)
|
||||||
|
{
|
||||||
|
TlsServer *const driver = OBJ_NEW_ALLOC();
|
||||||
|
|
||||||
|
*driver = (TlsServer)
|
||||||
|
{
|
||||||
|
.host = strDup(host),
|
||||||
|
.context = tlsContext(),
|
||||||
|
.timeout = timeout,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set callback to free context
|
||||||
|
memContextCallbackSet(objMemContext(driver), tlsServerFreeResource, driver);
|
||||||
|
|
||||||
|
// Set options
|
||||||
|
SSL_CTX_set_options(driver->context,
|
||||||
|
// Disable SSL and TLS v1/v1.1
|
||||||
|
SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
|
||||||
|
// Let server set cipher order
|
||||||
|
SSL_OP_CIPHER_SERVER_PREFERENCE |
|
||||||
|
#ifdef SSL_OP_NO_RENEGOTIATION
|
||||||
|
// Disable renegotiation, available since 1.1.0h. This affects only TLSv1.2 and older protocol versions as TLSv1.3 has
|
||||||
|
// no support for renegotiation.
|
||||||
|
SSL_OP_NO_RENEGOTIATION |
|
||||||
|
#endif
|
||||||
|
// Disable session tickets
|
||||||
|
SSL_OP_NO_TICKET);
|
||||||
|
|
||||||
|
// Disable session caching
|
||||||
|
SSL_CTX_set_session_cache_mode(driver->context, SSL_SESS_CACHE_OFF);
|
||||||
|
|
||||||
|
// Setup ephemeral DH and ECDH keys
|
||||||
|
tlsServerDh(driver->context);
|
||||||
|
tlsServerEcdh(driver->context);
|
||||||
|
|
||||||
|
// Load certificate and key
|
||||||
|
tlsCertKeyLoad(driver->context, certFile, keyFile);
|
||||||
|
|
||||||
|
// If a CA store is specified then client certificates will be verified
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
if (caFile != NULL) // {vm_covered}
|
||||||
|
{
|
||||||
|
// Load CA store
|
||||||
|
cryptoError( // {vm_covered}
|
||||||
|
SSL_CTX_load_verify_locations(driver->context, strZ(caFile), NULL) != 1, // {vm_covered}
|
||||||
|
strZ(strNewFmt("unable to load CA file '%s'", strZ(caFile)))); // {vm_covered}
|
||||||
|
|
||||||
|
// Tell OpenSSL to send the list of root certs we trust to clients in CertificateRequests. This lets a client with a
|
||||||
|
// keystore select the appropriate client certificate to send to us. Also, this ensures that the SSL context will own
|
||||||
|
// the rootCertList and free it when no longer needed.
|
||||||
|
STACK_OF(X509_NAME) *rootCertList = SSL_load_client_CA_file(strZ(caFile)); // {vm_covered}
|
||||||
|
cryptoError( // {vm_covered}
|
||||||
|
rootCertList == NULL, strZ(strNewFmt("unable to generate CA list from '%s'", strZ(caFile)))); // {vm_covered}
|
||||||
|
|
||||||
|
SSL_CTX_set_client_CA_list(driver->context, rootCertList); // {vm_covered}
|
||||||
|
|
||||||
|
// Always ask for SSL client cert, but don't fail when not presented. In this case the server will disconnect after
|
||||||
|
// sending a data end message to the client. The client can use this to verify that the server is running without the
|
||||||
|
// need to authenticate.
|
||||||
|
SSL_CTX_set_verify(driver->context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); // {vm_covered}
|
||||||
|
|
||||||
|
// Set a flag so the client cert will be checked later
|
||||||
|
driver->verifyPeer = true; // {vm_covered}
|
||||||
|
}
|
||||||
|
|
||||||
|
statInc(TLS_STAT_SERVER_STR);
|
||||||
|
|
||||||
|
this = ioServerNew(driver, &tlsServerInterface);
|
||||||
|
}
|
||||||
|
OBJ_NEW_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(IO_SERVER, this);
|
||||||
|
}
|
30
src/common/io/tls/server.h
Normal file
30
src/common/io/tls/server.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
TLS Server
|
||||||
|
|
||||||
|
A simple TLS server intended to expose services by accepting TLS over an IoSession.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef COMMON_IO_TLS_SERVER_H
|
||||||
|
#define COMMON_IO_TLS_SERVER_H
|
||||||
|
|
||||||
|
#include "common/io/server.h"
|
||||||
|
#include "common/io/tls/client.h"
|
||||||
|
#include "common/time.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Io server type
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define IO_SERVER_TLS_TYPE IO_CLIENT_TLS_TYPE
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Statistics constants
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#define TLS_STAT_SERVER "tls.server" // Servers created
|
||||||
|
STRING_DECLARE(TLS_STAT_SERVER_STR);
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Constructors
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
IoServer *tlsServerNew(
|
||||||
|
const String *host, const String *caFile, const String *keyFile, const String *certFile, TimeMSec timeout);
|
||||||
|
|
||||||
|
#endif
|
@ -23,7 +23,7 @@ typedef struct TlsSession
|
|||||||
{
|
{
|
||||||
IoSession *ioSession; // Io session
|
IoSession *ioSession; // Io session
|
||||||
SSL *session; // TLS session on the file descriptor
|
SSL *session; // TLS session on the file descriptor
|
||||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
TimeMSec timeout; // Timeout for any i/o operation (read, write, etc.)
|
||||||
bool shutdownOnClose; // Shutdown the TLS connection when closing the session
|
bool shutdownOnClose; // Shutdown the TLS connection when closing the session
|
||||||
|
|
||||||
IoRead *read; // Read interface
|
IoRead *read; // Read interface
|
||||||
|
@ -22,6 +22,8 @@ Command constants
|
|||||||
#define CFGCMD_REPO_PUT "repo-put"
|
#define CFGCMD_REPO_PUT "repo-put"
|
||||||
#define CFGCMD_REPO_RM "repo-rm"
|
#define CFGCMD_REPO_RM "repo-rm"
|
||||||
#define CFGCMD_RESTORE "restore"
|
#define CFGCMD_RESTORE "restore"
|
||||||
|
#define CFGCMD_SERVER_PING "server-ping"
|
||||||
|
#define CFGCMD_SERVER_START "server-start"
|
||||||
#define CFGCMD_STANZA_CREATE "stanza-create"
|
#define CFGCMD_STANZA_CREATE "stanza-create"
|
||||||
#define CFGCMD_STANZA_DELETE "stanza-delete"
|
#define CFGCMD_STANZA_DELETE "stanza-delete"
|
||||||
#define CFGCMD_STANZA_UPGRADE "stanza-upgrade"
|
#define CFGCMD_STANZA_UPGRADE "stanza-upgrade"
|
||||||
@ -30,7 +32,7 @@ Command constants
|
|||||||
#define CFGCMD_VERIFY "verify"
|
#define CFGCMD_VERIFY "verify"
|
||||||
#define CFGCMD_VERSION "version"
|
#define CFGCMD_VERSION "version"
|
||||||
|
|
||||||
#define CFG_COMMAND_TOTAL 20
|
#define CFG_COMMAND_TOTAL 22
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Option group constants
|
Option group constants
|
||||||
@ -115,9 +117,15 @@ Option constants
|
|||||||
#define CFGOPT_TCP_KEEP_ALIVE_COUNT "tcp-keep-alive-count"
|
#define CFGOPT_TCP_KEEP_ALIVE_COUNT "tcp-keep-alive-count"
|
||||||
#define CFGOPT_TCP_KEEP_ALIVE_IDLE "tcp-keep-alive-idle"
|
#define CFGOPT_TCP_KEEP_ALIVE_IDLE "tcp-keep-alive-idle"
|
||||||
#define CFGOPT_TCP_KEEP_ALIVE_INTERVAL "tcp-keep-alive-interval"
|
#define CFGOPT_TCP_KEEP_ALIVE_INTERVAL "tcp-keep-alive-interval"
|
||||||
|
#define CFGOPT_TLS_SERVER_ADDRESS "tls-server-address"
|
||||||
|
#define CFGOPT_TLS_SERVER_AUTH "tls-server-auth"
|
||||||
|
#define CFGOPT_TLS_SERVER_CA_FILE "tls-server-ca-file"
|
||||||
|
#define CFGOPT_TLS_SERVER_CERT_FILE "tls-server-cert-file"
|
||||||
|
#define CFGOPT_TLS_SERVER_KEY_FILE "tls-server-key-file"
|
||||||
|
#define CFGOPT_TLS_SERVER_PORT "tls-server-port"
|
||||||
#define CFGOPT_TYPE "type"
|
#define CFGOPT_TYPE "type"
|
||||||
|
|
||||||
#define CFG_OPTION_TOTAL 132
|
#define CFG_OPTION_TOTAL 148
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Option value constants
|
Option value constants
|
||||||
@ -188,6 +196,11 @@ Option value constants
|
|||||||
#define CFGOPTVAL_OUTPUT_TEXT STRID5("text", 0xa60b40)
|
#define CFGOPTVAL_OUTPUT_TEXT STRID5("text", 0xa60b40)
|
||||||
#define CFGOPTVAL_OUTPUT_TEXT_Z "text"
|
#define CFGOPTVAL_OUTPUT_TEXT_Z "text"
|
||||||
|
|
||||||
|
#define CFGOPTVAL_PG_HOST_TYPE_SSH STRID5("ssh", 0x22730)
|
||||||
|
#define CFGOPTVAL_PG_HOST_TYPE_SSH_Z "ssh"
|
||||||
|
#define CFGOPTVAL_PG_HOST_TYPE_TLS STRID5("tls", 0x4d940)
|
||||||
|
#define CFGOPTVAL_PG_HOST_TYPE_TLS_Z "tls"
|
||||||
|
|
||||||
#define CFGOPTVAL_REMOTE_TYPE_PG STRID5("pg", 0xf00)
|
#define CFGOPTVAL_REMOTE_TYPE_PG STRID5("pg", 0xf00)
|
||||||
#define CFGOPTVAL_REMOTE_TYPE_PG_Z "pg"
|
#define CFGOPTVAL_REMOTE_TYPE_PG_Z "pg"
|
||||||
#define CFGOPTVAL_REMOTE_TYPE_REPO STRID5("repo", 0x7c0b20)
|
#define CFGOPTVAL_REMOTE_TYPE_REPO STRID5("repo", 0x7c0b20)
|
||||||
@ -215,6 +228,11 @@ Option value constants
|
|||||||
#define CFGOPTVAL_REPO_GCS_KEY_TYPE_TOKEN STRID5("token", 0xe2adf40)
|
#define CFGOPTVAL_REPO_GCS_KEY_TYPE_TOKEN STRID5("token", 0xe2adf40)
|
||||||
#define CFGOPTVAL_REPO_GCS_KEY_TYPE_TOKEN_Z "token"
|
#define CFGOPTVAL_REPO_GCS_KEY_TYPE_TOKEN_Z "token"
|
||||||
|
|
||||||
|
#define CFGOPTVAL_REPO_HOST_TYPE_SSH STRID5("ssh", 0x22730)
|
||||||
|
#define CFGOPTVAL_REPO_HOST_TYPE_SSH_Z "ssh"
|
||||||
|
#define CFGOPTVAL_REPO_HOST_TYPE_TLS STRID5("tls", 0x4d940)
|
||||||
|
#define CFGOPTVAL_REPO_HOST_TYPE_TLS_Z "tls"
|
||||||
|
|
||||||
#define CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_DIFF STRID5("diff", 0x319240)
|
#define CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_DIFF STRID5("diff", 0x319240)
|
||||||
#define CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_DIFF_Z "diff"
|
#define CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_DIFF_Z "diff"
|
||||||
#define CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_FULL STRID5("full", 0x632a60)
|
#define CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_FULL STRID5("full", 0x632a60)
|
||||||
@ -305,6 +323,8 @@ typedef enum
|
|||||||
cfgCmdRepoPut,
|
cfgCmdRepoPut,
|
||||||
cfgCmdRepoRm,
|
cfgCmdRepoRm,
|
||||||
cfgCmdRestore,
|
cfgCmdRestore,
|
||||||
|
cfgCmdServerPing,
|
||||||
|
cfgCmdServerStart,
|
||||||
cfgCmdStanzaCreate,
|
cfgCmdStanzaCreate,
|
||||||
cfgCmdStanzaDelete,
|
cfgCmdStanzaDelete,
|
||||||
cfgCmdStanzaUpgrade,
|
cfgCmdStanzaUpgrade,
|
||||||
@ -380,11 +400,16 @@ typedef enum
|
|||||||
cfgOptPg,
|
cfgOptPg,
|
||||||
cfgOptPgDatabase,
|
cfgOptPgDatabase,
|
||||||
cfgOptPgHost,
|
cfgOptPgHost,
|
||||||
|
cfgOptPgHostCaFile,
|
||||||
|
cfgOptPgHostCaPath,
|
||||||
|
cfgOptPgHostCertFile,
|
||||||
cfgOptPgHostCmd,
|
cfgOptPgHostCmd,
|
||||||
cfgOptPgHostConfig,
|
cfgOptPgHostConfig,
|
||||||
cfgOptPgHostConfigIncludePath,
|
cfgOptPgHostConfigIncludePath,
|
||||||
cfgOptPgHostConfigPath,
|
cfgOptPgHostConfigPath,
|
||||||
|
cfgOptPgHostKeyFile,
|
||||||
cfgOptPgHostPort,
|
cfgOptPgHostPort,
|
||||||
|
cfgOptPgHostType,
|
||||||
cfgOptPgHostUser,
|
cfgOptPgHostUser,
|
||||||
cfgOptPgLocal,
|
cfgOptPgLocal,
|
||||||
cfgOptPgPath,
|
cfgOptPgPath,
|
||||||
@ -413,11 +438,16 @@ typedef enum
|
|||||||
cfgOptRepoGcsKeyType,
|
cfgOptRepoGcsKeyType,
|
||||||
cfgOptRepoHardlink,
|
cfgOptRepoHardlink,
|
||||||
cfgOptRepoHost,
|
cfgOptRepoHost,
|
||||||
|
cfgOptRepoHostCaFile,
|
||||||
|
cfgOptRepoHostCaPath,
|
||||||
|
cfgOptRepoHostCertFile,
|
||||||
cfgOptRepoHostCmd,
|
cfgOptRepoHostCmd,
|
||||||
cfgOptRepoHostConfig,
|
cfgOptRepoHostConfig,
|
||||||
cfgOptRepoHostConfigIncludePath,
|
cfgOptRepoHostConfigIncludePath,
|
||||||
cfgOptRepoHostConfigPath,
|
cfgOptRepoHostConfigPath,
|
||||||
|
cfgOptRepoHostKeyFile,
|
||||||
cfgOptRepoHostPort,
|
cfgOptRepoHostPort,
|
||||||
|
cfgOptRepoHostType,
|
||||||
cfgOptRepoHostUser,
|
cfgOptRepoHostUser,
|
||||||
cfgOptRepoLocal,
|
cfgOptRepoLocal,
|
||||||
cfgOptRepoPath,
|
cfgOptRepoPath,
|
||||||
@ -460,6 +490,12 @@ typedef enum
|
|||||||
cfgOptTcpKeepAliveCount,
|
cfgOptTcpKeepAliveCount,
|
||||||
cfgOptTcpKeepAliveIdle,
|
cfgOptTcpKeepAliveIdle,
|
||||||
cfgOptTcpKeepAliveInterval,
|
cfgOptTcpKeepAliveInterval,
|
||||||
|
cfgOptTlsServerAddress,
|
||||||
|
cfgOptTlsServerAuth,
|
||||||
|
cfgOptTlsServerCaFile,
|
||||||
|
cfgOptTlsServerCertFile,
|
||||||
|
cfgOptTlsServerKeyFile,
|
||||||
|
cfgOptTlsServerPort,
|
||||||
cfgOptType,
|
cfgOptType,
|
||||||
} ConfigOption;
|
} ConfigOption;
|
||||||
|
|
||||||
|
@ -286,6 +286,34 @@ cfgLoadUpdateOption(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set pg-host-port/repo-host-port default when pg-host-type/repo-host-type is tls. ??? This should be handled in the parser but
|
||||||
|
// it requires a default that depends on another option value and that is not currently possible.
|
||||||
|
#define HOST_PORT_TLS 8432
|
||||||
|
|
||||||
|
if (cfgOptionValid(cfgOptRepoHostPort))
|
||||||
|
{
|
||||||
|
for (unsigned int repoIdx = 0; repoIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); repoIdx++)
|
||||||
|
{
|
||||||
|
if (cfgOptionIdxStrId(cfgOptRepoHostType, repoIdx) == CFGOPTVAL_REPO_HOST_TYPE_TLS &&
|
||||||
|
cfgOptionIdxSource(cfgOptRepoHostPort, repoIdx) == cfgSourceDefault)
|
||||||
|
{
|
||||||
|
cfgOptionIdxSet(cfgOptRepoHostPort, repoIdx, cfgSourceDefault, VARINT64(HOST_PORT_TLS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfgOptionValid(cfgOptPgHostPort))
|
||||||
|
{
|
||||||
|
for (unsigned int pgIdx = 0; pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); pgIdx++)
|
||||||
|
{
|
||||||
|
if (cfgOptionIdxStrId(cfgOptPgHostType, pgIdx) == CFGOPTVAL_PG_HOST_TYPE_TLS &&
|
||||||
|
cfgOptionIdxSource(cfgOptPgHostPort, pgIdx) == cfgSourceDefault)
|
||||||
|
{
|
||||||
|
cfgOptionIdxSet(cfgOptPgHostPort, pgIdx, cfgSourceDefault, VARINT64(HOST_PORT_TLS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check/update compress-type if compress is valid. There should be no references to the compress option outside this block.
|
// Check/update compress-type if compress is valid. There should be no references to the compress option outside this block.
|
||||||
if (cfgOptionValid(cfgOptCompress))
|
if (cfgOptionValid(cfgOptCompress))
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
14
src/main.c
14
src/main.c
@ -25,6 +25,8 @@ Main
|
|||||||
#include "command/repo/put.h"
|
#include "command/repo/put.h"
|
||||||
#include "command/repo/rm.h"
|
#include "command/repo/rm.h"
|
||||||
#include "command/restore/restore.h"
|
#include "command/restore/restore.h"
|
||||||
|
#include "command/server/ping.h"
|
||||||
|
#include "command/server/server.h"
|
||||||
#include "command/stanza/create.h"
|
#include "command/stanza/create.h"
|
||||||
#include "command/stanza/delete.h"
|
#include "command/stanza/delete.h"
|
||||||
#include "command/stanza/upgrade.h"
|
#include "command/stanza/upgrade.h"
|
||||||
@ -231,6 +233,18 @@ main(int argListSize, const char *argList[])
|
|||||||
cmdStorageRemove();
|
cmdStorageRemove();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Server start command
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
case cfgCmdServerStart:
|
||||||
|
cmdServer(UINT64_MAX);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Server ping command
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
case cfgCmdServerPing:
|
||||||
|
cmdServerPing();
|
||||||
|
break;
|
||||||
|
|
||||||
// Restore command
|
// Restore command
|
||||||
// -----------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
case cfgCmdRestore:
|
case cfgCmdRestore:
|
||||||
|
@ -42,6 +42,7 @@ Constants
|
|||||||
#define PROTOCOL_GREETING_VERSION "version"
|
#define PROTOCOL_GREETING_VERSION "version"
|
||||||
STRING_DECLARE(PROTOCOL_GREETING_VERSION_STR);
|
STRING_DECLARE(PROTOCOL_GREETING_VERSION_STR);
|
||||||
|
|
||||||
|
#define PROTOCOL_COMMAND_CONFIG STRID5("config", 0xe9339e30)
|
||||||
#define PROTOCOL_COMMAND_EXIT STRID5("exit", 0xa27050)
|
#define PROTOCOL_COMMAND_EXIT STRID5("exit", 0xa27050)
|
||||||
#define PROTOCOL_COMMAND_NOOP STRID5("noop", 0x83dee0)
|
#define PROTOCOL_COMMAND_NOOP STRID5("noop", 0x83dee0)
|
||||||
|
|
||||||
@ -91,6 +92,13 @@ protocolClientMove(ProtocolClient *const this, MemContext *const parentNew)
|
|||||||
return objMove(this, parentNew);
|
return objMove(this, parentNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not send exit command to the server when the client is freed
|
||||||
|
__attribute__((always_inline)) static inline void
|
||||||
|
protocolClientNoExit(ProtocolClient *const this)
|
||||||
|
{
|
||||||
|
memContextCallbackClear(objMemContext(this));
|
||||||
|
}
|
||||||
|
|
||||||
// Send noop to test connection or keep it alive
|
// Send noop to test connection or keep it alive
|
||||||
void protocolClientNoOp(ProtocolClient *this);
|
void protocolClientNoOp(ProtocolClient *this);
|
||||||
|
|
||||||
|
@ -8,9 +8,15 @@ Protocol Helper
|
|||||||
#include "common/crypto/common.h"
|
#include "common/crypto/common.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/exec.h"
|
#include "common/exec.h"
|
||||||
|
#include "common/io/client.h"
|
||||||
|
#include "common/io/socket/client.h"
|
||||||
|
#include "common/io/socket/server.h"
|
||||||
|
#include "common/io/tls/client.h"
|
||||||
|
#include "common/io/tls/server.h"
|
||||||
#include "common/memContext.h"
|
#include "common/memContext.h"
|
||||||
#include "config/config.intern.h"
|
#include "config/config.intern.h"
|
||||||
#include "config/exec.h"
|
#include "config/exec.h"
|
||||||
|
#include "config/load.h"
|
||||||
#include "config/parse.h"
|
#include "config/parse.h"
|
||||||
#include "config/protocol.h"
|
#include "config/protocol.h"
|
||||||
#include "postgres/version.h"
|
#include "postgres/version.h"
|
||||||
@ -29,6 +35,8 @@ Local variables
|
|||||||
typedef struct ProtocolHelperClient
|
typedef struct ProtocolHelperClient
|
||||||
{
|
{
|
||||||
Exec *exec; // Executed client
|
Exec *exec; // Executed client
|
||||||
|
IoClient *ioClient; // Io client, e.g. TlsClient
|
||||||
|
IoSession *ioSession; // Io session, e.g. TlsSession
|
||||||
ProtocolClient *client; // Protocol client
|
ProtocolClient *client; // Protocol client
|
||||||
} ProtocolHelperClient;
|
} ProtocolHelperClient;
|
||||||
|
|
||||||
@ -282,6 +290,12 @@ protocolHelperClientFree(ProtocolHelperClient *protocolHelperClient)
|
|||||||
}
|
}
|
||||||
TRY_END();
|
TRY_END();
|
||||||
|
|
||||||
|
// Free the io client/session (there should be no errors)
|
||||||
|
ioSessionFree(protocolHelperClient->ioSession);
|
||||||
|
ioClientFree(protocolHelperClient->ioClient);
|
||||||
|
|
||||||
|
protocolHelperClient->ioSession = NULL;
|
||||||
|
protocolHelperClient->ioClient = NULL;
|
||||||
protocolHelperClient->client = NULL;
|
protocolHelperClient->client = NULL;
|
||||||
protocolHelperClient->exec = NULL;
|
protocolHelperClient->exec = NULL;
|
||||||
}
|
}
|
||||||
@ -306,6 +320,117 @@ protocolLocalFree(unsigned int processId)
|
|||||||
FUNCTION_LOG_RETURN_VOID();
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
// Helper to check if client is authorized for a stanza
|
||||||
|
static bool
|
||||||
|
protocolServerAuthorize(const String *authListStr, const String *const stanza)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM(STRING, authListStr);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, stanza);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
ASSERT(authListStr != NULL);
|
||||||
|
|
||||||
|
// Empty list is not valid. ??? It would be better if this were done during config parsing.
|
||||||
|
authListStr = strTrim(strDup(authListStr));
|
||||||
|
|
||||||
|
if (strEmpty(authListStr))
|
||||||
|
THROW(OptionInvalidValueError, "'" CFGOPT_TLS_SERVER_AUTH "' option must have a value");
|
||||||
|
|
||||||
|
// If * then all stanzas are authorized
|
||||||
|
if (strEqZ(authListStr, "*"))
|
||||||
|
FUNCTION_TEST_RETURN(true);
|
||||||
|
|
||||||
|
// Check the list of stanzas for a match with the specified stanza. Each entry will need to be trimmed before comparing.
|
||||||
|
if (stanza != NULL)
|
||||||
|
{
|
||||||
|
StringList *authList = strLstNewSplitZ(authListStr, COMMA_Z);
|
||||||
|
|
||||||
|
for (unsigned int authListIdx = 0; authListIdx < strLstSize(authList); authListIdx++)
|
||||||
|
{
|
||||||
|
if (strEq(strTrim(strLstGet(authList, authListIdx)), stanza))
|
||||||
|
FUNCTION_TEST_RETURN(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolServer *
|
||||||
|
protocolServer(IoServer *const tlsServer, IoSession *const socketSession)
|
||||||
|
{
|
||||||
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
|
FUNCTION_LOG_PARAM(IO_SERVER, tlsServer);
|
||||||
|
FUNCTION_LOG_PARAM(IO_SESSION, socketSession);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ProtocolServer *result = NULL;
|
||||||
|
|
||||||
|
MEM_CONTEXT_TEMP_BEGIN()
|
||||||
|
{
|
||||||
|
// Start TLS
|
||||||
|
IoSession *const tlsSession = ioServerAccept(tlsServer, socketSession);
|
||||||
|
|
||||||
|
result = protocolServerNew(
|
||||||
|
PROTOCOL_SERVICE_REMOTE_STR, PROTOCOL_SERVICE_REMOTE_STR, ioSessionIoRead(tlsSession),
|
||||||
|
ioSessionIoWrite(tlsSession));
|
||||||
|
|
||||||
|
// If session is authenticated
|
||||||
|
if (ioSessionAuthenticated(tlsSession))
|
||||||
|
{
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
// Get list of authorized stanzas for this client
|
||||||
|
CHECK(cfgOptionTest(cfgOptTlsServerAuth));
|
||||||
|
const String *const clientAuthList = strDup(
|
||||||
|
varStr(kvGet(cfgOptionKv(cfgOptTlsServerAuth), VARSTR(ioSessionPeerName(tlsSession)))));
|
||||||
|
|
||||||
|
// Error if the client is not authorized for anything
|
||||||
|
if (clientAuthList == NULL)
|
||||||
|
THROW(AccessError, "access denied");
|
||||||
|
|
||||||
|
// Get parameter list from the client and load it
|
||||||
|
const ProtocolServerCommandGetResult command = protocolServerCommandGet(result);
|
||||||
|
CHECK(command.id == PROTOCOL_COMMAND_CONFIG);
|
||||||
|
|
||||||
|
StringList *const paramList = pckReadStrLstP(pckReadNew(command.param));
|
||||||
|
strLstInsert(paramList, 0, cfgExe());
|
||||||
|
cfgLoad(strLstSize(paramList), strLstPtr(paramList));
|
||||||
|
|
||||||
|
// Error if the client is authorized for the requested stanza
|
||||||
|
if (!protocolServerAuthorize(clientAuthList, cfgOptionStrNull(cfgOptStanza)))
|
||||||
|
THROW(AccessError, "access denied");
|
||||||
|
}
|
||||||
|
CATCH_ANY()
|
||||||
|
{
|
||||||
|
protocolServerError(result, errorCode(), STR(errorMessage()), STR(errorStackTrace()));
|
||||||
|
RETHROW();
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
|
// Ack the config command
|
||||||
|
protocolServerDataEndPut(result);
|
||||||
|
|
||||||
|
ioSessionMove(tlsSession, memContextPrior());
|
||||||
|
protocolServerMove(result, memContextPrior());
|
||||||
|
}
|
||||||
|
// Else the client can only detect that the server is alive
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send a data end message and return a NULL server. Do not waste time looking at what the client wrote.
|
||||||
|
protocolServerDataEndPut(result);
|
||||||
|
|
||||||
|
// Set result to NULL so there is no server for the caller to use. The TLS session will be freed when the temp mem
|
||||||
|
// context ends.
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_TEMP_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN(PROTOCOL_SERVER, result);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Get the command line required for remote protocol execution
|
Get the command line required for remote protocol execution
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -511,22 +636,84 @@ protocolRemoteExec(
|
|||||||
|
|
||||||
ASSERT(helper != NULL);
|
ASSERT(helper != NULL);
|
||||||
|
|
||||||
// Execute the protocol command
|
// Get remote info
|
||||||
const char *const host =
|
const bool isRepo = protocolStorageType == protocolStorageTypeRepo;
|
||||||
strZ(cfgOptionIdxStr(protocolStorageType == protocolStorageTypeRepo ? cfgOptRepoHost : cfgOptPgHost, hostIdx));
|
const StringId remoteType = cfgOptionIdxStrId(isRepo ? cfgOptRepoHostType : cfgOptPgHostType, hostIdx);
|
||||||
|
const String *const host = cfgOptionIdxStr(isRepo ? cfgOptRepoHost : cfgOptPgHost, hostIdx);
|
||||||
|
|
||||||
helper->exec = execNew(
|
// Handle remote types
|
||||||
cfgOptionStr(cfgOptCmdSsh), protocolRemoteParamSsh(protocolStorageType, hostIdx),
|
IoRead *read;
|
||||||
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u process on '%s'", processId, host), cfgOptionUInt64(cfgOptProtocolTimeout));
|
IoWrite *write;
|
||||||
execOpen(helper->exec);
|
|
||||||
|
switch (remoteType)
|
||||||
|
{
|
||||||
|
// SSH remote
|
||||||
|
case CFGOPTVAL_REPO_HOST_TYPE_SSH:
|
||||||
|
{
|
||||||
|
// Exec SSH
|
||||||
|
helper->exec = execNew(
|
||||||
|
cfgOptionStr(cfgOptCmdSsh), protocolRemoteParamSsh(protocolStorageType, hostIdx),
|
||||||
|
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u process on '%s'", processId, strZ(host)),
|
||||||
|
cfgOptionUInt64(cfgOptProtocolTimeout));
|
||||||
|
execOpen(helper->exec);
|
||||||
|
|
||||||
|
read = execIoRead(helper->exec);
|
||||||
|
write = execIoWrite(helper->exec);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS remote
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
ASSERT(remoteType == CFGOPTVAL_REPO_HOST_TYPE_TLS);
|
||||||
|
|
||||||
|
// Negotiate TLS
|
||||||
|
helper->ioClient = tlsClientNew(
|
||||||
|
sckClientNew(
|
||||||
|
host, cfgOptionIdxUInt(isRepo ? cfgOptRepoHostPort : cfgOptPgHostPort, hostIdx),
|
||||||
|
cfgOptionUInt64(cfgOptIoTimeout), cfgOptionUInt64(cfgOptProtocolTimeout)),
|
||||||
|
host, cfgOptionUInt64(cfgOptIoTimeout), cfgOptionUInt64(cfgOptProtocolTimeout), true,
|
||||||
|
cfgOptionIdxStrNull(isRepo ? cfgOptRepoHostCaFile : cfgOptPgHostCaFile, hostIdx),
|
||||||
|
cfgOptionIdxStrNull(isRepo ? cfgOptRepoHostCaPath : cfgOptPgHostCaPath, hostIdx),
|
||||||
|
cfgOptionIdxStr(isRepo ? cfgOptRepoHostCertFile : cfgOptPgHostCertFile, hostIdx),
|
||||||
|
cfgOptionIdxStr(isRepo ? cfgOptRepoHostKeyFile : cfgOptPgHostKeyFile, hostIdx));
|
||||||
|
helper->ioSession = ioClientOpen(helper->ioClient);
|
||||||
|
|
||||||
|
read = ioSessionIoRead(helper->ioSession);
|
||||||
|
write = ioSessionIoWrite(helper->ioSession);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create protocol object
|
// Create protocol object
|
||||||
helper->client = protocolClientNew(
|
helper->client = protocolClientNew(
|
||||||
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u protocol on '%s'", processId, host), PROTOCOL_SERVICE_REMOTE_STR,
|
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u %s protocol on '%s'", processId, strZ(strIdToStr(remoteType)), strZ(host)),
|
||||||
execIoRead(helper->exec), execIoWrite(helper->exec));
|
PROTOCOL_SERVICE_REMOTE_STR, read, write);
|
||||||
|
|
||||||
// Move client to exec context so they are freed together
|
// Remote initialization
|
||||||
protocolClientMove(helper->client, execMemContext(helper->exec));
|
switch (remoteType)
|
||||||
|
{
|
||||||
|
// SSH remote
|
||||||
|
case CFGOPTVAL_REPO_HOST_TYPE_SSH:
|
||||||
|
// Move client to exec context so they are freed together
|
||||||
|
protocolClientMove(helper->client, execMemContext(helper->exec));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TLS remote
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
ASSERT(remoteType == CFGOPTVAL_REPO_HOST_TYPE_TLS);
|
||||||
|
|
||||||
|
// Pass parameters to server
|
||||||
|
ProtocolCommand *command = protocolCommandNew(PROTOCOL_COMMAND_CONFIG);
|
||||||
|
pckWriteStrLstP(protocolCommandParam(command), protocolRemoteParam(protocolStorageType, hostIdx));
|
||||||
|
protocolClientExecute(helper->client, command, false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ typedef enum
|
|||||||
protocolStorageTypeRepo = STRID5("repo", 0x7c0b20),
|
protocolStorageTypeRepo = STRID5("repo", 0x7c0b20),
|
||||||
} ProtocolStorageType;
|
} ProtocolStorageType;
|
||||||
|
|
||||||
#include "protocol/client.h"
|
#include "common/io/server.h"
|
||||||
|
#include "protocol/server.h"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Constants
|
Constants
|
||||||
@ -59,6 +60,9 @@ ProtocolClient *protocolRemoteGet(ProtocolStorageType protocolStorageType, unsig
|
|||||||
// Free (shutdown) a remote
|
// Free (shutdown) a remote
|
||||||
void protocolRemoteFree(unsigned int hostId);
|
void protocolRemoteFree(unsigned int hostId);
|
||||||
|
|
||||||
|
// Initialize a server
|
||||||
|
ProtocolServer *protocolServer(IoServer *const tlsServer, IoSession *const socketSession);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Destructor
|
Destructor
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
@ -737,7 +737,10 @@ storageAzureNew(
|
|||||||
|
|
||||||
// Create the http client used to service requests
|
// Create the http client used to service requests
|
||||||
driver->httpClient = httpClientNew(
|
driver->httpClient = httpClientNew(
|
||||||
tlsClientNew(sckClientNew(driver->host, port, timeout), driver->host, timeout, verifyPeer, caFile, caPath), timeout);
|
tlsClientNew(
|
||||||
|
sckClientNew(driver->host, port, timeout, timeout), driver->host, timeout, timeout, verifyPeer, caFile, caPath,
|
||||||
|
NULL, NULL),
|
||||||
|
timeout);
|
||||||
|
|
||||||
// Create list of redacted headers
|
// Create list of redacted headers
|
||||||
driver->headerRedactList = strLstNew();
|
driver->headerRedactList = strLstNew();
|
||||||
|
@ -955,7 +955,7 @@ storageGcsNew(
|
|||||||
STRDEF("metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"),
|
STRDEF("metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"),
|
||||||
.type = httpProtocolTypeHttp);
|
.type = httpProtocolTypeHttp);
|
||||||
driver->authClient = httpClientNew(
|
driver->authClient = httpClientNew(
|
||||||
sckClientNew(httpUrlHost(driver->authUrl), httpUrlPort(driver->authUrl), timeout), timeout);
|
sckClientNew(httpUrlHost(driver->authUrl), httpUrlPort(driver->authUrl), timeout, timeout), timeout);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -970,8 +970,8 @@ storageGcsNew(
|
|||||||
|
|
||||||
driver->authClient = httpClientNew(
|
driver->authClient = httpClientNew(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(httpUrlHost(driver->authUrl), httpUrlPort(driver->authUrl), timeout),
|
sckClientNew(httpUrlHost(driver->authUrl), httpUrlPort(driver->authUrl), timeout, timeout),
|
||||||
httpUrlHost(driver->authUrl), timeout, verifyPeer, caFile, caPath),
|
httpUrlHost(driver->authUrl), timeout, timeout, verifyPeer, caFile, caPath, NULL, NULL),
|
||||||
timeout);
|
timeout);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -990,7 +990,8 @@ storageGcsNew(
|
|||||||
// Create the http client used to service requests
|
// Create the http client used to service requests
|
||||||
driver->httpClient = httpClientNew(
|
driver->httpClient = httpClientNew(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(driver->endpoint, httpUrlPort(url), timeout), driver->endpoint, timeout, verifyPeer, caFile, caPath),
|
sckClientNew(driver->endpoint, httpUrlPort(url), timeout, timeout), driver->endpoint, timeout, timeout, verifyPeer,
|
||||||
|
caFile, caPath, NULL, NULL),
|
||||||
timeout);
|
timeout);
|
||||||
|
|
||||||
// Create list of redacted headers
|
// Create list of redacted headers
|
||||||
|
@ -1004,7 +1004,9 @@ storageS3New(
|
|||||||
host = driver->bucketEndpoint;
|
host = driver->bucketEndpoint;
|
||||||
|
|
||||||
driver->httpClient = httpClientNew(
|
driver->httpClient = httpClientNew(
|
||||||
tlsClientNew(sckClientNew(host, port, timeout), host, timeout, verifyPeer, caFile, caPath), timeout);
|
tlsClientNew(
|
||||||
|
sckClientNew(host, port, timeout, timeout), host, timeout, timeout, verifyPeer, caFile, caPath, NULL, NULL),
|
||||||
|
timeout);
|
||||||
|
|
||||||
// Initialize authentication
|
// Initialize authentication
|
||||||
switch (driver->keyType)
|
switch (driver->keyType)
|
||||||
@ -1017,7 +1019,8 @@ storageS3New(
|
|||||||
driver->credRole = strDup(credRole);
|
driver->credRole = strDup(credRole);
|
||||||
driver->credHost = S3_CREDENTIAL_HOST_STR;
|
driver->credHost = S3_CREDENTIAL_HOST_STR;
|
||||||
driver->credExpirationTime = time(NULL);
|
driver->credExpirationTime = time(NULL);
|
||||||
driver->credHttpClient = httpClientNew(sckClientNew(driver->credHost, S3_CREDENTIAL_PORT, timeout), timeout);
|
driver->credHttpClient = httpClientNew(
|
||||||
|
sckClientNew(driver->credHost, S3_CREDENTIAL_PORT, timeout, timeout), timeout);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
1
test/certificate/.gitignore
vendored
1
test/certificate/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.csr
|
*.csr
|
||||||
*.srl
|
*.srl
|
||||||
|
index.*
|
||||||
|
@ -14,35 +14,44 @@ openssl req -new -x509 -extensions v3_ca -key pgbackrest-test-ca.key -out pgback
|
|||||||
openssl x509 -in pgbackrest-test-ca.crt -text -noout
|
openssl x509 -in pgbackrest-test-ca.crt -text -noout
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating the Test Key (pgbackrest-test.key)
|
## Generating the Server Test Key (pgbackrest-test-server.key)
|
||||||
|
|
||||||
This key will be used for all server certificates to keep things simple.
|
This key will be used for all server certificates to keep things simple.
|
||||||
|
|
||||||
```
|
```
|
||||||
cd [pgbackrest-root]/test/certificate
|
cd [pgbackrest-root]/test/certificate
|
||||||
openssl genrsa -out pgbackrest-test.key 4096
|
openssl genrsa -out pgbackrest-test-server.key 4096
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating the Alt Name Test Certificate (pgbackrest-test-alt-name.crt)
|
## Generating the Server Test Certificate (pgbackrest-test-server.crt/key)
|
||||||
|
|
||||||
This certificate will include alternate names and will only be used in unit tests to check alternate name verification functionality.
|
|
||||||
|
|
||||||
```
|
|
||||||
cd [pgbackrest-root]/test/certificate
|
|
||||||
openssl req -new -sha256 -nodes -out pgbackrest-test-alt-name.csr -key pgbackrest-test.key -config pgbackrest-test-alt-name.cnf
|
|
||||||
openssl x509 -req -in pgbackrest-test-alt-name.csr -CA pgbackrest-test-ca.crt -CAkey pgbackrest-test-ca.key -CAcreateserial \
|
|
||||||
-out pgbackrest-test-alt-name.crt -days 99999 -extensions v3_req -extfile pgbackrest-test-alt-name.cnf
|
|
||||||
openssl x509 -in pgbackrest-test-alt-name.crt -text -noout
|
|
||||||
```
|
|
||||||
|
|
||||||
## Generating the Test Certificate (pgbackrest-test.crt)
|
|
||||||
|
|
||||||
This certificate will be used in unit and integration tests. It is expected to pass verification but won't be subjected to extensive testing.
|
This certificate will be used in unit and integration tests. It is expected to pass verification but won't be subjected to extensive testing.
|
||||||
|
|
||||||
```
|
```
|
||||||
cd [pgbackrest-root]/test/certificate
|
cd [pgbackrest-root]/test/certificate
|
||||||
openssl req -new -sha256 -nodes -out pgbackrest-test.csr -key pgbackrest-test.key -config pgbackrest-test.cnf
|
openssl req -new -sha256 -nodes -out pgbackrest-test-server.csr -key pgbackrest-test-server.key -config pgbackrest-test-server.cnf
|
||||||
openssl x509 -req -in pgbackrest-test.csr -CA pgbackrest-test-ca.crt -CAkey pgbackrest-test-ca.key -CAcreateserial \
|
openssl x509 -req -in pgbackrest-test-server.csr -CA pgbackrest-test-ca.crt -CAkey pgbackrest-test-ca.key -CAcreateserial \
|
||||||
-out pgbackrest-test.crt -days 99999 -extensions v3_req -extfile pgbackrest-test.cnf
|
-out pgbackrest-test-server.crt -days 99999 -extensions v3_req -extfile pgbackrest-test-server.cnf
|
||||||
openssl x509 -in pgbackrest-test.crt -text -noout
|
openssl x509 -in pgbackrest-test-server.crt -text -noout
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generating the Client Test Key (pgbackrest-test-client.key)
|
||||||
|
|
||||||
|
This key will be used for all client certificates to keep things simple.
|
||||||
|
|
||||||
|
```
|
||||||
|
cd [pgbackrest-root]/test/certificate
|
||||||
|
openssl genrsa -out pgbackrest-test-client.key 4096
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generating the Client Test Certificate (pgbackrest-test-client.crt/key)
|
||||||
|
|
||||||
|
This certificate will be used in unit and integration tests. It is expected to pass verification but won't be subjected to extensive testing.
|
||||||
|
|
||||||
|
```
|
||||||
|
cd [pgbackrest-root]/test/certificate
|
||||||
|
openssl req -new -sha256 -nodes -out pgbackrest-test-client.csr -key pgbackrest-test-client.key -config pgbackrest-test-client.cnf
|
||||||
|
openssl x509 -req -in pgbackrest-test-client.csr -CA pgbackrest-test-ca.crt -CAkey pgbackrest-test-ca.key -CAcreateserial \
|
||||||
|
-out pgbackrest-test-client.crt -days 99999 -extensions v3_req -extfile pgbackrest-test-client.cnf
|
||||||
|
openssl x509 -in pgbackrest-test-client.crt -text -noout
|
||||||
```
|
```
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIF4jCCA8qgAwIBAgIJAN+gSjwW7yR+MA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
|
|
||||||
BAYTAlVTMQwwCgYDVQQIDANBbGwxDDAKBgNVBAcMA0FsbDETMBEGA1UECgwKcGdC
|
|
||||||
YWNrUmVzdDEcMBoGA1UEAwwTdGVzdC5wZ2JhY2tyZXN0Lm9yZzAgFw0xODExMjAx
|
|
||||||
MzU2MjlaGA8yMjkyMDkwMzEzNTYyOVowejELMAkGA1UEBhMCVVMxDDAKBgNVBAgM
|
|
||||||
A0FsbDEMMAoGA1UEBwwDQWxsMRMwEQYDVQQKDApwZ0JhY2tSZXN0MRwwGgYDVQQL
|
|
||||||
DBNVbml0IFRlc3RpbmcgRG9tYWluMRwwGgYDVQQDDBN0ZXN0LnBnYmFja3Jlc3Qu
|
|
||||||
b3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwzNZDX/VhTA6lALX
|
|
||||||
DZ4AOHv4OQH5wTZipa97XdTrI2TIfMGEffLmv5wzN85pku5HXBuHGJUaUENXt1Ss
|
|
||||||
GwdfBx/gZZEA8oONqkrxOoJTrABWIAs5k6TTUd+f3Y39rlsyQj076f1sw6Mw9qoC
|
|
||||||
h+JKXDDqw8kGwQHifXdtCrxL9OfV4eq+gYKrqdlyFM08WfKxe0Js8bB5cZ4Bt/GC
|
|
||||||
2JhQzQ9bMjYJlxSXIXivP/FFunVT5hZ8gsUVAH+/sm8xlQ4sedW7mIBKkjT3tgL0
|
|
||||||
FvchB3XyoZ6Sr0JKVaMOcQjIsTzOqdgawgArO541ZwUWHdJH+DODr/gBWXSnnzhH
|
|
||||||
ED5DAvRMPdO/t353qS/ihpacTqQ91B4UKxK1pVNC84ch3spCLnQncl7kn7RhcdCc
|
|
||||||
b5g4ZfahRmq79QSoMDvN4+7MtyERLXtSttSWiBzQVVj/jcFNDeGeDjKp6Z55xoso
|
|
||||||
tMZ3yVajl4IbuQS1pfTLjp7WdJ58y5hQ+8O/ebjUYIxOo5kZhRZV/jxqoR7Ga9MG
|
|
||||||
bAQ7BPcTuItpfGqiWcdYU+ZdyyFwvpXov6qNoCYt58nj7s+FAbed7EzRHa2Z3RVG
|
|
||||||
kcqv2iX5EddydHmqKip+QUUR4cPLUXn+kvOHtJEOgAWDURh0DVfhrMD5dX1d+9de
|
|
||||||
BUwZ89gYvxkkErPL1o8OPRxyiucCAwEAAaOBhjCBgzAJBgNVHRMEAjAAMAsGA1Ud
|
|
||||||
DwQEAwIF4DBpBgNVHREEYjBgghN0ZXN0LnBnYmFja3Jlc3Qub3JnghUqLnRlc3Qu
|
|
||||||
cGdiYWNrcmVzdC5vcmeHBH8AAAGCFHRlc3QyLnBnYmFja3Jlc3Qub3JnghYqLnRl
|
|
||||||
c3QyLnBnYmFja3Jlc3Qub3JnMA0GCSqGSIb3DQEBCwUAA4ICAQABqorGy+U2CBBl
|
|
||||||
ei2Q0zTccJVPqz3xL6UpZVh0X/SoZFisZNyLPskxAh070q8C11g4uqyPoXPp2eJt
|
|
||||||
smwop2pY6glzO+7b9kEUo2527s8BJejlIzAe9bQ8eZ1Hbqlh52B+wzEE7Ci22KDC
|
|
||||||
O3RZCya6WiMHXxFCjPR7m4qaoodU4XtRefepg/bs0qUq5rrsHDRfvaitISUOeXnj
|
|
||||||
NSsLyiVLbwkCW3mL7bEFAG1Th8GWa809zpw8fJiUkhavtDe35UesHM5fOZ8oqY28
|
|
||||||
BIcSc5yVgOxDAHDQI9lf9umAN5ZakT9lo5WdndG9eUZGOK72s8Vy1ReiKH+vX2qw
|
|
||||||
3cI69akD+UBLqvO9NFMJPurDLdM82B453EaBqDhm1oPPwHsXc8wiNG6jYmIAHlvN
|
|
||||||
qX1qXcdJjp54PSv6RFm/ZxcS6CCRRzPv46Zi86cynY32qmEYU5Et3tGVwx6KywRx
|
|
||||||
HKF206NUzyHYW8cuDywTpQZSYuAHrjcWGzS/Fg1aTIGULRffFLTvmt6URHjpfFwJ
|
|
||||||
bRkMcw+k1xdV01rTA2jnDbFAC5f6V7QOGwcqSzc25cz1PDHWweCw4oDwpAxRFx14
|
|
||||||
X98jbWjo6YYsc9wWpcQt5NICO5wHoaJfhawf7suJmuluQTzOsH2ZS6O0zVJmbsVs
|
|
||||||
KveXMVBWdJoaJjUqEBy6tJHB5uRxJg==
|
|
||||||
-----END CERTIFICATE-----
|
|
26
test/certificate/pgbackrest-test-client.cnf
Normal file
26
test/certificate/pgbackrest-test-client.cnf
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[req]
|
||||||
|
default_bits=4096
|
||||||
|
prompt=no
|
||||||
|
default_md=sha256
|
||||||
|
req_extensions=v3_req
|
||||||
|
distinguished_name=dn
|
||||||
|
|
||||||
|
[ca]
|
||||||
|
default_ca=ca_pgbackrest
|
||||||
|
|
||||||
|
[ca_pgbackrest]
|
||||||
|
database = index.txt
|
||||||
|
unique_subject = no
|
||||||
|
default_md = sha256
|
||||||
|
|
||||||
|
[dn]
|
||||||
|
C=US
|
||||||
|
ST=All
|
||||||
|
L=All
|
||||||
|
O=pgBackRest
|
||||||
|
OU=Unit Testing Domain
|
||||||
|
CN=pgbackrest-client
|
||||||
|
|
||||||
|
[v3_req]
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
keyUsage=nonRepudiation,digitalSignature,keyEncipherment
|
32
test/certificate/pgbackrest-test-client.crt
Normal file
32
test/certificate/pgbackrest-test-client.crt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFfjCCA2agAwIBAgIUJCya0E5vFzyH2AgiM3HSAHmpZ1IwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwXDELMAkGA1UEBhMCVVMxDDAKBgNVBAgMA0FsbDEMMAoGA1UEBwwDQWxsMRMw
|
||||||
|
EQYDVQQKDApwZ0JhY2tSZXN0MRwwGgYDVQQDDBN0ZXN0LnBnYmFja3Jlc3Qub3Jn
|
||||||
|
MCAXDTIxMDgyNDIxMDA1M1oYDzIyOTUwNjA4MjEwMDUzWjB4MQswCQYDVQQGEwJV
|
||||||
|
UzEMMAoGA1UECAwDQWxsMQwwCgYDVQQHDANBbGwxEzARBgNVBAoMCnBnQmFja1Jl
|
||||||
|
c3QxHDAaBgNVBAsME1VuaXQgVGVzdGluZyBEb21haW4xGjAYBgNVBAMMEXBnYmFj
|
||||||
|
a3Jlc3QtY2xpZW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsrlq
|
||||||
|
GJfMWq+FrbzKp7dIZ17OzghEQdQOBufpN6b2TUZrMT8ix0hD3CP0od2VfBv/Z+x1
|
||||||
|
CTWGQ9dripEFH8DJ4E9Evd3RpnNT6lONXqf10n4ohqK+4DGjLJjn1czfoKpNnF7d
|
||||||
|
WpfB5FY+fjS3MNxTFJUh+KkmkW4ra/GnAQd2X9wVDfz+xGgdOPHrWfGhu3hEWIQw
|
||||||
|
AULHEKT+oPJghIcmYfrt0hQTDu6MHi+f+CmTl/VYFjmaxkyBPeklsW/EPx1GBS8y
|
||||||
|
kgzmmhUV+EeBGr4vZ3FDaMcPkCeWljqfxetbLhBBrcAWxaCcPTDRafpzJTSDkCQi
|
||||||
|
U/7SYw0L0sg9Vz0sYpROupyIGDHxHKzLeaySDykSUR7Wi5A6L9nHxQAbdFeq+PFc
|
||||||
|
uQyndLs8qCuvjy5kcCyjn36TfcSQX9x4uyvevdVjVZayKzMN8r69uPoFvG+2/9LZ
|
||||||
|
lhcwDuczZiy7bQGkeb0sujjLweoN6LGrDl6c7C4MpJ4oPWkmAnkJRipFsD9xRjEc
|
||||||
|
nfo248PF5z5uGqImrxExHikYZwnsG+KsnFg8lfQuoh9McvW3Z1Wb/8CZ4wM2Izaq
|
||||||
|
4DOkGiyO9pZpFRxqeRgTV0vn15W6CgMoI0I+DvYuNcEHts9ZlPZeGRxyjR62u4hh
|
||||||
|
gmZDcs7S8Z72k5gG7YUfHkVjvZvyCmyGb66Z0vkCAwEAAaMaMBgwCQYDVR0TBAIw
|
||||||
|
ADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQELBQADggIBAJH9UKmWwm662dwBLBF0
|
||||||
|
hsZ2gsQckKTu2nySazQ6JXiJFobStoRjixIjM6hmTbxNtndQqqDbymMhl8L++Gvo
|
||||||
|
LOocWXZWgWskly/vAjEZCRxq0ZmQcgZcyKz1Xms9WzCkdSCaZGpAXPma6PnHk/xS
|
||||||
|
cqBIXo0h0zMHfIon9n+kNGJqZ82V2KFZjPrbi0DDISheVGVvmC3cUm8eOh0jjHXS
|
||||||
|
1d28VXqXsQncegmjeHiehw88XrkbI9Vf8lveTMLN0p7fYmkaMWNRP0BCCw49+Xzy
|
||||||
|
rlHHD+2bXn0Uq9bMefkiR0ZAZFgzsP4GUUFx3IPSO8iOxfzBlg8qidXqgtKV1Y98
|
||||||
|
FUI5JQ49HSQ6CK5wBkUUA8oivsy7c7JVfb+8E48CgAzHpHH8PxkIFCpAD2jwGmsq
|
||||||
|
gMfMkUkS5cvC8M6RUvfmBwLPI/ZbqMtJuO50f/rC9eO5cYBT0S+MTfEwrQ/FpeRZ
|
||||||
|
w5v2Bpi1qPYHCjNXlzniIRfvMuYwia8p3S0ZB1UIcWTSTAxjy6j+sOVBxPAyKj6t
|
||||||
|
V0LgWtOgDwDqf9Xv3XiSIDqZU4t5suiEnIWbDXnZCrwBtQI3W8H1uCqtaWG7zERr
|
||||||
|
+MDNlqFC8Q+gjzGo6mZmzGxejEBYS5mNT/j37bqxGGB2TaWZVc9oPq0nAF7vBZl5
|
||||||
|
g8C/t+7nWYzBTv0EPl3jMDF4
|
||||||
|
-----END CERTIFICATE-----
|
51
test/certificate/pgbackrest-test-client.key
Normal file
51
test/certificate/pgbackrest-test-client.key
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIJKgIBAAKCAgEAsrlqGJfMWq+FrbzKp7dIZ17OzghEQdQOBufpN6b2TUZrMT8i
|
||||||
|
x0hD3CP0od2VfBv/Z+x1CTWGQ9dripEFH8DJ4E9Evd3RpnNT6lONXqf10n4ohqK+
|
||||||
|
4DGjLJjn1czfoKpNnF7dWpfB5FY+fjS3MNxTFJUh+KkmkW4ra/GnAQd2X9wVDfz+
|
||||||
|
xGgdOPHrWfGhu3hEWIQwAULHEKT+oPJghIcmYfrt0hQTDu6MHi+f+CmTl/VYFjma
|
||||||
|
xkyBPeklsW/EPx1GBS8ykgzmmhUV+EeBGr4vZ3FDaMcPkCeWljqfxetbLhBBrcAW
|
||||||
|
xaCcPTDRafpzJTSDkCQiU/7SYw0L0sg9Vz0sYpROupyIGDHxHKzLeaySDykSUR7W
|
||||||
|
i5A6L9nHxQAbdFeq+PFcuQyndLs8qCuvjy5kcCyjn36TfcSQX9x4uyvevdVjVZay
|
||||||
|
KzMN8r69uPoFvG+2/9LZlhcwDuczZiy7bQGkeb0sujjLweoN6LGrDl6c7C4MpJ4o
|
||||||
|
PWkmAnkJRipFsD9xRjEcnfo248PF5z5uGqImrxExHikYZwnsG+KsnFg8lfQuoh9M
|
||||||
|
cvW3Z1Wb/8CZ4wM2Izaq4DOkGiyO9pZpFRxqeRgTV0vn15W6CgMoI0I+DvYuNcEH
|
||||||
|
ts9ZlPZeGRxyjR62u4hhgmZDcs7S8Z72k5gG7YUfHkVjvZvyCmyGb66Z0vkCAwEA
|
||||||
|
AQKCAgBB0LHXWJ8yjgyGTE28sWwCVRGHIdgw/awksuZZTizJjDMRMZTXGi+TM9J0
|
||||||
|
gSr5Rz4owRTgTUuiVAQQRRND/DTbW5WO7c60oye11QrsXqHR4A+AdRIhcWYLmEtX
|
||||||
|
mliHy+9EtFKDd/s44OGmjDch0SDvJXQbI/9F8vIekCDV6i+XYW6HdjFDlqucOspW
|
||||||
|
lvreFI3motciv7qa0IfMMTWF2Fc0IbnOcQILr6D9xL/+HSFzBjBoDtKGT8oQSHlO
|
||||||
|
/D+ill8grZ7L1eBdwYITqhFLDdpbF4ShYxzCEzILJI+NzPwI3IezOleoc1rV1dJo
|
||||||
|
WohonQwN2qChmedT/ovqFT8xjx92mCx2m5/cwD4VtlER7KNVPphGnrGx7i4L9QlM
|
||||||
|
x8YnG2Bv4534I7G4+tZIBoyZpMsCXU6qvp0BRNi1/g7KfsBCAFokt1SJs3913I1W
|
||||||
|
RkJ3j774AThCATmttGg3BKZ2ghmOHuKDulbW/AmbqJtqRQve8oXPYAPi8YC/+1BF
|
||||||
|
nIpOHI32W53Iv/chLw9c5zo47iJdo6tpzcyJPtieiDlK8BHkVdlet8AAMOmg5a0j
|
||||||
|
x6txJ7WwHSgODGuhnBb/nQuMhf/y9Dgk33tQ1rgtWxTqJqWo0Vj70sbmLixceNVc
|
||||||
|
b3chpMY4B5SRjrSPBDfVr0UdL0h01dsnxasMqgxX2E4ft+WA2QKCAQEA4eehhPZD
|
||||||
|
raJofwCZtMN9di9Lf5cAbzSX1yB7A8wotPGP8nqd2S5b1uLZiH7M0nAq5U3n2pla
|
||||||
|
XS92Upzw173NHE1MUwia9IHfydkp5t1vSFn4etXP0ug3qpMQESwH9jfEF2CqXvzT
|
||||||
|
ndKftOSb9EOxFJ/uwLfkBIry2ffEDRMkrioEeE9Kan+BVI7K405oCrg7/Kqe/YPm
|
||||||
|
uYfkllUU4iHwff3egJ61r+8+g3jBBkcN+APE1QOKYdWWB5nuJ6knWazGl6S0gKuU
|
||||||
|
olrgn63gQ+qV1pi+7N6dIjwt73wLNIdjXUIngOFhBTrCF27lHdmbR5dNaLkRETCT
|
||||||
|
/YmdHbgxCCVc8wKCAQEAyoi3Hu0dIl7kKaW0Lv6kr9ZCSU2qfGUEUnNV8HuwWQHj
|
||||||
|
UfDlRsJCnaDTUTA0oQXd37tLLS0pTZpKJJdzixwS+oLg4HLBJO2wxiTJ7eAAwbee
|
||||||
|
byhLJBnbtlZClK5w5dTJlcB+SVQ1vX3W5DfaNwc8Qw+6BmQ0QJCbiGiALMUiE/YU
|
||||||
|
Mv+PMvdVzz/PK4F0QiezRqqL4uTv3lIKnFhYHdH1uGe/Qke9Ircwh3tre46V9a0I
|
||||||
|
9h0WFcLpTMVjMH4wO1JGtQMg5i0hxS0YAA/QRJzsu9rTDWlvVJ8wMeiYpHsocP0h
|
||||||
|
QkfV0b9VCeLvo/CFHPj4Jj4Qwl+P0gjFLEoTZJHbYwKCAQEAuZF3yewtvhVaN3F7
|
||||||
|
0dSAXDQPlbip36/ZRxtkUcNEcRa5w1rcDYqaYJOqVAitIfSIGCL94UD1zPRvAv/u
|
||||||
|
i5pbQfNxTggUmeORvJKKbB3cCxf1GJpIhJzDFXiGy0RbKfO3PejnKu4Ou2dIT+U3
|
||||||
|
AtkUPrf9/QtR4DVvtoNj5cWi7PqQ/29K1t70k0xU95Hxv1SF2lEiF2hhgGhT6vXr
|
||||||
|
GLL+hdCkFQ3Ke8JQnNj13r1BiUk3SDAHXcSA4K+exa+bJnvaCrl+mO/ZQeDbAfBn
|
||||||
|
+AJcoZKJy7Q2aef7Z+2CmtzYT8RHBQSemRgiVfN/fBzEBHQSX4MetPstpiiECuTC
|
||||||
|
Skm+5wKCAQEAkH2Wvv6EsXenKTspX/mVPkkKQ0egYFylB7l2zzk+51EcfuHwgFmo
|
||||||
|
stIA0EQm19Xao3n4OQOmGtH/ITnXWaAuvf/PNPFJb/IPEl0+nnEXuRwpcL37VYcJ
|
||||||
|
I31IxM/qhV0Yb7jDn8bvDAAR5gEesfF8gY9ftJ2aVZGVFG0RPF9rX3hIktWVsNOZ
|
||||||
|
qWCpiS0y5ttx3/FeGQIhSqeXIFE6lBOtTODfJwcNHQ46Ff3sAVsJCxtmcEbx8ZZ7
|
||||||
|
YKTVjcwI1tlszkisGOqL1CLGo4yklb6qeZ60wTW+Ek37US/Sbk3a3TkJmEKtfZUV
|
||||||
|
sxbuxjOak7/fMVFIHZOVhE9zc5RpX29bZwKCAQEAgNInsAnvlePu/tNp9l/UyBpL
|
||||||
|
WJ92xirUpnooXyUXnw4Et65IKwAr4besgotwg8RsQy9xwsEgasI3eTgouZgVSTUI
|
||||||
|
rHnMiC+vy8nbwL13GnUQJqPRNZaZTBML/lYpPuBBHJ5rVSL19ciNZNLLi3avSwoz
|
||||||
|
kbTplnIALmHTYbjdirfRKii2t9qkrDU+SptPUmMfJeemZmwUD0YTzMLkpf+mFwGS
|
||||||
|
FF9omqBo3GRR/AcFxsMvpMbOXJl7VUzYeSsovtlZrVhhtXetJHnJLIU+2r/hEBRy
|
||||||
|
eaK4jPloDpoHD7y9BWc/UfloNaoszinl1DqMvUvTZK2yWHx2WyIQyREs11xOwA==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
@ -5,6 +5,14 @@ default_md = sha256
|
|||||||
req_extensions = v3_req
|
req_extensions = v3_req
|
||||||
distinguished_name = dn
|
distinguished_name = dn
|
||||||
|
|
||||||
|
[ca]
|
||||||
|
default_ca=ca_pgbackrest
|
||||||
|
|
||||||
|
[ca_pgbackrest]
|
||||||
|
database=index.txt
|
||||||
|
unique_subject=no
|
||||||
|
default_md=sha256
|
||||||
|
|
||||||
[ dn ]
|
[ dn ]
|
||||||
C=US
|
C=US
|
||||||
ST=All
|
ST=All
|
||||||
@ -19,8 +27,16 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
|||||||
subjectAltName = @alt_names
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
[ alt_names ]
|
[ alt_names ]
|
||||||
|
# Used in container unit tests
|
||||||
DNS.1 = test.pgbackrest.org
|
DNS.1 = test.pgbackrest.org
|
||||||
DNS.2 = *.test.pgbackrest.org
|
DNS.2 = *.test.pgbackrest.org
|
||||||
|
DNS.3 = *.test2.pgbackrest.org
|
||||||
|
|
||||||
|
# Used in non-container unit tests
|
||||||
|
DNS.4 = 127.0.0.1
|
||||||
IP.1 = 127.0.0.1
|
IP.1 = 127.0.0.1
|
||||||
DNS.3 = test2.pgbackrest.org
|
|
||||||
DNS.4 = *.test2.pgbackrest.org
|
# Used in integration tests
|
||||||
|
DNS.5 = db-primary
|
||||||
|
DNS.6 = db-standby
|
||||||
|
DNS.7 = backup
|
35
test/certificate/pgbackrest-test-server.crt
Normal file
35
test/certificate/pgbackrest-test-server.crt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIGAjCCA+qgAwIBAgIUW0gPWoZD5DqjIWIP3PliYA0IAOQwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwXDELMAkGA1UEBhMCVVMxDDAKBgNVBAgMA0FsbDEMMAoGA1UEBwwDQWxsMRMw
|
||||||
|
EQYDVQQKDApwZ0JhY2tSZXN0MRwwGgYDVQQDDBN0ZXN0LnBnYmFja3Jlc3Qub3Jn
|
||||||
|
MCAXDTIxMDgyNjEyMjkwM1oYDzIyOTUwNjEwMTIyOTAzWjB6MQswCQYDVQQGEwJV
|
||||||
|
UzEMMAoGA1UECAwDQWxsMQwwCgYDVQQHDANBbGwxEzARBgNVBAoMCnBnQmFja1Jl
|
||||||
|
c3QxHDAaBgNVBAsME1VuaXQgVGVzdGluZyBEb21haW4xHDAaBgNVBAMME3Rlc3Qu
|
||||||
|
cGdiYWNrcmVzdC5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDD
|
||||||
|
M1kNf9WFMDqUAtcNngA4e/g5AfnBNmKlr3td1OsjZMh8wYR98ua/nDM3zmmS7kdc
|
||||||
|
G4cYlRpQQ1e3VKwbB18HH+BlkQDyg42qSvE6glOsAFYgCzmTpNNR35/djf2uWzJC
|
||||||
|
PTvp/WzDozD2qgKH4kpcMOrDyQbBAeJ9d20KvEv059Xh6r6Bgqup2XIUzTxZ8rF7
|
||||||
|
QmzxsHlxngG38YLYmFDND1syNgmXFJcheK8/8UW6dVPmFnyCxRUAf7+ybzGVDix5
|
||||||
|
1buYgEqSNPe2AvQW9yEHdfKhnpKvQkpVow5xCMixPM6p2BrCACs7njVnBRYd0kf4
|
||||||
|
M4Ov+AFZdKefOEcQPkMC9Ew907+3fnepL+KGlpxOpD3UHhQrErWlU0LzhyHeykIu
|
||||||
|
dCdyXuSftGFx0JxvmDhl9qFGarv1BKgwO83j7sy3IREte1K21JaIHNBVWP+NwU0N
|
||||||
|
4Z4OMqnpnnnGiyi0xnfJVqOXghu5BLWl9MuOntZ0nnzLmFD7w795uNRgjE6jmRmF
|
||||||
|
FlX+PGqhHsZr0wZsBDsE9xO4i2l8aqJZx1hT5l3LIXC+lei/qo2gJi3nyePuz4UB
|
||||||
|
t53sTNEdrZndFUaRyq/aJfkR13J0eaoqKn5BRRHhw8tRef6S84e0kQ6ABYNRGHQN
|
||||||
|
V+GswPl1fV37114FTBnz2Bi/GSQSs8vWjw49HHKK5wIDAQABo4GbMIGYMAkGA1Ud
|
||||||
|
EwQCMAAwCwYDVR0PBAQDAgXgMH4GA1UdEQR3MHWCE3Rlc3QucGdiYWNrcmVzdC5v
|
||||||
|
cmeCFSoudGVzdC5wZ2JhY2tyZXN0Lm9yZ4IWKi50ZXN0Mi5wZ2JhY2tyZXN0Lm9y
|
||||||
|
Z4IJMTI3LjAuMC4xhwR/AAABggpkYi1wcmltYXJ5ggpkYi1zdGFuZGJ5ggZiYWNr
|
||||||
|
dXAwDQYJKoZIhvcNAQELBQADggIBAMbSq1/hjvQZJ2PFE/VVz9OcA7vlewq632eE
|
||||||
|
P5BalSJJgLVEsv1AxPx8VT08xfFQHQtEcCg/PFqT3RQ5yb1kHfa6glJkjYIdKQbn
|
||||||
|
lv9OVc/iutQwKPwk32QQjSgQFb/m0tXv9SlQ+gNTdkK4UKffXPj5rpgwaSiVwuLF
|
||||||
|
d+3TUpJihS48LLRC27kcL5Ur69/fu0ZD7xZSoCr/n8MUq4f9LwOhBqq+h64wM9cV
|
||||||
|
V79iPWmEJXoNAJrPYmK+XNhcro071c4m+HR4CCNikjxz/GUUf/NGHWT3pL0Ildku
|
||||||
|
X3dHmsNRVT/wLqi2v2oa6zr9FfVzjDAdCfnvTLOJ6H6dmofzQUFJBSWfhqGNDR8U
|
||||||
|
oblwirM2sjaOUjnkBS6Cb26yHSClStI+GZvS0KZfSVd2Qbe4YmtQMTNl/hdZGK3z
|
||||||
|
ZoqV++idVR+A0NQP8xR4VWqQdq0BR5eQOXDA4wtqvivqlIXpbJvqh1kBHPU9cAF+
|
||||||
|
g/t3Wa7EomwLazRaV9djLUpon6wGwScKJGzv+vyQSgXN1tQG9tLV4NCFUKDueUUZ
|
||||||
|
U/j1t64KF9hp5NU2A16zLp6V5GPIJhufXOYa66AFjV8c880eLd5YlkfzgyYwReOx
|
||||||
|
7vHkiLylbx2tc6aYUqdwjpMwnkxTsn52BBVxDvXToBIRdq/ea/LnZ/yhpnaac/Um
|
||||||
|
bJOTMee+
|
||||||
|
-----END CERTIFICATE-----
|
@ -1,18 +0,0 @@
|
|||||||
[req]
|
|
||||||
default_bits = 4096
|
|
||||||
prompt = no
|
|
||||||
default_md = sha256
|
|
||||||
req_extensions = v3_req
|
|
||||||
distinguished_name = dn
|
|
||||||
|
|
||||||
[ dn ]
|
|
||||||
C=US
|
|
||||||
ST=All
|
|
||||||
L=All
|
|
||||||
O=pgBackRest
|
|
||||||
OU=Unit Testing Domain
|
|
||||||
CN = *.test.pgbackrest.org
|
|
||||||
|
|
||||||
[ v3_req ]
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
|
@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFdzCCA1+gAwIBAgIJAN+gSjwW7yR/MA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
|
|
||||||
BAYTAlVTMQwwCgYDVQQIDANBbGwxDDAKBgNVBAcMA0FsbDETMBEGA1UECgwKcGdC
|
|
||||||
YWNrUmVzdDEcMBoGA1UEAwwTdGVzdC5wZ2JhY2tyZXN0Lm9yZzAgFw0xODExMjAx
|
|
||||||
MzU2NDJaGA8yMjkyMDkwMzEzNTY0MlowfDELMAkGA1UEBhMCVVMxDDAKBgNVBAgM
|
|
||||||
A0FsbDEMMAoGA1UEBwwDQWxsMRMwEQYDVQQKDApwZ0JhY2tSZXN0MRwwGgYDVQQL
|
|
||||||
DBNVbml0IFRlc3RpbmcgRG9tYWluMR4wHAYDVQQDDBUqLnRlc3QucGdiYWNrcmVz
|
|
||||||
dC5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDDM1kNf9WFMDqU
|
|
||||||
AtcNngA4e/g5AfnBNmKlr3td1OsjZMh8wYR98ua/nDM3zmmS7kdcG4cYlRpQQ1e3
|
|
||||||
VKwbB18HH+BlkQDyg42qSvE6glOsAFYgCzmTpNNR35/djf2uWzJCPTvp/WzDozD2
|
|
||||||
qgKH4kpcMOrDyQbBAeJ9d20KvEv059Xh6r6Bgqup2XIUzTxZ8rF7QmzxsHlxngG3
|
|
||||||
8YLYmFDND1syNgmXFJcheK8/8UW6dVPmFnyCxRUAf7+ybzGVDix51buYgEqSNPe2
|
|
||||||
AvQW9yEHdfKhnpKvQkpVow5xCMixPM6p2BrCACs7njVnBRYd0kf4M4Ov+AFZdKef
|
|
||||||
OEcQPkMC9Ew907+3fnepL+KGlpxOpD3UHhQrErWlU0LzhyHeykIudCdyXuSftGFx
|
|
||||||
0JxvmDhl9qFGarv1BKgwO83j7sy3IREte1K21JaIHNBVWP+NwU0N4Z4OMqnpnnnG
|
|
||||||
iyi0xnfJVqOXghu5BLWl9MuOntZ0nnzLmFD7w795uNRgjE6jmRmFFlX+PGqhHsZr
|
|
||||||
0wZsBDsE9xO4i2l8aqJZx1hT5l3LIXC+lei/qo2gJi3nyePuz4UBt53sTNEdrZnd
|
|
||||||
FUaRyq/aJfkR13J0eaoqKn5BRRHhw8tRef6S84e0kQ6ABYNRGHQNV+GswPl1fV37
|
|
||||||
114FTBnz2Bi/GSQSs8vWjw49HHKK5wIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1Ud
|
|
||||||
DwQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAgEAsjmEXx1dc2bbQHUOZTqfTNZ38/ux
|
|
||||||
O4V8uXGcKER7bR7TKP6NYwYmgUqcwA50FJkBQ8wULF2C/tLsp1AyAu3wlhn+yVsP
|
|
||||||
zeZL+p/fOzXDhTyz0Ggx19tyol4o2q+bxyd+KS8rrcSvzC9Jz7Wjuhs9/M5r2gWr
|
|
||||||
WJydwYbGo4MbAcdPWWJdYRf93vlUqG3Qh3oBnwDntGr0xrBPRBbfcIg+f1c/fnAb
|
|
||||||
S94rkrmRCtCGqf09IKjVgnlNhXERM2YLoiLcMIwJCLPU8TWoar+paDBgevqIzMvD
|
|
||||||
k+WYc/NuHpwkDv2e7iVuWarB5r7BAB0olu4qOC8jyGeD8vrJgLah8qyW1slOAH9h
|
|
||||||
7h0vGQ6+Gjp14ZVWQUwjvnINyX2xUc3gkkQvaons+Ny7xtyu3tOy6v4Ukl/ryT87
|
|
||||||
IbgkoCj8T+9whp4PqHBDNUmEicJs18q/VRYa4yTE5hh2ecKaveb++YtdZxwJxZR4
|
|
||||||
Le1+GHj4wQJzQR+Hv42G7C444FIx0G266RIMRoNgbroRPN5mNwdiAg2oejB6qWlX
|
|
||||||
IOi4+eWbpQk2AM0tvB+eSY/JxHn+5XiVyXiN4hO7ndsAwT7Jj3VNKEjRZyZhTwM9
|
|
||||||
YO7FOaKbDLnn4IswCgw2iz916fghgBfKLLcjpe/Y9kJvY1g/Fd77zXMHMPs1Zbv3
|
|
||||||
4MleZ146f1S0En0=
|
|
||||||
-----END CERTIFICATE-----
|
|
@ -305,17 +305,29 @@ unit:
|
|||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
- common/io/client
|
- common/io/client
|
||||||
|
- common/io/server
|
||||||
- common/io/session
|
- common/io/session
|
||||||
- common/io/tls/client
|
- common/io/tls/client
|
||||||
|
- common/io/tls/common
|
||||||
|
- common/io/tls/server
|
||||||
- common/io/tls/session
|
- common/io/tls/session
|
||||||
- common/io/socket/client
|
- common/io/socket/client
|
||||||
- common/io/socket/common
|
- common/io/socket/common
|
||||||
|
- common/io/socket/server
|
||||||
- common/io/socket/session
|
- common/io/socket/session
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- common/io/fdRead
|
- common/io/fdRead
|
||||||
- common/io/read
|
- common/io/read
|
||||||
|
|
||||||
|
depend:
|
||||||
|
- storage/posix/read
|
||||||
|
- storage/posix/storage
|
||||||
|
- storage/posix/write
|
||||||
|
- storage/read
|
||||||
|
- storage/storage
|
||||||
|
- storage/write
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
- name: io-http
|
- name: io-http
|
||||||
total: 6
|
total: 6
|
||||||
@ -344,14 +356,6 @@ unit:
|
|||||||
coverage:
|
coverage:
|
||||||
- common/ini
|
- common/ini
|
||||||
|
|
||||||
depend:
|
|
||||||
- storage/posix/read
|
|
||||||
- storage/posix/storage
|
|
||||||
- storage/posix/write
|
|
||||||
- storage/read
|
|
||||||
- storage/storage
|
|
||||||
- storage/write
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
- name: compress
|
- name: compress
|
||||||
total: 5
|
total: 5
|
||||||
@ -448,7 +452,7 @@ unit:
|
|||||||
test:
|
test:
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
- name: protocol
|
- name: protocol
|
||||||
total: 7
|
total: 8
|
||||||
harness:
|
harness:
|
||||||
name: protocol
|
name: protocol
|
||||||
shim:
|
shim:
|
||||||
@ -857,6 +861,14 @@ unit:
|
|||||||
coverage:
|
coverage:
|
||||||
- command/local/local
|
- command/local/local
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------
|
||||||
|
- name: server
|
||||||
|
total: 2
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- command/server/ping
|
||||||
|
- command/server/server
|
||||||
|
|
||||||
# **********************************************************************************************************************************
|
# **********************************************************************************************************************************
|
||||||
# Integration tests
|
# Integration tests
|
||||||
#
|
#
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 001 - rmt 0, storage posix, enc 0, delta 1
|
run 001 - rmt 0, tls 0, storage posix, enc 0, delta 1
|
||||||
==============================================
|
=====================================================
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] version
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] version
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 002 - rmt 1, storage s3, enc 1, delta 0
|
run 002 - rmt 1, tls 1, storage s3, enc 1, delta 0
|
||||||
===========================================
|
==================================================
|
||||||
|
|
||||||
stanza-create db - create required data for stanza (backup host)
|
stanza-create db - create required data for stanza (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-create
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-create
|
||||||
@ -77,8 +77,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -86,8 +89,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -272,8 +278,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -281,8 +290,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -506,8 +518,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -515,8 +530,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -713,8 +731,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -722,8 +743,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -928,8 +952,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -937,8 +964,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -1160,8 +1190,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -1169,8 +1202,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
||||||
|
|
||||||
@ -1372,8 +1408,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -1381,8 +1420,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
||||||
|
|
||||||
@ -1587,8 +1629,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -1596,8 +1641,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
||||||
|
|
||||||
@ -1803,8 +1851,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -1812,8 +1863,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
||||||
|
|
||||||
@ -2013,8 +2067,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -2022,8 +2079,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
||||||
|
|
||||||
@ -2228,8 +2288,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -2237,8 +2300,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
pg1-path=[TEST_PATH]/db-primary/db/base-2
|
||||||
|
|
||||||
@ -2443,7 +2509,7 @@ restore_command = '[BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.con
|
|||||||
diff backup - option backup-standby reset - backup performed from primary (backup host)
|
diff backup - option backup-standby reset - backup performed from primary (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --log-level-console=info --backup-standby --type=diff --stanza=db backup
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --no-online --log-level-console=info --backup-standby --type=diff --stanza=db backup
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: backup command begin [BACKREST-VERSION]: --backup-standby --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/backup/lock --log-level-console=info --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base-2/base --process-max=2 --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-storage-verify-tls --repo1-type=s3 --stanza=db --start-fast --type=diff
|
P00 INFO: backup command begin [BACKREST-VERSION]: --backup-standby --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/backup/lock --log-level-console=info --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base-2/base --process-max=2 --protocol-timeout=60 --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-storage-verify-tls --repo1-type=s3 --stanza=db --start-fast --type=diff
|
||||||
P00 WARN: option 'repo1-retention-full' is not set for 'repo1-retention-full-type=count', the repository may run out of space
|
P00 WARN: option 'repo1-retention-full' is not set for 'repo1-retention-full-type=count', the repository may run out of space
|
||||||
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
|
HINT: to retain full backups indefinitely (without warning), set option 'repo1-retention-full' to the maximum.
|
||||||
P00 WARN: option backup-standby is enabled but backup is offline - backups will be performed from the primary
|
P00 WARN: option backup-standby is enabled but backup is offline - backups will be performed from the primary
|
||||||
@ -2479,8 +2545,11 @@ log-timestamp=n
|
|||||||
process-max=2
|
process-max=2
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -2488,8 +2557,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base-2/base
|
pg1-path=[TEST_PATH]/db-primary/db/base-2/base
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 001 - rmt 0, storage posix, enc 1, cmp lz4
|
run 001 - rmt 0, tls 0, storage posix, enc 1, cmp lz4
|
||||||
==============================================
|
=====================================================
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1,36 +1,38 @@
|
|||||||
run 002 - rmt 1, storage s3, enc 0, cmp zst
|
run 002 - rmt 1, tls 1, storage s3, enc 0, cmp zst
|
||||||
===========================================
|
==================================================
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [103]: unable to find a valid repository:
|
P00 ERROR: [103]: unable to find a valid repository:
|
||||||
repo1: [FileMissingError] unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
repo1: [FileMissingError] unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
||||||
FileMissingError: raised from remote-0 protocol on 'backup': unable to open missing file '/archive/db/archive.info' for read
|
FileMissingError: raised from remote-0 tls protocol on 'backup': unable to open missing file '/archive/db/archive.info' for read
|
||||||
FileMissingError: raised from remote-0 protocol on 'backup': unable to open missing file '/archive/db/archive.info.copy' for read
|
FileMissingError: raised from remote-0 tls protocol on 'backup': unable to open missing file '/archive/db/archive.info.copy' for read
|
||||||
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
||||||
HINT: is archive_command configured correctly in postgresql.conf?
|
HINT: is archive_command configured correctly in postgresql.conf?
|
||||||
HINT: has a stanza-create been performed?
|
HINT: has a stanza-create been performed?
|
||||||
HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.
|
HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: aborted with exception [103]
|
P00 INFO: archive-push command end: aborted with exception [103]
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 WARN: repo1: [FileMissingError] unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
P00 WARN: repo1: [FileMissingError] unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
||||||
FileMissingError: raised from remote-0 protocol on 'backup': unable to open missing file '/archive/db/archive.info' for read
|
FileMissingError: raised from remote-0 tls protocol on 'backup': unable to open missing file '/archive/db/archive.info' for read
|
||||||
FileMissingError: raised from remote-0 protocol on 'backup': unable to open missing file '/archive/db/archive.info.copy' for read
|
FileMissingError: raised from remote-0 tls protocol on 'backup': unable to open missing file '/archive/db/archive.info.copy' for read
|
||||||
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
HINT: archive.info cannot be opened but is required to push/get WAL segments.
|
||||||
HINT: is archive_command configured correctly in postgresql.conf?
|
HINT: is archive_command configured correctly in postgresql.conf?
|
||||||
HINT: has a stanza-create been performed?
|
HINT: has a stanza-create been performed?
|
||||||
HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.
|
HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.
|
||||||
P00 ERROR: [103]: unable to find a valid repository
|
P00 ERROR: [103]: unable to find a valid repository
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: aborted with exception [103]
|
P00 INFO: archive-get command end: aborted with exception [103]
|
||||||
|
|
||||||
stanza-create db - stanza create (backup host)
|
stanza-create db - stanza create (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-create
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-create
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-storage-verify-tls --repo1-type=s3 --stanza=db
|
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-path=/ --repo1-s3-bucket=pgbackrest-dev --repo1-s3-endpoint=s3.amazonaws.com --repo1-s3-key=<redacted> --repo1-s3-key-secret=<redacted> --repo1-s3-region=us-east-1 --no-repo1-storage-verify-tls --repo1-type=s3 --stanza=db
|
||||||
P00 INFO: stanza-create for stanza 'db' on repo1
|
P00 INFO: stanza-create for stanza 'db' on repo1
|
||||||
P00 DETAIL: statistics: STATISTICS
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-create command end: completed successfully
|
P00 INFO: stanza-create command end: completed successfully
|
||||||
@ -73,54 +75,60 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push --cmd-ssh=/usr/bin/ssh --compress-type=zst [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push --cmd-ssh=/usr/bin/ssh --compress-type=zst [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001] --buffer-size=[BUFFER-SIZE] --cmd-ssh=/usr/bin/ssh --compress-level=3 --compress-level-network=1 --compress-type=zst --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001] --buffer-size=[BUFFER-SIZE] --cmd-ssh=/usr/bin/ssh --compress-level=3 --compress-level-network=1 --compress-type=zst --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: pushed WAL file '000000010000000100000001' to the archive
|
P00 INFO: pushed WAL file '000000010000000100000001' to the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 700000007000000070000000 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 700000007000000070000000 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [700000007000000070000000, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [700000007000000070000000, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: unable to find 700000007000000070000000 in the archive
|
P00 INFO: unable to find 700000007000000070000000 in the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: completed successfully
|
P00 INFO: archive-get command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: found 000000010000000100000001 in the repo1: 9.4-1 archive
|
P00 INFO: found 000000010000000100000001 in the repo1: 9.4-1 archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: completed successfully
|
P00 INFO: archive-get command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push --compress-type=zst --archive-async --process-max=2 [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push --compress-type=zst --archive-async --process-max=2 [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=zst --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --process-max=2 --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=zst --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --process-max=2 --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
||||||
P00 INFO: pushed WAL file '000000010000000100000002' to the archive asynchronously
|
P00 INFO: pushed WAL file '000000010000000100000002' to the archive asynchronously
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push --archive-async [TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push --archive-async [TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
||||||
P00 INFO: pushed WAL file '00000002.history' to the archive asynchronously
|
P00 INFO: pushed WAL file '00000002.history' to the archive asynchronously
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 WARN: repo1: [ArchiveMismatchError] unable to retrieve the archive id for database version '9.4' and system-id '1000000000000000094'
|
P00 WARN: repo1: [ArchiveMismatchError] unable to retrieve the archive id for database version '9.4' and system-id '1000000000000000094'
|
||||||
P00 ERROR: [103]: unable to find a valid repository
|
P00 ERROR: [103]: unable to find a valid repository
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: aborted with exception [103]
|
P00 INFO: archive-get command end: aborted with exception [103]
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [103]: unable to find a valid repository:
|
P00 ERROR: [103]: unable to find a valid repository:
|
||||||
repo1: [ArchiveMismatchError] PostgreSQL version 9.4, system-id 1000000000000000094 do not match repo1 stanza version 9.4, system-id 5000900090001855000
|
repo1: [ArchiveMismatchError] PostgreSQL version 9.4, system-id 1000000000000000094 do not match repo1 stanza version 9.4, system-id 5000900090001855000
|
||||||
HINT: are you archiving to the correct stanza?
|
HINT: are you archiving to the correct stanza?
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: aborted with exception [103]
|
P00 INFO: archive-push command end: aborted with exception [103]
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 WARN: repo1: [ArchiveMismatchError] unable to retrieve the archive id for database version '9.4' and system-id '1000000000000000094'
|
P00 WARN: repo1: [ArchiveMismatchError] unable to retrieve the archive id for database version '9.4' and system-id '1000000000000000094'
|
||||||
P00 ERROR: [103]: unable to find a valid repository
|
P00 ERROR: [103]: unable to find a valid repository
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: aborted with exception [103]
|
P00 INFO: archive-get command end: aborted with exception [103]
|
||||||
|
|
||||||
stop db stanza (db-primary host)
|
stop db stanza (db-primary host)
|
||||||
@ -131,14 +139,15 @@ P00 INFO: stop command end: completed successfully
|
|||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [062]: stop file exists for stanza db
|
P00 ERROR: [062]: stop file exists for stanza db
|
||||||
P00 INFO: archive-push command end: aborted with exception [062]
|
P00 INFO: archive-push command end: aborted with exception [062]
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000001 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000001, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [062]: stop file exists for stanza db
|
P00 ERROR: [062]: stop file exists for stanza db
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: aborted with exception [062]
|
P00 INFO: archive-get command end: aborted with exception [062]
|
||||||
|
|
||||||
start db stanza (db-primary host)
|
start db stanza (db-primary host)
|
||||||
@ -149,52 +158,59 @@ P00 INFO: start command end: completed successfully
|
|||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 WARN: WAL file '000000010000000100000002' already exists in the repo1 archive with the same checksum
|
P00 WARN: WAL file '000000010000000100000002' already exists in the repo1 archive with the same checksum
|
||||||
HINT: this is valid in some recovery scenarios but may also indicate a problem.
|
HINT: this is valid in some recovery scenarios but may also indicate a problem.
|
||||||
P00 INFO: pushed WAL file '000000010000000100000002' to the archive
|
P00 INFO: pushed WAL file '000000010000000100000002' to the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [045]: WAL file '000000010000000100000002' already exists in the repo1 archive with a different checksum
|
P00 ERROR: [045]: WAL file '000000010000000100000002' already exists in the repo1 archive with a different checksum
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: aborted with exception [045]
|
P00 INFO: archive-push command end: aborted with exception [045]
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get --cmd-ssh=/usr/bin/ssh --archive-async 000000010000000100000002 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get --cmd-ssh=/usr/bin/ssh --archive-async 000000010000000100000002 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --archive-async --buffer-size=[BUFFER-SIZE] --cmd-ssh=/usr/bin/ssh --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --archive-async --buffer-size=[BUFFER-SIZE] --cmd-ssh=/usr/bin/ssh --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
||||||
P00 INFO: found 000000010000000100000002 in the archive asynchronously
|
P00 INFO: found 000000010000000100000002 in the archive asynchronously
|
||||||
P00 INFO: archive-get command end: completed successfully
|
P00 INFO: archive-get command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get --archive-async 00000001.history [TEST_PATH]/db-primary/db/base/pg_xlog/00000001.history
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get --archive-async 00000001.history [TEST_PATH]/db-primary/db/base/pg_xlog/00000001.history
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [00000001.history, [TEST_PATH]/db-primary/db/base/pg_xlog/00000001.history] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [00000001.history, [TEST_PATH]/db-primary/db/base/pg_xlog/00000001.history] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
||||||
P00 INFO: unable to find 00000001.history in the archive
|
P00 INFO: unable to find 00000001.history in the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: completed successfully
|
P00 INFO: archive-get command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get --archive-async 00000002.history [TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get --archive-async 00000002.history [TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [00000002.history, [TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [00000002.history, [TEST_PATH]/db-primary/db/base/pg_xlog/00000002.history] --archive-async --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --spool-path=[TEST_PATH]/db-primary/spool --stanza=db
|
||||||
P00 INFO: found 00000002.history in the repo1: 9.4-1 archive
|
P00 INFO: found 00000002.history in the repo1: 9.4-1 archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: completed successfully
|
P00 INFO: archive-get command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: pushed WAL file '000000010000000100000002.partial' to the archive
|
P00 INFO: pushed WAL file '000000010000000100000002.partial' to the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 WARN: WAL file '000000010000000100000002.partial' already exists in the repo1 archive with the same checksum
|
P00 WARN: WAL file '000000010000000100000002.partial' already exists in the repo1 archive with the same checksum
|
||||||
HINT: this is valid in some recovery scenarios but may also indicate a problem.
|
HINT: this is valid in some recovery scenarios but may also indicate a problem.
|
||||||
P00 INFO: pushed WAL file '000000010000000100000002.partial' to the archive
|
P00 INFO: pushed WAL file '000000010000000100000002.partial' to the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002.partial] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=none --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [045]: WAL file '000000010000000100000002.partial' already exists in the repo1 archive with a different checksum
|
P00 ERROR: [045]: WAL file '000000010000000100000002.partial' already exists in the repo1 archive with a different checksum
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: aborted with exception [045]
|
P00 INFO: archive-push command end: aborted with exception [045]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 001 - rmt 0, cmp bz2, error version, storage gcs, enc 1
|
run 001 - rmt 0, tls 0, cmp bz2, error version, storage gcs, enc 1
|
||||||
===========================================================
|
==================================================================
|
||||||
|
|
||||||
stanza-create db - create required data for stanza (db-primary host)
|
stanza-create db - create required data for stanza (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-create
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-create
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 002 - rmt 1, cmp lz4, error connect, storage azure, enc 0
|
run 002 - rmt 1, tls 0, cmp lz4, error connect, storage azure, enc 0
|
||||||
=============================================================
|
====================================================================
|
||||||
|
|
||||||
stanza-create db - create required data for stanza (backup host)
|
stanza-create db - create required data for stanza (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-create
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-create
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 001 - remote 0, storage gcs, enc 0, cmp zst
|
run 001 - remote 0, tls 0, storage gcs, enc 0, cmp zst
|
||||||
===============================================
|
======================================================
|
||||||
|
|
||||||
stanza-create db - fail on missing control file (db-primary host)
|
stanza-create db - fail on missing control file (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online --log-level-file=[LOG-LEVEL-FILE] stanza-create
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online --log-level-file=[LOG-LEVEL-FILE] stanza-create
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
run 002 - remote 1, storage azure, enc 1, cmp lz4
|
run 002 - remote 1, tls 1, storage azure, enc 1, cmp lz4
|
||||||
=================================================
|
========================================================
|
||||||
|
|
||||||
stanza-create db - fail on missing control file (backup host)
|
stanza-create db - fail on missing control file (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online --log-level-file=[LOG-LEVEL-FILE] stanza-create
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online --log-level-file=[LOG-LEVEL-FILE] stanza-create
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
||||||
P00 ERROR: [055]: raised from remote-0 protocol on 'db-primary': unable to open missing file '[TEST_PATH]/db-primary/db/base/global/pg_control' for read
|
P00 ERROR: [055]: raised from remote-0 tls protocol on 'db-primary': unable to open missing file '[TEST_PATH]/db-primary/db/base/global/pg_control' for read
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-create command end: aborted with exception [055]
|
P00 INFO: stanza-create command end: aborted with exception [055]
|
||||||
|
|
||||||
stanza-upgrade db - fail on stanza not initialized since archive.info is missing (backup host)
|
stanza-upgrade db - fail on stanza not initialized since archive.info is missing (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
||||||
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
||||||
P00 ERROR: [055]: unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
P00 ERROR: [055]: unable to load info file '/archive/db/archive.info' or '/archive/db/archive.info.copy':
|
||||||
FileMissingError: unable to open missing file '/archive/db/archive.info' for read
|
FileMissingError: unable to open missing file '/archive/db/archive.info' for read
|
||||||
@ -26,8 +27,9 @@ P00 INFO: stanza-upgrade command end: aborted with exception [055]
|
|||||||
stanza-create db - successfully create the stanza (db-primary host)
|
stanza-create db - successfully create the stanza (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-create
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-create
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: stanza-create for stanza 'db' on repo1
|
P00 INFO: stanza-create for stanza 'db' on repo1
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-create command end: completed successfully
|
P00 INFO: stanza-create command end: completed successfully
|
||||||
|
|
||||||
+ supplemental file: /backup/db/backup.info
|
+ supplemental file: /backup/db/backup.info
|
||||||
@ -75,9 +77,10 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
stanza-create db - do not fail on rerun of stanza-create - info files exist and DB section ok (db-primary host)
|
stanza-create db - do not fail on rerun of stanza-create - info files exist and DB section ok (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-create
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-create
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: stanza-create for stanza 'db' on repo1
|
P00 INFO: stanza-create for stanza 'db' on repo1
|
||||||
P00 INFO: stanza 'db' already exists on repo1 and is valid
|
P00 INFO: stanza 'db' already exists on repo1 and is valid
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-create command end: completed successfully
|
P00 INFO: stanza-create command end: completed successfully
|
||||||
|
|
||||||
+ supplemental file: /backup/db/backup.info
|
+ supplemental file: /backup/db/backup.info
|
||||||
@ -125,7 +128,7 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
stanza-create db - fail on database mismatch and warn force option deprecated (backup host)
|
stanza-create db - fail on database mismatch and warn force option deprecated (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online --force stanza-create
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online --force stanza-create
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
||||||
P00 WARN: option --force is no longer supported
|
P00 WARN: option --force is no longer supported
|
||||||
P00 INFO: stanza-create for stanza 'db' on repo1
|
P00 INFO: stanza-create for stanza 'db' on repo1
|
||||||
P00 ERROR: [028]: backup and archive info files exist but do not match the database
|
P00 ERROR: [028]: backup and archive info files exist but do not match the database
|
||||||
@ -179,7 +182,7 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
stanza-upgrade db - already up to date (backup host)
|
stanza-upgrade db - already up to date (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
||||||
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
||||||
P00 INFO: stanza 'db' on repo1 is already up to date
|
P00 INFO: stanza 'db' on repo1 is already up to date
|
||||||
P00 DETAIL: statistics: STATISTICS
|
P00 DETAIL: statistics: STATISTICS
|
||||||
@ -229,14 +232,16 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: pushed WAL file '000000010000000100000001' to the archive
|
P00 INFO: pushed WAL file '000000010000000100000001' to the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-push command begin [BACKREST-VERSION]: [[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002] --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: pushed WAL file '000000010000000100000002' to the archive
|
P00 INFO: pushed WAL file '000000010000000100000002' to the archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-push command end: completed successfully
|
P00 INFO: archive-push command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
||||||
@ -248,7 +253,7 @@ P00 ERROR: [103]: unable to find a valid repository:
|
|||||||
stanza-upgrade db - successful upgrade creates additional history (backup host)
|
stanza-upgrade db - successful upgrade creates additional history (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
||||||
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
||||||
P00 DETAIL: statistics: STATISTICS
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-upgrade command end: completed successfully
|
P00 INFO: stanza-upgrade command end: completed successfully
|
||||||
@ -299,8 +304,9 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: archive-get command begin [BACKREST-VERSION]: [000000010000000100000002, [TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG] --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: found 000000010000000100000002 in the repo1: 9.3-1 archive
|
P00 INFO: found 000000010000000100000002 in the repo1: 9.3-1 archive
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: archive-get command end: completed successfully
|
P00 INFO: archive-get command end: completed successfully
|
||||||
|
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --log-level-console=warn --archive-push-queue-max=33554432 --stanza=db archive-push [TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001
|
||||||
@ -309,7 +315,7 @@ P00 INFO: archive-get command end: completed successfully
|
|||||||
full backup - create first full backup (backup host)
|
full backup - create first full backup (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --repo1-retention-full=2 --no-online --type=full --stanza=db backup
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --repo1-retention-full=2 --no-online --type=full --stanza=db backup
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-retention-full=2 --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db --start-fast --type=full
|
P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-retention-full=2 --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db --start-fast --type=full
|
||||||
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG (16MB, 33%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG (16MB, 33%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
||||||
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002 (16MB, 66%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002 (16MB, 66%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
||||||
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001 (16MB, 99%) checksum f92539dea1f9482e2946c1138eeeecdea29d7f19
|
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000001 (16MB, 99%) checksum f92539dea1f9482e2946c1138eeeecdea29d7f19
|
||||||
@ -345,8 +351,11 @@ log-subprocess=[LOG-SUBPROCESS]
|
|||||||
log-timestamp=n
|
log-timestamp=n
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -354,8 +363,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -391,8 +403,9 @@ start-fast=y
|
|||||||
stanza-upgrade db - successfully upgrade (db-primary host)
|
stanza-upgrade db - successfully upgrade (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --no-online --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-upgrade command end: completed successfully
|
P00 INFO: stanza-upgrade command end: completed successfully
|
||||||
|
|
||||||
+ supplemental file: /backup/db/backup.info
|
+ supplemental file: /backup/db/backup.info
|
||||||
@ -447,7 +460,7 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
stanza-upgrade db - upgrade fails with mismatched db-ids (backup host)
|
stanza-upgrade db - upgrade fails with mismatched db-ids (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --no-online stanza-upgrade
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
P00 INFO: stanza-upgrade command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db
|
||||||
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
P00 INFO: stanza-upgrade for stanza 'db' on repo1
|
||||||
P00 ERROR: [028]: backup info file and archive info file do not match
|
P00 ERROR: [028]: backup info file and archive info file do not match
|
||||||
archive: id = 2, version = 9.5, system-id = 1000000000000000095
|
archive: id = 2, version = 9.5, system-id = 1000000000000000095
|
||||||
@ -509,7 +522,7 @@ backrest-checksum="[CHECKSUM]"
|
|||||||
diff backup - diff changed to full backup (backup host)
|
diff backup - diff changed to full backup (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --repo1-retention-full=2 --no-online --type=diff --stanza=db backup
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --repo1-retention-full=2 --no-online --type=diff --stanza=db backup
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-retention-full=2 --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db --start-fast --type=diff
|
P00 INFO: backup command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level=3 --compress-level-network=1 --compress-type=lz4 --config=[TEST_PATH]/backup/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --job-retry=0 --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/backup/log[] --no-log-timestamp --no-online --pg1-host=db-primary --pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --pg1-host-cmd=[BACKREST-BIN] --pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf --pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --pg1-host-type=tls --pg1-host-user=[USER-1] --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo1-azure-account=<redacted> --repo1-azure-container=azcontainer --repo1-azure-key=<redacted> --repo1-cipher-pass=<redacted> --repo1-cipher-type=aes-256-cbc --repo1-path=/ --repo1-retention-full=2 --repo1-storage-host=azure --no-repo1-storage-verify-tls --repo1-type=azure --stanza=db --start-fast --type=diff
|
||||||
P00 WARN: no prior backup exists, diff backup has been changed to full
|
P00 WARN: no prior backup exists, diff backup has been changed to full
|
||||||
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG (16MB, 33%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/RECOVERYXLOG (16MB, 33%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
||||||
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002 (16MB, 66%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
P01 DETAIL: backup file db-primary:[TEST_PATH]/db-primary/db/base/pg_xlog/000000010000000100000002 (16MB, 66%) checksum 51a8525d254c01f5edddda30b7fe697c7e44705c
|
||||||
@ -547,8 +560,11 @@ log-subprocess=[LOG-SUBPROCESS]
|
|||||||
log-timestamp=n
|
log-timestamp=n
|
||||||
protocol-timeout=60
|
protocol-timeout=60
|
||||||
repo1-host=backup
|
repo1-host=backup
|
||||||
|
repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
repo1-host-cmd=[BACKREST-BIN]
|
repo1-host-cmd=[BACKREST-BIN]
|
||||||
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf
|
||||||
|
repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
repo1-host-type=tls
|
||||||
repo1-host-user=[USER-1]
|
repo1-host-user=[USER-1]
|
||||||
spool-path=[TEST_PATH]/db-primary/spool
|
spool-path=[TEST_PATH]/db-primary/spool
|
||||||
|
|
||||||
@ -556,8 +572,11 @@ spool-path=[TEST_PATH]/db-primary/spool
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
[db]
|
[db]
|
||||||
pg1-host=db-primary
|
pg1-host=db-primary
|
||||||
|
pg1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt
|
||||||
pg1-host-cmd=[BACKREST-BIN]
|
pg1-host-cmd=[BACKREST-BIN]
|
||||||
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
pg1-host-config=[TEST_PATH]/db-primary/pgbackrest.conf
|
||||||
|
pg1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key
|
||||||
|
pg1-host-type=tls
|
||||||
pg1-host-user=[USER-1]
|
pg1-host-user=[USER-1]
|
||||||
pg1-path=[TEST_PATH]/db-primary/db/base
|
pg1-path=[TEST_PATH]/db-primary/db/base
|
||||||
|
|
||||||
@ -593,9 +612,10 @@ start-fast=y
|
|||||||
stanza-delete db - fail on missing stop file (db-primary host)
|
stanza-delete db - fail on missing stop file (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --repo=1 --stanza=db stanza-delete
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --repo=1 --stanza=db stanza-delete
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-delete command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo=1 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: stanza-delete command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo=1 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
P00 ERROR: [055]: stop file does not exist for stanza 'db'
|
P00 ERROR: [055]: stop file does not exist for stanza 'db'
|
||||||
HINT: has the pgbackrest stop command been run on this server for this stanza?
|
HINT: has the pgbackrest stop command been run on this server for this stanza?
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-delete command end: aborted with exception [055]
|
P00 INFO: stanza-delete command end: aborted with exception [055]
|
||||||
|
|
||||||
db must not exist for successful delete
|
db must not exist for successful delete
|
||||||
@ -617,7 +637,8 @@ P00 INFO: stop command end: completed successfully
|
|||||||
stanza-delete db - successfully delete the stanza (db-primary host)
|
stanza-delete db - successfully delete the stanza (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --repo=1 --stanza=db stanza-delete
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --repo=1 --stanza=db stanza-delete
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
P00 INFO: stanza-delete command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo=1 --repo1-host=backup --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-user=[USER-1] --stanza=db
|
P00 INFO: stanza-delete command begin [BACKREST-VERSION]: --buffer-size=[BUFFER-SIZE] --compress-level-network=1 --config=[TEST_PATH]/db-primary/pgbackrest.conf --db-timeout=45 --exec-id=[EXEC-ID] --lock-path=[TEST_PATH]/db-primary/lock --log-level-console=detail --log-level-file=[LOG-LEVEL-FILE] --log-level-stderr=off --log-path=[TEST_PATH]/db-primary/log[] --no-log-timestamp --pg1-path=[TEST_PATH]/db-primary/db/base --protocol-timeout=60 --repo=1 --repo1-host=backup --repo1-host-cert-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.crt --repo1-host-cmd=[BACKREST-BIN] --repo1-host-config=[TEST_PATH]/backup/pgbackrest.conf --repo1-host-key-file=[REPO_PATH]/test/certificate/pgbackrest-test-client.key --repo1-host-type=tls --repo1-host-user=[USER-1] --stanza=db
|
||||||
|
P00 DETAIL: statistics: STATISTICS
|
||||||
P00 INFO: stanza-delete command end: completed successfully
|
P00 INFO: stanza-delete command end: completed successfully
|
||||||
|
|
||||||
db must not exist for successful delete
|
db must not exist for successful delete
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
run 001 - bkp 1, sby 1, dst backup, cmp none, storage posix, enc 0
|
run 001 - bkp 1, sby 1, tls 0, dst backup, cmp none, storage posix, enc 0
|
||||||
==================================================================
|
=========================================================================
|
||||||
|
|
||||||
stanza-create db - main create stanza info files (db-primary host)
|
stanza-create db - main create stanza info files (db-primary host)
|
||||||
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db stanza-create
|
> [CONTAINER-EXEC] db-primary [BACKREST-BIN] --config=[TEST_PATH]/db-primary/pgbackrest.conf --stanza=db stanza-create
|
||||||
@ -10,7 +10,7 @@ check db - verify check command runs successfully (db-primary host)
|
|||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
check db - verify check command runs successfully (backup host)
|
check db - verify check command runs successfully (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --archive-timeout=5 --reset-pg2-host --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path --stanza=db check
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --archive-timeout=5 --reset-pg2-host --reset-pg2-host-type --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path --stanza=db check
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
full backup - fail on backup lock exists (backup host)
|
full backup - fail on backup lock exists (backup host)
|
||||||
@ -484,7 +484,7 @@ archive-copy=y
|
|||||||
start-fast=y
|
start-fast=y
|
||||||
|
|
||||||
check db - verify check command on standby (db-standby host)
|
check db - verify check command on standby (db-standby host)
|
||||||
> [CONTAINER-EXEC] db-standby [BACKREST-BIN] --config=[TEST_PATH]/db-standby/pgbackrest.conf --reset-pg2-host --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path --stanza=db check
|
> [CONTAINER-EXEC] db-standby [BACKREST-BIN] --config=[TEST_PATH]/db-standby/pgbackrest.conf --reset-pg2-host --reset-pg2-host-type --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path --stanza=db check
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
diff backup - backup for adhoc expire (backup host)
|
diff backup - backup for adhoc expire (backup host)
|
||||||
@ -736,7 +736,7 @@ archive-copy=y
|
|||||||
start-fast=y
|
start-fast=y
|
||||||
|
|
||||||
check db - check command with tablespace (backup host)
|
check db - check command with tablespace (backup host)
|
||||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --archive-timeout=5 --reset-pg2-host --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path --stanza=db check
|
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --archive-timeout=5 --reset-pg2-host --reset-pg2-host-type --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path --stanza=db check
|
||||||
------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
restore, type 'default', expect exit 38 - pg running (db-primary host)
|
restore, type 'default', expect exit 38 - pg running (db-primary host)
|
||||||
|
@ -42,6 +42,7 @@ sub new
|
|||||||
$self->{strOption},
|
$self->{strOption},
|
||||||
$self->{strParam},
|
$self->{strParam},
|
||||||
$self->{bHostUpdate},
|
$self->{bHostUpdate},
|
||||||
|
$self->{strEntryPoint},
|
||||||
) =
|
) =
|
||||||
logDebugParam
|
logDebugParam
|
||||||
(
|
(
|
||||||
@ -55,6 +56,7 @@ sub new
|
|||||||
{name => 'strOption', required => false, trace => true},
|
{name => 'strOption', required => false, trace => true},
|
||||||
{name => 'strParam', required => false, trace => true},
|
{name => 'strParam', required => false, trace => true},
|
||||||
{name => 'bHostUpdate', required => false, trace => true, default => true},
|
{name => 'bHostUpdate', required => false, trace => true, default => true},
|
||||||
|
{name => 'strEntryPoint', required => false, trace => true},
|
||||||
);
|
);
|
||||||
|
|
||||||
executeTest("docker rm -f $self->{strContainer}", {bSuppressError => true});
|
executeTest("docker rm -f $self->{strContainer}", {bSuppressError => true});
|
||||||
@ -62,6 +64,7 @@ sub new
|
|||||||
executeTest("docker run -itd -h $self->{strName} --name=$self->{strContainer}" .
|
executeTest("docker run -itd -h $self->{strName} --name=$self->{strContainer}" .
|
||||||
(defined($self->{strOption}) ? ' ' . $self->{strOption} : '') .
|
(defined($self->{strOption}) ? ' ' . $self->{strOption} : '') .
|
||||||
(defined($self->{stryMount}) ? ' -v ' . join(' -v ', @{$self->{stryMount}}) : '') .
|
(defined($self->{stryMount}) ? ' -v ' . join(' -v ', @{$self->{stryMount}}) : '') .
|
||||||
|
(defined($self->{strEntryPoint}) ? " --entrypoint=$self->{strEntryPoint} --user=$self->{strUser}" : '') .
|
||||||
" $self->{strImage} " . (defined($self->{strParam}) ? ' ' . $self->{strParam} : ''),
|
" $self->{strImage} " . (defined($self->{strParam}) ? ' ' . $self->{strParam} : ''),
|
||||||
{bSuppressStdErr => true});
|
{bSuppressStdErr => true});
|
||||||
|
|
||||||
|
@ -407,8 +407,9 @@ sub run
|
|||||||
# declaration and the renamed implementation.
|
# declaration and the renamed implementation.
|
||||||
if ($strLine =~ /^{/)
|
if ($strLine =~ /^{/)
|
||||||
{
|
{
|
||||||
push(@stryShimModuleSrcRenamed, trim($strFunctionDeclaration) . ";");
|
push(
|
||||||
push(@stryShimModuleSrcRenamed, $strFunctionShim);
|
@stryShimModuleSrcRenamed,
|
||||||
|
trim($strFunctionDeclaration) . "; " . $strFunctionShim);
|
||||||
push(@stryShimModuleSrcRenamed, $strLine);
|
push(@stryShimModuleSrcRenamed, $strLine);
|
||||||
|
|
||||||
$strFunctionShim = undef;
|
$strFunctionShim = undef;
|
||||||
@ -416,7 +417,7 @@ sub run
|
|||||||
# Else keep constructing the declaration and implementation
|
# Else keep constructing the declaration and implementation
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$strFunctionDeclaration .= "${strLine}\n";
|
$strFunctionDeclaration .= trim($strLine);
|
||||||
$strFunctionShim .= "${strLine}\n";
|
$strFunctionShim .= "${strLine}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,10 +437,10 @@ sub run
|
|||||||
{
|
{
|
||||||
my $strLineLast = pop(@stryShimModuleSrcRenamed);
|
my $strLineLast = pop(@stryShimModuleSrcRenamed);
|
||||||
|
|
||||||
$strFunctionDeclaration = "${strLineLast} ${strLine}\n";
|
$strFunctionDeclaration = "${strLineLast} ${strLine}";
|
||||||
|
|
||||||
$strLine =~ s/^${strFunction}\(/${strFunction}_SHIMMED\(/;
|
$strLine =~ s/^${strFunction}\(/${strFunction}_SHIMMED\(/;
|
||||||
$strFunctionShim = "${strLineLast}\n${strLine}\n";
|
$strFunctionShim = "${strLineLast}\n${strLine}";
|
||||||
|
|
||||||
$bFound = true;
|
$bFound = true;
|
||||||
last;
|
last;
|
||||||
|
@ -48,6 +48,7 @@ sub new
|
|||||||
$self->{strCommandMain},
|
$self->{strCommandMain},
|
||||||
$self->{strPgSqlBin},
|
$self->{strPgSqlBin},
|
||||||
$self->{strTestPath},
|
$self->{strTestPath},
|
||||||
|
$self->{strRepoPath},
|
||||||
) =
|
) =
|
||||||
logDebugParam
|
logDebugParam
|
||||||
(
|
(
|
||||||
@ -60,6 +61,7 @@ sub new
|
|||||||
{name => 'strCommandMain', trace => true},
|
{name => 'strCommandMain', trace => true},
|
||||||
{name => 'strPgSqlBin', required => false, trace => true},
|
{name => 'strPgSqlBin', required => false, trace => true},
|
||||||
{name => 'strTestPath', trace => true},
|
{name => 'strTestPath', trace => true},
|
||||||
|
{name => 'strRepoPath', trace => true},
|
||||||
);
|
);
|
||||||
|
|
||||||
# Initialize the test log
|
# Initialize the test log
|
||||||
@ -366,6 +368,9 @@ sub regExpReplaceAll
|
|||||||
# Replace the test path
|
# Replace the test path
|
||||||
$strLine =~ s/$self->{strTestPath}/[TEST_PATH]/g;
|
$strLine =~ s/$self->{strTestPath}/[TEST_PATH]/g;
|
||||||
|
|
||||||
|
# Replace the repo path
|
||||||
|
$strLine =~ s/$self->{strRepoPath}/[REPO_PATH]/g;
|
||||||
|
|
||||||
# Replace the pgsql path (if exists)
|
# Replace the pgsql path (if exists)
|
||||||
if (defined($self->{strPgSqlBin}))
|
if (defined($self->{strPgSqlBin}))
|
||||||
{
|
{
|
||||||
|
@ -243,7 +243,7 @@ sub begin
|
|||||||
{
|
{
|
||||||
$self->{oExpect} = new pgBackRestTest::Common::LogTest(
|
$self->{oExpect} = new pgBackRestTest::Common::LogTest(
|
||||||
$self->module(), $self->moduleTest(), $self->runCurrent(), $self->doLogForce(), $strDescription,
|
$self->module(), $self->moduleTest(), $self->runCurrent(), $self->doLogForce(), $strDescription,
|
||||||
$self->{strBackRestExe}, $self->pgBinPath(), $self->testPath());
|
$self->{strBackRestExe}, $self->pgBinPath(), $self->testPath(), $self->basePath());
|
||||||
|
|
||||||
&log(INFO, ' expect log: ' . $self->{oExpect}->{strFileName});
|
&log(INFO, ' expect log: ' . $self->{oExpect}->{strFileName});
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ use pgBackRestTest::Common::ContainerTest;
|
|||||||
use pgBackRestTest::Common::ExecuteTest;
|
use pgBackRestTest::Common::ExecuteTest;
|
||||||
use pgBackRestTest::Common::HostGroupTest;
|
use pgBackRestTest::Common::HostGroupTest;
|
||||||
use pgBackRestTest::Common::RunTest;
|
use pgBackRestTest::Common::RunTest;
|
||||||
|
use pgBackRestTest::Common::VmTest;
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
# Error constants
|
# Error constants
|
||||||
@ -156,7 +157,7 @@ sub new
|
|||||||
$strUser = testRunGet()->pgUser();
|
$strUser = testRunGet()->pgUser();
|
||||||
|
|
||||||
# Create the host
|
# Create the host
|
||||||
my $self = $class->SUPER::new($strName, {strImage => $strImage, strUser => $strUser});
|
my $self = $class->SUPER::new($strName, {strImage => $strImage, strUser => $strUser, bTls => $oParam->{bTls}});
|
||||||
bless $self, $class;
|
bless $self, $class;
|
||||||
|
|
||||||
# If repo is on local filesystem then set the repo-path locally
|
# If repo is on local filesystem then set the repo-path locally
|
||||||
@ -1285,6 +1286,13 @@ sub configCreate
|
|||||||
$oParamHash{$strStanza}{'pg1-host-cmd'} = $oHostDb1->backrestExe();
|
$oParamHash{$strStanza}{'pg1-host-cmd'} = $oHostDb1->backrestExe();
|
||||||
$oParamHash{$strStanza}{'pg1-host-config'} = $oHostDb1->backrestConfig();
|
$oParamHash{$strStanza}{'pg1-host-config'} = $oHostDb1->backrestConfig();
|
||||||
|
|
||||||
|
if ($oParam->{bTls})
|
||||||
|
{
|
||||||
|
$oParamHash{$strStanza}{'pg1-host-type'} = 'tls';
|
||||||
|
$oParamHash{$strStanza}{'pg1-host-cert-file'} = testRunGet()->basePath() . HOST_CLIENT_CERT;
|
||||||
|
$oParamHash{$strStanza}{'pg1-host-key-file'} = testRunGet()->basePath() . HOST_CLIENT_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
# Port can't be configured for a synthetic host
|
# Port can't be configured for a synthetic host
|
||||||
if (!$self->synthetic())
|
if (!$self->synthetic())
|
||||||
{
|
{
|
||||||
@ -1297,12 +1305,15 @@ sub configCreate
|
|||||||
if (defined($oHostDb2))
|
if (defined($oHostDb2))
|
||||||
{
|
{
|
||||||
# Add an invalid replica to simulate more than one replica. A warning should be thrown when a stanza is created and a
|
# Add an invalid replica to simulate more than one replica. A warning should be thrown when a stanza is created and a
|
||||||
# valid replica should be chosen.
|
# valid replica should be chosen. Only do this for SSH since TLS takes longer to timeout.
|
||||||
$oParamHash{$strStanza}{"pg2-host"} = BOGUS;
|
if (!$oParam->{bTls})
|
||||||
$oParamHash{$strStanza}{"pg2-host-user"} = $oHostDb2->userGet();
|
{
|
||||||
$oParamHash{$strStanza}{"pg2-host-cmd"} = $oHostDb2->backrestExe();
|
$oParamHash{$strStanza}{"pg2-host"} = BOGUS;
|
||||||
$oParamHash{$strStanza}{"pg2-host-config"} = $oHostDb2->backrestConfig();
|
$oParamHash{$strStanza}{"pg2-host-user"} = $oHostDb2->userGet();
|
||||||
$oParamHash{$strStanza}{"pg2-path"} = $oHostDb2->dbBasePath();
|
$oParamHash{$strStanza}{"pg2-host-cmd"} = $oHostDb2->backrestExe();
|
||||||
|
$oParamHash{$strStanza}{"pg2-host-config"} = $oHostDb2->backrestConfig();
|
||||||
|
$oParamHash{$strStanza}{"pg2-path"} = $oHostDb2->dbBasePath();
|
||||||
|
}
|
||||||
|
|
||||||
# Set a flag so we know there's a bogus host
|
# Set a flag so we know there's a bogus host
|
||||||
$self->{bBogusHost} = true;
|
$self->{bBogusHost} = true;
|
||||||
@ -1314,6 +1325,13 @@ sub configCreate
|
|||||||
$oParamHash{$strStanza}{"pg256-host-config"} = $oHostDb2->backrestConfig();
|
$oParamHash{$strStanza}{"pg256-host-config"} = $oHostDb2->backrestConfig();
|
||||||
$oParamHash{$strStanza}{"pg256-path"} = $oHostDb2->dbBasePath();
|
$oParamHash{$strStanza}{"pg256-path"} = $oHostDb2->dbBasePath();
|
||||||
|
|
||||||
|
if ($oParam->{bTls})
|
||||||
|
{
|
||||||
|
$oParamHash{$strStanza}{'pg256-host-type'} = 'tls';
|
||||||
|
$oParamHash{$strStanza}{'pg256-host-cert-file'} = testRunGet()->basePath() . HOST_CLIENT_CERT;
|
||||||
|
$oParamHash{$strStanza}{'pg256-host-key-file'} = testRunGet()->basePath() . HOST_CLIENT_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
# Only test explicit ports on the backup server. This is so locally configured ports are also tested.
|
# Only test explicit ports on the backup server. This is so locally configured ports are also tested.
|
||||||
if (!$self->synthetic() && $self->nameTest(HOST_BACKUP))
|
if (!$self->synthetic() && $self->nameTest(HOST_BACKUP))
|
||||||
{
|
{
|
||||||
@ -1348,12 +1366,27 @@ sub configCreate
|
|||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-cmd'} = $oHostBackup->backrestExe();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-cmd'} = $oHostBackup->backrestExe();
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-config'} = $oHostBackup->backrestConfig();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-config'} = $oHostBackup->backrestConfig();
|
||||||
|
|
||||||
|
if ($oParam->{bTls})
|
||||||
|
{
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-type'} = 'tls';
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-cert-file'} = testRunGet()->basePath() . HOST_CLIENT_CERT;
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo1-host-key-file'} = testRunGet()->basePath() . HOST_CLIENT_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
if ($iRepoTotal == 2)
|
if ($iRepoTotal == 2)
|
||||||
{
|
{
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host'} = $oHostBackup->nameGet();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host'} = $oHostBackup->nameGet();
|
||||||
|
$oParam->{bTls} ? $oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-type'} = 'tls' : undef;
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-user'} = $oHostBackup->userGet();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-user'} = $oHostBackup->userGet();
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-cmd'} = $oHostBackup->backrestExe();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-cmd'} = $oHostBackup->backrestExe();
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-config'} = $oHostBackup->backrestConfig();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-config'} = $oHostBackup->backrestConfig();
|
||||||
|
|
||||||
|
if ($oParam->{bTls})
|
||||||
|
{
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-type'} = 'tls';
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-cert-file'} = testRunGet()->basePath() . HOST_CLIENT_CERT;
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'repo2-host-key-file'} = testRunGet()->basePath() . HOST_CLIENT_KEY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'log-path'} = $self->logPath();
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'log-path'} = $self->logPath();
|
||||||
|
@ -44,6 +44,21 @@ use constant HOST_AZURE => 'azure';
|
|||||||
use constant HOST_S3 => 's3-server';
|
use constant HOST_S3 => 's3-server';
|
||||||
push @EXPORT, qw(HOST_S3);
|
push @EXPORT, qw(HOST_S3);
|
||||||
|
|
||||||
|
####################################################################################################################################
|
||||||
|
# CA/cert/key constants
|
||||||
|
####################################################################################################################################
|
||||||
|
use constant HOST_CERT_PATH => '/test/certificate/';
|
||||||
|
|
||||||
|
use constant HOST_CLIENT_CERT => HOST_CERT_PATH . 'pgbackrest-test-client.crt';
|
||||||
|
push @EXPORT, qw(HOST_CLIENT_CERT);
|
||||||
|
use constant HOST_CLIENT_KEY => HOST_CERT_PATH . 'pgbackrest-test-client.key';
|
||||||
|
push @EXPORT, qw(HOST_CLIENT_KEY);
|
||||||
|
|
||||||
|
use constant HOST_SERVER_CA => HOST_CERT_PATH . 'pgbackrest-test-ca.crt';
|
||||||
|
push @EXPORT, qw(HOST_SERVER_CA);
|
||||||
|
use constant HOST_SERVER_CERT => HOST_CERT_PATH . 'pgbackrest-test-server.crt';
|
||||||
|
use constant HOST_SERVER_KEY => HOST_CERT_PATH . 'pgbackrest-test-server.key';
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
# new
|
# new
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
@ -68,6 +83,12 @@ sub new
|
|||||||
my $strTestPath = testRunGet()->testPath() . ($strName eq HOST_BASE ? '' : "/${strName}");
|
my $strTestPath = testRunGet()->testPath() . ($strName eq HOST_BASE ? '' : "/${strName}");
|
||||||
storageTest()->pathCreate($strTestPath, {strMode => '0770'});
|
storageTest()->pathCreate($strTestPath, {strMode => '0770'});
|
||||||
|
|
||||||
|
# Make sure keys have the correct permissions
|
||||||
|
if (chmod(0600, testRunGet()->basePath() . HOST_SERVER_KEY, testRunGet()->basePath() . HOST_CLIENT_KEY) != 2)
|
||||||
|
{
|
||||||
|
confess "unable to set mode on keys";
|
||||||
|
}
|
||||||
|
|
||||||
# Create the host
|
# Create the host
|
||||||
my $strProjectPath = dirname(dirname(abs_path($0)));
|
my $strProjectPath = dirname(dirname(abs_path($0)));
|
||||||
my $strBinPath = dirname(dirname($strTestPath)) . '/bin/' . testRunGet()->vm() . '/' . PROJECT_EXE;
|
my $strBinPath = dirname(dirname($strTestPath)) . '/bin/' . testRunGet()->vm() . '/' . PROJECT_EXE;
|
||||||
@ -75,7 +96,13 @@ sub new
|
|||||||
|
|
||||||
my $self = $class->SUPER::new(
|
my $self = $class->SUPER::new(
|
||||||
$strName, $strContainer, $$oParam{strImage}, $$oParam{strUser}, testRunGet()->vm(),
|
$strName, $strContainer, $$oParam{strImage}, $$oParam{strUser}, testRunGet()->vm(),
|
||||||
["${strProjectPath}:${strProjectPath}", "${strTestPath}:${strTestPath}", "${strBinPath}:${strBinPath}:ro"]);
|
["${strProjectPath}:${strProjectPath}", "${strTestPath}:${strTestPath}", "${strBinPath}:${strBinPath}:ro"], undef,
|
||||||
|
$oParam->{bTls} ?
|
||||||
|
'server-start --log-level-console=debug --tls-server-ca-file=' . testRunGet()->basePath() . HOST_SERVER_CA .
|
||||||
|
' --tls-server-cert-file=' . testRunGet()->basePath() . HOST_SERVER_CERT . ' --tls-server-key-file=' .
|
||||||
|
testRunGet()->basePath() . HOST_SERVER_KEY . ' --tls-server-auth=pgbackrest-client=* --tls-server-address=0.0.0.0' :
|
||||||
|
undef,
|
||||||
|
undef, $oParam->{bTls} ? testRunGet()->backrestExe() : undef);
|
||||||
bless $self, $class;
|
bless $self, $class;
|
||||||
|
|
||||||
# Set test path
|
# Set test path
|
||||||
|
@ -73,6 +73,7 @@ sub new
|
|||||||
{
|
{
|
||||||
strName => $bStandby ? HOST_DB_STANDBY : HOST_DB_PRIMARY,
|
strName => $bStandby ? HOST_DB_STANDBY : HOST_DB_PRIMARY,
|
||||||
strImage => $$oParam{strImage},
|
strImage => $$oParam{strImage},
|
||||||
|
bTls => $oParam->{bTls},
|
||||||
strBackupDestination => $$oParam{strBackupDestination},
|
strBackupDestination => $$oParam{strBackupDestination},
|
||||||
oLogTest => $$oParam{oLogTest},
|
oLogTest => $$oParam{oLogTest},
|
||||||
bSynthetic => $$oParam{bSynthetic},
|
bSynthetic => $$oParam{bSynthetic},
|
||||||
|
@ -55,6 +55,7 @@ sub new
|
|||||||
my $self = $class->SUPER::new(
|
my $self = $class->SUPER::new(
|
||||||
{
|
{
|
||||||
strImage => containerRepo() . ':' . testRunGet()->vm() . "-test",
|
strImage => containerRepo() . ':' . testRunGet()->vm() . "-test",
|
||||||
|
bTls => $oParam->{bTls},
|
||||||
strBackupDestination => $$oParam{strBackupDestination},
|
strBackupDestination => $$oParam{strBackupDestination},
|
||||||
oLogTest => $$oParam{oLogTest},
|
oLogTest => $$oParam{oLogTest},
|
||||||
bSynthetic => true,
|
bSynthetic => true,
|
||||||
|
@ -62,6 +62,7 @@ sub new
|
|||||||
my $self = $class->SUPER::new(
|
my $self = $class->SUPER::new(
|
||||||
{
|
{
|
||||||
strImage => containerRepo() . ':' . testRunGet()->vm() . "-test",
|
strImage => containerRepo() . ':' . testRunGet()->vm() . "-test",
|
||||||
|
bTls => $oParam->{bTls},
|
||||||
strBackupDestination => $$oParam{strBackupDestination},
|
strBackupDestination => $$oParam{strBackupDestination},
|
||||||
oLogTest => $$oParam{oLogTest},
|
oLogTest => $$oParam{oLogTest},
|
||||||
bStandby => $$oParam{bStandby},
|
bStandby => $$oParam{bStandby},
|
||||||
|
@ -88,7 +88,7 @@ sub setup
|
|||||||
|
|
||||||
$oHostBackup = new pgBackRestTest::Env::Host::HostBackupTest(
|
$oHostBackup = new pgBackRestTest::Env::Host::HostBackupTest(
|
||||||
{strBackupDestination => $strBackupDestination, bSynthetic => $bSynthetic, oLogTest => $oLogTest,
|
{strBackupDestination => $strBackupDestination, bSynthetic => $bSynthetic, oLogTest => $oLogTest,
|
||||||
bRepoLocal => $oConfigParam->{strStorage} eq POSIX, bRepoEncrypt => $bRepoEncrypt});
|
bRepoLocal => $oConfigParam->{strStorage} eq POSIX, bRepoEncrypt => $bRepoEncrypt, bTls => $oConfigParam->{bTls}});
|
||||||
$oHostGroup->hostAdd($oHostBackup);
|
$oHostGroup->hostAdd($oHostBackup);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -104,13 +104,13 @@ sub setup
|
|||||||
{
|
{
|
||||||
$oHostDbPrimary = new pgBackRestTest::Env::Host::HostDbSyntheticTest(
|
$oHostDbPrimary = new pgBackRestTest::Env::Host::HostDbSyntheticTest(
|
||||||
{strBackupDestination => $strBackupDestination, oLogTest => $oLogTest,
|
{strBackupDestination => $strBackupDestination, oLogTest => $oLogTest,
|
||||||
bRepoLocal => $oConfigParam->{strStorage} eq POSIX, bRepoEncrypt => $bRepoEncrypt});
|
bRepoLocal => $oConfigParam->{strStorage} eq POSIX, bRepoEncrypt => $bRepoEncrypt, bTls => $oConfigParam->{bTls}});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$oHostDbPrimary = new pgBackRestTest::Env::Host::HostDbTest(
|
$oHostDbPrimary = new pgBackRestTest::Env::Host::HostDbTest(
|
||||||
{strBackupDestination => $strBackupDestination, oLogTest => $oLogTest, bRepoLocal =>
|
{strBackupDestination => $strBackupDestination, oLogTest => $oLogTest, bRepoLocal =>
|
||||||
$oConfigParam->{strStorage} eq POSIX, bRepoEncrypt => $bRepoEncrypt});
|
$oConfigParam->{strStorage} eq POSIX, bRepoEncrypt => $bRepoEncrypt, bTls => $oConfigParam->{bTls}});
|
||||||
}
|
}
|
||||||
|
|
||||||
$oHostGroup->hostAdd($oHostDbPrimary);
|
$oHostGroup->hostAdd($oHostDbPrimary);
|
||||||
@ -122,7 +122,7 @@ sub setup
|
|||||||
{
|
{
|
||||||
$oHostDbStandby = new pgBackRestTest::Env::Host::HostDbTest(
|
$oHostDbStandby = new pgBackRestTest::Env::Host::HostDbTest(
|
||||||
{strBackupDestination => $strBackupDestination, bStandby => true, oLogTest => $oLogTest,
|
{strBackupDestination => $strBackupDestination, bStandby => true, oLogTest => $oLogTest,
|
||||||
bRepoLocal => $oConfigParam->{strStorage} eq POSIX});
|
bRepoLocal => $oConfigParam->{strStorage} eq POSIX, bTls => $oConfigParam->{bTls}});
|
||||||
|
|
||||||
$oHostGroup->hostAdd($oHostDbStandby);
|
$oHostGroup->hostAdd($oHostDbStandby);
|
||||||
}
|
}
|
||||||
@ -140,6 +140,7 @@ sub setup
|
|||||||
|
|
||||||
# Create db-primary config
|
# Create db-primary config
|
||||||
$oHostDbPrimary->configCreate({
|
$oHostDbPrimary->configCreate({
|
||||||
|
bTls => $oConfigParam->{bTls},
|
||||||
strBackupSource => $$oConfigParam{strBackupSource},
|
strBackupSource => $$oConfigParam{strBackupSource},
|
||||||
strCompressType => $$oConfigParam{strCompressType},
|
strCompressType => $$oConfigParam{strCompressType},
|
||||||
bHardlink => $bHostBackup ? undef : $$oConfigParam{bHardLink},
|
bHardlink => $bHostBackup ? undef : $$oConfigParam{bHardLink},
|
||||||
@ -151,6 +152,7 @@ sub setup
|
|||||||
if (defined($oHostBackup))
|
if (defined($oHostBackup))
|
||||||
{
|
{
|
||||||
$oHostBackup->configCreate({
|
$oHostBackup->configCreate({
|
||||||
|
bTls => $oConfigParam->{bTls},
|
||||||
strCompressType => $$oConfigParam{strCompressType},
|
strCompressType => $$oConfigParam{strCompressType},
|
||||||
bHardlink => $$oConfigParam{bHardLink},
|
bHardlink => $$oConfigParam{bHardLink},
|
||||||
strStorage => $oConfigParam->{strStorage},
|
strStorage => $oConfigParam->{strStorage},
|
||||||
@ -176,6 +178,7 @@ sub setup
|
|||||||
if (defined($oHostDbStandby))
|
if (defined($oHostDbStandby))
|
||||||
{
|
{
|
||||||
$oHostDbStandby->configCreate({
|
$oHostDbStandby->configCreate({
|
||||||
|
bTls => $oConfigParam->{bTls},
|
||||||
strBackupSource => $$oConfigParam{strBackupSource},
|
strBackupSource => $$oConfigParam{strBackupSource},
|
||||||
strCompressType => $$oConfigParam{strCompressType},
|
strCompressType => $$oConfigParam{strCompressType},
|
||||||
bHardlink => $bHostBackup ? undef : $$oConfigParam{bHardLink},
|
bHardlink => $bHostBackup ? undef : $$oConfigParam{bHardLink},
|
||||||
|
@ -205,12 +205,12 @@ sub run
|
|||||||
|
|
||||||
foreach my $rhRun
|
foreach my $rhRun
|
||||||
(
|
(
|
||||||
{vm => VM2, remote => false, storage => GCS, encrypt => false, delta => true, compress => BZ2},
|
{vm => VM2, remote => false, tls => false, storage => GCS, encrypt => false, delta => true, compress => BZ2},
|
||||||
{vm => VM2, remote => true, storage => AZURE, encrypt => true, delta => false, compress => GZ},
|
{vm => VM2, remote => true, tls => false, storage => AZURE, encrypt => true, delta => false, compress => GZ},
|
||||||
{vm => VM3, remote => false, storage => POSIX, encrypt => false, delta => true, compress => ZST},
|
{vm => VM3, remote => false, tls => false, storage => POSIX, encrypt => false, delta => true, compress => ZST},
|
||||||
{vm => VM3, remote => true, storage => S3, encrypt => true, delta => false, compress => LZ4},
|
{vm => VM3, remote => true, tls => true, storage => S3, encrypt => true, delta => false, compress => LZ4},
|
||||||
{vm => VM4, remote => false, storage => GCS, encrypt => false, delta => false, compress => GZ},
|
{vm => VM4, remote => false, tls => false, storage => GCS, encrypt => false, delta => false, compress => GZ},
|
||||||
{vm => VM4, remote => true, storage => S3, encrypt => true, delta => true, compress => ZST},
|
{vm => VM4, remote => true, tls => true, storage => S3, encrypt => true, delta => true, compress => ZST},
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
# Only run tests for this vm
|
# Only run tests for this vm
|
||||||
@ -218,18 +218,20 @@ sub run
|
|||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
my $bRemote = $rhRun->{remote};
|
my $bRemote = $rhRun->{remote};
|
||||||
|
my $bTls = $rhRun->{tls};
|
||||||
my $strStorage = $rhRun->{storage};
|
my $strStorage = $rhRun->{storage};
|
||||||
my $bEncrypt = $rhRun->{encrypt};
|
my $bEncrypt = $rhRun->{encrypt};
|
||||||
my $bDeltaBackup = $rhRun->{delta};
|
my $bDeltaBackup = $rhRun->{delta};
|
||||||
my $strCompressType = $rhRun->{compress};
|
my $strCompressType = $rhRun->{compress};
|
||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
if (!$self->begin("rmt ${bRemote}, storage ${strStorage}, enc ${bEncrypt}, delta ${bDeltaBackup}")) {next}
|
if (!$self->begin("rmt ${bRemote}, tls ${bTls}, storage ${strStorage}, enc ${bEncrypt}, delta ${bDeltaBackup}")) {next}
|
||||||
|
|
||||||
# Create hosts, file object, and config
|
# Create hosts, file object, and config
|
||||||
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
||||||
true, $self->expect(), {bHostBackup => $bRemote, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
true, $self->expect(),
|
||||||
strCompressType => NONE});
|
{bHostBackup => $bRemote, bTls => $bTls, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
||||||
|
strCompressType => NONE});
|
||||||
|
|
||||||
# If S3 set process max to 2. This seems like the best place for parallel testing since it will help speed S3 processing
|
# If S3 set process max to 2. This seems like the best place for parallel testing since it will help speed S3 processing
|
||||||
# without slowing down the other tests too much.
|
# without slowing down the other tests too much.
|
||||||
|
@ -43,12 +43,12 @@ sub run
|
|||||||
|
|
||||||
foreach my $rhRun
|
foreach my $rhRun
|
||||||
(
|
(
|
||||||
{vm => VM2, remote => false, storage => S3, encrypt => false, compress => NONE, error => 0},
|
{vm => VM2, remote => false, tls => false, storage => S3, encrypt => false, compress => NONE, error => 0},
|
||||||
{vm => VM2, remote => true, storage => POSIX, encrypt => true, compress => NONE, error => 0},
|
{vm => VM2, remote => true, tls => true, storage => POSIX, encrypt => true, compress => NONE, error => 0},
|
||||||
{vm => VM3, remote => false, storage => GCS, encrypt => true, compress => BZ2, error => 0},
|
{vm => VM3, remote => false, tls => false, storage => GCS, encrypt => true, compress => BZ2, error => 0},
|
||||||
{vm => VM3, remote => true, storage => AZURE, encrypt => false, compress => LZ4, error => 1},
|
{vm => VM3, remote => true, tls => false, storage => AZURE, encrypt => false, compress => LZ4, error => 1},
|
||||||
{vm => VM4, remote => false, storage => S3, encrypt => true, compress => NONE, error => 0},
|
{vm => VM4, remote => false, tls => false, storage => S3, encrypt => true, compress => NONE, error => 0},
|
||||||
{vm => VM4, remote => true, storage => GCS, encrypt => false, compress => ZST, error => 0},
|
{vm => VM4, remote => true, tls => true, storage => GCS, encrypt => false, compress => ZST, error => 0},
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
# Only run tests for this vm
|
# Only run tests for this vm
|
||||||
@ -56,6 +56,7 @@ sub run
|
|||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
my $bRemote = $rhRun->{remote};
|
my $bRemote = $rhRun->{remote};
|
||||||
|
my $bTls = $rhRun->{tls};
|
||||||
my $strStorage = $rhRun->{storage};
|
my $strStorage = $rhRun->{storage};
|
||||||
my $bEncrypt = $rhRun->{encrypt};
|
my $bEncrypt = $rhRun->{encrypt};
|
||||||
my $strCompressType = $rhRun->{compress};
|
my $strCompressType = $rhRun->{compress};
|
||||||
@ -63,13 +64,14 @@ sub run
|
|||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
if (!$self->begin(
|
if (!$self->begin(
|
||||||
"rmt ${bRemote}, cmp ${strCompressType}, error " . ($iError ? 'connect' : 'version') .
|
"rmt ${bRemote}, tls ${bTls}, cmp ${strCompressType}, error " . ($iError ? 'connect' : 'version') .
|
||||||
", storage ${strStorage}, enc ${bEncrypt}")) {next}
|
", storage ${strStorage}, enc ${bEncrypt}")) {next}
|
||||||
|
|
||||||
# Create hosts, file object, and config
|
# Create hosts, file object, and config
|
||||||
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
||||||
true, $self->expect(), {bHostBackup => $bRemote, strCompressType => $strCompressType, bArchiveAsync => true,
|
true, $self->expect(),
|
||||||
strStorage => $strStorage, bRepoEncrypt => $bEncrypt});
|
{bHostBackup => $bRemote, bTls => $bTls, strCompressType => $strCompressType, bArchiveAsync => true,
|
||||||
|
strStorage => $strStorage, bRepoEncrypt => $bEncrypt});
|
||||||
|
|
||||||
# Create compression extension
|
# Create compression extension
|
||||||
my $strCompressExt = $strCompressType ne NONE ? ".${strCompressType}" : '';
|
my $strCompressExt = $strCompressType ne NONE ? ".${strCompressType}" : '';
|
||||||
|
@ -83,12 +83,12 @@ sub run
|
|||||||
|
|
||||||
foreach my $rhRun
|
foreach my $rhRun
|
||||||
(
|
(
|
||||||
{vm => VM2, remote => false, storage => S3, encrypt => true, compress => BZ2},
|
{vm => VM2, remote => false, tls => false, storage => S3, encrypt => true, compress => BZ2},
|
||||||
{vm => VM2, remote => true, storage => POSIX, encrypt => true, compress => BZ2},
|
{vm => VM2, remote => true, tls => false, storage => POSIX, encrypt => true, compress => BZ2},
|
||||||
{vm => VM3, remote => false, storage => POSIX, encrypt => true, compress => LZ4},
|
{vm => VM3, remote => false, tls => false, storage => POSIX, encrypt => true, compress => LZ4},
|
||||||
{vm => VM3, remote => true, storage => S3, encrypt => false, compress => ZST},
|
{vm => VM3, remote => true, tls => true, storage => S3, encrypt => false, compress => ZST},
|
||||||
{vm => VM4, remote => false, storage => AZURE, encrypt => true, compress => ZST},
|
{vm => VM4, remote => false, tls => false, storage => AZURE, encrypt => true, compress => ZST},
|
||||||
{vm => VM4, remote => true, storage => POSIX, encrypt => false, compress => GZ},
|
{vm => VM4, remote => true, tls => true, storage => POSIX, encrypt => false, compress => GZ},
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
# Only run tests for this vm
|
# Only run tests for this vm
|
||||||
@ -96,16 +96,18 @@ sub run
|
|||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
my $bRemote = $rhRun->{remote};
|
my $bRemote = $rhRun->{remote};
|
||||||
|
my $bTls = $rhRun->{tls};
|
||||||
my $strStorage = $rhRun->{storage};
|
my $strStorage = $rhRun->{storage};
|
||||||
my $bEncrypt = $rhRun->{encrypt};
|
my $bEncrypt = $rhRun->{encrypt};
|
||||||
my $strCompressType = $rhRun->{compress};
|
my $strCompressType = $rhRun->{compress};
|
||||||
|
|
||||||
if (!$self->begin("rmt ${bRemote}, storage ${strStorage}, enc ${bEncrypt}, cmp ${strCompressType}")) {next}
|
if (!$self->begin("rmt ${bRemote}, tls ${bTls}, storage ${strStorage}, enc ${bEncrypt}, cmp ${strCompressType}")) {next}
|
||||||
|
|
||||||
# Create hosts, file object, and config
|
# Create hosts, file object, and config
|
||||||
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
||||||
true, $self->expect(), {bHostBackup => $bRemote, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
true, $self->expect(),
|
||||||
strCompressType => NONE});
|
{bHostBackup => $bRemote, bTls => $bTls, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
||||||
|
strCompressType => NONE});
|
||||||
|
|
||||||
# Reduce console logging to detail
|
# Reduce console logging to detail
|
||||||
$oHostDbPrimary->configUpdate({&CFGDEF_SECTION_GLOBAL => {'log-level-console' => lc(DETAIL)}});
|
$oHostDbPrimary->configUpdate({&CFGDEF_SECTION_GLOBAL => {'log-level-console' => lc(DETAIL)}});
|
||||||
|
@ -41,12 +41,12 @@ sub run
|
|||||||
|
|
||||||
foreach my $rhRun
|
foreach my $rhRun
|
||||||
(
|
(
|
||||||
{vm => VM2, remote => false, storage => AZURE, encrypt => true, compress => BZ2},
|
{vm => VM2, remote => false, tls => false, storage => AZURE, encrypt => true, compress => BZ2},
|
||||||
{vm => VM2, remote => true, storage => POSIX, encrypt => false, compress => GZ},
|
{vm => VM2, remote => true, tls => true, storage => POSIX, encrypt => false, compress => GZ},
|
||||||
{vm => VM3, remote => false, storage => GCS, encrypt => false, compress => ZST},
|
{vm => VM3, remote => false, tls => false, storage => GCS, encrypt => false, compress => ZST},
|
||||||
{vm => VM3, remote => true, storage => AZURE, encrypt => true, compress => LZ4},
|
{vm => VM3, remote => true, tls => true, storage => AZURE, encrypt => true, compress => LZ4},
|
||||||
{vm => VM4, remote => false, storage => S3, encrypt => false, compress => GZ},
|
{vm => VM4, remote => false, tls => false, storage => S3, encrypt => false, compress => GZ},
|
||||||
{vm => VM4, remote => true, storage => GCS, encrypt => true, compress => ZST},
|
{vm => VM4, remote => true, tls => false, storage => GCS, encrypt => true, compress => ZST},
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
# Only run tests for this vm
|
# Only run tests for this vm
|
||||||
@ -54,17 +54,19 @@ sub run
|
|||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
my $bRemote = $rhRun->{remote};
|
my $bRemote = $rhRun->{remote};
|
||||||
|
my $bTls = $rhRun->{tls};
|
||||||
my $strStorage = $rhRun->{storage};
|
my $strStorage = $rhRun->{storage};
|
||||||
my $bEncrypt = $rhRun->{encrypt};
|
my $bEncrypt = $rhRun->{encrypt};
|
||||||
my $strCompressType = $rhRun->{compress};
|
my $strCompressType = $rhRun->{compress};
|
||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
if (!$self->begin("remote ${bRemote}, storage ${strStorage}, enc ${bEncrypt}, cmp ${strCompressType}")) {next}
|
if (!$self->begin("remote ${bRemote}, tls ${bTls}, storage ${strStorage}, enc ${bEncrypt}, cmp ${strCompressType}")) {next}
|
||||||
|
|
||||||
# Create hosts, file object, and config
|
# Create hosts, file object, and config
|
||||||
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
||||||
true, $self->expect(), {bHostBackup => $bRemote, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
true, $self->expect(),
|
||||||
strCompressType => $strCompressType});
|
{bHostBackup => $bRemote, bTls => $bTls, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
||||||
|
strCompressType => $strCompressType});
|
||||||
|
|
||||||
# Archive and backup info file names
|
# Archive and backup info file names
|
||||||
my $strArchiveInfoFile = $oHostBackup->repoArchivePath(ARCHIVE_INFO_FILE);
|
my $strArchiveInfoFile = $oHostBackup->repoArchivePath(ARCHIVE_INFO_FILE);
|
||||||
|
@ -52,20 +52,20 @@ sub run
|
|||||||
|
|
||||||
foreach my $rhRun
|
foreach my $rhRun
|
||||||
(
|
(
|
||||||
{pg => PG_VERSION_83, repoDest => HOST_DB_PRIMARY, storage => POSIX, encrypt => false, compress => NONE, repo => 2},
|
{pg => PG_VERSION_83, repoDest => HOST_DB_PRIMARY, tls => 0, storage => POSIX, encrypt => 0, compress => NONE, repo => 2},
|
||||||
{pg => PG_VERSION_84, repoDest => HOST_BACKUP, storage => AZURE, encrypt => true, compress => GZ, repo => 1},
|
{pg => PG_VERSION_84, repoDest => HOST_BACKUP, tls => 1, storage => AZURE, encrypt => 1, compress => GZ, repo => 1},
|
||||||
{pg => PG_VERSION_90, repoDest => HOST_DB_PRIMARY, storage => GCS, encrypt => true, compress => BZ2, repo => 2},
|
{pg => PG_VERSION_90, repoDest => HOST_DB_PRIMARY, tls => 0, storage => GCS, encrypt => 1, compress => BZ2, repo => 2},
|
||||||
{pg => PG_VERSION_91, repoDest => HOST_DB_STANDBY, storage => GCS, encrypt => false, compress => GZ, repo => 1},
|
{pg => PG_VERSION_91, repoDest => HOST_DB_STANDBY, tls => 1, storage => GCS, encrypt => 0, compress => GZ, repo => 1},
|
||||||
{pg => PG_VERSION_92, repoDest => HOST_DB_STANDBY, storage => POSIX, encrypt => true, compress => NONE, repo => 1},
|
{pg => PG_VERSION_92, repoDest => HOST_DB_STANDBY, tls => 0, storage => POSIX, encrypt => 1, compress => NONE, repo => 1},
|
||||||
{pg => PG_VERSION_93, repoDest => HOST_BACKUP, storage => AZURE, encrypt => false, compress => NONE, repo => 2},
|
{pg => PG_VERSION_93, repoDest => HOST_BACKUP, tls => 0, storage => AZURE, encrypt => 0, compress => NONE, repo => 2},
|
||||||
{pg => PG_VERSION_94, repoDest => HOST_DB_STANDBY, storage => POSIX, encrypt => true, compress => LZ4, repo => 1},
|
{pg => PG_VERSION_94, repoDest => HOST_DB_STANDBY, tls => 0, storage => POSIX, encrypt => 1, compress => LZ4, repo => 1},
|
||||||
{pg => PG_VERSION_95, repoDest => HOST_BACKUP, storage => S3, encrypt => false, compress => BZ2, repo => 1},
|
{pg => PG_VERSION_95, repoDest => HOST_BACKUP, tls => 1, storage => S3, encrypt => 0, compress => BZ2, repo => 1},
|
||||||
{pg => PG_VERSION_96, repoDest => HOST_BACKUP, storage => POSIX, encrypt => false, compress => NONE, repo => 2},
|
{pg => PG_VERSION_96, repoDest => HOST_BACKUP, tls => 0, storage => POSIX, encrypt => 0, compress => NONE, repo => 2},
|
||||||
{pg => PG_VERSION_10, repoDest => HOST_DB_STANDBY, storage => S3, encrypt => true, compress => GZ, repo => 2},
|
{pg => PG_VERSION_10, repoDest => HOST_DB_STANDBY, tls => 1, storage => S3, encrypt => 1, compress => GZ, repo => 2},
|
||||||
{pg => PG_VERSION_11, repoDest => HOST_BACKUP, storage => AZURE, encrypt => false, compress => ZST, repo => 2},
|
{pg => PG_VERSION_11, repoDest => HOST_BACKUP, tls => 1, storage => AZURE, encrypt => 0, compress => ZST, repo => 2},
|
||||||
{pg => PG_VERSION_12, repoDest => HOST_BACKUP, storage => S3, encrypt => true, compress => LZ4, repo => 1},
|
{pg => PG_VERSION_12, repoDest => HOST_BACKUP, tls => 0, storage => S3, encrypt => 1, compress => LZ4, repo => 1},
|
||||||
{pg => PG_VERSION_13, repoDest => HOST_DB_STANDBY, storage => GCS, encrypt => false, compress => ZST, repo => 1},
|
{pg => PG_VERSION_13, repoDest => HOST_DB_STANDBY, tls => 1, storage => GCS, encrypt => 0, compress => ZST, repo => 1},
|
||||||
{pg => PG_VERSION_14, repoDest => HOST_BACKUP, storage => POSIX, encrypt => true, compress => LZ4, repo => 2},
|
{pg => PG_VERSION_14, repoDest => HOST_BACKUP, tls => 0, storage => POSIX, encrypt => 1, compress => LZ4, repo => 2},
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
# Only run tests for this pg version
|
# Only run tests for this pg version
|
||||||
@ -74,6 +74,7 @@ sub run
|
|||||||
# Get run parameters
|
# Get run parameters
|
||||||
my $bHostBackup = $rhRun->{repoDest} eq HOST_BACKUP ? true : false;
|
my $bHostBackup = $rhRun->{repoDest} eq HOST_BACKUP ? true : false;
|
||||||
my $bHostStandby = $self->pgVersion() >= PG_VERSION_HOT_STANDBY ? true : false;
|
my $bHostStandby = $self->pgVersion() >= PG_VERSION_HOT_STANDBY ? true : false;
|
||||||
|
my $bTls = $rhRun->{tls};
|
||||||
my $strBackupDestination = $rhRun->{repoDest};
|
my $strBackupDestination = $rhRun->{repoDest};
|
||||||
my $strStorage = $rhRun->{storage};
|
my $strStorage = $rhRun->{storage};
|
||||||
my $bRepoEncrypt = $rhRun->{encrypt};
|
my $bRepoEncrypt = $rhRun->{encrypt};
|
||||||
@ -86,21 +87,23 @@ sub run
|
|||||||
|
|
||||||
# Increment the run, log, and decide whether this unit test should be run
|
# Increment the run, log, and decide whether this unit test should be run
|
||||||
next if (!$self->begin(
|
next if (!$self->begin(
|
||||||
"bkp ${bHostBackup}, sby ${bHostStandby}, dst ${strBackupDestination}, cmp ${strCompressType}" .
|
"bkp ${bHostBackup}, sby ${bHostStandby}, tls ${bTls}, dst ${strBackupDestination}, cmp ${strCompressType}" .
|
||||||
", storage ${strStorage}, enc ${bRepoEncrypt}",
|
", storage ${strStorage}, enc ${bRepoEncrypt}",
|
||||||
$bExpectVersion));
|
$bExpectVersion));
|
||||||
|
|
||||||
# Create hosts, file object, and config
|
# Create hosts, file object, and config
|
||||||
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
||||||
false, $self->expect(),
|
false, $self->expect(),
|
||||||
{bHostBackup => $bHostBackup, bStandby => $bHostStandby, strBackupDestination => $strBackupDestination,
|
{bHostBackup => $bHostBackup, bStandby => $bHostStandby, bTls => $bTls, strBackupDestination => $strBackupDestination,
|
||||||
strCompressType => $strCompressType, bArchiveAsync => false, strStorage => $strStorage,
|
strCompressType => $strCompressType, bArchiveAsync => false, strStorage => $strStorage,
|
||||||
bRepoEncrypt => $bRepoEncrypt, iRepoTotal => $iRepoTotal});
|
bRepoEncrypt => $bRepoEncrypt, iRepoTotal => $iRepoTotal});
|
||||||
|
|
||||||
# Some commands will fail because of the bogus host created when a standby is present. These options reset the bogus host
|
# Some commands will fail because of the bogus host created when a standby is present. These options reset the bogus host
|
||||||
# so it won't interfere with commands that won't tolerate a connection failure.
|
# so it won't interfere with commands that won't tolerate a connection failure.
|
||||||
my $strBogusReset = $oHostBackup->bogusHost() ?
|
my $strBogusReset = $oHostBackup->bogusHost() ?
|
||||||
' --reset-pg2-host --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user --reset-pg2-path' : '';
|
' --reset-pg2-host --reset-pg2-host-type --reset-pg2-host-cmd --reset-pg2-host-config --reset-pg2-host-user' .
|
||||||
|
' --reset-pg2-path' :
|
||||||
|
'';
|
||||||
|
|
||||||
# If S3 set process max to 2. This seems like the best place for parallel testing since it will help speed S3 processing
|
# If S3 set process max to 2. This seems like the best place for parallel testing since it will help speed S3 processing
|
||||||
# without slowing down the other tests too much.
|
# without slowing down the other tests too much.
|
||||||
@ -282,7 +285,7 @@ sub run
|
|||||||
# Update message for standby
|
# Update message for standby
|
||||||
$oHostDbPrimary->sqlExecute("update test set message = '$strStandbyMessage'");
|
$oHostDbPrimary->sqlExecute("update test set message = '$strStandbyMessage'");
|
||||||
|
|
||||||
if ($oHostDbStandby->pgVersion() >= PG_VERSION_BACKUP_STANDBY)
|
if ($oHostDbStandby->pgVersion() >= PG_VERSION_BACKUP_STANDBY && !$bTls)
|
||||||
{
|
{
|
||||||
# If there is only a primary and a replica and the replica is the backup destination, then if pg2-host and
|
# If there is only a primary and a replica and the replica is the backup destination, then if pg2-host and
|
||||||
# pg256-host are BOGUS, confirm failure to reach the primary
|
# pg256-host are BOGUS, confirm failure to reach the primary
|
||||||
|
@ -152,6 +152,9 @@ protocolLocalExec(
|
|||||||
ioFdReadNewOpen(strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol read", processId), pipeRead[0], 5000),
|
ioFdReadNewOpen(strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol read", processId), pipeRead[0], 5000),
|
||||||
ioFdWriteNewOpen(strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol write", processId), pipeWrite[1], 5000));
|
ioFdWriteNewOpen(strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u shim protocol write", processId), pipeWrite[1], 5000));
|
||||||
|
|
||||||
|
// Send one noop to catch any errors that might happen after the greeting
|
||||||
|
protocolClientNoOp(helper->client);
|
||||||
|
|
||||||
FUNCTION_LOG_RETURN_VOID();
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
// Else call the base function
|
// Else call the base function
|
||||||
@ -248,6 +251,9 @@ protocolRemoteExec(
|
|||||||
ioFdReadNewOpen(strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u shim protocol read", processId), pipeRead[0], 5000),
|
ioFdReadNewOpen(strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u shim protocol read", processId), pipeRead[0], 5000),
|
||||||
ioFdWriteNewOpen(strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u shim protocol write", processId), pipeWrite[1], 5000));
|
ioFdWriteNewOpen(strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u shim protocol write", processId), pipeWrite[1], 5000));
|
||||||
|
|
||||||
|
// Send one noop to catch any errors that might happen after the greeting
|
||||||
|
protocolClientNoOp(helper->client);
|
||||||
|
|
||||||
FUNCTION_LOG_RETURN_VOID();
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
// Else call the base function
|
// Else call the base function
|
||||||
|
@ -14,8 +14,8 @@ Server Test Harness
|
|||||||
|
|
||||||
#include "common/crypto/common.h"
|
#include "common/crypto/common.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/io/socket/common.h"
|
#include "common/io/socket/server.h"
|
||||||
#include "common/io/socket/session.h"
|
#include "common/io/tls/server.h"
|
||||||
#include "common/io/tls/session.h"
|
#include "common/io/tls/session.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/type/buffer.h"
|
#include "common/type/buffer.h"
|
||||||
@ -45,6 +45,29 @@ Constants
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#define HRN_SERVER_HOST "tls.test.pgbackrest.org"
|
#define HRN_SERVER_HOST "tls.test.pgbackrest.org"
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
void hrnServerInit(void)
|
||||||
|
{
|
||||||
|
FUNCTION_HARNESS_VOID();
|
||||||
|
|
||||||
|
// Set correct permissions on private keys
|
||||||
|
THROW_ON_SYS_ERROR(
|
||||||
|
chmod(strZ(strNewFmt("%s/" HRN_SERVER_CERT_PREFIX "server.key", hrnPathRepo())), 0600) == -1, FileModeError,
|
||||||
|
"unable to set mode on server key");
|
||||||
|
THROW_ON_SYS_ERROR(
|
||||||
|
chmod(strZ(strNewFmt("%s/" HRN_SERVER_CERT_PREFIX "client.key", hrnPathRepo())), 0600) == -1, FileModeError,
|
||||||
|
"unable to set mode on client key");
|
||||||
|
|
||||||
|
// Add hostname when running in a container
|
||||||
|
if (testContainer())
|
||||||
|
{
|
||||||
|
if (system("echo \"127.0.0.1 " HRN_SERVER_HOST "\" | sudo tee -a /etc/hosts > /dev/null") != 0)
|
||||||
|
THROW(AssertError, "unable to add test host to /etc/hosts");
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Send commands to the server
|
Send commands to the server
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -220,15 +243,8 @@ void hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam pa
|
|||||||
if (param.port == 0)
|
if (param.port == 0)
|
||||||
param.port = hrnServerPort(0);
|
param.port = hrnServerPort(0);
|
||||||
|
|
||||||
// Add test hosts
|
|
||||||
if (testContainer())
|
|
||||||
{
|
|
||||||
if (system("echo \"127.0.0.1 " HRN_SERVER_HOST "\" | sudo tee -a /etc/hosts > /dev/null") != 0)
|
|
||||||
THROW(AssertError, "unable to add test host to /etc/hosts");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize ssl and create a context
|
// Initialize ssl and create a context
|
||||||
SSL_CTX *serverContext = NULL;
|
IoServer *tlsServer = NULL;
|
||||||
|
|
||||||
if (protocol == hrnServerProtocolTls)
|
if (protocol == hrnServerProtocolTls)
|
||||||
{
|
{
|
||||||
@ -237,60 +253,14 @@ void hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam pa
|
|||||||
// If certificate and key are not set then use defaults
|
// If certificate and key are not set then use defaults
|
||||||
if (param.certificate == NULL)
|
if (param.certificate == NULL)
|
||||||
{
|
{
|
||||||
param.certificate = strNewFmt("%s/" HRN_SERVER_CERT_PREFIX ".crt", hrnPathRepo());
|
param.certificate = strNewFmt("%s/" HRN_SERVER_CERT_PREFIX "server.crt", hrnPathRepo());
|
||||||
param.key = strNewFmt("%s/" HRN_SERVER_CERT_PREFIX ".key", hrnPathRepo());
|
param.key = strNewFmt("%s/" HRN_SERVER_CERT_PREFIX "server.key", hrnPathRepo());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize TLS
|
tlsServer = tlsServerNew(STRDEF(HRN_SERVER_HOST), param.ca, param.key, param.certificate, 5000);
|
||||||
cryptoInit();
|
|
||||||
|
|
||||||
const SSL_METHOD *method = SSLv23_method();
|
|
||||||
cryptoError(method == NULL, "unable to load TLS method");
|
|
||||||
|
|
||||||
serverContext = SSL_CTX_new(method);
|
|
||||||
cryptoError(serverContext == NULL, "unable to create TLS context");
|
|
||||||
|
|
||||||
// Configure the context by setting key and cert
|
|
||||||
cryptoError(
|
|
||||||
SSL_CTX_use_certificate_file(serverContext, strZ(param.certificate), SSL_FILETYPE_PEM) <= 0,
|
|
||||||
"unable to load server certificate");
|
|
||||||
cryptoError(
|
|
||||||
SSL_CTX_use_PrivateKey_file(serverContext, strZ(param.key), SSL_FILETYPE_PEM) <= 0,
|
|
||||||
"unable to load server private key");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the socket
|
IoServer *socketServer = sckServerNew(STRDEF("localhost"), param.port, 5000);
|
||||||
int serverSocket;
|
|
||||||
|
|
||||||
struct sockaddr_in address;
|
|
||||||
|
|
||||||
address.sin_family = AF_INET;
|
|
||||||
address.sin_port = htons((uint16_t)param.port);
|
|
||||||
address.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
|
|
||||||
if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|
||||||
THROW_SYS_ERROR(AssertError, "unable to create socket");
|
|
||||||
|
|
||||||
// Set the address as reusable so we can bind again in the same process for testing
|
|
||||||
int reuseAddr = 1;
|
|
||||||
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr));
|
|
||||||
|
|
||||||
// Bind the address. It might take a bit to bind if another process was recently using it so retry a few times.
|
|
||||||
Wait *wait = waitNew(2000);
|
|
||||||
int result;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result = bind(serverSocket, (struct sockaddr *)&address, sizeof(address));
|
|
||||||
}
|
|
||||||
while (result < 0 && waitMore(wait));
|
|
||||||
|
|
||||||
if (result < 0)
|
|
||||||
THROW_SYS_ERROR(AssertError, "unable to bind socket");
|
|
||||||
|
|
||||||
// Listen for client connections
|
|
||||||
if (listen(serverSocket, 1) < 0)
|
|
||||||
THROW_SYS_ERROR(AssertError, "unable to listen on socket");
|
|
||||||
|
|
||||||
// Loop until no more commands
|
// Loop until no more commands
|
||||||
IoSession *serverSession = NULL;
|
IoSession *serverSession = NULL;
|
||||||
@ -316,25 +286,11 @@ void hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam pa
|
|||||||
|
|
||||||
case hrnServerCmdAccept:
|
case hrnServerCmdAccept:
|
||||||
{
|
{
|
||||||
// Accept the socket connection
|
serverSession = ioServerAccept(socketServer, NULL);
|
||||||
struct sockaddr_in addr;
|
|
||||||
unsigned int len = sizeof(addr);
|
|
||||||
|
|
||||||
int testClientSocket = accept(serverSocket, (struct sockaddr *)&addr, &len);
|
|
||||||
|
|
||||||
if (testClientSocket < 0)
|
|
||||||
THROW_SYS_ERROR(AssertError, "unable to accept socket");
|
|
||||||
|
|
||||||
// Create socket session
|
|
||||||
sckOptionSet(testClientSocket);
|
|
||||||
serverSession = sckSessionNew(ioSessionRoleServer, testClientSocket, STRDEF("localhost"), param.port, 5000);
|
|
||||||
|
|
||||||
// Start TLS if requested
|
// Start TLS if requested
|
||||||
if (protocol == hrnServerProtocolTls)
|
if (protocol == hrnServerProtocolTls)
|
||||||
{
|
serverSession = ioServerAccept(tlsServer, serverSession);
|
||||||
SSL *testClientSSL = SSL_new(serverContext);
|
|
||||||
serverSession = tlsSessionNew(testClientSSL, serverSession, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -402,9 +358,9 @@ void hrnServerRun(IoRead *read, HrnServerProtocol protocol, HrnServerRunParam pa
|
|||||||
}
|
}
|
||||||
while (!done);
|
while (!done);
|
||||||
|
|
||||||
// Free TLS context
|
// Free servers
|
||||||
if (protocol == hrnServerProtocolTls)
|
ioServerFree(tlsServer);
|
||||||
SSL_CTX_free(serverContext);
|
ioServerFree(socketServer);
|
||||||
|
|
||||||
FUNCTION_HARNESS_RETURN_VOID();
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ client using the hrnServerScript() functions.
|
|||||||
#ifndef TEST_COMMON_HARNESS_SERVER_H
|
#ifndef TEST_COMMON_HARNESS_SERVER_H
|
||||||
#define TEST_COMMON_HARNESS_SERVER_H
|
#define TEST_COMMON_HARNESS_SERVER_H
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "common/io/read.h"
|
#include "common/io/read.h"
|
||||||
#include "common/io/write.h"
|
#include "common/io/write.h"
|
||||||
|
|
||||||
@ -27,16 +29,25 @@ Maximum number of ports allowed for each test
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Path and prefix for test certificates
|
Path and prefix for test certificates
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#define HRN_SERVER_CERT_PREFIX "test/certificate/pgbackrest-test"
|
#define HRN_SERVER_CERT_PREFIX "test/certificate/pgbackrest-test-"
|
||||||
|
#define HRN_SERVER_CERT HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "server.crt"
|
||||||
|
#define HRN_SERVER_KEY HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "server.key"
|
||||||
|
#define HRN_SERVER_CA HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "ca.crt"
|
||||||
|
#define HRN_SERVER_CLIENT_CERT HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "client.crt"
|
||||||
|
#define HRN_SERVER_CLIENT_KEY HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "client.key"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
// Initialize the server
|
||||||
|
void hrnServerInit(void);
|
||||||
|
|
||||||
// Run server
|
// Run server
|
||||||
typedef struct HrnServerRunParam
|
typedef struct HrnServerRunParam
|
||||||
{
|
{
|
||||||
VAR_PARAM_HEADER;
|
VAR_PARAM_HEADER;
|
||||||
unsigned int port; // Server port, defaults to hrnServerPort(0)
|
unsigned int port; // Server port, defaults to hrnServerPort(0)
|
||||||
|
const String *ca; // TLS CA store when protocol = hrnServerProtocolTls
|
||||||
const String *certificate; // TLS certificate when protocol = hrnServerProtocolTls
|
const String *certificate; // TLS certificate when protocol = hrnServerProtocolTls
|
||||||
const String *key; // TLS key when protocol = hrnServerProtocolTls
|
const String *key; // TLS key when protocol = hrnServerProtocolTls
|
||||||
} HrnServerRunParam;
|
} HrnServerRunParam;
|
||||||
|
@ -128,15 +128,9 @@ testRun(void)
|
|||||||
protocolClientNoOp(client), PathCreateError,
|
protocolClientNoOp(client), PathCreateError,
|
||||||
"raised from test: unable to create path '/bogus': [13] Permission denied");
|
"raised from test: unable to create path '/bogus': [13] Permission denied");
|
||||||
|
|
||||||
// The server is in an error state so ignore any client errors
|
// Do not send the exit command before freeing since the server has already errored
|
||||||
TRY_BEGIN()
|
TEST_RESULT_VOID(protocolClientNoExit(client), "client no exit");
|
||||||
{
|
TEST_RESULT_VOID(protocolClientFree(client), "client free");
|
||||||
protocolClientFree(client);
|
|
||||||
}
|
|
||||||
CATCH_ANY()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
TRY_END();
|
|
||||||
}
|
}
|
||||||
HRN_FORK_PARENT_END();
|
HRN_FORK_PARENT_END();
|
||||||
}
|
}
|
||||||
@ -215,15 +209,9 @@ testRun(void)
|
|||||||
|
|
||||||
TEST_ERROR(protocolClientNoOp(client), StopError, "raised from test: stop file exists for all stanzas");
|
TEST_ERROR(protocolClientNoOp(client), StopError, "raised from test: stop file exists for all stanzas");
|
||||||
|
|
||||||
// The server is in an error state so ignore any client errors
|
// Do not send the exit command before freeing since the server has already errored
|
||||||
TRY_BEGIN()
|
TEST_RESULT_VOID(protocolClientNoExit(client), "client no exit");
|
||||||
{
|
TEST_RESULT_VOID(protocolClientFree(client), "client free");
|
||||||
protocolClientFree(client);
|
|
||||||
}
|
|
||||||
CATCH_ANY()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
TRY_END();
|
|
||||||
|
|
||||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/all" STOP_FILE_EXT);
|
HRN_STORAGE_REMOVE(hrnStorage, "lock/all" STOP_FILE_EXT);
|
||||||
}
|
}
|
||||||
|
216
test/src/module/command/serverTest.c
Normal file
216
test/src/module/command/serverTest.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Server Command
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "storage/posix/storage.h"
|
||||||
|
#include "storage/remote/storage.h"
|
||||||
|
|
||||||
|
#include "common/harnessConfig.h"
|
||||||
|
#include "common/harnessFork.h"
|
||||||
|
#include "common/harnessServer.h"
|
||||||
|
#include "common/harnessStorage.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Test Run
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
void
|
||||||
|
testRun(void)
|
||||||
|
{
|
||||||
|
FUNCTION_HARNESS_VOID();
|
||||||
|
|
||||||
|
Storage *storageTest = storagePosixNewP(TEST_PATH_STR, .write = true);
|
||||||
|
|
||||||
|
harnessLogLevelSet(logLevelDetail);
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("cmdServer()"))
|
||||||
|
{
|
||||||
|
TEST_TITLE("server");
|
||||||
|
|
||||||
|
HRN_FORK_BEGIN(.timeout = 5000)
|
||||||
|
{
|
||||||
|
HRN_FORK_CHILD_BEGIN(.prefix = "client repo")
|
||||||
|
{
|
||||||
|
StringList *argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, "/BOGUS");
|
||||||
|
hrnCfgArgRaw(argList, cfgOptRepoHost, hrnServerHost());
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostConfig, TEST_PATH "/pgbackrest.conf");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostType, "tls");
|
||||||
|
#if !TEST_IN_CONTAINER
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostCaFile, HRN_SERVER_CA);
|
||||||
|
#endif
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostCertFile, HRN_SERVER_CLIENT_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostKeyFile, HRN_SERVER_CLIENT_KEY);
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", hrnServerPort(0));
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
|
||||||
|
|
||||||
|
// Client 1
|
||||||
|
const Storage *storageRemote = NULL;
|
||||||
|
TEST_ASSIGN(
|
||||||
|
storageRemote,
|
||||||
|
storageRemoteNew(
|
||||||
|
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL,
|
||||||
|
protocolRemoteGet(protocolStorageTypeRepo, 0), cfgOptionUInt(cfgOptCompressLevelNetwork)),
|
||||||
|
"new storage 1");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(storageRemote, "client1.txt", "CLIENT1");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(protocolRemoteFree(0), "free client 1");
|
||||||
|
|
||||||
|
// Client 2
|
||||||
|
TEST_ASSIGN(
|
||||||
|
storageRemote,
|
||||||
|
storageRemoteNew(
|
||||||
|
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL,
|
||||||
|
protocolRemoteGet(protocolStorageTypeRepo, 0), cfgOptionUInt(cfgOptCompressLevelNetwork)),
|
||||||
|
"new storage 2");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(storageRemote, "client2.txt", "CLIENT2");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(protocolRemoteFree(0), "free client 2");
|
||||||
|
|
||||||
|
// Notify parent on exit
|
||||||
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
}
|
||||||
|
HRN_FORK_CHILD_END();
|
||||||
|
|
||||||
|
HRN_FORK_CHILD_BEGIN(.prefix = "client pg")
|
||||||
|
{
|
||||||
|
StringList *argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoPath, "/BOGUS");
|
||||||
|
hrnCfgArgRaw(argList, cfgOptPgHost, hrnServerHost());
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostType, "tls");
|
||||||
|
#if !TEST_IN_CONTAINER
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostCaFile, HRN_SERVER_CA);
|
||||||
|
#endif
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostCertFile, HRN_SERVER_CLIENT_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostKeyFile, HRN_SERVER_CLIENT_KEY);
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptPgHostPort, "%u", hrnServerPort(0));
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptProcess, "1");
|
||||||
|
HRN_CFG_LOAD(cfgCmdBackup, argList, .role = cfgCmdRoleLocal);
|
||||||
|
|
||||||
|
// Client 3
|
||||||
|
const Storage *storageRemote = NULL;
|
||||||
|
TEST_ASSIGN(
|
||||||
|
storageRemote,
|
||||||
|
storageRemoteNew(
|
||||||
|
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, true, NULL,
|
||||||
|
protocolRemoteGet(protocolStorageTypePg, 0), cfgOptionUInt(cfgOptCompressLevelNetwork)),
|
||||||
|
"new storage 3");
|
||||||
|
|
||||||
|
HRN_STORAGE_PUT_Z(storageRemote, "client3.txt", "CLIENT3");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(protocolRemoteFree(0), "free client 3");
|
||||||
|
|
||||||
|
// Notify parent on exit
|
||||||
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
}
|
||||||
|
HRN_FORK_CHILD_END();
|
||||||
|
|
||||||
|
HRN_FORK_PARENT_BEGIN(.prefix = "server")
|
||||||
|
{
|
||||||
|
StringList *argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerCaFile, HRN_SERVER_CA);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerCertFile, HRN_SERVER_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerKeyFile, HRN_SERVER_KEY);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "pgbackrest-client=db");
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
// Write a config file to demonstrate that settings are loaded
|
||||||
|
HRN_STORAGE_PUT_Z(storageTest, "pgbackrest.conf", "[global]\nrepo1-path=" TEST_PATH "/repo");
|
||||||
|
|
||||||
|
// Get pid of this process to identify child process later
|
||||||
|
pid_t pid = getpid();
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(cmdServer(3), "server");
|
||||||
|
|
||||||
|
// If this is a child process then exit immediately
|
||||||
|
if (pid != getpid())
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
// Wait for both child processes to exit
|
||||||
|
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||||
|
HRN_FORK_PARENT_NOTIFY_GET(1);
|
||||||
|
|
||||||
|
// Check that files written by child processes are present
|
||||||
|
TEST_STORAGE_GET(storageTest, "repo/client1.txt", "CLIENT1");
|
||||||
|
TEST_STORAGE_GET(storageTest, "repo/client2.txt", "CLIENT2");
|
||||||
|
TEST_STORAGE_GET(storageTest, "pg/client3.txt", "CLIENT3");
|
||||||
|
}
|
||||||
|
HRN_FORK_PARENT_END();
|
||||||
|
}
|
||||||
|
HRN_FORK_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("cmdServerPing()"))
|
||||||
|
{
|
||||||
|
TEST_TITLE("error on extra parameters");
|
||||||
|
|
||||||
|
StringList *argList = strLstNew();
|
||||||
|
strLstAddZ(argList, "host");
|
||||||
|
strLstAddZ(argList, "bogus");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerPing, argList);
|
||||||
|
|
||||||
|
TEST_ERROR(cmdServerPing(), ParamInvalidError, "extra parameters found");
|
||||||
|
|
||||||
|
HRN_FORK_BEGIN(.timeout = 5000)
|
||||||
|
{
|
||||||
|
|
||||||
|
HRN_FORK_CHILD_BEGIN(.prefix = "client")
|
||||||
|
{
|
||||||
|
TEST_TITLE("ping localhost");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerPing, argList);
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(cmdServerPing(), "ping");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("ping 12.0.0.1");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
|
||||||
|
strLstAddZ(argList, "127.0.0.1");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerPing, argList);
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(cmdServerPing(), "ping");
|
||||||
|
|
||||||
|
// Notify parent on exit
|
||||||
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
}
|
||||||
|
HRN_FORK_CHILD_END();
|
||||||
|
|
||||||
|
HRN_FORK_PARENT_BEGIN(.prefix = "server")
|
||||||
|
{
|
||||||
|
StringList *argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerCaFile, HRN_SERVER_CA);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerCertFile, HRN_SERVER_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerKeyFile, HRN_SERVER_KEY);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "bogus=*");
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptTlsServerPort, "%u", hrnServerPort(0));
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
// Get pid of this process to identify child process later
|
||||||
|
pid_t pid = getpid();
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(cmdServer(2), "server");
|
||||||
|
|
||||||
|
// If this is a child process then exit immediately
|
||||||
|
if (pid != getpid())
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
// Wait for child process to exit
|
||||||
|
HRN_FORK_PARENT_NOTIFY_GET(0);
|
||||||
|
}
|
||||||
|
HRN_FORK_PARENT_END();
|
||||||
|
}
|
||||||
|
HRN_FORK_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
|
}
|
@ -273,7 +273,7 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HttpClient *client = NULL;
|
HttpClient *client = NULL;
|
||||||
|
|
||||||
TEST_ASSIGN(client, httpClientNew(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 500), 500), "new client");
|
TEST_ASSIGN(client, httpClientNew(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 500, 500), 500), "new client");
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
httpRequestResponse(httpRequestNewP(client, STRDEF("GET"), STRDEF("/")), false), HostConnectError,
|
httpRequestResponse(httpRequestNewP(client, STRDEF("GET"), STRDEF("/")), false), HostConnectError,
|
||||||
@ -297,7 +297,7 @@ testRun(void)
|
|||||||
|
|
||||||
ioBufferSizeSet(35);
|
ioBufferSizeSet(35);
|
||||||
|
|
||||||
TEST_ASSIGN(client, httpClientNew(sckClientNew(hrnServerHost(), hrnServerPort(0), 5000), 5000), "new client");
|
TEST_ASSIGN(client, httpClientNew(sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), 5000), "new client");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("no output from server");
|
TEST_TITLE("no output from server");
|
||||||
|
@ -6,9 +6,126 @@ Test Tls Client
|
|||||||
|
|
||||||
#include "common/io/fdRead.h"
|
#include "common/io/fdRead.h"
|
||||||
#include "common/io/fdWrite.h"
|
#include "common/io/fdWrite.h"
|
||||||
|
#include "storage/posix/storage.h"
|
||||||
|
|
||||||
#include "common/harnessFork.h"
|
#include "common/harnessFork.h"
|
||||||
#include "common/harnessServer.h"
|
#include "common/harnessServer.h"
|
||||||
|
#include "common/harnessStorage.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Server cert with only a common name to test absence of alt names
|
||||||
|
|
||||||
|
To regenerate, run the following in a temp path:
|
||||||
|
|
||||||
|
openssl req -nodes -new -newkey rsa:4096 -sha256 -key ~/pgbackrest/test/certificate/pgbackrest-test-server.key \
|
||||||
|
-out server-cn-only.csr -subj "/CN=127.0.0.1"
|
||||||
|
openssl x509 -extensions usr_cert -req -days 99999 -CA ~/pgbackrest/test/certificate/pgbackrest-test-ca.crt \
|
||||||
|
-CAkey ~/pgbackrest/test/certificate/pgbackrest-test-ca.key -CAcreateserial -in server-cn-only.csr -out server-cn-only.crt
|
||||||
|
|
||||||
|
Then copy server-cn-only.crt into the variable below. Use a variable instead of a define so we know when the variable is not used.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static const char *const testServerCnOnlyCert =
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIE+TCCAuECFFtID1qGQ+Q6oyFiD9z5YmANCADjMA0GCSqGSIb3DQEBCwUAMFwx\n"
|
||||||
|
"CzAJBgNVBAYTAlVTMQwwCgYDVQQIDANBbGwxDDAKBgNVBAcMA0FsbDETMBEGA1UE\n"
|
||||||
|
"CgwKcGdCYWNrUmVzdDEcMBoGA1UEAwwTdGVzdC5wZ2JhY2tyZXN0Lm9yZzAgFw0y\n"
|
||||||
|
"MTA4MjYxMjIxNTNaGA8yMjk1MDYxMDEyMjE1M1owFDESMBAGA1UEAwwJMTI3LjAu\n"
|
||||||
|
"MC4xMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwzNZDX/VhTA6lALX\n"
|
||||||
|
"DZ4AOHv4OQH5wTZipa97XdTrI2TIfMGEffLmv5wzN85pku5HXBuHGJUaUENXt1Ss\n"
|
||||||
|
"GwdfBx/gZZEA8oONqkrxOoJTrABWIAs5k6TTUd+f3Y39rlsyQj076f1sw6Mw9qoC\n"
|
||||||
|
"h+JKXDDqw8kGwQHifXdtCrxL9OfV4eq+gYKrqdlyFM08WfKxe0Js8bB5cZ4Bt/GC\n"
|
||||||
|
"2JhQzQ9bMjYJlxSXIXivP/FFunVT5hZ8gsUVAH+/sm8xlQ4sedW7mIBKkjT3tgL0\n"
|
||||||
|
"FvchB3XyoZ6Sr0JKVaMOcQjIsTzOqdgawgArO541ZwUWHdJH+DODr/gBWXSnnzhH\n"
|
||||||
|
"ED5DAvRMPdO/t353qS/ihpacTqQ91B4UKxK1pVNC84ch3spCLnQncl7kn7RhcdCc\n"
|
||||||
|
"b5g4ZfahRmq79QSoMDvN4+7MtyERLXtSttSWiBzQVVj/jcFNDeGeDjKp6Z55xoso\n"
|
||||||
|
"tMZ3yVajl4IbuQS1pfTLjp7WdJ58y5hQ+8O/ebjUYIxOo5kZhRZV/jxqoR7Ga9MG\n"
|
||||||
|
"bAQ7BPcTuItpfGqiWcdYU+ZdyyFwvpXov6qNoCYt58nj7s+FAbed7EzRHa2Z3RVG\n"
|
||||||
|
"kcqv2iX5EddydHmqKip+QUUR4cPLUXn+kvOHtJEOgAWDURh0DVfhrMD5dX1d+9de\n"
|
||||||
|
"BUwZ89gYvxkkErPL1o8OPRxyiucCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAlwMZ\n"
|
||||||
|
"tlqvggfXsJh/AQdl1XxqQKzwC+1OyPozqTUMaEiHLgswJw8eXaZB1/8g9ZODPO3N\n"
|
||||||
|
"tLh6JfE4gJJ6gs89YmaZLR0oH3RkoFXSi4+t+WdyF0t3QrBuVx4uO3BeEdD1aLXm\n"
|
||||||
|
"lxS7004mJAEMn9FTBBMwek/DGS1Ic/tHwFCRvvE73mFcPL2Qs03ZzRuYUEI1Ckef\n"
|
||||||
|
"ONFu6/pydIS5MK0QCP/MfUlKP1D3u2aFEbdNHy4GjzGpfg+1DD/ebSswQG1YpjnN\n"
|
||||||
|
"5XLEQZ9IKE2ULq9GnnhqPNUTdX6HFHxVvyZUe/iXasOCX7C9PBipj3tulLcPMbLn\n"
|
||||||
|
"4tToEuLkvsLU2Z6I9mcS88Z30VyYu4BzM6tim7XvsOEObILjs2Qa0dJ2hSF6QJ9L\n"
|
||||||
|
"NUrbWS591v/PvUdk68kC8UL7o7UVS3lsZoRIZD+X+xdEi+zy4DNIMKUBnWtKamUU\n"
|
||||||
|
"1VOosL6vDSZYGg0InGfaBm3Bz3elTrWUHCapNQ5Zsxk+Sq+IQ4hauczrOsd6jugR\n"
|
||||||
|
"m1JzWMUZROfSrcVfighZSencJwJEmyCQwnMUyovPs2v7S+1QQEY210ZZd5Fphoye\n"
|
||||||
|
"1oA2FndLfr8BOG88+TzwdFilOiZ28lIpMFas38uybJBwlxVYN4/aLyIQGp6AyzGR\n"
|
||||||
|
"XqmU0pBFqRYS8xENKxk7lPnxFKyEpb3NK3wk3mo=\n"
|
||||||
|
"-----END CERTIFICATE-----";
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Client key with a password
|
||||||
|
|
||||||
|
To regenerate, run the following in a temp path:
|
||||||
|
|
||||||
|
openssl genrsa -aes256 -passout pass:xxxx -out client-pwd.key 1024
|
||||||
|
|
||||||
|
Then copy server-pwd.key into the variable below. Use a variable instead of a define so we know when the variable is not used.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static const char *const testClientPwdKey =
|
||||||
|
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||||
|
"Proc-Type: 4,ENCRYPTED\n"
|
||||||
|
"DEK-Info: AES-256-CBC,86BD081993E54559E92BFF24921DCD00\n"
|
||||||
|
"\n"
|
||||||
|
"MglGBz4qfnUUs7IuueInkDrn5GRp6V7ZOs/S8rkrOp0i7MTfFJk1cYByu0FCcLqo\n"
|
||||||
|
"O3UX1dLPOzu74hJGOmOUHEJzrzA09wFIshTZo96z60+gQGcPEWkkkG9eRadJG5EN\n"
|
||||||
|
"TiAq1xopmAYK+srSBsPD7Xf9KeYpFM4Fa98pWbEhzMBiozgh2fH8+6OK8izDFJ57\n"
|
||||||
|
"aW8p/9lwZtkO2nd6G4meU+vyVDsL4GpdHcryi+MGGXfhkrr6mFAQ3PLpHTwr6xNI\n"
|
||||||
|
"wp6IjuLpNwlkNadq8Wgi8qy4YhpdqmSVt/oFJ25HMH+0UT+EAk0f/WMqOgkSmi3y\n"
|
||||||
|
"HgmG7YYAHel5tVeY59/ovxMvc290KQkthVgYBIT/Sy3O4pTRgu+xBkB5VfxjI9gj\n"
|
||||||
|
"yVVHsvJHwWdNyUf093Qvroul6Ulob7DOXmPvRWuu6YIBASYIGrmtI2cZ0SQBoySp\n"
|
||||||
|
"V65yTAwoi7bqsmwCo4sEjKE6FSeVINY/EvwYLbfyGUOmaunWkWkNPsg9fvwTZNOc\n"
|
||||||
|
"3G1IAypM4++02wVVeLdc0+n9FdE6QX3MWpUeZ5YaOzjBjCisk+jJ46L79bi6Z/Xc\n"
|
||||||
|
"H1XXBsMnmFhkhd3lraMQ8QYpWus890OmCnimB59SM1W2LgROwv/fXt/8rwgJY1v5\n"
|
||||||
|
"6VP5KAZkXpCq20gG6C7GW3jL5/prnPoe+uXku4m4iAReUmTewqht8WUyQaiAWy+e\n"
|
||||||
|
"nH5HoTaB3+9ZLu2RivU9l6y1YwYSAbSWBPbnN4HmjP4rmLG5t1ky9igYfJ3NL3LV\n"
|
||||||
|
"gJPetwzWuiONyshwMzcg0bE/NjzTXcCaFVKSJ/M++Kd+abDcixUQ3u6htVFHW/L/\n"
|
||||||
|
"-----END RSA PRIVATE KEY-----";
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Client cert signed by another CA used to generate invalid client cert error
|
||||||
|
|
||||||
|
To regenerate, run the following in a temp path:
|
||||||
|
|
||||||
|
openssl genrsa -out bogus-ca.key 4096
|
||||||
|
openssl req -new -x509 -sha256 -days 99999 -key bogus-ca.key -out bogus-ca.crt -subj "/CN=bogus"
|
||||||
|
openssl req -nodes -new -newkey rsa:4096 -sha256 -key ~/pgbackrest/test/certificate/pgbackrest-test-client.key \
|
||||||
|
-out client-bad-ca.csr -subj "/CN=bogus"
|
||||||
|
openssl x509 -extensions usr_cert -req -days 99999 -CA bogus-ca.crt -CAkey bogus-ca.key -CAcreateserial -in client-bad-ca.csr \
|
||||||
|
-out client-bad-ca.crt
|
||||||
|
|
||||||
|
Then copy client-bad-ca.crt into the variable below. Use a variable instead of a define so we know when the variable is not used.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static const char *const testClientBadCa =
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIEqTCCApECFAzHjCL/QJZZRmBhloX298J4V4HbMA0GCSqGSIb3DQEBCwUAMBAx\n"
|
||||||
|
"DjAMBgNVBAMMBWJvZ3VzMCAXDTIxMDgyNjE0MzYyMloYDzIyOTUwNjEwMTQzNjIy\n"
|
||||||
|
"WjAQMQ4wDAYDVQQDDAVib2d1czCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n"
|
||||||
|
"ggIBALK5ahiXzFqvha28yqe3SGdezs4IREHUDgbn6Tem9k1GazE/IsdIQ9wj9KHd\n"
|
||||||
|
"lXwb/2fsdQk1hkPXa4qRBR/AyeBPRL3d0aZzU+pTjV6n9dJ+KIaivuAxoyyY59XM\n"
|
||||||
|
"36CqTZxe3VqXweRWPn40tzDcUxSVIfipJpFuK2vxpwEHdl/cFQ38/sRoHTjx61nx\n"
|
||||||
|
"obt4RFiEMAFCxxCk/qDyYISHJmH67dIUEw7ujB4vn/gpk5f1WBY5msZMgT3pJbFv\n"
|
||||||
|
"xD8dRgUvMpIM5poVFfhHgRq+L2dxQ2jHD5AnlpY6n8XrWy4QQa3AFsWgnD0w0Wn6\n"
|
||||||
|
"cyU0g5AkIlP+0mMNC9LIPVc9LGKUTrqciBgx8Rysy3mskg8pElEe1ouQOi/Zx8UA\n"
|
||||||
|
"G3RXqvjxXLkMp3S7PKgrr48uZHAso59+k33EkF/ceLsr3r3VY1WWsiszDfK+vbj6\n"
|
||||||
|
"Bbxvtv/S2ZYXMA7nM2Ysu20BpHm9LLo4y8HqDeixqw5enOwuDKSeKD1pJgJ5CUYq\n"
|
||||||
|
"RbA/cUYxHJ36NuPDxec+bhqiJq8RMR4pGGcJ7BvirJxYPJX0LqIfTHL1t2dVm//A\n"
|
||||||
|
"meMDNiM2quAzpBosjvaWaRUcankYE1dL59eVugoDKCNCPg72LjXBB7bPWZT2Xhkc\n"
|
||||||
|
"co0etruIYYJmQ3LO0vGe9pOYBu2FHx5FY72b8gpshm+umdL5AgMBAAEwDQYJKoZI\n"
|
||||||
|
"hvcNAQELBQADggIBAEN3778acjJ46yKzYoM+wiyyiMtmOrf+zvJsF0oK4KcWgec2\n"
|
||||||
|
"O2grmhxxDdF5c/P6XasDQFl8feQfGeDY76DaLrcmIiOYrtnqg11IZcPOHx5nbpu2\n"
|
||||||
|
"ZVV5LiMS8nHhQIyxMF/WYYKGzBQ5AY2+t6dozyDo3R4O7CCmsFKc8NaB4maC7Q16\n"
|
||||||
|
"7MxKXxtAH9I1PigjRMDpi1xQJbXJxFKhZrKBODtreL6cmv6yB4JJezI5ngIdODpI\n"
|
||||||
|
"MaIS0reRGN4QUpzDaXwYBTaOHaIDShPDOfiA5ai4xK/dEWG2rDu+yk7g5SEKMAxU\n"
|
||||||
|
"mfUCO1MGY6NwQupLUyfO2VjvfYeB+ipJq6F8tYMGrQJU/PCQT6nxaZdSoZZQF72y\n"
|
||||||
|
"OuYVfKjnj7MWapGKC3ea1oTUvkwDePe8xg3DBuXImp5mO4MG5K/oVv5SnNVmcUGq\n"
|
||||||
|
"L9WBrvypJK+3x3vbdyH02DR10TcMRSbDODmW59nx2PQEDUM7ddNZ60dRn8Hdgoz2\n"
|
||||||
|
"s/Sk3I1gXvZLQ/shS4Aa7XKz/TqhPNrBnMvSnp5/PtjjeBwxIBimuuM1ALFfwz91\n"
|
||||||
|
"KpzwqfTswuGIO8TWKJZzNTsdwScqmbZTtiVs6GaEZ3FQX5qnrbybX53S2R9fNKm+\n"
|
||||||
|
"qGj7FtRiSdjkZ7pmNpma6ycPR0RBZyL3aHnig+DDfRRt8TgrZzY3aXBReONb\n"
|
||||||
|
"-----END CERTIFICATE-----";
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Test Run
|
Test Run
|
||||||
@ -18,6 +135,13 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
FUNCTION_HARNESS_VOID();
|
FUNCTION_HARNESS_VOID();
|
||||||
|
|
||||||
|
// Create default storage object for testing
|
||||||
|
Storage *storageTest = storagePosixNewP(TEST_PATH_STR, .write = true);
|
||||||
|
|
||||||
|
THROW_ON_SYS_ERROR_FMT(chmod(HRN_SERVER_KEY, 0600) == -1, FileModeError, "unable to set mode on " HRN_SERVER_KEY);
|
||||||
|
THROW_ON_SYS_ERROR_FMT(
|
||||||
|
chmod(HRN_SERVER_CLIENT_KEY, 0600) == -1, FileModeError, "unable to set mode on " HRN_SERVER_CLIENT_KEY);
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("Socket Common"))
|
if (testBegin("Socket Common"))
|
||||||
{
|
{
|
||||||
@ -149,7 +273,7 @@ testRun(void)
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("unable to connect to blocking socket");
|
TEST_TITLE("unable to connect to blocking socket");
|
||||||
|
|
||||||
IoClient *socketClient = sckClientNew(STR(hostLocal), 7777, 0);
|
IoClient *socketClient = sckClientNew(STR(hostLocal), 7777, 0, 0);
|
||||||
TEST_RESULT_STR_Z(ioClientName(socketClient), "127.0.0.1:7777", " check name");
|
TEST_RESULT_STR_Z(ioClientName(socketClient), "127.0.0.1:7777", " check name");
|
||||||
|
|
||||||
socketLocal.block = true;
|
socketLocal.block = true;
|
||||||
@ -179,21 +303,21 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
IoClient *client = NULL;
|
IoClient *client = NULL;
|
||||||
|
|
||||||
TEST_ASSIGN(client, sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100), "new client");
|
TEST_ASSIGN(client, sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), "new client");
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused",
|
ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused",
|
||||||
hrnServerPort(0));
|
hrnServerPort(0));
|
||||||
|
|
||||||
// This address should not be in use in a test environment -- if it is the test will fail
|
// This address should not be in use in a test environment -- if it is the test will fail
|
||||||
TEST_ASSIGN(client, sckClientNew(STRDEF("172.31.255.255"), hrnServerPort(0), 100), "new client");
|
TEST_ASSIGN(client, sckClientNew(STRDEF("172.31.255.255"), hrnServerPort(0), 100, 100), "new client");
|
||||||
TEST_ERROR_FMT(ioClientOpen(client), HostConnectError, "timeout connecting to '172.31.255.255:%u'", hrnServerPort(0));
|
TEST_ERROR_FMT(ioClientOpen(client), HostConnectError, "timeout connecting to '172.31.255.255:%u'", hrnServerPort(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional coverage not provided by testing with actual certificates
|
// Additional coverage not provided by testing with actual certificates
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("asn1ToStr(), tlsClientHostVerify(), and tlsClientHostVerifyName()"))
|
if (testBegin("tlsAsn1ToStr(), tlsClientHostVerify(), and tlsClientHostVerifyName()"))
|
||||||
{
|
{
|
||||||
TEST_ERROR(asn1ToStr(NULL), CryptoError, "TLS certificate name entry is missing");
|
TEST_ERROR(tlsAsn1ToStr(NULL), CryptoError, "TLS certificate name entry is missing");
|
||||||
|
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
tlsClientHostVerifyName(
|
tlsClientHostVerifyName(
|
||||||
@ -214,33 +338,140 @@ testRun(void)
|
|||||||
// Connection errors
|
// Connection errors
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_ASSIGN(
|
TEST_ASSIGN(
|
||||||
client, tlsClientNew(sckClientNew(STRDEF("99.99.99.99.99"), 7777, 0), STRDEF("X"), 0, true, NULL, NULL),
|
client,
|
||||||
|
tlsClientNew(sckClientNew(STRDEF("99.99.99.99.99"), 7777, 0, 0), STRDEF("X"), 0, 0, true, NULL, NULL, NULL, NULL),
|
||||||
"new client");
|
"new client");
|
||||||
TEST_RESULT_STR_Z(ioClientName(client), "99.99.99.99.99:7777", " check name");
|
TEST_RESULT_STR_Z(ioClientName(client), "99.99.99.99.99:7777", " check name");
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
ioClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known");
|
ioClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known");
|
||||||
|
|
||||||
TEST_ASSIGN(
|
TEST_ASSIGN(
|
||||||
client, tlsClientNew(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100), STRDEF("X"), 100, true, NULL, NULL),
|
client,
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), STRDEF("X"), 100, 100, true, NULL, NULL, NULL, NULL),
|
||||||
"new client");
|
"new client");
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused",
|
ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused",
|
||||||
hrnServerPort(0));
|
hrnServerPort(0));
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("bogus client cert/path");
|
TEST_TITLE("missing ca cert/path");
|
||||||
|
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, STRDEF("bogus.crt"),
|
||||||
STRDEF("localhost"), hrnServerPort(0), 5000), STRDEF("X"), 0, true, STRDEF("bogus.crt"), STRDEF("/bogus"))),
|
STRDEF("/bogus"), NULL, NULL)),
|
||||||
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
|
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("missing client cert");
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF("/bogus"), STRDEF("/bogus"))),
|
||||||
|
CryptoError, "unable to load cert file '/bogus': [33558530] No such file or directory");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("missing client key");
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF("/bogus"))),
|
||||||
|
CryptoError, "unable to load key file '/bogus': [33558530] No such file or directory");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("client cert and key do not match");
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(HRN_SERVER_KEY))),
|
||||||
|
CryptoError,
|
||||||
|
"unable to load key file '" HRN_PATH_REPO "/test/certificate/pgbackrest-test-server.key': [185073780] key values"
|
||||||
|
" mismatch");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("client cert with passphrase");
|
||||||
|
|
||||||
|
storagePutP(storageNewWriteP(storageTest, STRDEF("client-pwd.key"), .modeFile = 0600), BUFSTRZ(testClientPwdKey));
|
||||||
|
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
TEST_ERROR(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-pwd.key")),
|
||||||
|
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': [101077092] bad decrypt");
|
||||||
|
}
|
||||||
|
CATCH(TestError)
|
||||||
|
{
|
||||||
|
TEST_ERROR( // {uncovered - 32-bit error}
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-pwd.key")),
|
||||||
|
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': [151429224] bad password read");
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
|
storageRemoveP(storageTest, STRDEF("client-pwd.key"));
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("key with bad user permissions");
|
||||||
|
|
||||||
|
storagePutP(storageNewWriteP(storageTest, STRDEF("client-bad-perm.key"), .modeFile = 0640), BUFSTRDEF("bogus"));
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-bad-perm.key"))),
|
||||||
|
FileReadError,
|
||||||
|
"key file '" TEST_PATH "/client-bad-perm.key' has group or other permissions\n"
|
||||||
|
"HINT: file must have permissions u=rw (0600) or less if owned by the '" TEST_USER "' user\n"
|
||||||
|
"HINT: file must have permissions u=rw, g=r (0640) or less if owned by root\n");
|
||||||
|
|
||||||
|
storageRemoveP(storageTest, STRDEF("client-bad-perm.key"));
|
||||||
|
|
||||||
|
#ifdef TEST_CONTAINER_REQUIRED
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("key with bad user");
|
||||||
|
|
||||||
|
storagePutP(storageNewWriteP(storageTest, STRDEF("client-bad-perm.key"), .modeFile = 0660), BUFSTRDEF("bogus"));
|
||||||
|
HRN_SYSTEM_FMT("sudo chown postgres %s", strZ(storagePathP(storageTest, STRDEF("client-bad-perm.key"))));
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-bad-perm.key"))),
|
||||||
|
FileReadError, "key file '" TEST_PATH "/client-bad-perm.key' must be owned by the '" TEST_USER "' user or root");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("key with bad root permissions");
|
||||||
|
|
||||||
|
HRN_SYSTEM_FMT("sudo chown root %s", strZ(storagePathP(storageTest, STRDEF("client-bad-perm.key"))));
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
|
||||||
|
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-bad-perm.key"))),
|
||||||
|
FileReadError,
|
||||||
|
"key file '" TEST_PATH "/client-bad-perm.key' has group or other permissions\n"
|
||||||
|
"HINT: file must have permissions u=rw (0600) or less if owned by the '" TEST_USER "' user\n"
|
||||||
|
"HINT: file must have permissions u=rw, g=r (0640) or less if owned by root\n");
|
||||||
|
|
||||||
|
HRN_SYSTEM_FMT("sudo rm %s", strZ(storagePathP(storageTest, STRDEF("client-bad-perm.key"))));
|
||||||
|
|
||||||
// Certificate location and validation errors
|
// Certificate location and validation errors
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
// Add test hosts
|
// Add test hosts
|
||||||
#ifdef TEST_CONTAINER_REQUIRED
|
|
||||||
HRN_SYSTEM(
|
HRN_SYSTEM(
|
||||||
"echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" | sudo tee -a /etc/hosts >"
|
"echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" | sudo tee -a /etc/hosts >"
|
||||||
" /dev/null");
|
" /dev/null");
|
||||||
@ -253,8 +484,8 @@ testRun(void)
|
|||||||
TEST_RESULT_VOID(
|
TEST_RESULT_VOID(
|
||||||
hrnServerRunP(
|
hrnServerRunP(
|
||||||
HRN_FORK_CHILD_READ(), hrnServerProtocolTls,
|
HRN_FORK_CHILD_READ(), hrnServerProtocolTls,
|
||||||
.certificate = STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "-alt-name.crt"),
|
.certificate = STRDEF(HRN_SERVER_CERT),
|
||||||
.key = STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX ".key")),
|
.key = STRDEF(HRN_SERVER_KEY)),
|
||||||
"tls alt name server run");
|
"tls alt name server run");
|
||||||
}
|
}
|
||||||
HRN_FORK_CHILD_END();
|
HRN_FORK_CHILD_END();
|
||||||
@ -272,8 +503,8 @@ testRun(void)
|
|||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000), STRDEF("X"), 0, true, NULL,
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL,
|
||||||
STRDEF("/bogus"))),
|
STRDEF("/bogus"), NULL, NULL)),
|
||||||
CryptoError,
|
CryptoError,
|
||||||
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
|
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
|
||||||
hrnServerPort(0));
|
hrnServerPort(0));
|
||||||
@ -287,8 +518,8 @@ testRun(void)
|
|||||||
TEST_RESULT_VOID(
|
TEST_RESULT_VOID(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(STRDEF("test.pgbackrest.org"), hrnServerPort(0), 5000), STRDEF("test.pgbackrest.org"),
|
sckClientNew(STRDEF("test.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
|
||||||
0, true, STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "-ca.crt"), NULL)),
|
STRDEF("test.pgbackrest.org"), 0, 0, true, STRDEF(HRN_SERVER_CA), NULL, NULL, NULL)),
|
||||||
"open connection");
|
"open connection");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
@ -300,9 +531,8 @@ testRun(void)
|
|||||||
TEST_RESULT_VOID(
|
TEST_RESULT_VOID(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(STRDEF("host.test2.pgbackrest.org"), hrnServerPort(0), 5000),
|
sckClientNew(STRDEF("host.test2.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
|
||||||
STRDEF("host.test2.pgbackrest.org"), 0, true,
|
STRDEF("host.test2.pgbackrest.org"), 0, 0, true, STRDEF(HRN_SERVER_CA), NULL, NULL, NULL)),
|
||||||
STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "-ca.crt"), NULL)),
|
|
||||||
"open connection");
|
"open connection");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
@ -314,8 +544,8 @@ testRun(void)
|
|||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(STRDEF("test3.pgbackrest.org"), hrnServerPort(0), 5000), STRDEF("test3.pgbackrest.org"),
|
sckClientNew(STRDEF("test3.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
|
||||||
0, true, STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX "-ca.crt"), NULL)),
|
STRDEF("test3.pgbackrest.org"), 0, 0, true, STRDEF(HRN_SERVER_CA), NULL, NULL, NULL)),
|
||||||
CryptoError,
|
CryptoError,
|
||||||
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
|
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
|
||||||
|
|
||||||
@ -328,9 +558,8 @@ testRun(void)
|
|||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000), STRDEF("X"), 0, true,
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
|
||||||
STRDEF(HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX ".crt"),
|
STRDEF(HRN_SERVER_CERT), NULL, NULL, NULL)),
|
||||||
NULL)),
|
|
||||||
CryptoError,
|
CryptoError,
|
||||||
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
|
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
|
||||||
hrnServerPort(0));
|
hrnServerPort(0));
|
||||||
@ -344,7 +573,8 @@ testRun(void)
|
|||||||
TEST_RESULT_VOID(
|
TEST_RESULT_VOID(
|
||||||
ioClientOpen(
|
ioClientOpen(
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000), STRDEF("X"), 0, false, NULL, NULL)),
|
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, false, NULL, NULL,
|
||||||
|
NULL, NULL)),
|
||||||
"open connection");
|
"open connection");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
@ -353,6 +583,137 @@ testRun(void)
|
|||||||
HRN_FORK_PARENT_END();
|
HRN_FORK_PARENT_END();
|
||||||
}
|
}
|
||||||
HRN_FORK_END();
|
HRN_FORK_END();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Put root-owned server key
|
||||||
|
storagePutP(
|
||||||
|
storageNewWriteP(storageTest, STRDEF("server-root-perm.key"), .modeFile = 0640),
|
||||||
|
storageGetP(storageNewReadP(storagePosixNewP(FSLASH_STR), STRDEF(HRN_SERVER_KEY))));
|
||||||
|
HRN_SYSTEM_FMT("sudo chown root %s", strZ(storagePathP(storageTest, STRDEF("server-root-perm.key"))));
|
||||||
|
THROW_ON_SYS_ERROR(
|
||||||
|
symlink(TEST_PATH "/server-root-perm.key", TEST_PATH "/server-root-perm-link") == -1, FileOpenError,
|
||||||
|
"unable to create symlink");
|
||||||
|
|
||||||
|
// Put CN only server cert
|
||||||
|
storagePutP(storageNewWriteP(storageTest, STRDEF("server-cn-only.crt")), BUFSTRZ(testServerCnOnlyCert));
|
||||||
|
|
||||||
|
// Put bad CA client cert
|
||||||
|
storagePutP(storageNewWriteP(storageTest, STRDEF("client-bad-ca.crt")), BUFSTRZ(testClientBadCa));
|
||||||
|
|
||||||
|
HRN_FORK_BEGIN()
|
||||||
|
{
|
||||||
|
HRN_FORK_CHILD_BEGIN(.prefix = "test server", .timeout = 5000)
|
||||||
|
{
|
||||||
|
// TLS server to accept connections
|
||||||
|
IoServer *socketServer = sckServerNew(STRDEF("localhost"), hrnServerPort(0), 5000);
|
||||||
|
IoServer *tlsServer = tlsServerNew(
|
||||||
|
STRDEF("localhost"), STRDEF(HRN_SERVER_CA), STRDEF(TEST_PATH "/server-root-perm-link"),
|
||||||
|
STRDEF(TEST_PATH "/server-cn-only.crt"), 5000);
|
||||||
|
IoSession *socketSession = NULL;
|
||||||
|
|
||||||
|
TEST_RESULT_STR(ioServerName(socketServer), strNewFmt("localhost:%u", hrnServerPort(0)), "socket server name");
|
||||||
|
TEST_RESULT_STR_Z(ioServerName(tlsServer), "localhost", "tls server name");
|
||||||
|
|
||||||
|
// Invalid client cert
|
||||||
|
if (TEST_64BIT()) // Older 32-bit gives inconsistent results
|
||||||
|
{
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioServerAccept(tlsServer, socketSession), ServiceError,
|
||||||
|
"TLS error [1:337100934] certificate verify failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid client cert
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
IoSession *tlsSession = NULL;
|
||||||
|
TEST_ASSIGN(tlsSession, ioServerAccept(tlsServer, socketSession), "open server session");
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(ioSessionAuthenticated(tlsSession), true, "server session authenticated");
|
||||||
|
TEST_RESULT_STR_Z(ioSessionPeerName(tlsSession), "pgbackrest-client", "check peer name");
|
||||||
|
TEST_RESULT_VOID(ioWrite(ioSessionIoWrite(tlsSession), BUFSTRDEF("message")), "server write");
|
||||||
|
TEST_RESULT_VOID(ioWriteFlush(ioSessionIoWrite(tlsSession)), "server write flush");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(ioSessionFree(tlsSession), "free server session");
|
||||||
|
|
||||||
|
// No client cert
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
TEST_ASSIGN(tlsSession, ioServerAccept(tlsServer, socketSession), "open server session");
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(ioSessionAuthenticated(tlsSession), false, "server session not authenticated");
|
||||||
|
TEST_RESULT_VOID(ioWrite(ioSessionIoWrite(tlsSession), BUFSTRDEF("message2")), "server write");
|
||||||
|
TEST_RESULT_VOID(ioWriteFlush(ioSessionIoWrite(tlsSession)), "server write flush");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(ioSessionFree(tlsSession), "free server session");
|
||||||
|
|
||||||
|
// Free socket
|
||||||
|
ioServerFree(socketServer);
|
||||||
|
}
|
||||||
|
HRN_FORK_CHILD_END();
|
||||||
|
|
||||||
|
HRN_FORK_PARENT_BEGIN(.prefix = "test client")
|
||||||
|
{
|
||||||
|
IoSession *clientSession = NULL;
|
||||||
|
|
||||||
|
if (TEST_64BIT()) // Older 32-bit gives inconsistent results
|
||||||
|
{
|
||||||
|
TEST_TITLE("client cert is invalid (signed by another CA)");
|
||||||
|
|
||||||
|
TEST_ASSIGN(
|
||||||
|
clientSession,
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
|
||||||
|
true, NULL, NULL, STRDEF(TEST_PATH "/client-bad-ca.crt"), STRDEF(HRN_SERVER_CLIENT_KEY))),
|
||||||
|
"client open");
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
ioRead(ioSessionIoRead(clientSession), bufNew(1)), ServiceError,
|
||||||
|
"TLS error [1:336151576] tlsv1 alert unknown ca");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(ioSessionFree(clientSession), "free client session");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("client cert is valid");
|
||||||
|
|
||||||
|
TEST_ASSIGN(
|
||||||
|
clientSession,
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000, true,
|
||||||
|
NULL, NULL, STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(HRN_SERVER_CLIENT_KEY))),
|
||||||
|
"client open");
|
||||||
|
|
||||||
|
Buffer *buffer = bufNew(7);
|
||||||
|
TEST_RESULT_VOID(ioRead(ioSessionIoRead(clientSession), buffer), "client read");
|
||||||
|
TEST_RESULT_STR_Z(strNewBuf(buffer), "message", "check read");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(ioSessionFree(clientSession), "free client session");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("no client cert");
|
||||||
|
|
||||||
|
TEST_ASSIGN(
|
||||||
|
clientSession,
|
||||||
|
ioClientOpen(
|
||||||
|
tlsClientNew(
|
||||||
|
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000, true,
|
||||||
|
NULL, NULL, NULL, NULL)),
|
||||||
|
"client open");
|
||||||
|
|
||||||
|
buffer = bufNew(8);
|
||||||
|
TEST_RESULT_VOID(ioRead(ioSessionIoRead(clientSession), buffer), "client read");
|
||||||
|
TEST_RESULT_STR_Z(strNewBuf(buffer), "message2", "check read");
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(ioSessionFree(clientSession), "free client session");
|
||||||
|
}
|
||||||
|
HRN_FORK_PARENT_END();
|
||||||
|
}
|
||||||
|
HRN_FORK_END();
|
||||||
|
|
||||||
|
storageRemoveP(storageTest, STRDEF("server-root-perm-link"), .errorOnMissing = true);
|
||||||
|
HRN_SYSTEM_FMT("sudo rm %s", strZ(storagePathP(storageTest, STRDEF("server-root-perm.key"))));
|
||||||
#endif // TEST_CONTAINER_REQUIRED
|
#endif // TEST_CONTAINER_REQUIRED
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,8 +739,8 @@ testRun(void)
|
|||||||
TEST_ASSIGN(
|
TEST_ASSIGN(
|
||||||
client,
|
client,
|
||||||
tlsClientNew(
|
tlsClientNew(
|
||||||
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000), hrnServerHost(), 0, TEST_IN_CONTAINER, NULL,
|
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER, NULL,
|
||||||
NULL),
|
NULL, NULL, NULL),
|
||||||
"new client");
|
"new client");
|
||||||
|
|
||||||
hrnServerScriptAccept(tls);
|
hrnServerScriptAccept(tls);
|
||||||
|
@ -387,6 +387,47 @@ testRun(void)
|
|||||||
|
|
||||||
TEST_RESULT_BOOL(cfgOptionTest(cfgOptRepoRetentionArchive), false, "repo1-retention-archive not set");
|
TEST_RESULT_BOOL(cfgOptionTest(cfgOptRepoRetentionArchive), false, "repo1-retention-archive not set");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("set default when pg-host-type is tls");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoRetentionFull, "1");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHost, 1, "host1");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 1, "/pg1");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostType, 1, "tls");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostCertFile, 1, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostKeyFile, 1, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHost, 2, "host2");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 2, "/pg2");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostType, 2, "tls");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostCertFile, 2, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostKeyFile, 2, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostPort, 2, "3333");
|
||||||
|
HRN_CFG_LOAD(cfgCmdBackup, argList);
|
||||||
|
|
||||||
|
TEST_RESULT_UINT(cfgOptionIdxUInt(cfgOptPgHostPort, 0), 8432, "default port");
|
||||||
|
TEST_RESULT_UINT(cfgOptionIdxUInt(cfgOptPgHostPort, 1), 3333, "set port");
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("set default when repo-host-type is tls");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHost, 1, "host1");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostType, 1, "tls");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostCertFile, 1, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostKeyFile, 1, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHost, 2, "host2");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostType, 2, "tls");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostCertFile, 2, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostKeyFile, 2, "/not-used");
|
||||||
|
hrnCfgArgKeyRawZ(argList, cfgOptRepoHostPort, 2, "4444");
|
||||||
|
HRN_CFG_LOAD(cfgCmdInfo, argList);
|
||||||
|
|
||||||
|
TEST_RESULT_UINT(cfgOptionIdxUInt(cfgOptRepoHostPort, 0), 8432, "default port");
|
||||||
|
TEST_RESULT_UINT(cfgOptionIdxUInt(cfgOptRepoHostPort, 1), 4444, "set port");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("invalid bucket name with verification enabled fails");
|
TEST_TITLE("invalid bucket name with verification enabled fails");
|
||||||
|
|
||||||
|
@ -714,7 +714,7 @@ testRun(void)
|
|||||||
hrnLogReplaceAdd("(could not connect to server|connection to server on socket).*$", NULL, "PG ERROR", false);
|
hrnLogReplaceAdd("(could not connect to server|connection to server on socket).*$", NULL, "PG ERROR", false);
|
||||||
TEST_RESULT_LOG(
|
TEST_RESULT_LOG(
|
||||||
"P00 WARN: unable to check pg-4: [DbConnectError] unable to connect to 'dbname='postgres' port=5433': error\n"
|
"P00 WARN: unable to check pg-4: [DbConnectError] unable to connect to 'dbname='postgres' port=5433': error\n"
|
||||||
"P00 WARN: unable to check pg-5: [DbConnectError] raised from remote-0 protocol on 'localhost':"
|
"P00 WARN: unable to check pg-5: [DbConnectError] raised from remote-0 ssh protocol on 'localhost':"
|
||||||
" unable to connect to 'dbname='postgres' port=5432': [PG ERROR]");
|
" unable to connect to 'dbname='postgres' port=5432': [PG ERROR]");
|
||||||
|
|
||||||
TEST_RESULT_INT(result.primaryIdx, 3, "check primary idx");
|
TEST_RESULT_INT(result.primaryIdx, 3, "check primary idx");
|
||||||
|
@ -14,6 +14,7 @@ Test Protocol
|
|||||||
#include "common/harnessError.h"
|
#include "common/harnessError.h"
|
||||||
#include "common/harnessFork.h"
|
#include "common/harnessFork.h"
|
||||||
#include "common/harnessPack.h"
|
#include "common/harnessPack.h"
|
||||||
|
#include "common/harnessServer.h"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Test protocol server command handlers
|
Test protocol server command handlers
|
||||||
@ -693,6 +694,183 @@ testRun(void)
|
|||||||
HRN_FORK_END();
|
HRN_FORK_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// *****************************************************************************************************************************
|
||||||
|
if (testBegin("protocolRemoteExec() and protocolServer()"))
|
||||||
|
{
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("invalid allow list");
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
protocolServerAuthorize(STRDEF(" "), NULL), OptionInvalidValueError, "'tls-server-auth' option must have a value");
|
||||||
|
|
||||||
|
HRN_FORK_BEGIN()
|
||||||
|
{
|
||||||
|
HRN_FORK_CHILD_BEGIN()
|
||||||
|
{
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("ping server");
|
||||||
|
|
||||||
|
// Connect to server without any verification
|
||||||
|
IoClient *tlsClient = tlsClientNew(
|
||||||
|
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 5000, 5000, false, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
IoSession *tlsSession = ioClientOpen(tlsClient);
|
||||||
|
|
||||||
|
// Send ping
|
||||||
|
ProtocolClient *protocolClient = protocolClientNew(
|
||||||
|
PROTOCOL_SERVICE_REMOTE_STR, PROTOCOL_SERVICE_REMOTE_STR, ioSessionIoRead(tlsSession),
|
||||||
|
ioSessionIoWrite(tlsSession));
|
||||||
|
protocolClientNoExit(protocolClient);
|
||||||
|
protocolClientNoOp(protocolClient);
|
||||||
|
protocolClientFree(protocolClient);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("connect to repo server");
|
||||||
|
|
||||||
|
StringList *argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, "/pg");
|
||||||
|
hrnCfgArgRaw(argList, cfgOptRepoHost, hrnServerHost());
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostType, "tls");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostCertFile, HRN_SERVER_CLIENT_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostKeyFile, HRN_SERVER_CLIENT_KEY);
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", hrnServerPort(0));
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
HRN_CFG_LOAD(cfgCmdArchiveGet, argList);
|
||||||
|
|
||||||
|
ProtocolHelperClient helper = {0};
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(protocolRemoteExec(&helper, protocolStorageTypeRepo, 0, 0), "get remote protocol");
|
||||||
|
TEST_RESULT_VOID(protocolClientFree(helper.client), "free remote protocol");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("access denied connecting to repo server (invalid stanza)");
|
||||||
|
|
||||||
|
TEST_ERROR_FMT(
|
||||||
|
protocolRemoteExec(&helper, protocolStorageTypeRepo, 0, 0), AccessError,
|
||||||
|
"raised from remote-0 tls protocol on '%s': access denied", strZ(hrnServerHost()));
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("access denied connecting to repo server (invalid client)");
|
||||||
|
|
||||||
|
TEST_ERROR_FMT(
|
||||||
|
protocolRemoteExec(&helper, protocolStorageTypeRepo, 0, 0), AccessError,
|
||||||
|
"raised from remote-0 tls protocol on '%s': access denied", strZ(hrnServerHost()));
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("access denied connecting to repo server without a stanza");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRaw(argList, cfgOptRepoHost, hrnServerHost());
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostType, "tls");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostCertFile, HRN_SERVER_CLIENT_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoHostKeyFile, HRN_SERVER_CLIENT_KEY);
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptRepoHostPort, "%u", hrnServerPort(0));
|
||||||
|
HRN_CFG_LOAD(cfgCmdInfo, argList);
|
||||||
|
|
||||||
|
TEST_ERROR_FMT(
|
||||||
|
protocolRemoteExec(&helper, protocolStorageTypeRepo, 0, 0), AccessError,
|
||||||
|
"raised from remote-0 tls protocol on '%s': access denied", strZ(hrnServerHost()));
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("connect to pg server");
|
||||||
|
|
||||||
|
argList = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptRepoPath, "/repo");
|
||||||
|
hrnCfgArgRaw(argList, cfgOptPgHost, hrnServerHost());
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, "/pg");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostType, "tls");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostCertFile, HRN_SERVER_CLIENT_CERT);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgHostKeyFile, HRN_SERVER_CLIENT_KEY);
|
||||||
|
hrnCfgArgRawFmt(argList, cfgOptPgHostPort, "%u", hrnServerPort(0));
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptProcess, "1");
|
||||||
|
HRN_CFG_LOAD(cfgCmdBackup, argList, .role = cfgCmdRoleLocal);
|
||||||
|
|
||||||
|
helper = (ProtocolHelperClient){0};
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(protocolRemoteExec(&helper, protocolStorageTypePg, 0, 0), "get remote protocol");
|
||||||
|
TEST_RESULT_VOID(protocolClientFree(helper.client), "free remote protocol");
|
||||||
|
}
|
||||||
|
HRN_FORK_CHILD_END();
|
||||||
|
|
||||||
|
HRN_FORK_PARENT_BEGIN()
|
||||||
|
{
|
||||||
|
IoServer *const tlsServer = tlsServerNew(
|
||||||
|
STRDEF("localhost"), STRDEF(HRN_SERVER_CA), STRDEF(HRN_SERVER_KEY), STRDEF(HRN_SERVER_CERT), 5000);
|
||||||
|
IoServer *const socketServer = sckServerNew(STRDEF("localhost"), hrnServerPort(0), 5000);
|
||||||
|
ProtocolServer *server = NULL;
|
||||||
|
|
||||||
|
// Server ping
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
IoSession *socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ASSIGN(server, protocolServer(tlsServer, socketSession), "server start");
|
||||||
|
TEST_RESULT_PTR(server, NULL, "server is null");
|
||||||
|
|
||||||
|
// Repo server (archive-get)
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
StringList *const argListBase = strLstNew();
|
||||||
|
hrnCfgArgRawZ(argListBase, cfgOptTlsServerCaFile, HRN_SERVER_CA);
|
||||||
|
hrnCfgArgRawZ(argListBase, cfgOptTlsServerCertFile, HRN_SERVER_CERT);
|
||||||
|
hrnCfgArgRawZ(argListBase, cfgOptTlsServerKeyFile, HRN_SERVER_KEY);
|
||||||
|
|
||||||
|
StringList *argList = strLstDup(argListBase);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "pgbackrest-client=db");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ASSIGN(server, protocolServer(tlsServer, socketSession), "server start");
|
||||||
|
TEST_RESULT_PTR_NE(server, NULL, "server is not null");
|
||||||
|
TEST_RESULT_UINT(protocolServerCommandGet(server).id, PROTOCOL_COMMAND_EXIT, "server exit");
|
||||||
|
|
||||||
|
// Repo server access denied (archive-get) invalid stanza
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
argList = strLstDup(argListBase);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "pgbackrest-client=bogus");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ERROR(protocolServer(tlsServer, socketSession), AccessError, "access denied");
|
||||||
|
|
||||||
|
// Repo server access denied (archive-get) invalid client
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
argList = strLstDup(argListBase);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "bogus=*");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ERROR(protocolServer(tlsServer, socketSession), AccessError, "access denied");
|
||||||
|
|
||||||
|
// Repo server access denied (info)
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
argList = strLstDup(argListBase);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "pgbackrest-client=db");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ERROR(protocolServer(tlsServer, socketSession), AccessError, "access denied");
|
||||||
|
|
||||||
|
// Pg server (backup)
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
argList = strLstDup(argListBase);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptTlsServerAuth, "pgbackrest-client=*");
|
||||||
|
HRN_CFG_LOAD(cfgCmdServerStart, argList);
|
||||||
|
|
||||||
|
socketSession = ioServerAccept(socketServer, NULL);
|
||||||
|
|
||||||
|
TEST_ASSIGN(server, protocolServer(tlsServer, socketSession), "server start");
|
||||||
|
TEST_RESULT_PTR_NE(server, NULL, "server is not null");
|
||||||
|
TEST_RESULT_UINT(protocolServerCommandGet(server).id, PROTOCOL_COMMAND_EXIT, "server exit");
|
||||||
|
}
|
||||||
|
HRN_FORK_PARENT_END();
|
||||||
|
}
|
||||||
|
HRN_FORK_END();
|
||||||
|
}
|
||||||
|
|
||||||
// *****************************************************************************************************************************
|
// *****************************************************************************************************************************
|
||||||
if (testBegin("ProtocolParallel and ProtocolParallelJob"))
|
if (testBegin("ProtocolParallel and ProtocolParallelJob"))
|
||||||
{
|
{
|
||||||
|
@ -430,7 +430,7 @@ testRun(void)
|
|||||||
// Replace the default authClient with one that points locally. The default host and url will still be used so they
|
// Replace the default authClient with one that points locally. The default host and url will still be used so they
|
||||||
// can be verified when testing auth.
|
// can be verified when testing auth.
|
||||||
((StorageGcs *)storageDriver(storage))->authClient = httpClientNew(
|
((StorageGcs *)storageDriver(storage))->authClient = httpClientNew(
|
||||||
sckClientNew(hrnServerHost(), testPortMeta, 2000), 2000);
|
sckClientNew(hrnServerHost(), testPortMeta, 2000, 2000), 2000);
|
||||||
|
|
||||||
// Tests need the chunk size to be 16
|
// Tests need the chunk size to be 16
|
||||||
((StorageGcs *)storageDriver(storage))->chunkSize = 16;
|
((StorageGcs *)storageDriver(storage))->chunkSize = 16;
|
||||||
|
@ -265,7 +265,8 @@ testRun(void)
|
|||||||
httpClientToLog(driver->httpClient),
|
httpClientToLog(driver->httpClient),
|
||||||
strNewFmt(
|
strNewFmt(
|
||||||
"{ioClient: {type: tls, driver: {ioClient: {type: socket, driver: {host: bucket.s3.amazonaws.com, port: 443"
|
"{ioClient: {type: tls, driver: {ioClient: {type: socket, driver: {host: bucket.s3.amazonaws.com, port: 443"
|
||||||
", timeout: 60000}}, timeout: 60000, verifyPeer: %s}}, reusable: 0, timeout: 60000}",
|
", timeoutConnect: 60000, timeoutSession: 60000}}, timeoutConnect: 60000, timeoutSession: 60000"
|
||||||
|
", verifyPeer: %s}}, reusable: 0, timeout: 60000}",
|
||||||
cvtBoolToConstZ(TEST_IN_CONTAINER)),
|
cvtBoolToConstZ(TEST_IN_CONTAINER)),
|
||||||
"check http client");
|
"check http client");
|
||||||
|
|
||||||
@ -320,7 +321,7 @@ testRun(void)
|
|||||||
argList = strLstDup(commonArgWithoutEndpointList);
|
argList = strLstDup(commonArgWithoutEndpointList);
|
||||||
hrnCfgArgRawZ(argList, cfgOptRepoS3Endpoint, "custom.endpoint:333");
|
hrnCfgArgRawZ(argList, cfgOptRepoS3Endpoint, "custom.endpoint:333");
|
||||||
hrnCfgArgRawZ(argList, cfgOptRepoStorageCaPath, "/path/to/cert");
|
hrnCfgArgRawZ(argList, cfgOptRepoStorageCaPath, "/path/to/cert");
|
||||||
hrnCfgArgRawZ(argList, cfgOptRepoStorageCaFile, HRN_PATH_REPO "/" HRN_SERVER_CERT_PREFIX ".crt");
|
hrnCfgArgRawZ(argList, cfgOptRepoStorageCaFile, HRN_SERVER_CA);
|
||||||
hrnCfgEnvRaw(cfgOptRepoS3Token, securityToken);
|
hrnCfgEnvRaw(cfgOptRepoS3Token, securityToken);
|
||||||
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
|
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
|
||||||
|
|
||||||
@ -331,7 +332,8 @@ testRun(void)
|
|||||||
httpClientToLog(driver->httpClient),
|
httpClientToLog(driver->httpClient),
|
||||||
strNewFmt(
|
strNewFmt(
|
||||||
"{ioClient: {type: tls, driver: {ioClient: {type: socket, driver: {host: bucket.custom.endpoint, port: 333"
|
"{ioClient: {type: tls, driver: {ioClient: {type: socket, driver: {host: bucket.custom.endpoint, port: 333"
|
||||||
", timeout: 60000}}, timeout: 60000, verifyPeer: %s}}, reusable: 0, timeout: 60000}",
|
", timeoutConnect: 60000, timeoutSession: 60000}}, timeoutConnect: 60000, timeoutSession: 60000"
|
||||||
|
", verifyPeer: %s}}, reusable: 0, timeout: 60000}",
|
||||||
cvtBoolToConstZ(TEST_IN_CONTAINER)),
|
cvtBoolToConstZ(TEST_IN_CONTAINER)),
|
||||||
"check http client");
|
"check http client");
|
||||||
|
|
||||||
@ -455,7 +457,7 @@ testRun(void)
|
|||||||
|
|
||||||
// Testing requires the auth http client to be redirected
|
// Testing requires the auth http client to be redirected
|
||||||
driver->credHost = hrnServerHost();
|
driver->credHost = hrnServerHost();
|
||||||
driver->credHttpClient = httpClientNew(sckClientNew(host, authPort, 5000), 5000);
|
driver->credHttpClient = httpClientNew(sckClientNew(host, authPort, 5000, 5000), 5000);
|
||||||
|
|
||||||
// Now that we have checked the role when set explicitly, null it out to make sure it is retrieved automatically
|
// Now that we have checked the role when set explicitly, null it out to make sure it is retrieved automatically
|
||||||
driver->credRole = NULL;
|
driver->credRole = NULL;
|
||||||
|
@ -102,6 +102,11 @@ The test code is included directly so it can freely interact with the included C
|
|||||||
#include "common/memContext.h"
|
#include "common/memContext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HRN_FEATURE_LOG
|
||||||
|
#include "common/harnessLog.h"
|
||||||
|
void harnessLogLevelDefaultSet(LogLevel logLevel);
|
||||||
|
#endif
|
||||||
|
|
||||||
{[C_TEST_INCLUDE]}
|
{[C_TEST_INCLUDE]}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
@ -109,7 +114,10 @@ Includes that are not generally used by tests
|
|||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "common/io/socket/common.h"
|
#if defined(HRN_INTEST_SOCKET) || defined(HRN_FEATURE_SOCKET)
|
||||||
|
#include "common/io/socket/common.h"
|
||||||
|
#include "common/harnessServer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HRN_FEATURE_STAT
|
#ifdef HRN_FEATURE_STAT
|
||||||
#include "common/stat.h"
|
#include "common/stat.h"
|
||||||
@ -162,11 +170,6 @@ main(int argListSize, const char *argList[])
|
|||||||
statInit();
|
statInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use aggressive keep-alive settings for testing
|
|
||||||
#if defined(HRN_INTEST_SOCKET) || defined(HRN_FEATURE_SOCKET)
|
|
||||||
sckInit(false, true, 2, 5, 5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set neutral umask for testing
|
// Set neutral umask for testing
|
||||||
umask(0000);
|
umask(0000);
|
||||||
|
|
||||||
@ -192,6 +195,12 @@ main(int argListSize, const char *argList[])
|
|||||||
harnessLogLevelDefaultSet({[C_LOG_LEVEL_TEST]});
|
harnessLogLevelDefaultSet({[C_LOG_LEVEL_TEST]});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Use aggressive keep-alive settings for testing
|
||||||
|
#if defined(HRN_INTEST_SOCKET) || defined(HRN_FEATURE_SOCKET)
|
||||||
|
sckInit(false, true, 2, 5, 5);
|
||||||
|
hrnServerInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize tests
|
// Initialize tests
|
||||||
// run, selected
|
// run, selected
|
||||||
{[C_TEST_LIST]}
|
{[C_TEST_LIST]}
|
||||||
|
Reference in New Issue
Block a user