mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 19:10:21 +00:00
rbd: provide alternatives to preserve the ceph log files
Currently, we delete the ceph client log file on unmap/detach. This patch provides additional alternatives for users who would like to persist the log files. Strategies: ----------- `remove`: delete log file on unmap/detach `compress`: compress the log file to gzip on unmap/detach `preserve`: preserve the log file in text format Note that the default strategy will be remove on unmap, and these options can be tweaked from the storage class Compression size details example: On Map: (with debug-rbd=20) --------- $ ls -lh -rw-r--r-- 1 root root 526K Sep 1 18:15 rbd-nbd-0001-0024-fed5480a-f00f-417a-a51d-31d8a8144c03-0000000000000003-d2e89c87-0b4d-11ec-8ea6-160f128e682d.log On unmap: --------- $ ls -lh -rw-r--r-- 1 root root 33K Sep 1 18:15 rbd-nbd-0001-0024-fed5480a-f00f-417a-a51d-31d8a8144c03-0000000000000003-d2e89c87-0b4d-11ec-8ea6-160f128e682d.gz Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
This commit is contained in:
parent
10bbb049f7
commit
c9cc36d8db
@ -152,6 +152,7 @@ charts and their default values.
|
|||||||
| `storageclass.imageFeatures` | Specifies RBD image features | `layering` |
|
| `storageclass.imageFeatures` | Specifies RBD image features | `layering` |
|
||||||
| `storageClass.mounter` | Specifies RBD mounter | `""` |
|
| `storageClass.mounter` | Specifies RBD mounter | `""` |
|
||||||
| `storageClass.cephLogDir` | ceph client log location, it is the target bindmount path used inside container | `"/var/log/ceph"` |
|
| `storageClass.cephLogDir` | ceph client log location, it is the target bindmount path used inside container | `"/var/log/ceph"` |
|
||||||
|
| `storageClass.cephLogStrategy` | ceph client log strategy, available options `remove` or `compress` or `preserve` | `"remove"` |
|
||||||
| `storageClass.volumeNamePrefix` | Prefix to use for naming RBD images | `""` |
|
| `storageClass.volumeNamePrefix` | Prefix to use for naming RBD images | `""` |
|
||||||
| `storageClass.encrypted` | Specifies whether volume should be encrypted. Set it to true if you want to enable encryption | `""` |
|
| `storageClass.encrypted` | Specifies whether volume should be encrypted. Set it to true if you want to enable encryption | `""` |
|
||||||
| `storageClass.encryptionKMSID` | Specifies the encryption kms id | `""` |
|
| `storageClass.encryptionKMSID` | Specifies the encryption kms id | `""` |
|
||||||
|
@ -21,6 +21,9 @@ parameters:
|
|||||||
{{- if .Values.storageClass.cephLogDir }}
|
{{- if .Values.storageClass.cephLogDir }}
|
||||||
cephLogDir: {{ .Values.storageClass.cephLogDir }}
|
cephLogDir: {{ .Values.storageClass.cephLogDir }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- if .Values.storageClass.cephLogStrategy }}
|
||||||
|
cephLogStrategy: {{ .Values.storageClass.cephLogStrategy }}
|
||||||
|
{{- end }}
|
||||||
{{- if .Values.storageClass.dataPool }}
|
{{- if .Values.storageClass.dataPool }}
|
||||||
dataPool: {{ .Values.storageClass.dataPool }}
|
dataPool: {{ .Values.storageClass.dataPool }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -289,12 +289,20 @@ storageClass:
|
|||||||
|
|
||||||
# (optional) ceph client log location, eg: rbd-nbd
|
# (optional) ceph client log location, eg: rbd-nbd
|
||||||
# By default host-path /var/log/ceph of node is bind-mounted into
|
# By default host-path /var/log/ceph of node is bind-mounted into
|
||||||
# csi-rbdplugin pod at /var/log/ceph mount path. See docs/rbd-nbd.md
|
# csi-rbdplugin pod at /var/log/ceph mount path. This is to configure
|
||||||
# for available configuration options.
|
# target bindmount path used inside container for ceph clients logging.
|
||||||
# This is to configure target bindmount path used inside container.
|
# See docs/rbd-nbd.md for available configuration options.
|
||||||
# cephLogDir: /var/log/ceph
|
# cephLogDir: /var/log/ceph
|
||||||
cephLogDir: ""
|
cephLogDir: ""
|
||||||
|
|
||||||
|
# (optional) ceph client log strategy
|
||||||
|
# By default, log file belonging to a particular volume will be deleted
|
||||||
|
# on unmap, but you can choose to just compress instead of deleting it
|
||||||
|
# or even preserve the log file in text format as it is.
|
||||||
|
# Available options `remove` or `compress` or `preserve`
|
||||||
|
# cephLogStrategy: remove
|
||||||
|
cephLogStrategy: ""
|
||||||
|
|
||||||
# (optional) Prefix to use for naming RBD images.
|
# (optional) Prefix to use for naming RBD images.
|
||||||
# If omitted, defaults to "csi-vol-".
|
# If omitted, defaults to "csi-vol-".
|
||||||
# volumeNamePrefix: "foo-bar-"
|
# volumeNamePrefix: "foo-bar-"
|
||||||
|
@ -71,11 +71,18 @@ parameters:
|
|||||||
|
|
||||||
# (optional) ceph client log location, eg: rbd-nbd
|
# (optional) ceph client log location, eg: rbd-nbd
|
||||||
# By default host-path /var/log/ceph of node is bind-mounted into
|
# By default host-path /var/log/ceph of node is bind-mounted into
|
||||||
# csi-rbdplugin pod at /var/log/ceph mount path. See docs/rbd-nbd.md
|
# csi-rbdplugin pod at /var/log/ceph mount path. This is to configure
|
||||||
# for available configuration options.
|
# target bindmount path used inside container for ceph clients logging.
|
||||||
# This is to configure target bindmount path used inside container.
|
# See docs/rbd-nbd.md for available configuration options.
|
||||||
# cephLogDir: /var/log/ceph
|
# cephLogDir: /var/log/ceph
|
||||||
|
|
||||||
|
# (optional) ceph client log strategy
|
||||||
|
# By default, log file belonging to a particular volume will be deleted
|
||||||
|
# on unmap, but you can choose to just compress instead of deleting it
|
||||||
|
# or even preserve the log file in text format as it is.
|
||||||
|
# Available options `remove` or `compress` or `preserve`
|
||||||
|
# cephLogStrategy: remove
|
||||||
|
|
||||||
# (optional) Prefix to use for naming RBD images.
|
# (optional) Prefix to use for naming RBD images.
|
||||||
# If omitted, defaults to "csi-vol-".
|
# If omitted, defaults to "csi-vol-".
|
||||||
# volumeNamePrefix: "foo-bar-"
|
# volumeNamePrefix: "foo-bar-"
|
||||||
|
@ -225,6 +225,10 @@ func populateRbdVol(
|
|||||||
if rv.LogDir == "" {
|
if rv.LogDir == "" {
|
||||||
rv.LogDir = defaultLogDir
|
rv.LogDir = defaultLogDir
|
||||||
}
|
}
|
||||||
|
rv.LogStrategy = req.GetVolumeContext()["cephLogStrategy"]
|
||||||
|
if rv.LogStrategy == "" {
|
||||||
|
rv.LogStrategy = defaultLogStrategy
|
||||||
|
}
|
||||||
|
|
||||||
return rv, err
|
return rv, err
|
||||||
}
|
}
|
||||||
@ -846,6 +850,7 @@ func (ns *NodeServer) NodeUnstageVolume(
|
|||||||
volumeID: req.GetVolumeId(),
|
volumeID: req.GetVolumeId(),
|
||||||
unmapOptions: imgInfo.UnmapOptions,
|
unmapOptions: imgInfo.UnmapOptions,
|
||||||
logDir: imgInfo.LogDir,
|
logDir: imgInfo.LogDir,
|
||||||
|
logStrategy: imgInfo.LogStrategy,
|
||||||
}
|
}
|
||||||
if err = detachRBDImageOrDeviceSpec(ctx, &dArgs); err != nil {
|
if err = detachRBDImageOrDeviceSpec(ctx, &dArgs); err != nil {
|
||||||
log.ErrorLog(
|
log.ErrorLog(
|
||||||
|
@ -102,6 +102,7 @@ type detachRBDImageArgs struct {
|
|||||||
volumeID string
|
volumeID string
|
||||||
unmapOptions string
|
unmapOptions string
|
||||||
logDir string
|
logDir string
|
||||||
|
logStrategy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// rbdGetDeviceList queries rbd about mapped devices and returns a list of rbdDeviceInfo
|
// rbdGetDeviceList queries rbd about mapped devices and returns a list of rbdDeviceInfo
|
||||||
@ -383,6 +384,7 @@ func createPath(ctx context.Context, volOpt *rbdVolume, device string, cr *util.
|
|||||||
volumeID: volOpt.VolID,
|
volumeID: volOpt.VolID,
|
||||||
unmapOptions: volOpt.UnmapOptions,
|
unmapOptions: volOpt.UnmapOptions,
|
||||||
logDir: volOpt.LogDir,
|
logDir: volOpt.LogDir,
|
||||||
|
logStrategy: volOpt.LogStrategy,
|
||||||
}
|
}
|
||||||
detErr := detachRBDImageOrDeviceSpec(ctx, &dArgs)
|
detErr := detachRBDImageOrDeviceSpec(ctx, &dArgs)
|
||||||
if detErr != nil {
|
if detErr != nil {
|
||||||
@ -490,10 +492,7 @@ func detachRBDImageOrDeviceSpec(
|
|||||||
}
|
}
|
||||||
if dArgs.isNbd && dArgs.logDir != "" {
|
if dArgs.isNbd && dArgs.logDir != "" {
|
||||||
logFile := getCephClientLogFileName(dArgs.volumeID, dArgs.logDir, "rbd-nbd")
|
logFile := getCephClientLogFileName(dArgs.volumeID, dArgs.logDir, "rbd-nbd")
|
||||||
if err = os.Remove(logFile); err != nil {
|
go strategicActionOnLogFile(ctx, dArgs.logStrategy, logFile)
|
||||||
log.WarningLog(ctx, "failed to remove logfile: %s, error: %v",
|
|
||||||
logFile, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -53,6 +53,7 @@ const (
|
|||||||
rbdDefaultMounter = "rbd"
|
rbdDefaultMounter = "rbd"
|
||||||
rbdNbdMounter = "rbd-nbd"
|
rbdNbdMounter = "rbd-nbd"
|
||||||
defaultLogDir = "/var/log/ceph"
|
defaultLogDir = "/var/log/ceph"
|
||||||
|
defaultLogStrategy = "remove" // supports remove, compress and preserve
|
||||||
|
|
||||||
// Output strings returned during invocation of "ceph rbd task add remove <imagespec>" when
|
// Output strings returned during invocation of "ceph rbd task add remove <imagespec>" when
|
||||||
// command is not supported by ceph manager. Used to check errors and recover when the command
|
// command is not supported by ceph manager. Used to check errors and recover when the command
|
||||||
@ -140,6 +141,7 @@ type rbdVolume struct {
|
|||||||
MapOptions string
|
MapOptions string
|
||||||
UnmapOptions string
|
UnmapOptions string
|
||||||
LogDir string
|
LogDir string
|
||||||
|
LogStrategy string
|
||||||
VolName string `json:"volName"`
|
VolName string `json:"volName"`
|
||||||
MonValueFromSecret string `json:"monValueFromSecret"`
|
MonValueFromSecret string `json:"monValueFromSecret"`
|
||||||
VolSize int64 `json:"volSize"`
|
VolSize int64 `json:"volSize"`
|
||||||
@ -1515,8 +1517,9 @@ type rbdImageMetadataStash struct {
|
|||||||
UnmapOptions string `json:"unmapOptions"`
|
UnmapOptions string `json:"unmapOptions"`
|
||||||
NbdAccess bool `json:"accessType"`
|
NbdAccess bool `json:"accessType"`
|
||||||
Encrypted bool `json:"encrypted"`
|
Encrypted bool `json:"encrypted"`
|
||||||
DevicePath string `json:"device"` // holds NBD device path for now
|
DevicePath string `json:"device"` // holds NBD device path for now
|
||||||
LogDir string `json:"logDir"` // holds the client log path
|
LogDir string `json:"logDir"` // holds the client log path
|
||||||
|
LogStrategy string `json:"logFileStrategy"` // ceph client log strategy
|
||||||
}
|
}
|
||||||
|
|
||||||
// file name in which image metadata is stashed.
|
// file name in which image metadata is stashed.
|
||||||
@ -1548,6 +1551,7 @@ func stashRBDImageMetadata(volOptions *rbdVolume, metaDataPath string) error {
|
|||||||
if volOptions.Mounter == rbdTonbd && hasNBD {
|
if volOptions.Mounter == rbdTonbd && hasNBD {
|
||||||
imgMeta.NbdAccess = true
|
imgMeta.NbdAccess = true
|
||||||
imgMeta.LogDir = volOptions.LogDir
|
imgMeta.LogDir = volOptions.LogDir
|
||||||
|
imgMeta.LogStrategy = volOptions.LogStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
encodedBytes, err := json.Marshal(imgMeta)
|
encodedBytes, err := json.Marshal(imgMeta)
|
||||||
@ -2021,3 +2025,23 @@ func CheckSliceContains(options []string, opt string) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// strategicActionOnLogFile act on log file based on cephLogStrategy.
|
||||||
|
func strategicActionOnLogFile(ctx context.Context, logStrategy, logFile string) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch strings.ToLower(logStrategy) {
|
||||||
|
case "compress":
|
||||||
|
if err = log.GzipLogFile(logFile); err != nil {
|
||||||
|
log.ErrorLog(ctx, "failed to compress logfile %q: %v", logFile, err)
|
||||||
|
}
|
||||||
|
case "remove":
|
||||||
|
if err = os.Remove(logFile); err != nil {
|
||||||
|
log.ErrorLog(ctx, "failed to remove logfile %q: %v", logFile, err)
|
||||||
|
}
|
||||||
|
case "preserve":
|
||||||
|
// do nothing
|
||||||
|
default:
|
||||||
|
log.ErrorLog(ctx, "unknown cephLogStrategy option %q: hint: 'remove'|'compress'|'preserve'", logStrategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,6 +17,9 @@ limitations under the License.
|
|||||||
package rbd
|
package rbd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -208,3 +211,75 @@ func TestGetCephClientLogFileName(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStrategicActionOnLogFile(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
ctx := context.TODO()
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
var logFile [3]string
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
f, err := ioutil.TempFile(tmpDir, "rbd-*.log")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("creating tempfile failed: %v", err)
|
||||||
|
}
|
||||||
|
logFile[i] = f.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
logStrategy string
|
||||||
|
logFile string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test for compress",
|
||||||
|
args: args{
|
||||||
|
logStrategy: "compress",
|
||||||
|
logFile: logFile[0],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test for remove",
|
||||||
|
args: args{
|
||||||
|
logStrategy: "remove",
|
||||||
|
logFile: logFile[1],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test for preserve",
|
||||||
|
args: args{
|
||||||
|
logStrategy: "preserve",
|
||||||
|
logFile: logFile[2],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
strategicActionOnLogFile(ctx, tt.args.logStrategy, tt.args.logFile)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
switch tt.args.logStrategy {
|
||||||
|
case "compress":
|
||||||
|
newExt := strings.Replace(tt.args.logFile, ".log", ".gz", -1)
|
||||||
|
if _, err = os.Stat(newExt); os.IsNotExist(err) {
|
||||||
|
t.Errorf("compressed logFile (%s) not found: %v", newExt, err)
|
||||||
|
}
|
||||||
|
os.Remove(newExt)
|
||||||
|
case "remove":
|
||||||
|
if _, err = os.Stat(tt.args.logFile); !os.IsNotExist(err) {
|
||||||
|
t.Errorf("logFile (%s) not removed: %v", tt.args.logFile, err)
|
||||||
|
}
|
||||||
|
case "preserve":
|
||||||
|
if _, err = os.Stat(tt.args.logFile); os.IsNotExist(err) {
|
||||||
|
t.Errorf("logFile (%s) not preserved: %v", tt.args.logFile, err)
|
||||||
|
}
|
||||||
|
os.Remove(tt.args.logFile)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user