mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
dynamic host volumes: add -type flag to volume init (#24667)
Adds a `-type` flag to the `volume init` command that generates an example volume specification with only those fields relevant to dynamic host volumes. This changeset also moves the string literals into uses of `go:embed` Ref: https://github.com/hashicorp/nomad/pull/24479
This commit is contained in:
@@ -22,3 +22,15 @@ var NodePoolSpec []byte
|
|||||||
|
|
||||||
//go:embed pool.nomad.json
|
//go:embed pool.nomad.json
|
||||||
var NodePoolSpecJSON []byte
|
var NodePoolSpecJSON []byte
|
||||||
|
|
||||||
|
//go:embed volume.csi.hcl
|
||||||
|
var CSIVolumeSpecHCL []byte
|
||||||
|
|
||||||
|
//go:embed volume.csi.json
|
||||||
|
var CSIVolumeSpecJSON []byte
|
||||||
|
|
||||||
|
//go:embed volume.host.hcl
|
||||||
|
var HostVolumeSpecHCL []byte
|
||||||
|
|
||||||
|
//go:embed volume.host.json
|
||||||
|
var HostVolumeSpecJSON []byte
|
||||||
|
|||||||
70
command/asset/volume.csi.hcl
Normal file
70
command/asset/volume.csi.hcl
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
id = "ebs_prod_db1"
|
||||||
|
namespace = "default"
|
||||||
|
name = "database"
|
||||||
|
type = "csi"
|
||||||
|
plugin_id = "plugin_id"
|
||||||
|
|
||||||
|
# For 'nomad volume register', provide the external ID from the storage
|
||||||
|
# provider. This field should be omitted when creating a volume with
|
||||||
|
# 'nomad volume create'
|
||||||
|
external_id = "vol-23452345"
|
||||||
|
|
||||||
|
# For 'nomad volume create', specify a snapshot ID or volume to clone. You can
|
||||||
|
# specify only one of these two fields.
|
||||||
|
snapshot_id = "snap-12345"
|
||||||
|
# clone_id = "vol-abcdef"
|
||||||
|
|
||||||
|
# Optional: for 'nomad volume create', specify a maximum and minimum capacity.
|
||||||
|
# Registering an existing volume will record but ignore these fields.
|
||||||
|
capacity_min = "10GiB"
|
||||||
|
capacity_max = "20G"
|
||||||
|
|
||||||
|
# Required (at least one): for 'nomad volume create', specify one or more
|
||||||
|
# capabilities to validate. Registering an existing volume will record but
|
||||||
|
# ignore these fields.
|
||||||
|
capability {
|
||||||
|
access_mode = "single-node-writer"
|
||||||
|
attachment_mode = "file-system"
|
||||||
|
}
|
||||||
|
|
||||||
|
capability {
|
||||||
|
access_mode = "single-node-reader"
|
||||||
|
attachment_mode = "block-device"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: for 'nomad volume create', specify mount options to validate for
|
||||||
|
# 'attachment_mode = "file-system". Registering an existing volume will record
|
||||||
|
# but ignore these fields.
|
||||||
|
mount_options {
|
||||||
|
fs_type = "ext4"
|
||||||
|
mount_flags = ["ro"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: specify one or more locations where the volume must be accessible
|
||||||
|
# from. Refer to the plugin documentation for what segment values are supported.
|
||||||
|
topology_request {
|
||||||
|
preferred {
|
||||||
|
topology { segments { rack = "R1" } }
|
||||||
|
}
|
||||||
|
required {
|
||||||
|
topology { segments { rack = "R1" } }
|
||||||
|
topology { segments { rack = "R2", zone = "us-east-1a" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: provide any secrets specified by the plugin.
|
||||||
|
secrets {
|
||||||
|
example_secret = "xyzzy"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: provide a map of keys to string values expected by the plugin.
|
||||||
|
parameters {
|
||||||
|
skuname = "Premium_LRS"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: for 'nomad volume register', provide a map of keys to string
|
||||||
|
# values expected by the plugin. This field will populated automatically by
|
||||||
|
# 'nomad volume create'.
|
||||||
|
context {
|
||||||
|
endpoint = "http://192.168.1.101:9425"
|
||||||
|
}
|
||||||
72
command/asset/volume.csi.json
Normal file
72
command/asset/volume.csi.json
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"id": "ebs_prod_db1",
|
||||||
|
"namespace": "default",
|
||||||
|
"name": "database",
|
||||||
|
"type": "csi",
|
||||||
|
"plugin_id": "plugin_id",
|
||||||
|
"external_id": "vol-23452345",
|
||||||
|
"snapshot_id": "snap-12345",
|
||||||
|
"capacity_min": "10GiB",
|
||||||
|
"capacity_max": "20G",
|
||||||
|
"capability": [
|
||||||
|
{
|
||||||
|
"access_mode": "single-node-writer",
|
||||||
|
"attachment_mode": "file-system"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"access_mode": "single-node-reader",
|
||||||
|
"attachment_mode": "block-device"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"context": [
|
||||||
|
{
|
||||||
|
"endpoint": "http://192.168.1.101:9425"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mount_options": [
|
||||||
|
{
|
||||||
|
"fs_type": "ext4",
|
||||||
|
"mount_flags": [
|
||||||
|
"ro"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"topology_request": {
|
||||||
|
"preferred": [
|
||||||
|
{
|
||||||
|
"topology": {
|
||||||
|
"segments": {
|
||||||
|
"rack": "R1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required": [
|
||||||
|
{
|
||||||
|
"topology": {
|
||||||
|
"segments": {
|
||||||
|
"rack": "R1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"topology": {
|
||||||
|
"segments": {
|
||||||
|
"rack": "R2",
|
||||||
|
"zone": "us-east-1a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"skuname": "Premium_LRS"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"secrets": [
|
||||||
|
{
|
||||||
|
"example_secret": "xyzzy"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
28
command/asset/volume.host.hcl
Normal file
28
command/asset/volume.host.hcl
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
id = "disk_prod_db1"
|
||||||
|
namespace = "default"
|
||||||
|
name = "database"
|
||||||
|
type = "host"
|
||||||
|
plugin_id = "plugin_id"
|
||||||
|
|
||||||
|
# Optional: for 'nomad volume create', specify a maximum and minimum capacity.
|
||||||
|
# Registering an existing volume will record but ignore these fields.
|
||||||
|
capacity_min = "10GiB"
|
||||||
|
capacity_max = "20G"
|
||||||
|
|
||||||
|
# Required (at least one): for 'nomad volume create', specify one or more
|
||||||
|
# capabilities to validate. Registering an existing volume will record but
|
||||||
|
# ignore these fields.
|
||||||
|
capability {
|
||||||
|
access_mode = "single-node-writer"
|
||||||
|
attachment_mode = "file-system"
|
||||||
|
}
|
||||||
|
|
||||||
|
capability {
|
||||||
|
access_mode = "single-node-reader"
|
||||||
|
attachment_mode = "block-device"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: provide a map of keys to string values expected by the plugin.
|
||||||
|
parameters {
|
||||||
|
skuname = "Premium_LRS"
|
||||||
|
}
|
||||||
24
command/asset/volume.host.json
Normal file
24
command/asset/volume.host.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"id": "disk_prod_db1",
|
||||||
|
"namespace": "default",
|
||||||
|
"name": "database",
|
||||||
|
"type": "host",
|
||||||
|
"plugin_id": "plugin_id",
|
||||||
|
"capacity_min": "10GiB",
|
||||||
|
"capacity_max": "20G",
|
||||||
|
"capability": [
|
||||||
|
{
|
||||||
|
"access_mode": "single-node-writer",
|
||||||
|
"attachment_mode": "file-system"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"access_mode": "single-node-reader",
|
||||||
|
"attachment_mode": "block-device"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"skuname": "Premium_LRS"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -8,17 +8,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/nomad/command/asset"
|
||||||
"github.com/posener/complete"
|
"github.com/posener/complete"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultHclVolumeInitName is the default name we use when initializing
|
// defaultHclVolumeInitName is the default name we use when initializing
|
||||||
// the example volume file in HCL format
|
// the example volume file in HCL format
|
||||||
DefaultHclVolumeInitName = "volume.hcl"
|
defaultHclVolumeInitName = "volume.hcl"
|
||||||
|
|
||||||
// DefaultHclVolumeInitName is the default name we use when initializing
|
// DefaultHclVolumeInitName is the default name we use when initializing
|
||||||
// the example volume file in JSON format
|
// the example volume file in JSON format
|
||||||
DefaultJsonVolumeInitName = "volume.json"
|
defaultJsonVolumeInitName = "volume.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VolumeInitCommand generates a new volume spec that you can customize to
|
// VolumeInitCommand generates a new volume spec that you can customize to
|
||||||
@@ -39,6 +40,11 @@ Init Options:
|
|||||||
|
|
||||||
-json
|
-json
|
||||||
Create an example JSON volume specification.
|
Create an example JSON volume specification.
|
||||||
|
|
||||||
|
-type
|
||||||
|
Create an example for a specific type of volume (one of "csi" or "host",
|
||||||
|
defaults to "csi").
|
||||||
|
|
||||||
`
|
`
|
||||||
return strings.TrimSpace(helpText)
|
return strings.TrimSpace(helpText)
|
||||||
}
|
}
|
||||||
@@ -50,6 +56,7 @@ func (c *VolumeInitCommand) Synopsis() string {
|
|||||||
func (c *VolumeInitCommand) AutocompleteFlags() complete.Flags {
|
func (c *VolumeInitCommand) AutocompleteFlags() complete.Flags {
|
||||||
return complete.Flags{
|
return complete.Flags{
|
||||||
"-json": complete.PredictNothing,
|
"-json": complete.PredictNothing,
|
||||||
|
"-type": complete.PredictSet("host", "csi"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +68,11 @@ func (c *VolumeInitCommand) Name() string { return "volume init" }
|
|||||||
|
|
||||||
func (c *VolumeInitCommand) Run(args []string) int {
|
func (c *VolumeInitCommand) Run(args []string) int {
|
||||||
var jsonOutput bool
|
var jsonOutput bool
|
||||||
|
var volType string
|
||||||
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
|
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
|
||||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||||
flags.BoolVar(&jsonOutput, "json", false, "")
|
flags.BoolVar(&jsonOutput, "json", false, "")
|
||||||
|
flags.StringVar(&volType, "type", "csi", "type of volume")
|
||||||
|
|
||||||
if err := flags.Parse(args); err != nil {
|
if err := flags.Parse(args); err != nil {
|
||||||
return 1
|
return 1
|
||||||
@@ -77,11 +86,17 @@ func (c *VolumeInitCommand) Run(args []string) int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName := DefaultHclVolumeInitName
|
fileName := defaultHclVolumeInitName
|
||||||
fileContent := defaultHclVolumeSpec
|
fileContent := asset.CSIVolumeSpecHCL
|
||||||
if jsonOutput {
|
|
||||||
fileName = DefaultJsonVolumeInitName
|
if volType == "host" && !jsonOutput {
|
||||||
fileContent = defaultJsonVolumeSpec
|
fileContent = asset.HostVolumeSpecHCL
|
||||||
|
} else if volType == "host" && jsonOutput {
|
||||||
|
fileName = defaultJsonVolumeInitName
|
||||||
|
fileContent = asset.HostVolumeSpecJSON
|
||||||
|
} else if jsonOutput {
|
||||||
|
fileName = defaultJsonVolumeInitName
|
||||||
|
fileContent = asset.CSIVolumeSpecJSON
|
||||||
}
|
}
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
fileName = args[0]
|
fileName = args[0]
|
||||||
@@ -99,7 +114,7 @@ func (c *VolumeInitCommand) Run(args []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write out the example
|
// Write out the example
|
||||||
err = os.WriteFile(fileName, []byte(fileContent), 0660)
|
err = os.WriteFile(fileName, fileContent, 0660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Failed to write %q: %v", fileName, err))
|
c.Ui.Error(fmt.Sprintf("Failed to write %q: %v", fileName, err))
|
||||||
return 1
|
return 1
|
||||||
@@ -109,151 +124,3 @@ func (c *VolumeInitCommand) Run(args []string) int {
|
|||||||
c.Ui.Output(fmt.Sprintf("Example volume specification written to %s", fileName))
|
c.Ui.Output(fmt.Sprintf("Example volume specification written to %s", fileName))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultHclVolumeSpec = strings.TrimSpace(`
|
|
||||||
id = "ebs_prod_db1"
|
|
||||||
namespace = "default"
|
|
||||||
name = "database"
|
|
||||||
type = "csi"
|
|
||||||
plugin_id = "plugin_id"
|
|
||||||
|
|
||||||
# For 'nomad volume register', provide the external ID from the storage
|
|
||||||
# provider. This field should be omitted when creating a volume with
|
|
||||||
# 'nomad volume create'
|
|
||||||
external_id = "vol-23452345"
|
|
||||||
|
|
||||||
# For 'nomad volume create', specify a snapshot ID or volume to clone. You can
|
|
||||||
# specify only one of these two fields.
|
|
||||||
snapshot_id = "snap-12345"
|
|
||||||
# clone_id = "vol-abcdef"
|
|
||||||
|
|
||||||
# Optional: for 'nomad volume create', specify a maximum and minimum capacity.
|
|
||||||
# Registering an existing volume will record but ignore these fields.
|
|
||||||
capacity_min = "10GiB"
|
|
||||||
capacity_max = "20G"
|
|
||||||
|
|
||||||
# Required (at least one): for 'nomad volume create', specify one or more
|
|
||||||
# capabilities to validate. Registering an existing volume will record but
|
|
||||||
# ignore these fields.
|
|
||||||
capability {
|
|
||||||
access_mode = "single-node-writer"
|
|
||||||
attachment_mode = "file-system"
|
|
||||||
}
|
|
||||||
|
|
||||||
capability {
|
|
||||||
access_mode = "single-node-reader"
|
|
||||||
attachment_mode = "block-device"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Optional: for 'nomad volume create', specify mount options to validate for
|
|
||||||
# 'attachment_mode = "file-system". Registering an existing volume will record
|
|
||||||
# but ignore these fields.
|
|
||||||
mount_options {
|
|
||||||
fs_type = "ext4"
|
|
||||||
mount_flags = ["ro"]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Optional: specify one or more locations where the volume must be accessible
|
|
||||||
# from. Refer to the plugin documentation for what segment values are supported.
|
|
||||||
topology_request {
|
|
||||||
preferred {
|
|
||||||
topology { segments { rack = "R1" } }
|
|
||||||
}
|
|
||||||
required {
|
|
||||||
topology { segments { rack = "R1" } }
|
|
||||||
topology { segments { rack = "R2", zone = "us-east-1a" } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Optional: provide any secrets specified by the plugin.
|
|
||||||
secrets {
|
|
||||||
example_secret = "xyzzy"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Optional: provide a map of keys to string values expected by the plugin.
|
|
||||||
parameters {
|
|
||||||
skuname = "Premium_LRS"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Optional: for 'nomad volume register', provide a map of keys to string
|
|
||||||
# values expected by the plugin. This field will populated automatically by
|
|
||||||
# 'nomad volume create'.
|
|
||||||
context {
|
|
||||||
endpoint = "http://192.168.1.101:9425"
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
var defaultJsonVolumeSpec = strings.TrimSpace(`
|
|
||||||
{
|
|
||||||
"id": "ebs_prod_db1",
|
|
||||||
"namespace": "default",
|
|
||||||
"name": "database",
|
|
||||||
"type": "csi",
|
|
||||||
"plugin_id": "plugin_id",
|
|
||||||
"external_id": "vol-23452345",
|
|
||||||
"snapshot_id": "snap-12345",
|
|
||||||
"capacity_min": "10GiB",
|
|
||||||
"capacity_max": "20G",
|
|
||||||
"capability": [
|
|
||||||
{
|
|
||||||
"access_mode": "single-node-writer",
|
|
||||||
"attachment_mode": "file-system"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"access_mode": "single-node-reader",
|
|
||||||
"attachment_mode": "block-device"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"context": [
|
|
||||||
{
|
|
||||||
"endpoint": "http://192.168.1.101:9425"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mount_options": [
|
|
||||||
{
|
|
||||||
"fs_type": "ext4",
|
|
||||||
"mount_flags": [
|
|
||||||
"ro"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"topology_request": {
|
|
||||||
"preferred": [
|
|
||||||
{
|
|
||||||
"topology": {
|
|
||||||
"segments": {
|
|
||||||
"rack": "R1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"required": [
|
|
||||||
{
|
|
||||||
"topology": {
|
|
||||||
"segments": {
|
|
||||||
"rack": "R1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"topology": {
|
|
||||||
"segments": {
|
|
||||||
"rack": "R2",
|
|
||||||
"zone": "us-east-1a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"skuname": "Premium_LRS"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"secrets": [
|
|
||||||
{
|
|
||||||
"example_secret": "xyzzy"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user