-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: Build and publish image | ||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
IMAGE_NAME: ${{ github.repository }} | ||
|
||
jobs: | ||
build-and-push-image: | ||
runs-on: ubuntu-latest | ||
defaults: | ||
run: | ||
working-directory: './app' | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Log in to the Container registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GH_TOKEN }} | ||
|
||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
|
||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v6 | ||
with: | ||
context: . | ||
push: true | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
FROM docker.io/golang:1.22.0 | ||
|
||
LABEL org.opencontainers.image.title=ceph-cft | ||
LABEL org.opencontainers.image.description="Configure your ceph cluster with environment variables" | ||
LABEL org.opencontainers.image.version=0.1.0 | ||
LABEL org.opencontainers.image.licenses=GPL-3.0 | ||
LABEL org.opencontainers.image.url=https://github.com/pr0ton11/ceph-cft | ||
LABEL org.opencontainers.image.source=https://github.com/pr0ton11/ceph-cft | ||
LABEL org.opencontainers.image.authors=pr0ton11 | ||
|
||
ENV CGO_ENABLED=0 | ||
ENV GOOS=linux | ||
|
||
COPY . /app | ||
|
||
WORKDIR /app | ||
|
||
RUN go mod download && go build -ldflags="-s -w" -o /app/ceph-cft |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Ceph Config Format Tool | ||
|
||
This tool allows to configure your Ceph cluster simply by defining environment variables prefixed with *CEPH_* | ||
|
||
Uses restrictions of https://docs.ceph.com/en/latest/rados/configuration/ceph-conf | ||
|
||
## How does it work? | ||
|
||
It iterates through the defined environment variables and: | ||
|
||
* Detects if a variable if prefixed with Ceph | ||
* Contains a valid configuration section (default: global) | ||
* Supports fine grained configuration of specific individual daemons (e.g client.1) by replacing *__* with *.* | ||
* Writes the updated ceph configuration file | ||
|
||
## How do I use it | ||
|
||
Just run ceph-cft before you start your ceph daemons and it will update / override the configuration values in ceph.conf based on environment variables. | ||
|
||
## How do I define a custom path to ceph.conf? | ||
|
||
This can be accomplished by setting the environment variable ``` CFT_CONFIG_PATH ```. Default is ```/etc/ceph/ceph.conf```. | ||
|
||
## Examples | ||
|
||
The following environment variables were set: | ||
|
||
``` | ||
CEPH_GLOBAL_LOG_FILE='/var/log/ceph/$cluster-$type.$id.log' | ||
CEPH_OSD_OP_QUEUE=wpq | ||
CEPH_MON_LOG_TO_SYSLOG=true | ||
CEPH_TEST_WITHOUT_SECTION=works | ||
CEPH_CONTAINS_WHITESPACES="Hello World" | ||
CEPH_OSD__1_OBJECTER_INFLIGHT_OPS=512 | ||
``` | ||
|
||
This leads to the generation of the following configuration file: | ||
|
||
``` | ||
[global] | ||
log_file = /var/log/ceph/$cluster-$type.$id.log | ||
test_without_section = works | ||
contains_whitespaces = "hello world" | ||
[osd] | ||
op_queue = wpq | ||
[mon] | ||
log_to_syslog = true | ||
[osd.1] | ||
objecter_inflight_ops = 512 | ||
``` | ||
|
||
|
||
## Where is it used | ||
|
||
This tool is used for the following projects: | ||
|
||
* https://github.com/pr0ton11/radosgw | ||
* https://github.com/pr0ton11/ceph-yocto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/pr0ton11/ceph-cft | ||
|
||
go 1.22.4 | ||
|
||
require gopkg.in/ini.v1 v1.67.0 // indirect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= | ||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"os" | ||
"strings" | ||
|
||
"gopkg.in/ini.v1" | ||
) | ||
|
||
// Allowed section prefixes in the configuration file | ||
var ALLOWED_SECTION_PREFIX []string = []string{"global", "mon", "mgr", "osd", "mds", "client"} | ||
|
||
// This application is a simple utility to manage the Ceph configuration file by defining configuration values as environment variables. | ||
// The application will load the current configuration file, update the values based on the environment variables, and write the updated configuration file. | ||
// Format of the environment variables: CEPH_{SECTION}_{KEY}={VALUE} | ||
// Example: CEPH_GLOBAL_CLUSTER_NETWORK=10.0.0.0/24 | ||
// If the section is not defined, the application will use the default section (GLOBAL). | ||
|
||
func main() { | ||
// Retrieve the configuration path | ||
configPath, ok := os.LookupEnv("CFT_CONFIG_PATH") | ||
// Otherwise, use the default path to the configuration file | ||
if !ok { | ||
configPath = "/etc/ceph/ceph.conf" | ||
} | ||
|
||
// Load the current configuration | ||
current, err := ini.Load(configPath) | ||
if err != nil { | ||
log.Printf("Error loading the current configuration file %s: %v", configPath, err) | ||
current = ini.Empty() | ||
} | ||
|
||
// Iterate over the environment variables | ||
for _, env := range os.Environ() { | ||
// Workaround for the issue that dots are not allowed in environment variables | ||
// Replace the double underscore with a dot | ||
env = strings.Replace(env, "__", ".", -1) | ||
// Convert the environment variable to lower case for simplicity | ||
env = strings.ToLower(env) | ||
// Split the environment variable into key and value | ||
assignment := strings.Split(env, "=") | ||
// Assign the key | ||
key := assignment[0] | ||
// Assign the value | ||
value := assignment[1] | ||
|
||
// Check if the environment variable is a ceph configuration variable | ||
if strings.HasPrefix(key, "ceph_") { | ||
log.Printf("Found key: %s with value: %s", key, value) | ||
// Split the key further into section and configuration key | ||
keyParts := strings.Split(key, "_") | ||
// Set flag to detect if the section is defined | ||
sectionDetected := false | ||
// Check if the section is defined | ||
detectedSection := "global" | ||
// Only allow prefixes if they are defined in the allowed section prefixes | ||
for _, section := range ALLOWED_SECTION_PREFIX { | ||
if strings.HasPrefix(keyParts[1], section) { | ||
sectionDetected = true | ||
detectedSection = keyParts[1] | ||
} | ||
} | ||
// Output a warning if the section is not defined | ||
if !sectionDetected { | ||
log.Printf("No section deteced in key %s, using default %s", key, detectedSection) | ||
} else { | ||
log.Printf("Detected section: %s for key %s", detectedSection, key) | ||
} | ||
// Cleanup the key by removing both the prefix and the section if defined | ||
if sectionDetected { | ||
key = strings.Join(keyParts[2:], "_") | ||
} else { | ||
key = strings.Join(keyParts[1:], "_") | ||
} | ||
|
||
// If the value contains a space, wrap it in quotes | ||
if strings.Contains(value, " ") { | ||
if !strings.HasPrefix(value, "\"") && !strings.HasSuffix(value, "\"") { | ||
value = "\"" + value + "\"" | ||
} | ||
} | ||
|
||
// Update the configuration | ||
log.Printf("Setting key: %s with value: %s in section: %s", key, value, detectedSection) | ||
current.Section(detectedSection).Key(key).SetValue(value) | ||
} | ||
|
||
// Write the updated configuration | ||
err = current.SaveTo(configPath) | ||
if err != nil { | ||
log.Printf("Error saving the updated configuration file %s: %v", configPath, err) | ||
} | ||
} | ||
|
||
} |