WIP : InfluxDB support #450 #1058

Closed
gautamaggarwal2810 wants to merge 1 commits from gautamaggarwal2810/borgmatic:issue999 into main
Contributor

This is first draft for issue #450.

This is first draft for issue #450.
gautamaggarwal2810 added 1 commit 2025-04-07 07:24:17 +00:00
witten reviewed 2025-04-09 03:51:20 +00:00
witten left a comment
Owner

This looks like a great start! I haven't looked at tests yet, but I wanted to get you some feedback sooner rather than later. Let me know if you have any questions.

This looks like a great start! I haven't looked at tests yet, but I wanted to get you some feedback sooner rather than later. Let me know if you have any questions.
@@ -1181,6 +1181,81 @@ properties:
description: |
Support for the "borgmatic bootstrap" action, used to extract
borgmatic configuration files from a backup archive.
influxdb_databases:
Owner

I would recommend moving this schema section to the bottom of the existing schema for databases. My thinking is that since this is the last database added, it's less of a major database (for borgmatic users) than the existing ones like PostgreSQL.

I would recommend moving this schema section to the bottom of the existing schema for databases. My thinking is that since this is the last database added, it's less of a major database (for borgmatic users) than the existing ones like PostgreSQL.
gautamaggarwal2810 marked this conversation as resolved
@@ -1184,0 +1192,4 @@
influx_command:
type: string
description: |
The InfluxDB executable to use. Defaults to `influx`.
Owner

I think the convention in schema descriptions for this kind of thing is double quotes (e.g. "influx").

I think the convention in schema descriptions for this kind of thing is double quotes (e.g. `"influx"`).
gautamaggarwal2810 marked this conversation as resolved
@@ -1184,0 +1196,4 @@
token:
type: string
description: |
Token to authenticate request. Required to use InfluxDB.
Owner

Each of these need examples (e.g. example: ...) so that they show up properly in generated configuration. You can try borgmatic config generate -d test.yaml to verify.

Each of these need examples (e.g. `example: ...`) so that they show up properly in generated configuration. You can try `borgmatic config generate -d test.yaml` to verify.
gautamaggarwal2810 marked this conversation as resolved
@@ -1184,0 +1201,4 @@
type: string
description: |
HTTP address of InfluxDB. Defaults to http://127.0.0.1:8086.
example: https://example.com:8086
Owner

Other database hooks tend to use hostname to mean a bare hostname (e.g. example.com) and then have a separate port option for any port. And in fact I think you'll need something like that so that borgmatic restore works with this.

The main downside I can see of this is that there wouldn't be a way to specify http vs. https. Maybe a separate tls boolean option would make sense here? But then that might need to be plumbed through to restore as well...

I dunno, let me know your thoughts on this. I'm not super familiar with InfluxDB, so maybe giving connection strings as URLs is standard.

Other database hooks tend to use `hostname` to mean a bare hostname (e.g. `example.com`) and then have a separate `port` option for any port. And in fact I think you'll need something like that so that `borgmatic restore` works with this. The main downside I can see of this is that there wouldn't be a way to specify `http` vs. `https`. Maybe a separate `tls` boolean option would make sense here? But then that might need to be plumbed through to `restore` as well... I dunno, let me know your thoughts on this. I'm not super familiar with InfluxDB, so maybe giving connection strings as URLs is standard.
Author
Contributor

Yes giving connection strings as URL is standard in Influxdb. But it would diverge from conventions used for other database hooks and can cause confusion for users familiar with other hooks.

If consistency with other hooks is a priority, we can take up hostname,port and tls approach.

But if Influxdb users are more accustomed to connection strings, we can retain URL approach but document clearly to avoid confusion.

So how should I proceed on this??

Yes giving connection strings as URL is standard in Influxdb. But it would diverge from conventions used for other database hooks and can cause confusion for users familiar with other hooks. If consistency with other hooks is a priority, we can take up hostname,port and tls approach. But if Influxdb users are more accustomed to connection strings, we can retain URL approach but document clearly to avoid confusion. So how should I proceed on this??
Owner

My thinking is that consistency with other hooks should be the priority here, not just because of consistency for consistency's sake, but for the very practical reason that a bunch of the existing database code assumes there's a hostname, port, etc. and it would actually be more work to not have those.

My thinking is that consistency with other hooks should be the priority here, not just because of consistency for consistency's sake, but for the very practical reason that a bunch of the existing database code assumes there's a hostname, port, etc. and it would actually be more work to not have those.
@@ -1184,0 +1202,4 @@
description: |
HTTP address of InfluxDB. Defaults to http://127.0.0.1:8086.
example: https://example.com:8086
org_id:
Owner

borgmatic option names tend towards the super verbose and spelled out. So calling this organization_id might be more in keeping with that convention. (Usually id itself isn't expanded because it's so ubiquitous.)

borgmatic option names tend towards the super verbose and spelled out. So calling this `organization_id` might be more in keeping with that convention. (Usually `id` itself isn't expanded because it's so ubiquitous.)
@@ -1184,0 +1206,4 @@
type: number
description: |
The ID of the organization.
org_name:
Owner

Similar here.

Similar here.
@@ -1184,0 +1209,4 @@
org_name:
type: string
description: |
The name of the organization.
Owner

Should probably mention that it's mutually exclutive with org_id.

Should probably mention that it's mutually exclutive with `org_id`.
@@ -1184,0 +1217,4 @@
bucket_id:
type: number
description: |
The ID of the bucket to backup.
Owner

IMO this should mention that this option is mutually exclusive with bucket_name.

IMO this should mention that this option is mutually exclusive with `bucket_name`.
@@ -1184,0 +1218,4 @@
type: number
description: |
The ID of the bucket to backup.
configs_path:
Owner

Maybe configs_path -> configurations_path?

Maybe `configs_path` -> `configurations_path`?
@@ -1184,0 +1222,4 @@
type: string
description: |
Path to the influx CLI configurations.
active_config:
Owner

Similar here.. Maybe active_config -> active_configuration.

Similar here.. Maybe `active_config` -> `active_configuration`.
@@ -1184,0 +1229,4 @@
restore_bucket:
type: string
description: |
New name to use for the restored bucket.
Owner

It might be good to add similar restore_* option name variants for other options as well. For instance, many database hooks have options like restore_hostname, restore_port, etc.

It might be good to add similar `restore_*` option name variants for other options as well. For instance, many database hooks have options like `restore_hostname`, `restore_port`, etc.
@@ -1184,0 +1230,4 @@
type: string
description: |
New name to use for the restored bucket.
new_org:
Owner

And I recommend calling this restore_org or better yet restore_organization.

And I recommend calling this `restore_org` or better yet `restore_organization`.
@@ -1184,0 +1246,4 @@
full:
type: boolean
description: |
Fully restore and replace all data on server.
Owner

How does this work exactly? Does it ignore the restore_bucket and restore all buckets? Or something else?

How does this work exactly? Does it ignore the `restore_bucket` and restore all buckets? Or something else?
@@ -0,0 +23,4 @@
def use_streaming(databases, config):
'''
Return whether dump streaming is used for this hook. (Spoiler: It isn't.)
Owner

This comment should be updated so it's consistent with what the function does!

This comment should be updated so it's consistent with what the function does!
@@ -0,0 +40,4 @@
Dump the given InfluxDB databases to a named pipe. The databases are supplied as a sequence of
dicts, one dict describing each database as per the configuration schema. Use the borgmatic
runtime directory to construct the destination path (used for the directory format and the given
log prefix in any log entries.
Owner

Missing close parenthesis.

Missing close parenthesis.
@@ -0,0 +58,4 @@
make_dump_path(borgmatic_runtime_directory),
name,
database.get('hostname'),
database.get('port'),
Owner

It doesn't look like port is actually in the schema—although see above for idea about how it could be!

It doesn't look like `port` is actually in the schema—although see above for idea about how it could be!
@@ -0,0 +71,4 @@
dump.create_named_pipe_for_dump(dump_filename)
try:
execute_command(command, shell=True, run_to_completion=False)
Owner

I think you can probably safely omit shell=True, because I don't see anything in the command building below that relies on shell features (redirection, etc.)

I think you can probably safely omit `shell=True`, because I don't see anything in the command building below that relies on shell features (redirection, etc.)
@@ -0,0 +73,4 @@
try:
execute_command(command, shell=True, run_to_completion=False)
except subprocess.CalledProcessError as error:
logger.error(f"Command failed: {error}")
Owner

Feel free to disagree, but I don't feel like this kind of catch-and-log-and-raise adds a ton of value, especially since it's just displaying the error—which presumably borgmatic already does higher up in the call stack...?

Feel free to disagree, but I don't feel like this kind of catch-and-log-and-raise adds a ton of value, especially since it's just displaying the error—which presumably borgmatic already does higher up in the call stack...?
@@ -0,0 +80,4 @@
patterns.append(
borgmatic.borg.pattern.Pattern(
os.path.join(borgmatic_runtime_directory, 'influxdb_databases')
)
Owner

I think this needs:

source=borgmatic.borg.pattern.Pattern_source.HOOK,

... added in, so that downstream hooks like filesystem snapshotting work properly.

I think this needs: ``` source=borgmatic.borg.pattern.Pattern_source.HOOK, ``` ... added in, so that downstream hooks like filesystem snapshotting work properly.
@@ -0,0 +90,4 @@
'''
Return the backup command.
'''
hostname = database.get('dump_hostname', database.get('hostname')) # Prioritize 'dump_hostname'
Owner

It doesn't look like dump_hostname is in the schema...? Was it intended to be?

It doesn't look like `dump_hostname` is in the schema...? Was it intended to be?
@@ -0,0 +164,4 @@
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
dump_filename = dump.make_data_source_dump_filename(
make_dump_path(borgmatic_runtime_directory),
data_source['name'],
Owner

I didn't actually see a name option in the schema. There probably needs to be one there for the rest of the database machinery to work as well...?

I didn't actually see a `name` option in the schema. There probably needs to be one there for the rest of the database machinery to work as well...?
@@ -0,0 +165,4 @@
dump_filename = dump.make_data_source_dump_filename(
make_dump_path(borgmatic_runtime_directory),
data_source['name'],
data_source.get('hostname'),
Owner

Probably needs port as well if it's there in the make_data_source_dump_filename() call in dump_data_sources(). Otherwise the filenames won't match.

Probably needs `port` as well if it's there in the `make_data_source_dump_filename()` call in `dump_data_sources()`. Otherwise the filenames won't match.
Author
Contributor

Thanks for your feedback @witten. I will make the suggested changes. I am sorry that my response is a bit late but I had a very hectic week at university, so couldnt start before.

Thanks for your feedback @witten. I will make the suggested changes. I am sorry that my response is a bit late but I had a very hectic week at university, so couldnt start before.
Owner

Hey no worries.. School comes first!

Hey no worries.. School comes first!
Owner

Just checking in.. Please let me know if you plan to get back to this. Thanks!

Just checking in.. Please let me know if you plan to get back to this. Thanks!
First-time contributor

@gautamaggarwal2810 Do you want me to implement the suggested changes here? I would love to see this feature released.

@gautamaggarwal2810 Do you want me to implement the suggested changes here? I would love to see this feature released.
Owner

As far as I'm concerned, abandoned PRs are fair game for you to pick up and run with (or rewrite). I totally understand that people get busy with real life.

As far as I'm concerned, abandoned PRs are fair game for you to pick up and run with (or rewrite). I totally understand that people get busy with real life.
First-time contributor

Tried to continue this PR on #1142

Tried to continue this PR on https://projects.torsion.org/borgmatic-collective/borgmatic/pulls/1142
Owner

Closing this due to the continued PR at #1142. Please follow along there. And big thanks to @gautamaggarwal2810 for getting this ball rolling!

Closing this due to the continued PR at #1142. Please follow along there. And big thanks to @gautamaggarwal2810 for getting this ball rolling!
witten closed this pull request 2025-09-09 16:36:54 +00:00

Pull request closed

Sign in to join this conversation.
No Reviewers
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#1058