Unverified Commit 37ed7550 authored by Nick Ethier's avatar Nick Ethier
Browse files

docker: move recoverable error proto to shared structs

parent 396f6ab1
Showing with 621 additions and 568 deletions
+621 -568
package docker
import (
"strconv"
"strings"
"time"
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/plugins/base"
"github.com/hashicorp/nomad/plugins/drivers"
"github.com/hashicorp/nomad/plugins/shared/hclspec"
"github.com/hashicorp/nomad/plugins/shared/loader"
)
func PluginLoader(opts map[string]string) (map[string]interface{}, error) {
conf := map[string]interface{}{}
if v, ok := opts["docker.endpoint"]; ok {
conf["endpoint"] = v
}
if v, ok := opts["docker.auth.config"]; ok {
conf["auth_config"] = v
}
if v, ok := opts["docker.auth.helper"]; ok {
conf["auth_helper"] = v
}
if _, ok := opts["docker.tls.cert"]; ok {
conf["tls"] = map[string]interface{}{
"cert": opts["docker.tls.cert"],
"key": opts["docker.tls.key"],
"ca": opts["docker.tls.ca"],
}
}
if v, ok := opts["docker.cleanup.image.delay"]; ok {
conf["image_gc_delay"] = v
}
if v, ok := opts["docker.volumes.selinuxlabel"]; ok {
conf["volumes_selinuxlabel"] = v
}
if v, ok := opts["docker.caps.whitelist"]; ok {
conf["allow_caps"] = strings.Split(v, ",")
}
if v, err := strconv.ParseBool(opts["docker.cleanup.image"]); err == nil {
conf["image_gc"] = v
}
if v, err := strconv.ParseBool(opts["docker.volumes.enabled"]); err == nil {
conf["volumes_enabled"] = v
}
if v, err := strconv.ParseBool(opts["docker.privileged.enabled"]); err == nil {
conf["allow_privileged"] = v
}
if v, err := strconv.ParseBool(opts["docker.cleanup.container"]); err == nil {
conf["container_gc"] = v
}
return conf, nil
}
var (
// PluginID is the rawexec plugin metadata registered in the plugin
// catalog.
PluginID = loader.PluginID{
Name: pluginName,
PluginType: base.PluginTypeDriver,
}
// PluginConfig is the rawexec factory function registered in the
// plugin catalog.
PluginConfig = &loader.InternalPluginConfig{
Config: map[string]interface{}{},
Factory: func(l hclog.Logger) interface{} { return NewDockerDriver(l) },
}
// pluginInfo is the response returned for the PluginInfo RPC
pluginInfo = &base.PluginInfoResponse{
Type: base.PluginTypeDriver,
PluginApiVersion: "0.0.1",
PluginVersion: "0.1.0",
Name: pluginName,
}
// configSpec is the hcl specification returned by the ConfigSchema RPC
configSpec = hclspec.NewObject(map[string]*hclspec.Spec{
"endpoint": hclspec.NewAttr("endpoint", "string", false),
"auth_config": hclspec.NewAttr("auth_config", "string", false),
"auth_helper": hclspec.NewAttr("auth_helper", "string", false),
"tls": hclspec.NewBlock("tls", false, hclspec.NewObject(map[string]*hclspec.Spec{
"cert": hclspec.NewAttr("cert", "string", false),
"key": hclspec.NewAttr("key", "string", false),
"ca": hclspec.NewAttr("ca", "string", false),
})),
"image_gc": hclspec.NewDefault(
hclspec.NewAttr("image_gc", "bool", false),
hclspec.NewLiteral("true"),
),
"image_gc_delay": hclspec.NewAttr("image_gc_delay", "string", false),
"volumes_enabled": hclspec.NewDefault(
hclspec.NewAttr("volumes_enabled", "bool", false),
hclspec.NewLiteral("true"),
),
"volumes_selinuxlabel": hclspec.NewAttr("volumes_selinuxlabel", "string", false),
"allow_privileged": hclspec.NewAttr("allow_privileged", "bool", false),
"allow_caps": hclspec.NewDefault(
hclspec.NewAttr("allow_caps", "list(string)", false),
hclspec.NewLiteral(`["CHOWN","DAC_OVERRIDE","FSETID","FOWNER","MKNOD","NET_RAW","SETGID","SETUID","SETFCAP","SETPCAP","NET_BIND_SERVICE","SYS_CHROOT","KILL","AUDIT_WRITE"]`),
),
"container_gc": hclspec.NewDefault(
hclspec.NewAttr("container_gc", "bool", false),
hclspec.NewLiteral("true"),
),
})
// taskConfigSpec is the hcl specification for the driver config section of
// a task within a job. It is returned in the TaskConfigSchema RPC
taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{
"image": hclspec.NewAttr("image", "string", true),
"advertise_ipv6_address": hclspec.NewAttr("advertise_ipv6_address", "bool", false),
"args": hclspec.NewAttr("args", "list(string)", false),
"auth": hclspec.NewBlock("auth", false, hclspec.NewObject(map[string]*hclspec.Spec{
"username": hclspec.NewAttr("username", "string", false),
"password": hclspec.NewAttr("password", "string", false),
"email": hclspec.NewAttr("email", "string", false),
"server_address": hclspec.NewAttr("server_address", "string", false),
})),
"auth_soft_fail": hclspec.NewAttr("auth_soft_fail", "bool", false),
"cap_add": hclspec.NewAttr("cap_add", "list(string)", false),
"cap_drop": hclspec.NewAttr("cap_drop", "list(string)", false),
"command": hclspec.NewAttr("command", "string", false),
"cpu_hard_limit": hclspec.NewAttr("cpu_hard_limit", "bool", false),
"cpu_cfs_period": hclspec.NewAttr("cpu_cfs_period", "number", false),
"devices": hclspec.NewBlockSet("devices", hclspec.NewObject(map[string]*hclspec.Spec{
"host_path": hclspec.NewAttr("host_path", "string", false),
"container_path": hclspec.NewAttr("container_path", "string", false),
"cgroup_permissions": hclspec.NewAttr("cgroup_permissions", "string", false),
})),
"dns_search_domains": hclspec.NewAttr("dns_search_domains", "list(string)", false),
"dns_options": hclspec.NewAttr("dns_options", "list(string)", false),
"dns_servers": hclspec.NewAttr("dns_servers", "list(string)", false),
"entrypoint": hclspec.NewAttr("entrypoint", "list(string)", false),
"extra_hosts": hclspec.NewAttr("extra_hosts", "list(string)", false),
"force_pull": hclspec.NewAttr("force_pull", "bool", false),
"hostname": hclspec.NewAttr("hostname", "string", false),
"interactive": hclspec.NewAttr("interactive", "bool", false),
"ipc_mode": hclspec.NewAttr("ipc_mode", "string", false),
"ipv4_address": hclspec.NewAttr("ipv4_address", "string", false),
"ipv6_address": hclspec.NewAttr("ipv6_address", "string", false),
"labels": hclspec.NewAttr("labels", "map(string)", false),
"load": hclspec.NewAttr("load", "string", false),
"logging": hclspec.NewAttr("logging", "map(string)", false),
"mac_address": hclspec.NewAttr("mac_address", "map(string)", false),
"mounts": hclspec.NewBlockSet("mounts", hclspec.NewObject(map[string]*hclspec.Spec{
"target": hclspec.NewAttr("target", "string", false),
"source": hclspec.NewAttr("source", "string", false),
"readonly": hclspec.NewAttr("readonly", "bool", false),
"volume_options": hclspec.NewBlockSet("volume_options", hclspec.NewObject(map[string]*hclspec.Spec{
"no_copy": hclspec.NewAttr("no_copy", "bool", false),
"labels": hclspec.NewAttr("labels", "map(string)", false),
"driver_config": hclspec.NewBlockSet("driver_config", hclspec.NewObject(map[string]*hclspec.Spec{
"name": hclspec.NewAttr("name", "string", false),
"options": hclspec.NewAttr("name", "map(string)", false),
})),
})),
})),
"network_aliases": hclspec.NewAttr("network_aliases", "list(string)", false),
"network_mode": hclspec.NewAttr("network_mode", "string", false),
"pids_limit": hclspec.NewAttr("pids_limit", "number", false),
"pid_mode": hclspec.NewAttr("pid_mode", "string", false),
"port_map": hclspec.NewAttr("port_map", "map(number)", false),
"privileged": hclspec.NewAttr("privileged", "bool", false),
"readonly_rootfs": hclspec.NewAttr("readonly_rootfs", "bool", false),
"security_opt": hclspec.NewAttr("security_opt", "list(string)", false),
"shm_size": hclspec.NewAttr("shm_size", "number", false),
"sysctl": hclspec.NewAttr("sysctl", "map(string)", false),
"tty": hclspec.NewAttr("tty", "bool", false),
"ulimit": hclspec.NewAttr("ulimit", "map(string)", false),
"uts_mode": hclspec.NewAttr("uts_mode", "string", false),
"userns_mode": hclspec.NewAttr("userns_mode", "string", false),
"volumes": hclspec.NewAttr("volumes", "list(string)", false),
"volume_driver": hclspec.NewAttr("volume_driver", "string", false),
"work_dir": hclspec.NewAttr("work_dir", "string", false),
})
// capabilities is returned by the Capabilities RPC and indicates what
// optional features this driver supports
capabilities = &drivers.Capabilities{
SendSignals: true,
Exec: true,
FSIsolation: structs.FSIsolationImage,
}
)
type TaskConfig struct {
Image string `codec:"image"`
AdvertiseIPv6Addr bool `codec:"advertise_ipv6_address"`
Args []string `codec:"args"`
Auth DockerAuth `codec:"auth"`
AuthSoftFail bool `codec:"auth_soft_fail"`
CapAdd []string `codec:"cap_add"`
CapDrop []string `codec:"cap_drop"`
Command string `codec:"command"`
CPUCFSPeriod int64 `codec:"cpu_cfs_period"`
CPUHardLimit bool `codec:"cpu_hard_limit"`
Devices []DockerDevice `codec:"devices"`
DNSSearchDomains []string `codec:"dns_search_domains"`
DNSOptions []string `codec:"dns_options"`
DNSServers []string `codec:"dns_servers"`
Entrypoint []string `codec:"entrypoint"`
ExtraHosts []string `codec:"extra_hosts"`
ForcePull bool `codec:"force_pull"`
Hostname string `codec:"hostname"`
Interactive bool `codec:"interactive"`
IPCMode string `codec:"ipc_mode"`
IPv4Address string `codec:"ipv4_address"`
IPv6Address string `codec:"ipv6_address"`
Labels map[string]string `codec:"labels"`
LoadImage string `codec:"load"`
Logging DockerLogging `codec:"logging"`
MacAddress string `codec:"mac_address"`
Mounts []DockerMount `codec:"mounts"`
NetworkAliases []string `codec:"network_aliases"`
NetworkMode string `codec:"network_mode"`
PidsLimit int64 `codec:"pids_limit"`
PidMode string `codec:"pid_mode"`
PortMap map[string]int `codec:"port_map"`
Privileged bool `codec:"privileged"`
ReadonlyRootfs bool `codec:"readonly_rootfs"`
SecurityOpt []string `codec:"security_opt"`
ShmSize int64 `codec:"shm_size"`
Sysctl map[string]string `codec:"sysctl"`
TTY bool `codec:"tty"`
Ulimit map[string]string `codec:"ulimit"`
UTSMode string `codec:"uts_mode"`
UsernsMode string `codec:"userns_mode"`
Volumes []string `codec:"volumes"`
VolumeDriver string `codec:"volume_driver"`
WorkDir string `codec:"work_dir"`
}
type DockerAuth struct {
Username string `codec:"username"`
Password string `codec:"password"`
Email string `codec:"email"`
ServerAddr string `codec:"server_address"`
}
type DockerDevice struct {
HostPath string `codec:"host_path"`
ContainerPath string `codec:"container_path"`
CgroupPermissions string `codec:"cgroup_permissions"`
}
type DockerLogging struct {
Type string `codec:"type"`
Config map[string]string `codec:"config"`
}
type DockerMount struct {
Target string `codec:"target"`
Source string `codec:"source"`
ReadOnly bool `codec:"readonly"`
VolumeOptions DockerVolumeOptions `codec:"volume_options"`
}
type DockerVolumeOptions struct {
NoCopy bool `codec:"no_copy"`
Labels map[string]string `codec:"labels"`
DriverConfig DockerVolumeDriverConfig `codec:"driver_config"`
}
// VolumeDriverConfig holds a map of volume driver specific options
type DockerVolumeDriverConfig struct {
Name string `codec:"name"`
Options map[string]string `codec:"options"`
}
type DriverConfig struct {
Endpoint string `codec:"endpoint"`
AuthConfig string `codec:"auth_config"`
AuthHelper string `codec:"auth_helper"`
TLS TLSConfig `codec:"tls"`
ImageGC bool `codec:"image_gc"`
ImageGCDelay string `codec:"image_gc_delay"`
imageGCDelayDuration time.Duration `codec:"-"`
VolumesEnabled bool `codec:"volumes_enabled"`
VolumesSelinuxLabel string `codec:"volumes_selinuxlabel"`
AllowPrivileged bool `codec:"allow_privileged"`
AllowCaps []string `codec:"allow_caps"`
ContainerGC bool `codec:"container_gc"`
}
type TLSConfig struct {
Cert string `codec:"cert"`
Key string `codec:"key"`
CA string `codec:"ca"`
}
......@@ -26,7 +26,6 @@ import (
"github.com/hashicorp/nomad/plugins/drivers"
"github.com/hashicorp/nomad/plugins/drivers/utils"
"github.com/hashicorp/nomad/plugins/shared/hclspec"
"github.com/hashicorp/nomad/plugins/shared/loader"
)
const (
......@@ -56,181 +55,6 @@ const (
)
var (
// PluginID is the rawexec plugin metadata registered in the plugin
// catalog.
PluginID = loader.PluginID{
Name: pluginName,
PluginType: base.PluginTypeDriver,
}
// PluginConfig is the rawexec factory function registered in the
// plugin catalog.
PluginConfig = &loader.InternalPluginConfig{
Config: map[string]interface{}{},
Factory: func(l hclog.Logger) interface{} { return NewDockerDriver(l) },
}
)
func PluginLoader(opts map[string]string) (map[string]interface{}, error) {
conf := map[string]interface{}{}
if v, ok := opts["docker.endpoint"]; ok {
conf["endpoint"] = v
}
if v, ok := opts["docker.auth.config"]; ok {
conf["auth_config"] = v
}
if v, ok := opts["docker.auth.helper"]; ok {
conf["auth_helper"] = v
}
if _, ok := opts["docker.tls.cert"]; ok {
conf["tls"] = map[string]interface{}{
"cert": opts["docker.tls.cert"],
"key": opts["docker.tls.key"],
"ca": opts["docker.tls.ca"],
}
}
if v, ok := opts["docker.cleanup.image.delay"]; ok {
conf["image_gc_delay"] = v
}
if v, ok := opts["docker.volumes.selinuxlabel"]; ok {
conf["volumes_selinuxlabel"] = v
}
if v, ok := opts["docker.caps.whitelist"]; ok {
conf["allow_caps"] = strings.Split(v, ",")
}
if v, err := strconv.ParseBool(opts["docker.cleanup.image"]); err == nil {
conf["image_gc"] = v
}
if v, err := strconv.ParseBool(opts["docker.volumes.enabled"]); err == nil {
conf["volumes_enabled"] = v
}
if v, err := strconv.ParseBool(opts["docker.privileged.enabled"]); err == nil {
conf["allow_privileged"] = v
}
if v, err := strconv.ParseBool(opts["docker.cleanup.container"]); err == nil {
conf["container_gc"] = v
}
return conf, nil
}
var (
// pluginInfo is the response returned for the PluginInfo RPC
pluginInfo = &base.PluginInfoResponse{
Type: base.PluginTypeDriver,
PluginApiVersion: "0.0.1",
PluginVersion: "0.1.0",
Name: pluginName,
}
// configSpec is the hcl specification returned by the ConfigSchema RPC
configSpec = hclspec.NewObject(map[string]*hclspec.Spec{
"endpoint": hclspec.NewAttr("endpoint", "string", false),
"auth_config": hclspec.NewAttr("auth_config", "string", false),
"auth_helper": hclspec.NewAttr("auth_helper", "string", false),
"tls": hclspec.NewBlock("tls", false, hclspec.NewObject(map[string]*hclspec.Spec{
"cert": hclspec.NewAttr("cert", "string", false),
"key": hclspec.NewAttr("key", "string", false),
"ca": hclspec.NewAttr("ca", "string", false),
})),
"image_gc": hclspec.NewDefault(
hclspec.NewAttr("image_gc", "bool", false),
hclspec.NewLiteral("true"),
),
"image_gc_delay": hclspec.NewAttr("image_gc_delay", "string", false),
"volumes_enabled": hclspec.NewDefault(
hclspec.NewAttr("volumes_enabled", "bool", false),
hclspec.NewLiteral("true"),
),
"volumes_selinuxlabel": hclspec.NewAttr("volumes_selinuxlabel", "string", false),
"allow_privileged": hclspec.NewAttr("allow_privileged", "bool", false),
"allow_caps": hclspec.NewDefault(
hclspec.NewAttr("allow_caps", "list(string)", false),
hclspec.NewLiteral(`["CHOWN","DAC_OVERRIDE","FSETID","FOWNER","MKNOD","NET_RAW","SETGID","SETUID","SETFCAP","SETPCAP","NET_BIND_SERVICE","SYS_CHROOT","KILL","AUDIT_WRITE"]`),
),
"container_gc": hclspec.NewDefault(
hclspec.NewAttr("container_gc", "bool", false),
hclspec.NewLiteral("true"),
),
})
// taskConfigSpec is the hcl specification for the driver config section of
// a task within a job. It is returned in the TaskConfigSchema RPC
taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{
"image": hclspec.NewAttr("image", "string", true),
"advertise_ipv6_address": hclspec.NewAttr("advertise_ipv6_address", "bool", false),
"args": hclspec.NewAttr("args", "list(string)", false),
"auth": hclspec.NewBlock("auth", false, hclspec.NewObject(map[string]*hclspec.Spec{
"username": hclspec.NewAttr("username", "string", false),
"password": hclspec.NewAttr("password", "string", false),
"email": hclspec.NewAttr("email", "string", false),
"server_address": hclspec.NewAttr("server_address", "string", false),
})),
"auth_soft_fail": hclspec.NewAttr("auth_soft_fail", "bool", false),
"cap_add": hclspec.NewAttr("cap_add", "list(string)", false),
"cap_drop": hclspec.NewAttr("cap_drop", "list(string)", false),
"command": hclspec.NewAttr("command", "string", false),
"cpu_hard_limit": hclspec.NewAttr("cpu_hard_limit", "bool", false),
"cpu_cfs_period": hclspec.NewAttr("cpu_cfs_period", "number", false),
"devices": hclspec.NewBlockSet("devices", hclspec.NewObject(map[string]*hclspec.Spec{
"host_path": hclspec.NewAttr("host_path", "string", false),
"container_path": hclspec.NewAttr("container_path", "string", false),
"cgroup_permissions": hclspec.NewAttr("cgroup_permissions", "string", false),
})),
"dns_search_domains": hclspec.NewAttr("dns_search_domains", "list(string)", false),
"dns_options": hclspec.NewAttr("dns_options", "list(string)", false),
"dns_servers": hclspec.NewAttr("dns_servers", "list(string)", false),
"entrypoint": hclspec.NewAttr("entrypoint", "list(string)", false),
"extra_hosts": hclspec.NewAttr("extra_hosts", "list(string)", false),
"force_pull": hclspec.NewAttr("force_pull", "bool", false),
"hostname": hclspec.NewAttr("hostname", "string", false),
"interactive": hclspec.NewAttr("interactive", "bool", false),
"ipc_mode": hclspec.NewAttr("ipc_mode", "string", false),
"ipv4_address": hclspec.NewAttr("ipv4_address", "string", false),
"ipv6_address": hclspec.NewAttr("ipv6_address", "string", false),
"labels": hclspec.NewAttr("labels", "map(string)", false),
"load": hclspec.NewAttr("load", "string", false),
"logging": hclspec.NewAttr("logging", "map(string)", false),
"mac_address": hclspec.NewAttr("mac_address", "map(string)", false),
"mounts": hclspec.NewBlockSet("mounts", hclspec.NewObject(map[string]*hclspec.Spec{
"target": hclspec.NewAttr("target", "string", false),
"source": hclspec.NewAttr("source", "string", false),
"readonly": hclspec.NewAttr("readonly", "bool", false),
"volume_options": hclspec.NewBlockSet("volume_options", hclspec.NewObject(map[string]*hclspec.Spec{
"no_copy": hclspec.NewAttr("no_copy", "bool", false),
"labels": hclspec.NewAttr("labels", "map(string)", false),
"driver_config": hclspec.NewBlockSet("driver_config", hclspec.NewObject(map[string]*hclspec.Spec{
"name": hclspec.NewAttr("name", "string", false),
"options": hclspec.NewAttr("name", "map(string)", false),
})),
})),
})),
"network_aliases": hclspec.NewAttr("network_aliases", "list(string)", false),
"network_mode": hclspec.NewAttr("network_mode", "string", false),
"pids_limit": hclspec.NewAttr("pids_limit", "number", false),
"pid_mode": hclspec.NewAttr("pid_mode", "string", false),
"port_map": hclspec.NewAttr("port_map", "map(number)", false),
"privileged": hclspec.NewAttr("privileged", "bool", false),
"readonly_rootfs": hclspec.NewAttr("readonly_rootfs", "bool", false),
"security_opt": hclspec.NewAttr("security_opt", "list(string)", false),
"shm_size": hclspec.NewAttr("shm_size", "number", false),
"sysctl": hclspec.NewAttr("sysctl", "map(string)", false),
"tty": hclspec.NewAttr("tty", "bool", false),
"ulimit": hclspec.NewAttr("ulimit", "map(string)", false),
"uts_mode": hclspec.NewAttr("uts_mode", "string", false),
"userns_mode": hclspec.NewAttr("userns_mode", "string", false),
"volumes": hclspec.NewAttr("volumes", "list(string)", false),
"volume_driver": hclspec.NewAttr("volume_driver", "string", false),
"work_dir": hclspec.NewAttr("work_dir", "string", false),
})
// capabilities is returned by the Capabilities RPC and indicates what
// optional features this driver supports
capabilities = &drivers.Capabilities{
SendSignals: true,
Exec: true,
FSIsolation: structs.FSIsolationImage,
}
// createClientsLock is a lock that protects reading/writing global client
// variables
createClientsLock sync.Mutex
......@@ -244,10 +68,6 @@ var (
// running operations such as waiting on containers and collect stats
waitClient *docker.Client
// healthCheckClient is a docker client with a timeout of 1 minute. This is
// necessary to have a shorter timeout than other API or fingerprint calls
healthCheckClient *docker.Client
// The statistics the Docker driver exposes
DockerMeasuredMemStats = []string{"RSS", "Cache", "Swap", "Max Usage"}
DockerMeasuredCpuStats = []string{"Throttled Periods", "Throttled Time", "Percent"}
......@@ -264,111 +84,6 @@ var (
}
)
type TaskConfig struct {
Image string `codec:"image"`
AdvertiseIPv6Addr bool `codec:"advertise_ipv6_address"`
Args []string `codec:"args"`
Auth DockerAuth `codec:"auth"`
AuthSoftFail bool `codec:"auth_soft_fail"`
CapAdd []string `codec:"cap_add"`
CapDrop []string `codec:"cap_drop"`
Command string `codec:"command"`
CPUCFSPeriod int64 `codec:"cpu_cfs_period"`
CPUHardLimit bool `codec:"cpu_hard_limit"`
Devices []DockerDevice `codec:"devices"`
DNSSearchDomains []string `codec:"dns_search_domains"`
DNSOptions []string `codec:"dns_options"`
DNSServers []string `codec:"dns_servers"`
Entrypoint []string `codec:"entrypoint"`
ExtraHosts []string `codec:"extra_hosts"`
ForcePull bool `codec:"force_pull"`
Hostname string `codec:"hostname"`
Interactive bool `codec:"interactive"`
IPCMode string `codec:"ipc_mode"`
IPv4Address string `codec:"ipv4_address"`
IPv6Address string `codec:"ipv6_address"`
Labels map[string]string `codec:"labels"`
LoadImage string `codec:"load"`
Logging DockerLogging `codec:"logging"`
MacAddress string `codec:"mac_address"`
Mounts []DockerMount `codec:"mounts"`
NetworkAliases []string `codec:"network_aliases"`
NetworkMode string `codec:"network_mode"`
PidsLimit int64 `codec:"pids_limit"`
PidMode string `codec:"pid_mode"`
PortMap map[string]int `codec:"port_map"`
Privileged bool `codec:"privileged"`
ReadonlyRootfs bool `codec:"readonly_rootfs"`
SecurityOpt []string `codec:"security_opt"`
ShmSize int64 `codec:"shm_size"`
Sysctl map[string]string `codec:"sysctl"`
TTY bool `codec:"tty"`
Ulimit map[string]string `codec:"ulimit"`
UTSMode string `codec:"uts_mode"`
UsernsMode string `codec:"userns_mode"`
Volumes []string `codec:"volumes"`
VolumeDriver string `codec:"volume_driver"`
WorkDir string `codec:"work_dir"`
}
type DockerAuth struct {
Username string `codec:"username"`
Password string `codec:"password"`
Email string `codec:"email"`
ServerAddr string `codec:"server_address"`
}
type DockerDevice struct {
HostPath string `codec:"host_path"`
ContainerPath string `codec:"container_path"`
CgroupPermissions string `codec:"cgroup_permissions"`
}
type DockerLogging struct {
Type string `codec:"type"`
Config map[string]string `codec:"config"`
}
type DockerMount struct {
Target string `codec:"target"`
Source string `codec:"source"`
ReadOnly bool `codec:"readonly"`
VolumeOptions DockerVolumeOptions `codec:"volume_options"`
}
type DockerVolumeOptions struct {
NoCopy bool `codec:"no_copy"`
Labels map[string]string `codec:"labels"`
DriverConfig DockerVolumeDriverConfig `codec:"driver_config"`
}
// VolumeDriverConfig holds a map of volume driver specific options
type DockerVolumeDriverConfig struct {
Name string `codec:"name"`
Options map[string]string `codec:"options"`
}
type DriverConfig struct {
Endpoint string `codec:"endpoint"`
AuthConfig string `codec:"auth_config"`
AuthHelper string `codec:"auth_helper"`
TLS TLSConfig `codec:"tls"`
ImageGC bool `codec:"image_gc"`
ImageGCDelay string `codec:"image_gc_delay"`
imageGCDelayDuration time.Duration `codec:"-"`
VolumesEnabled bool `codec:"volumes_enabled"`
VolumesSelinuxLabel string `codec:"volumes_selinuxlabel"`
AllowPrivileged bool `codec:"allow_privileged"`
AllowCaps []string `codec:"allow_caps"`
ContainerGC bool `codec:"container_gc"`
}
type TLSConfig struct {
Cert string `codec:"cert"`
Key string `codec:"key"`
CA string `codec:"ca"`
}
type Driver struct {
// eventer is used to handle multiplexing of TaskEvents calls such that an
// event can be broadcast to all callers
......@@ -657,7 +372,7 @@ CREATE:
dlogger, pluginClient, err := docklog.LaunchDockerLogger(d.logger)
if err != nil {
d.logger.Error("an error occured after container startup, terminating container", "container_id", container.ID)
d.logger.Error("an error occurred after container startup, terminating container", "container_id", container.ID)
client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID, Force: true})
return nil, nil, fmt.Errorf("failed to launch docker logger plugin: %v", err)
}
......@@ -673,7 +388,7 @@ CREATE:
}); err != nil {
pluginClient.Kill()
d.logger.Error("an error occured after container startup, terminating container", "container_id", container.ID)
d.logger.Error("an error occurred after container startup, terminating container", "container_id", container.ID)
client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID, Force: true})
return nil, nil, fmt.Errorf("failed to launch docker logger process %s: %v", container.ID, err)
}
......@@ -704,7 +419,7 @@ CREATE:
if err := handle.SetDriverState(h.buildState()); err != nil {
d.logger.Error("unable to encode container state into handle", "error", err)
d.logger.Error("an error occured after container startup, terminating container", "container_id", container.ID)
d.logger.Error("an error occurred after container startup, terminating container", "container_id", container.ID)
client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID, Force: true})
}
......
......@@ -349,7 +349,7 @@ func TestDockerDriver_Start_Wait(t *testing.T) {
select {
case <-waitCh:
t.Fatalf("wait channel should not have recieved an exit result")
t.Fatalf("wait channel should not have received an exit result")
case <-time.After(time.Duration(tu.TestMultiplier()*1) * time.Second):
}
}
......
......@@ -219,6 +219,7 @@ func (h *taskHandle) run() {
ExitCode: exitCode,
Signal: 0,
OOMKilled: oom,
Err: werr,
}
close(h.waitCh)
}
......
......@@ -15,6 +15,7 @@ import (
"github.com/hashicorp/nomad/plugins/drivers/proto"
"github.com/hashicorp/nomad/plugins/shared"
"github.com/hashicorp/nomad/plugins/shared/hclspec"
sproto "github.com/hashicorp/nomad/plugins/shared/structs/proto"
"google.golang.org/grpc/status"
)
......@@ -138,7 +139,7 @@ func (d *driverPluginClient) StartTask(c *TaskConfig) (*TaskHandle, *cstructs.Dr
if err != nil {
st := status.Convert(err)
if len(st.Details()) > 0 {
if rec, ok := st.Details()[0].(*proto.RecoverableError); ok {
if rec, ok := st.Details()[0].(*sproto.RecoverableError); ok {
return nil, nil, structs.NewRecoverableError(err, rec.Recoverable)
}
}
......
......@@ -18,7 +18,7 @@ import (
)
const (
// CheckBufSize is the size of the check output result<Paste>
// CheckBufSize is the size of the check output result
CheckBufSize = 4 * 1024
)
......
This diff is collapsed.
......@@ -7,12 +7,6 @@ import "google/protobuf/timestamp.proto";
import "github.com/hashicorp/nomad/plugins/shared/hclspec/hcl_spec.proto";
// RecoverableError is used with a grpc Status to indicate if the error is one
// which is recoverable and can be reattempted by the client.
message RecoverableError {
bool recoverable = 1;
}
// Driver service defines RPCs used to communicate with a nomad runtime driver.
// Some rpcs may not be implemented by the driver based on it's capabilities.
service Driver {
......
......@@ -13,6 +13,7 @@ import (
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/plugins/drivers/proto"
sproto "github.com/hashicorp/nomad/plugins/shared/structs/proto"
context "golang.org/x/net/context"
)
......@@ -102,7 +103,7 @@ func (b *driverPluginServer) StartTask(ctx context.Context, req *proto.StartTask
if err != nil {
if rec, ok := err.(structs.Recoverable); ok {
st := status.New(codes.FailedPrecondition, rec.Error())
st, err := st.WithDetails(&proto.RecoverableError{Recoverable: rec.IsRecoverable()})
st, err := st.WithDetails(&sproto.RecoverableError{Recoverable: rec.IsRecoverable()})
if err != nil {
// If this error, it will always error
panic(err)
......
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: plugins/shared/structs/proto/recoverable_error.proto
package proto
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// RecoverableError is used with a grpc Status to indicate if the error is one
// which is recoverable and can be reattempted by the client.
type RecoverableError struct {
Recoverable bool `protobuf:"varint,1,opt,name=recoverable,proto3" json:"recoverable,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RecoverableError) Reset() { *m = RecoverableError{} }
func (m *RecoverableError) String() string { return proto.CompactTextString(m) }
func (*RecoverableError) ProtoMessage() {}
func (*RecoverableError) Descriptor() ([]byte, []int) {
return fileDescriptor_recoverable_error_f746254fd69675b0, []int{0}
}
func (m *RecoverableError) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RecoverableError.Unmarshal(m, b)
}
func (m *RecoverableError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RecoverableError.Marshal(b, m, deterministic)
}
func (dst *RecoverableError) XXX_Merge(src proto.Message) {
xxx_messageInfo_RecoverableError.Merge(dst, src)
}
func (m *RecoverableError) XXX_Size() int {
return xxx_messageInfo_RecoverableError.Size(m)
}
func (m *RecoverableError) XXX_DiscardUnknown() {
xxx_messageInfo_RecoverableError.DiscardUnknown(m)
}
var xxx_messageInfo_RecoverableError proto.InternalMessageInfo
func (m *RecoverableError) GetRecoverable() bool {
if m != nil {
return m.Recoverable
}
return false
}
func init() {
proto.RegisterType((*RecoverableError)(nil), "hashicorp.nomad.plugins.shared.structs.RecoverableError")
}
func init() {
proto.RegisterFile("plugins/shared/structs/proto/recoverable_error.proto", fileDescriptor_recoverable_error_f746254fd69675b0)
}
var fileDescriptor_recoverable_error_f746254fd69675b0 = []byte{
// 138 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x29, 0xc8, 0x29, 0x4d,
0xcf, 0xcc, 0x2b, 0xd6, 0x2f, 0xce, 0x48, 0x2c, 0x4a, 0x4d, 0xd1, 0x2f, 0x2e, 0x29, 0x2a, 0x4d,
0x2e, 0x29, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0xd7, 0x2f, 0x4a, 0x4d, 0xce, 0x2f, 0x4b, 0x2d,
0x4a, 0x4c, 0xca, 0x49, 0x8d, 0x4f, 0x2d, 0x2a, 0xca, 0x2f, 0xd2, 0x03, 0x8b, 0x0b, 0xa9, 0x65,
0x24, 0x16, 0x67, 0x64, 0x26, 0xe7, 0x17, 0x15, 0xe8, 0xe5, 0xe5, 0xe7, 0x26, 0xa6, 0xe8, 0x41,
0x4d, 0xd1, 0x83, 0x98, 0xa2, 0x07, 0x35, 0x45, 0xc9, 0x84, 0x4b, 0x20, 0x08, 0x61, 0x84, 0x2b,
0xc8, 0x04, 0x21, 0x05, 0x2e, 0x6e, 0x24, 0x63, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x82, 0x90,
0x85, 0x9c, 0xd8, 0xa3, 0x58, 0xc1, 0xd6, 0x24, 0xb1, 0x81, 0x29, 0x63, 0x40, 0x00, 0x00, 0x00,
0xff, 0xff, 0xc5, 0x45, 0x79, 0xed, 0xa5, 0x00, 0x00, 0x00,
}
syntax = "proto3";
package hashicorp.nomad.plugins.shared.structs;
option go_package = "proto";
// RecoverableError is used with a grpc Status to indicate if the error is one
// which is recoverable and can be reattempted by the client.
message RecoverableError {
bool recoverable = 1;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment