mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
Add pod/attach to the APIServer.
This commit is contained in:
parent
452bdcae2d
commit
e8e756a719
@ -5637,6 +5637,152 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "/api/v1/namespaces/{namespace}/pods/{name}/attach",
|
||||||
|
"description": "API at /api/v1 version v1",
|
||||||
|
"operations": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"method": "GET",
|
||||||
|
"summary": "connect GET requests to attach of Pod",
|
||||||
|
"nickname": "connectGetNamespacedPodAttach",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "stdin",
|
||||||
|
"description": "redirect the standard input stream of the pod for this call; defaults to false",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "stdout",
|
||||||
|
"description": "redirect the standard output stream of the pod for this call; defaults to true",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "stderr",
|
||||||
|
"description": "redirect the standard error stream of the pod for this call; defaults to true",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "tty",
|
||||||
|
"description": "allocate a terminal for this attach call; defaults to false",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "container",
|
||||||
|
"description": "the container in which to execute the command. Defaults to only container if there is only one container in the pod.",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"paramType": "path",
|
||||||
|
"name": "namespace",
|
||||||
|
"description": "object name and auth scope, such as for teams and projects",
|
||||||
|
"required": true,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"paramType": "path",
|
||||||
|
"name": "name",
|
||||||
|
"description": "name of the Pod",
|
||||||
|
"required": true,
|
||||||
|
"allowMultiple": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"*/*"
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"*/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"method": "POST",
|
||||||
|
"summary": "connect POST requests to attach of Pod",
|
||||||
|
"nickname": "connectPostNamespacedPodAttach",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "stdin",
|
||||||
|
"description": "redirect the standard input stream of the pod for this call; defaults to false",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "stdout",
|
||||||
|
"description": "redirect the standard output stream of the pod for this call; defaults to true",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "stderr",
|
||||||
|
"description": "redirect the standard error stream of the pod for this call; defaults to true",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "tty",
|
||||||
|
"description": "allocate a terminal for this attach call; defaults to false",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"paramType": "query",
|
||||||
|
"name": "container",
|
||||||
|
"description": "the container in which to execute the command. Defaults to only container if there is only one container in the pod.",
|
||||||
|
"required": false,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"paramType": "path",
|
||||||
|
"name": "namespace",
|
||||||
|
"description": "object name and auth scope, such as for teams and projects",
|
||||||
|
"required": true,
|
||||||
|
"allowMultiple": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"paramType": "path",
|
||||||
|
"name": "name",
|
||||||
|
"description": "name of the Pod",
|
||||||
|
"required": true,
|
||||||
|
"allowMultiple": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"*/*"
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"*/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "/api/v1/namespaces/{namespace}/pods/{name}/binding",
|
"path": "/api/v1/namespaces/{namespace}/pods/{name}/binding",
|
||||||
"description": "API at /api/v1 version v1",
|
"description": "API at /api/v1 version v1",
|
||||||
|
@ -1200,6 +1200,18 @@ func deepCopy_api_Pod(in Pod, out *Pod, c *conversion.Cloner) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deepCopy_api_PodAttachOptions(in PodAttachOptions, out *PodAttachOptions, c *conversion.Cloner) error {
|
||||||
|
if err := deepCopy_api_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out.Stdin = in.Stdin
|
||||||
|
out.Stdout = in.Stdout
|
||||||
|
out.Stderr = in.Stderr
|
||||||
|
out.TTY = in.TTY
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func deepCopy_api_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error {
|
func deepCopy_api_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error {
|
||||||
out.Type = in.Type
|
out.Type = in.Type
|
||||||
out.Status = in.Status
|
out.Status = in.Status
|
||||||
@ -2144,6 +2156,7 @@ func init() {
|
|||||||
deepCopy_api_PersistentVolumeSpec,
|
deepCopy_api_PersistentVolumeSpec,
|
||||||
deepCopy_api_PersistentVolumeStatus,
|
deepCopy_api_PersistentVolumeStatus,
|
||||||
deepCopy_api_Pod,
|
deepCopy_api_Pod,
|
||||||
|
deepCopy_api_PodAttachOptions,
|
||||||
deepCopy_api_PodCondition,
|
deepCopy_api_PodCondition,
|
||||||
deepCopy_api_PodExecOptions,
|
deepCopy_api_PodExecOptions,
|
||||||
deepCopy_api_PodList,
|
deepCopy_api_PodList,
|
||||||
|
@ -59,6 +59,7 @@ func init() {
|
|||||||
&PersistentVolumeClaimList{},
|
&PersistentVolumeClaimList{},
|
||||||
&DeleteOptions{},
|
&DeleteOptions{},
|
||||||
&ListOptions{},
|
&ListOptions{},
|
||||||
|
&PodAttachOptions{},
|
||||||
&PodLogOptions{},
|
&PodLogOptions{},
|
||||||
&PodExecOptions{},
|
&PodExecOptions{},
|
||||||
&PodProxyOptions{},
|
&PodProxyOptions{},
|
||||||
@ -106,6 +107,7 @@ func (*PersistentVolumeClaim) IsAnAPIObject() {}
|
|||||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
||||||
func (*DeleteOptions) IsAnAPIObject() {}
|
func (*DeleteOptions) IsAnAPIObject() {}
|
||||||
func (*ListOptions) IsAnAPIObject() {}
|
func (*ListOptions) IsAnAPIObject() {}
|
||||||
|
func (*PodAttachOptions) IsAnAPIObject() {}
|
||||||
func (*PodLogOptions) IsAnAPIObject() {}
|
func (*PodLogOptions) IsAnAPIObject() {}
|
||||||
func (*PodExecOptions) IsAnAPIObject() {}
|
func (*PodExecOptions) IsAnAPIObject() {}
|
||||||
func (*PodProxyOptions) IsAnAPIObject() {}
|
func (*PodProxyOptions) IsAnAPIObject() {}
|
||||||
|
@ -1517,6 +1517,27 @@ type PodLogOptions struct {
|
|||||||
Previous bool
|
Previous bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PodAttachOptions is the query options to a Pod's remote attach call
|
||||||
|
// TODO: merge w/ PodExecOptions below for stdin, stdout, etc
|
||||||
|
type PodAttachOptions struct {
|
||||||
|
TypeMeta `json:",inline"`
|
||||||
|
|
||||||
|
// Stdin if true indicates that stdin is to be redirected for the attach call
|
||||||
|
Stdin bool `json:"stdin,omitempty" description:"redirect the standard input stream of the pod for this call; defaults to false"`
|
||||||
|
|
||||||
|
// Stdout if true indicates that stdout is to be redirected for the attach call
|
||||||
|
Stdout bool `json:"stdout,omitempty" description:"redirect the standard output stream of the pod for this call; defaults to true"`
|
||||||
|
|
||||||
|
// Stderr if true indicates that stderr is to be redirected for the attach call
|
||||||
|
Stderr bool `json:"stderr,omitempty" description:"redirect the standard error stream of the pod for this call; defaults to true"`
|
||||||
|
|
||||||
|
// TTY if true indicates that a tty will be allocated for the attach call
|
||||||
|
TTY bool `json:"tty,omitempty" description:"allocate a terminal for this attach call; defaults to false"`
|
||||||
|
|
||||||
|
// Container to attach to.
|
||||||
|
Container string `json:"container,omitempty" description:"the container in which to execute the command. Defaults to only container if there is only one container in the pod."`
|
||||||
|
}
|
||||||
|
|
||||||
// PodExecOptions is the query options to a Pod's remote exec call
|
// PodExecOptions is the query options to a Pod's remote exec call
|
||||||
type PodExecOptions struct {
|
type PodExecOptions struct {
|
||||||
TypeMeta
|
TypeMeta
|
||||||
|
@ -1392,6 +1392,21 @@ func convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convert_api_PodAttachOptions_To_v1_PodAttachOptions(in *api.PodAttachOptions, out *PodAttachOptions, s conversion.Scope) error {
|
||||||
|
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||||
|
defaulting.(func(*api.PodAttachOptions))(in)
|
||||||
|
}
|
||||||
|
if err := convert_api_TypeMeta_To_v1_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out.Stdin = in.Stdin
|
||||||
|
out.Stdout = in.Stdout
|
||||||
|
out.Stderr = in.Stderr
|
||||||
|
out.TTY = in.TTY
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func convert_api_PodCondition_To_v1_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error {
|
func convert_api_PodCondition_To_v1_PodCondition(in *api.PodCondition, out *PodCondition, s conversion.Scope) error {
|
||||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||||
defaulting.(func(*api.PodCondition))(in)
|
defaulting.(func(*api.PodCondition))(in)
|
||||||
@ -3642,6 +3657,21 @@ func convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convert_v1_PodAttachOptions_To_api_PodAttachOptions(in *PodAttachOptions, out *api.PodAttachOptions, s conversion.Scope) error {
|
||||||
|
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||||
|
defaulting.(func(*PodAttachOptions))(in)
|
||||||
|
}
|
||||||
|
if err := convert_v1_TypeMeta_To_api_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out.Stdin = in.Stdin
|
||||||
|
out.Stdout = in.Stdout
|
||||||
|
out.Stderr = in.Stderr
|
||||||
|
out.TTY = in.TTY
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func convert_v1_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error {
|
func convert_v1_PodCondition_To_api_PodCondition(in *PodCondition, out *api.PodCondition, s conversion.Scope) error {
|
||||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||||
defaulting.(func(*PodCondition))(in)
|
defaulting.(func(*PodCondition))(in)
|
||||||
@ -4595,6 +4625,7 @@ func init() {
|
|||||||
convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec,
|
convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec,
|
||||||
convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus,
|
convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus,
|
||||||
convert_api_PersistentVolume_To_v1_PersistentVolume,
|
convert_api_PersistentVolume_To_v1_PersistentVolume,
|
||||||
|
convert_api_PodAttachOptions_To_v1_PodAttachOptions,
|
||||||
convert_api_PodCondition_To_v1_PodCondition,
|
convert_api_PodCondition_To_v1_PodCondition,
|
||||||
convert_api_PodExecOptions_To_v1_PodExecOptions,
|
convert_api_PodExecOptions_To_v1_PodExecOptions,
|
||||||
convert_api_PodList_To_v1_PodList,
|
convert_api_PodList_To_v1_PodList,
|
||||||
@ -4707,6 +4738,7 @@ func init() {
|
|||||||
convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec,
|
convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec,
|
||||||
convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus,
|
convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus,
|
||||||
convert_v1_PersistentVolume_To_api_PersistentVolume,
|
convert_v1_PersistentVolume_To_api_PersistentVolume,
|
||||||
|
convert_v1_PodAttachOptions_To_api_PodAttachOptions,
|
||||||
convert_v1_PodCondition_To_api_PodCondition,
|
convert_v1_PodCondition_To_api_PodCondition,
|
||||||
convert_v1_PodExecOptions_To_api_PodExecOptions,
|
convert_v1_PodExecOptions_To_api_PodExecOptions,
|
||||||
convert_v1_PodList_To_api_PodList,
|
convert_v1_PodList_To_api_PodList,
|
||||||
|
@ -1203,6 +1203,18 @@ func deepCopy_v1_Pod(in Pod, out *Pod, c *conversion.Cloner) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deepCopy_v1_PodAttachOptions(in PodAttachOptions, out *PodAttachOptions, c *conversion.Cloner) error {
|
||||||
|
if err := deepCopy_v1_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out.Stdin = in.Stdin
|
||||||
|
out.Stdout = in.Stdout
|
||||||
|
out.Stderr = in.Stderr
|
||||||
|
out.TTY = in.TTY
|
||||||
|
out.Container = in.Container
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func deepCopy_v1_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error {
|
func deepCopy_v1_PodCondition(in PodCondition, out *PodCondition, c *conversion.Cloner) error {
|
||||||
out.Type = in.Type
|
out.Type = in.Type
|
||||||
out.Status = in.Status
|
out.Status = in.Status
|
||||||
@ -2152,6 +2164,7 @@ func init() {
|
|||||||
deepCopy_v1_PersistentVolumeSpec,
|
deepCopy_v1_PersistentVolumeSpec,
|
||||||
deepCopy_v1_PersistentVolumeStatus,
|
deepCopy_v1_PersistentVolumeStatus,
|
||||||
deepCopy_v1_Pod,
|
deepCopy_v1_Pod,
|
||||||
|
deepCopy_v1_PodAttachOptions,
|
||||||
deepCopy_v1_PodCondition,
|
deepCopy_v1_PodCondition,
|
||||||
deepCopy_v1_PodExecOptions,
|
deepCopy_v1_PodExecOptions,
|
||||||
deepCopy_v1_PodList,
|
deepCopy_v1_PodList,
|
||||||
|
@ -74,6 +74,7 @@ func addKnownTypes() {
|
|||||||
&PersistentVolumeClaimList{},
|
&PersistentVolumeClaimList{},
|
||||||
&DeleteOptions{},
|
&DeleteOptions{},
|
||||||
&ListOptions{},
|
&ListOptions{},
|
||||||
|
&PodAttachOptions{},
|
||||||
&PodLogOptions{},
|
&PodLogOptions{},
|
||||||
&PodExecOptions{},
|
&PodExecOptions{},
|
||||||
&PodProxyOptions{},
|
&PodProxyOptions{},
|
||||||
@ -121,6 +122,7 @@ func (*PersistentVolumeClaim) IsAnAPIObject() {}
|
|||||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
||||||
func (*DeleteOptions) IsAnAPIObject() {}
|
func (*DeleteOptions) IsAnAPIObject() {}
|
||||||
func (*ListOptions) IsAnAPIObject() {}
|
func (*ListOptions) IsAnAPIObject() {}
|
||||||
|
func (*PodAttachOptions) IsAnAPIObject() {}
|
||||||
func (*PodLogOptions) IsAnAPIObject() {}
|
func (*PodLogOptions) IsAnAPIObject() {}
|
||||||
func (*PodExecOptions) IsAnAPIObject() {}
|
func (*PodExecOptions) IsAnAPIObject() {}
|
||||||
func (*PodProxyOptions) IsAnAPIObject() {}
|
func (*PodProxyOptions) IsAnAPIObject() {}
|
||||||
|
@ -1475,6 +1475,28 @@ type PodLogOptions struct {
|
|||||||
Previous bool `json:"previous,omitempty" description:"return previous terminated container logs; defaults to false"`
|
Previous bool `json:"previous,omitempty" description:"return previous terminated container logs; defaults to false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PodAttachOptions is the query options to a Pod's remote attach call
|
||||||
|
// TODO: merge w/ PodExecOptions below for stdin, stdout, etc
|
||||||
|
type PodAttachOptions struct {
|
||||||
|
TypeMeta `json:",inline"`
|
||||||
|
|
||||||
|
// Stdin if true indicates that stdin is to be redirected for the attach call
|
||||||
|
Stdin bool `json:"stdin,omitempty" description:"redirect the standard input stream of the pod for this call; defaults to false"`
|
||||||
|
|
||||||
|
// Stdout if true indicates that stdout is to be redirected for the attach call
|
||||||
|
Stdout bool `json:"stdout,omitempty" description:"redirect the standard output stream of the pod for this call; defaults to true"`
|
||||||
|
|
||||||
|
// Stderr if true indicates that stderr is to be redirected for the attach call
|
||||||
|
Stderr bool `json:"stderr,omitempty" description:"redirect the standard error stream of the pod for this call; defaults to true"`
|
||||||
|
|
||||||
|
// TTY if true indicates that a tty will be allocated for the attach call, this is passed through to the container runtime so the tty
|
||||||
|
// is allocated on the worker node by the container runtime.
|
||||||
|
TTY bool `json:"tty,omitempty" description:"allocate a terminal for this attach call; defaults to false"`
|
||||||
|
|
||||||
|
// Container to attach to.
|
||||||
|
Container string `json:"container,omitempty" description:"the container in which to execute the command. Defaults to only container if there is only one container in the pod."`
|
||||||
|
}
|
||||||
|
|
||||||
// PodExecOptions is the query options to a Pod's remote exec call
|
// PodExecOptions is the query options to a Pod's remote exec call
|
||||||
type PodExecOptions struct {
|
type PodExecOptions struct {
|
||||||
TypeMeta `json:",inline"`
|
TypeMeta `json:",inline"`
|
||||||
|
@ -1012,6 +1012,7 @@ func (dm *DockerManager) AttachContainer(containerId string, stdin io.Reader, st
|
|||||||
InputStream: stdin,
|
InputStream: stdin,
|
||||||
OutputStream: stdout,
|
OutputStream: stdout,
|
||||||
ErrorStream: stderr,
|
ErrorStream: stderr,
|
||||||
|
Stream: true,
|
||||||
Logs: true,
|
Logs: true,
|
||||||
Stdin: stdin != nil,
|
Stdin: stdin != nil,
|
||||||
Stdout: stdout != nil,
|
Stdout: stdout != nil,
|
||||||
|
@ -470,6 +470,7 @@ func (m *Master) init(c *Config) {
|
|||||||
// TODO: Factor out the core API registration
|
// TODO: Factor out the core API registration
|
||||||
m.storage = map[string]rest.Storage{
|
m.storage = map[string]rest.Storage{
|
||||||
"pods": podStorage.Pod,
|
"pods": podStorage.Pod,
|
||||||
|
"pods/attach": podStorage.Attach,
|
||||||
"pods/status": podStorage.Status,
|
"pods/status": podStorage.Status,
|
||||||
"pods/log": podStorage.Log,
|
"pods/log": podStorage.Log,
|
||||||
"pods/exec": podStorage.Exec,
|
"pods/exec": podStorage.Exec,
|
||||||
|
@ -47,6 +47,7 @@ type PodStorage struct {
|
|||||||
Log *LogREST
|
Log *LogREST
|
||||||
Proxy *ProxyREST
|
Proxy *ProxyREST
|
||||||
Exec *ExecREST
|
Exec *ExecREST
|
||||||
|
Attach *AttachREST
|
||||||
PortForward *PortForwardREST
|
PortForward *PortForwardREST
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,6 +97,7 @@ func NewStorage(s tools.StorageInterface, k client.ConnectionInfoGetter) PodStor
|
|||||||
Log: &LogREST{store: store, kubeletConn: k},
|
Log: &LogREST{store: store, kubeletConn: k},
|
||||||
Proxy: &ProxyREST{store: store},
|
Proxy: &ProxyREST{store: store},
|
||||||
Exec: &ExecREST{store: store, kubeletConn: k},
|
Exec: &ExecREST{store: store, kubeletConn: k},
|
||||||
|
Attach: &AttachREST{store: store, kubeletConn: k},
|
||||||
PortForward: &PortForwardREST{store: store, kubeletConn: k},
|
PortForward: &PortForwardREST{store: store, kubeletConn: k},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,6 +286,43 @@ func (r *ProxyREST) Connect(ctx api.Context, id string, opts runtime.Object) (re
|
|||||||
// Support both GET and POST methods. Over time, we want to move all clients to start using POST and then stop supporting GET.
|
// Support both GET and POST methods. Over time, we want to move all clients to start using POST and then stop supporting GET.
|
||||||
var upgradeableMethods = []string{"GET", "POST"}
|
var upgradeableMethods = []string{"GET", "POST"}
|
||||||
|
|
||||||
|
// AttachREST implements the attach subresource for a Pod
|
||||||
|
type AttachREST struct {
|
||||||
|
store *etcdgeneric.Etcd
|
||||||
|
kubeletConn client.ConnectionInfoGetter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement Connecter
|
||||||
|
var _ = rest.Connecter(&AttachREST{})
|
||||||
|
|
||||||
|
// New creates a new Pod object
|
||||||
|
func (r *AttachREST) New() runtime.Object {
|
||||||
|
return &api.Pod{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect returns a handler for the pod exec proxy
|
||||||
|
func (r *AttachREST) Connect(ctx api.Context, name string, opts runtime.Object) (rest.ConnectHandler, error) {
|
||||||
|
attachOpts, ok := opts.(*api.PodAttachOptions)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Invalid options object: %#v", opts)
|
||||||
|
}
|
||||||
|
location, transport, err := pod.AttachLocation(r.store, r.kubeletConn, ctx, name, attachOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return genericrest.NewUpgradeAwareProxyHandler(location, transport, true), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConnectOptions returns the versioned object that represents exec parameters
|
||||||
|
func (r *AttachREST) NewConnectOptions() (runtime.Object, bool, string) {
|
||||||
|
return &api.PodAttachOptions{}, false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectMethods returns the methods supported by exec
|
||||||
|
func (r *AttachREST) ConnectMethods() []string {
|
||||||
|
return upgradeableMethods
|
||||||
|
}
|
||||||
|
|
||||||
// ExecREST implements the exec subresource for a Pod
|
// ExecREST implements the exec subresource for a Pod
|
||||||
type ExecREST struct {
|
type ExecREST struct {
|
||||||
store *etcdgeneric.Etcd
|
store *etcdgeneric.Etcd
|
||||||
|
@ -188,7 +188,6 @@ func ResourceLocation(getter ResourceGetter, ctx api.Context, id string) (*url.U
|
|||||||
// LogLocation returns a the log URL for a pod container. If opts.Container is blank
|
// LogLocation returns a the log URL for a pod container. If opts.Container is blank
|
||||||
// and only one container is present in the pod, that container is used.
|
// and only one container is present in the pod, that container is used.
|
||||||
func LogLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodLogOptions) (*url.URL, http.RoundTripper, error) {
|
func LogLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodLogOptions) (*url.URL, http.RoundTripper, error) {
|
||||||
|
|
||||||
pod, err := getPod(getter, ctx, name)
|
pod, err := getPod(getter, ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -228,17 +227,62 @@ func LogLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ct
|
|||||||
return loc, nodeTransport, nil
|
return loc, nodeTransport, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func streamParams(params url.Values, opts runtime.Object) error {
|
||||||
|
switch opts := opts.(type) {
|
||||||
|
case *api.PodExecOptions:
|
||||||
|
if opts.Stdin {
|
||||||
|
params.Add(api.ExecStdinParam, "1")
|
||||||
|
}
|
||||||
|
if opts.Stdout {
|
||||||
|
params.Add(api.ExecStdoutParam, "1")
|
||||||
|
}
|
||||||
|
if opts.Stderr {
|
||||||
|
params.Add(api.ExecStderrParam, "1")
|
||||||
|
}
|
||||||
|
if opts.TTY {
|
||||||
|
params.Add(api.ExecTTYParam, "1")
|
||||||
|
}
|
||||||
|
for _, c := range opts.Command {
|
||||||
|
params.Add("command", c)
|
||||||
|
}
|
||||||
|
case *api.PodAttachOptions:
|
||||||
|
if opts.Stdin {
|
||||||
|
params.Add(api.ExecStdinParam, "1")
|
||||||
|
}
|
||||||
|
if opts.Stdout {
|
||||||
|
params.Add(api.ExecStdoutParam, "1")
|
||||||
|
}
|
||||||
|
if opts.Stderr {
|
||||||
|
params.Add(api.ExecStderrParam, "1")
|
||||||
|
}
|
||||||
|
if opts.TTY {
|
||||||
|
params.Add(api.ExecTTYParam, "1")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unknown object for streaming: %v", opts)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttachLocation returns the attach URL for a pod container. If opts.Container is blank
|
||||||
|
// and only one container is present in the pod, that container is used.
|
||||||
|
func AttachLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodAttachOptions) (*url.URL, http.RoundTripper, error) {
|
||||||
|
return streamLocation(getter, connInfo, ctx, name, opts, opts.Container, "attach")
|
||||||
|
}
|
||||||
|
|
||||||
// ExecLocation returns the exec URL for a pod container. If opts.Container is blank
|
// ExecLocation returns the exec URL for a pod container. If opts.Container is blank
|
||||||
// and only one container is present in the pod, that container is used.
|
// and only one container is present in the pod, that container is used.
|
||||||
func ExecLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodExecOptions) (*url.URL, http.RoundTripper, error) {
|
func ExecLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodExecOptions) (*url.URL, http.RoundTripper, error) {
|
||||||
|
return streamLocation(getter, connInfo, ctx, name, opts, opts.Container, "exec")
|
||||||
|
}
|
||||||
|
|
||||||
|
func streamLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts runtime.Object, container, path string) (*url.URL, http.RoundTripper, error) {
|
||||||
pod, err := getPod(getter, ctx, name)
|
pod, err := getPod(getter, ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to figure out a container
|
// Try to figure out a container
|
||||||
container := opts.Container
|
|
||||||
if container == "" {
|
if container == "" {
|
||||||
if len(pod.Spec.Containers) == 1 {
|
if len(pod.Spec.Containers) == 1 {
|
||||||
container = pod.Spec.Containers[0].Name
|
container = pod.Spec.Containers[0].Name
|
||||||
@ -256,25 +300,13 @@ func ExecLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, c
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
if opts.Stdin {
|
if err := streamParams(params, opts); err != nil {
|
||||||
params.Add(api.ExecStdinParam, "1")
|
return nil, nil, err
|
||||||
}
|
|
||||||
if opts.Stdout {
|
|
||||||
params.Add(api.ExecStdoutParam, "1")
|
|
||||||
}
|
|
||||||
if opts.Stderr {
|
|
||||||
params.Add(api.ExecStderrParam, "1")
|
|
||||||
}
|
|
||||||
if opts.TTY {
|
|
||||||
params.Add(api.ExecTTYParam, "1")
|
|
||||||
}
|
|
||||||
for _, c := range opts.Command {
|
|
||||||
params.Add("command", c)
|
|
||||||
}
|
}
|
||||||
loc := &url.URL{
|
loc := &url.URL{
|
||||||
Scheme: nodeScheme,
|
Scheme: nodeScheme,
|
||||||
Host: fmt.Sprintf("%s:%d", nodeHost, nodePort),
|
Host: fmt.Sprintf("%s:%d", nodeHost, nodePort),
|
||||||
Path: fmt.Sprintf("/exec/%s/%s/%s", pod.Namespace, name, container),
|
Path: fmt.Sprintf("/%s/%s/%s/%s", path, pod.Namespace, name, container),
|
||||||
RawQuery: params.Encode(),
|
RawQuery: params.Encode(),
|
||||||
}
|
}
|
||||||
return loc, nodeTransport, nil
|
return loc, nodeTransport, nil
|
||||||
@ -282,7 +314,6 @@ func ExecLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, c
|
|||||||
|
|
||||||
// PortForwardLocation returns a the port-forward URL for a pod.
|
// PortForwardLocation returns a the port-forward URL for a pod.
|
||||||
func PortForwardLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string) (*url.URL, http.RoundTripper, error) {
|
func PortForwardLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string) (*url.URL, http.RoundTripper, error) {
|
||||||
|
|
||||||
pod, err := getPod(getter, ctx, name)
|
pod, err := getPod(getter, ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
Loading…
Reference in New Issue
Block a user