diff --git a/microceph/ceph/ceph_exporter.go b/microceph/ceph/ceph_exporter.go new file mode 100644 index 00000000..1d32d3e6 --- /dev/null +++ b/microceph/ceph/ceph_exporter.go @@ -0,0 +1,26 @@ +package ceph + +import ( + "fmt" + "path/filepath" + + "github.com/canonical/lxd/shared/logger" +) + +func bootstrapCephExporter(hostname string, path string) error { + args := []string{ + "auth", + "get-or-create", + fmt.Sprintf("client.ceph-exporter.%s", hostname), + "mon", "profile ceph-exporter", + "-o", filepath.Join(path, "keyring"), + } + + _, err := cephRun(args...) + if err != nil { + logger.Errorf("failed to bootstrap ceph-exporter daemon: %s", err.Error()) + return err + } + + return nil +} diff --git a/microceph/ceph/services_placement.go b/microceph/ceph/services_placement.go index b30786a4..ca1bc9e4 100644 --- a/microceph/ceph/services_placement.go +++ b/microceph/ceph/services_placement.go @@ -33,6 +33,7 @@ func GetServicePlacementTable() map[string](PlacementIntf) { "rgw": &RgwServicePlacement{}, "rbd-mirror": &ClientServicePlacement{"rbd-mirror"}, "cephfs-mirror": &ClientServicePlacement{"cephfs-mirror"}, + "ceph-exporter": &ClientServicePlacement{"ceph-exporter"}, } } diff --git a/microceph/ceph/services_placement_generic.go b/microceph/ceph/services_placement_generic.go index 968dea80..7e2ec9bb 100644 --- a/microceph/ceph/services_placement_generic.go +++ b/microceph/ceph/services_placement_generic.go @@ -23,6 +23,7 @@ func GetServiceKeyringTable() map[string](func(string, string) error) { "mds": bootstrapMds, "rbd-mirror": bootstrapRbdMirror, "cephfs-mirror": bootstrapFsMirror, + "ceph-exporter": bootstrapCephExporter, // Add more services here, for using the generic Interface implementation. } } diff --git a/microceph/cmd/microceph/enable.go b/microceph/cmd/microceph/enable.go index 074ad19a..feb00b00 100644 --- a/microceph/cmd/microceph/enable.go +++ b/microceph/cmd/microceph/enable.go @@ -22,6 +22,7 @@ func (c *cmdEnable) Command() *cobra.Command { enableNFSCmd := cmdEnableNFS{common: c.common} enableRbdMirrorCmd := cmdEnableRBDMirror{common: c.common} enableFsMirrorCmd := cmdEnableFsMirror{common: c.common} + enableCephExporterCmd := cmdEnableCephExporter{common: c.common} cmd.AddCommand(enableRGWCmd.Command()) cmd.AddCommand(enableMonCmd.Command()) @@ -30,6 +31,7 @@ func (c *cmdEnable) Command() *cobra.Command { cmd.AddCommand(enableNFSCmd.Command()) cmd.AddCommand(enableRbdMirrorCmd.Command()) cmd.AddCommand(enableFsMirrorCmd.Command()) + cmd.AddCommand(enableCephExporterCmd.Command()) // Workaround for subcommand usage errors. See: https://github.com/spf13/cobra/issues/706 cmd.Args = cobra.NoArgs diff --git a/microceph/cmd/microceph/enable_ceph_exporter.go b/microceph/cmd/microceph/enable_ceph_exporter.go new file mode 100644 index 00000000..18f2257d --- /dev/null +++ b/microceph/cmd/microceph/enable_ceph_exporter.go @@ -0,0 +1,54 @@ +package main + +import ( + "context" + + "github.com/canonical/microcluster/v3/microcluster" + "github.com/spf13/cobra" + + "github.com/canonical/microceph/microceph/api/types" + "github.com/canonical/microceph/microceph/client" +) + +type cmdEnableCephExporter struct { + common *CmdControl + wait bool + flagTarget string +} + +func (c *cmdEnableCephExporter) Command() *cobra.Command { + cmd := &cobra.Command{ + Use: "ceph-exporter [--target ] [--wait ]", + Short: "Enable the ceph exporter service on the --target server (default: this server)", + RunE: c.Run, + } + cmd.PersistentFlags().StringVar(&c.flagTarget, "target", "", "Server hostname (default: this server)") + cmd.Flags().BoolVar(&c.wait, "wait", true, "Wait for ceph-exporter service to be up.") + return cmd +} + +// Run handles the enable mon command. +func (c *cmdEnableCephExporter) Run(cmd *cobra.Command, args []string) error { + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) + if err != nil { + return err + } + + cli, err := m.LocalClient() + if err != nil { + return err + } + cli = cli.UseTarget(c.flagTarget) + req := &types.EnableService{ + Name: "ceph-exporter", + Wait: c.wait, + Payload: "", + } + + err = client.SendServicePlacementReq(context.Background(), cli, req, c.flagTarget) + if err != nil { + return err + } + + return nil +} diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 6fd552aa..de3f4b92 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -164,6 +164,16 @@ apps: - network - network-bind - process-control + "ceph-exporter": + command: commands/ceph-exporter.start + daemon: simple + install-mode: disable + after: + - daemon + plugs: + - network + - network-bind + - process-control log-rotate: command: commands/log-rotate.start daemon: oneshot @@ -277,6 +287,7 @@ parts: - radosgw - rbd-mirror - cephfs-mirror + - ceph-exporter # Utilities - coreutils - util-linux @@ -310,6 +321,7 @@ parts: - bin/radosgw-admin - bin/rbd-mirror - bin/cephfs-mirror + - bin/ceph-exporter - bin/truncate - bin/uuidgen - bin/findmnt diff --git a/snapcraft/commands/ceph-exporter.start b/snapcraft/commands/ceph-exporter.start new file mode 100755 index 00000000..803e66be --- /dev/null +++ b/snapcraft/commands/ceph-exporter.start @@ -0,0 +1,7 @@ +#!/bin/bash + +. "${SNAP}/commands/common" + +limits + +exec ceph-exporter -f --cluster ceph --id "ceph-exporter.$(hostname)"