Compare commits

...

14 Commits

Author SHA1 Message Date
3uzbcqje 8ed5721cd6 Removing debugging. 2026-08-27 23:56:45 +02:00
3uzbcqje 3daecd3465 Woodpecker is being a peckerwood. 2026-08-27 23:56:45 +02:00
3uzbcqje b14bcd15c2 Debugging 2026-08-27 23:56:44 +02:00
3uzbcqje 9411e6c2ee Removing bad escaping 2026-08-27 23:56:44 +02:00
3uzbcqje fbe76255d5 Going back to using a script, because Woodpecker CI requires $$ escaping, which is annoying. 2026-08-27 23:56:44 +02:00
3uzbcqje 6f98c392b5 Consolidating and simplifying CI 2026-08-27 23:56:44 +02:00
3uzbcqje b5006b7cce garage uses default branch name main-v2 2026-08-27 23:56:44 +02:00
3uzbcqje b41e0f49bf Adding workflow and script to build helm chart. 2026-08-27 23:56:43 +02:00
maximilien 05e294307e Merge pull request 'doc: update on k2v inclusion in builds' (#1513) from vincent/garage:main-v2 into main-v2
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1513
2026-08-23 19:57:51 +00:00
Vincent 109fbd49b1 Update information about k2v inclusion in builds 2026-08-23 20:57:21 +02:00
i5-650 d0176f8e30 deregister from consul on shutdown (fix #1062) (#1507)
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1507
2026-08-22 17:19:51 +00:00
i5-650 d9b1dba137 1250 - add NO_COLOR env var to disable logs colors (#1503)
Fix #1250

Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1503
Reviewed-by: Alex <lx@deuxfleurs.fr>
2026-08-19 08:03:44 +00:00
Agathe Porte c3c8af9a66 doc: quick-start: rework flag description (#1496)
Add a link to the manual install procedure, use a
quote to make the manual install path more visible
and mention the --default-access-key option.

Closes: #1446

Rendered output:

![image](/attachments/84bbe650-daff-40d1-b4bd-629abece27b0)

Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1496
2026-07-25 14:48:53 +00:00
Alex Auvolat ad78b9ee5c CI: revert spurrious changed introduced in #1487 that broke CI for main-v2 (#1499)
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1499
2026-07-25 13:25:17 +00:00
10 changed files with 139 additions and 14 deletions
+38
View File
@@ -0,0 +1,38 @@
steps:
helm:
when:
- event: pull_request
branch: main-v2
- event: push
branch: main-v2
image: alpine/helm:4.1.1
environment:
chart_dir: script/helm/garage
chart_name: garage
registry_host: codeberg.org
registry_user: ${CI_REPO_OWNER}
registry_path: ${CI_REPO}
# To create registry_password:
# 1. Go to https://codeberg.org/user/settings/applications.
# 2. Create a token with these settings:
# - Token name: https://git.deuxfleurs.fr/3uzbcqje/garage/src/branch/main-v2/.woodpecker/helm.yaml
# - Set package permission to "Read and write".
# 3. Click "Generate token".
# 4. Copy the token.
# 5. Log into https://ci.codeberg.org.
# 6. Find your repo, and add a secret with these settings:
# - Name: registry_password
# - Value: <the token you copied earlier>
# 7. Click "Add secret".
registry_password:
from_secret: registry_password
commands:
- |
if [[ "${CI_PIPELINE_EVENT}" == "push" && "${CI_COMMIT_BRANCH}" == "${CI_REPO_DEFAULT_BRANCH}" ]]; then
./pipeline.sh push
else
./pipeline.sh
fi
+11 -6
View File
@@ -133,12 +133,17 @@ Use the following command to launch the Garage server:
garage server --single-node --default-bucket garage server --single-node --default-bucket
``` ```
The `--single-node` flag instructs Garage to automatically configure a single-node cluster without data replication. - the `--single-node` flag instructs Garage to automatically configure a
The `--default-bucket` flag instructs Garage to create a default access key and a default bucket using the environment variables we defined above. single-node cluster without data replication;
Both flags are optional and can be omitted, in which case you will have to follow manual configuration steps described below. - the `--default-bucket` flag instructs Garage to create a default access key
and a default bucket using the environment variables we defined above (it
implies `--default-access-key`).
**For older versions of Garage (before v2.3.0):** automatic configuration using `--single-node` and `--default-bucket` is not available, > You can refer to the [manual configuration
you must follow the manual configuration steps. > steps](#manual-configuration) if:
>
> - you decide to no use these optional flags;
> - you are running an **older version of Garage (before v2.3.0)**.
Alternatively, if you cannot or do not wish to run the Garage binary directly, Alternatively, if you cannot or do not wish to run the Garage binary directly,
you may use Docker to run Garage in a container using the following command: you may use Docker to run Garage in a container using the following command:
@@ -292,7 +297,7 @@ An exhaustive list is maintained in the ["Integrations" > "Browsing tools" secti
## Manual configuration ## Manual configuration {#manual-configuration}
This section provides instructions that are equivalent to using the This section provides instructions that are equivalent to using the
`--single-node` and `--default-bucket` flags for automatic configuration. If `--single-node` and `--default-bucket` flags for automatic configuration. If
@@ -175,6 +175,9 @@ they do not exist in the configuration file:
Garage daemon send its logs to `journald` (using the native protocol of `systemd-journald`) Garage daemon send its logs to `journald` (using the native protocol of `systemd-journald`)
instead of printing to stderr. instead of printing to stderr.
- `NO_COLOR` (since `v2.4.0`): set this to `0` or `false` to disable
ANSI color codes in Garage's logs.
The following environment variables can be used to override the corresponding The following environment variables can be used to override the corresponding
values in the configuration file: values in the configuration file:
+5 -6
View File
@@ -8,12 +8,11 @@ which is an alternative storage API designed to help efficiently store
many small values in buckets (in opposition to S3 which is more designed many small values in buckets (in opposition to S3 which is more designed
to store large blobs). to store large blobs).
K2V is currently disabled at compile time in all builds, as the K2V is included in release builds since version 0.8.0. Precompiled builds
specification is still subject to changes. To build a Garage version with of earlier versions including `k2v` can be found in our download page under
K2V, the Cargo feature flag `k2v` must be activated. Special builds with "Extra builds": they can be easily identified as their tag name ends with
the `k2v` feature flag enabled can be obtained from our download page under `-k2v` (example: `v0.7.2-k2v`). Otherwise, when compiling Garage, the Cargo
"Extra builds": such builds can be identified easily as their tag name ends feature flag `k2v` must be activated.
with `-k2v` (example: `v0.7.2-k2v`).
The specification of the K2V API can be found The specification of the K2V API can be found
[here](https://git.deuxfleurs.fr/Deuxfleurs/garage/src/commit/f8be15c37db857e177d543de7be863692628d567/doc/drafts/k2v-spec.md). [here](https://git.deuxfleurs.fr/Deuxfleurs/garage/src/commit/f8be15c37db857e177d543de7be863692628d567/doc/drafts/k2v-spec.md).
Executable
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
# Not using "-x" because we aren't debugging.
set -Eeuo pipefail
# We get unbound var err if we don't set arg
arg="${1:-}"
echo "${registry_password}" | helm registry login -u "${registry_user}" --password-stdin "${registry_host}"
helm lint "${chart_dir}"
chart_version=$(grep '^version: ' "${chart_dir}/Chart.yaml" | cut -d' ' -f 2)
helm package "${chart_dir}"
# If chart already exists in the chart repository, don't push.
if helm pull "oci://${registry_host}/${registry_path}/${chart_name}" --version "${chart_version}" &> /dev/null; then
echo -e "\e[31mWARNING: Chart ${chart_name} version ${chart_version} already exists in the repository.\nThis means that the chart's code has not changed, or you forgot to update the version in Chart.yaml.\e[0m"
else
if [[ $arg == 'push' ]]; then
helm push "${chart_name}-${chart_version}.tgz" "oci://${registry_host}/${registry_path}"
fi
fi
+1 -1
View File
@@ -18,7 +18,7 @@ fi
$GARAGE_BIN -c /tmp/config.1.toml bucket create eprouvette $GARAGE_BIN -c /tmp/config.1.toml bucket create eprouvette
if [ "$GARAGE_OLDVER" = "v08" ]; then if [ "$GARAGE_OLDVER" = "v08" ]; then
KEY_INFO=$($GARAGE_BIN -c /tmp/config.1.toml key create opérateur) KEY_INFO=$($GARAGE_BIN -c /tmp/config.1.toml key new --name opérateur)
ACCESS_KEY=`echo $KEY_INFO|grep -Po 'GK[a-f0-9]+'` ACCESS_KEY=`echo $KEY_INFO|grep -Po 'GK[a-f0-9]+'`
SECRET_KEY=`echo $KEY_INFO|grep -Po 'Secret key: [a-f0-9]+'|grep -Po '[a-f0-9]+$'` SECRET_KEY=`echo $KEY_INFO|grep -Po 'Secret key: [a-f0-9]+'|grep -Po '[a-f0-9]+$'`
elif [ "$GARAGE_OLDVER" = "v1" ]; then elif [ "$GARAGE_OLDVER" = "v1" ]; then
+5
View File
@@ -276,6 +276,11 @@ fn init_logging(opt: &Opt) {
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_writer(std::io::stderr) .with_writer(std::io::stderr)
.with_env_filter(env_filter) .with_env_filter(env_filter)
.with_ansi(
std::env::var("NO_COLOR")
.map(|x| x != "0" && !x.eq_ignore_ascii_case("false"))
.unwrap_or(true),
)
.init(); .init();
} }
+14
View File
@@ -152,6 +152,14 @@ pub async fn run_server(
} }
} }
// Deregister from Consul (if enabled) in the background, in parallel with the
// rest of the shutdown sequence, so that it doesn't add to shutdown latency.
#[cfg(feature = "consul-discovery")]
let deregister_consul_task = tokio::spawn({
let system = garage.system.clone();
async move { system.deregister_from_discovery().await }
});
// Remove RPC handlers for system to break reference cycles // Remove RPC handlers for system to break reference cycles
info!("Deregistering RPC handlers for shutdown..."); info!("Deregistering RPC handlers for shutdown...");
garage.system.netapp.drop_all_handlers(); garage.system.netapp.drop_all_handlers();
@@ -168,6 +176,12 @@ pub async fn run_server(
// Await for all background tasks to end // Await for all background tasks to end
await_background_done.await?; await_background_done.await?;
// Await for Consul deregistration to end, if it hasn't already
#[cfg(feature = "consul-discovery")]
if let Err(e) = deregister_consul_task.await {
error!("Error while joining Consul deregistration task: {}", e);
}
info!("Cleaning up..."); info!("Cleaning up...");
Ok(()) Ok(())
+30
View File
@@ -183,6 +183,36 @@ impl ConsulDiscovery {
} }
// ---- PUBLISHING TO CONSUL CATALOG ---- // ---- PUBLISHING TO CONSUL CATALOG ----
#[cfg(feature = "consul-discovery")]
pub async fn deregister_consul_service(&self, node_id: NodeID) -> Result<(), ConsulError> {
let node = format!("garage:{}", hex::encode(&node_id[..8]));
let url = format!(
"{}/v1/{}",
self.config.consul_http_addr,
(match &self.config.api {
ConsulDiscoveryAPI::Catalog => format!("catalog/deregister"),
ConsulDiscoveryAPI::Agent => format!("agent/service/deregister/{}", node),
})
);
let req = self.client.put(&url);
let http = if matches!(&self.config.api, ConsulDiscoveryAPI::Catalog) {
let deregister_request = serde_json::json!({
"Node": node,
"ServiceID": node,
});
let req = req.json(&deregister_request);
req.send().await?
} else {
req.send().await?
};
http.error_for_status()?;
debug!("Deregistered service {} from Consul", node);
Ok(())
}
pub async fn publish_consul_service( pub async fn publish_consul_service(
&self, &self,
node_id: NodeID, node_id: NodeID,
+10 -1
View File
@@ -358,7 +358,7 @@ impl System {
); );
} }
pub fn cleanup(&self) { pub fn cleanup(self: &Arc<Self>) {
// Break reference cycle // Break reference cycle
self.metrics.store(None); self.metrics.store(None);
} }
@@ -650,6 +650,15 @@ impl System {
} }
} }
#[cfg(feature = "consul-discovery")]
pub async fn deregister_from_discovery(self: &Arc<Self>) {
if let Some(c) = &self.consul_discovery {
if let Err(e) = c.deregister_consul_service(self.netapp.id).await {
error!("Error while deregistering from Consul: {}", e);
}
}
}
async fn discovery_loop(self: &Arc<Self>, mut stop_signal: watch::Receiver<bool>) { async fn discovery_loop(self: &Arc<Self>, mut stop_signal: watch::Receiver<bool>) {
while !*stop_signal.borrow() { while !*stop_signal.borrow() {
let peers_up = self let peers_up = self