Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
03900b1d
Commit
03900b1d
authored
Jan 07, 2016
by
Justin Santa Barbara
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AWS: Use a strongly typed mountDevice
We've had problems in the past from using a string with passing the wrong value when detaching; stronger typing would have caught this for us.
parent
7ca0fa43
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
27 deletions
+35
-27
aws.go
pkg/cloudprovider/providers/aws/aws.go
+35
-27
No files found.
pkg/cloudprovider/providers/aws/aws.go
View file @
03900b1d
...
@@ -802,12 +802,16 @@ func (self *AWSCloud) GetZone() (cloudprovider.Zone, error) {
...
@@ -802,12 +802,16 @@ func (self *AWSCloud) GetZone() (cloudprovider.Zone, error) {
type
awsInstanceType
struct
{
type
awsInstanceType
struct
{
}
}
// Used to represent a mount device for attaching an EBS volume
// This should be stored as a single letter (i.e. c, not sdc or /dev/sdc)
type
mountDevice
string
// TODO: Also return number of mounts allowed?
// TODO: Also return number of mounts allowed?
func
(
self
*
awsInstanceType
)
getEBSMountDevices
()
[]
string
{
func
(
self
*
awsInstanceType
)
getEBSMountDevices
()
[]
mountDevice
{
// See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
// See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
devices
:=
[]
string
{}
devices
:=
[]
mountDevice
{}
for
c
:=
'f'
;
c
<=
'p'
;
c
++
{
for
c
:=
'f'
;
c
<=
'p'
;
c
++
{
devices
=
append
(
devices
,
fmt
.
Sprintf
(
"%c"
,
c
))
devices
=
append
(
devices
,
mountDevice
(
fmt
.
Sprintf
(
"%c"
,
c
)
))
}
}
return
devices
return
devices
}
}
...
@@ -825,7 +829,7 @@ type awsInstance struct {
...
@@ -825,7 +829,7 @@ type awsInstance struct {
// We must cache because otherwise there is a race condition,
// We must cache because otherwise there is a race condition,
// where we assign a device mapping and then get a second request before we attach the volume
// where we assign a device mapping and then get a second request before we attach the volume
deviceMappings
map
[
string
]
string
deviceMappings
map
[
mountDevice
]
string
}
}
func
newAWSInstance
(
ec2
EC2
,
awsID
,
nodeName
string
)
*
awsInstance
{
func
newAWSInstance
(
ec2
EC2
,
awsID
,
nodeName
string
)
*
awsInstance
{
...
@@ -864,9 +868,10 @@ func (self *awsInstance) getInfo() (*ec2.Instance, error) {
...
@@ -864,9 +868,10 @@ func (self *awsInstance) getInfo() (*ec2.Instance, error) {
return
instances
[
0
],
nil
return
instances
[
0
],
nil
}
}
// Assigns an unused mountpoint (device) for the specified volume.
// Gets the mountDevice already assigned to the volume, or assigns an unused mountDevice.
// If the volume is already assigned, this will return the existing mountpoint and true
// If the volume is already assigned, this will return the existing mountDevice with alreadyAttached=true.
func
(
self
*
awsInstance
)
assignMountpoint
(
volumeID
string
)
(
mountpoint
string
,
alreadyAttached
bool
,
err
error
)
{
// Otherwise the mountDevice is assigned by finding the first available mountDevice, and it is returned with alreadyAttached=false.
func
(
self
*
awsInstance
)
getMountDevice
(
volumeID
string
)
(
assigned
mountDevice
,
alreadyAttached
bool
,
err
error
)
{
instanceType
:=
self
.
getInstanceType
()
instanceType
:=
self
.
getInstanceType
()
if
instanceType
==
nil
{
if
instanceType
==
nil
{
return
""
,
false
,
fmt
.
Errorf
(
"could not get instance type for instance: %s"
,
self
.
awsID
)
return
""
,
false
,
fmt
.
Errorf
(
"could not get instance type for instance: %s"
,
self
.
awsID
)
...
@@ -884,35 +889,38 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a
...
@@ -884,35 +889,38 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
false
,
err
return
""
,
false
,
err
}
}
deviceMappings
:=
map
[
string
]
string
{}
deviceMappings
:=
map
[
mountDevice
]
string
{}
for
_
,
blockDevice
:=
range
info
.
BlockDeviceMappings
{
for
_
,
blockDevice
:=
range
info
.
BlockDeviceMappings
{
mountpoint
:=
orEmpty
(
blockDevice
.
DeviceName
)
name
:=
aws
.
StringValue
(
blockDevice
.
DeviceName
)
if
strings
.
HasPrefix
(
mountpoint
,
"/dev/sd"
)
{
if
strings
.
HasPrefix
(
name
,
"/dev/sd"
)
{
mountpoint
=
mountpoint
[
7
:
]
name
=
name
[
7
:
]
}
if
strings
.
HasPrefix
(
name
,
"/dev/xvd"
)
{
name
=
name
[
8
:
]
}
}
if
strings
.
HasPrefix
(
mountpoint
,
"/dev/xvd"
)
{
if
len
(
name
)
!=
1
{
mountpoint
=
mountpoint
[
8
:
]
glog
.
Warningf
(
"Unexpected EBS DeviceName: %q"
,
aws
.
StringValue
(
blockDevice
.
DeviceName
))
}
}
deviceMappings
[
mount
point
]
=
orEmpty
(
blockDevice
.
Ebs
.
VolumeId
)
deviceMappings
[
mount
Device
(
name
)]
=
aws
.
StringValue
(
blockDevice
.
Ebs
.
VolumeId
)
}
}
self
.
deviceMappings
=
deviceMappings
self
.
deviceMappings
=
deviceMappings
}
}
// Check to see if this volume is already assigned a device on this machine
// Check to see if this volume is already assigned a device on this machine
for
mount
point
,
mappingVolumeID
:=
range
self
.
deviceMappings
{
for
mount
Device
,
mappingVolumeID
:=
range
self
.
deviceMappings
{
if
volumeID
==
mappingVolumeID
{
if
volumeID
==
mappingVolumeID
{
glog
.
Warningf
(
"Got assignment call for already-assigned volume: %s@%s"
,
mount
point
,
mappingVolumeID
)
glog
.
Warningf
(
"Got assignment call for already-assigned volume: %s@%s"
,
mount
Device
,
mappingVolumeID
)
return
mount
point
,
true
,
nil
return
mount
Device
,
true
,
nil
}
}
}
}
// Check all the valid mountpoints to see if any of them are free
// Check all the valid mountpoints to see if any of them are free
valid
:=
instanceType
.
getEBSMountDevices
()
valid
:=
instanceType
.
getEBSMountDevices
()
chosen
:=
""
chosen
:=
mountDevice
(
""
)
for
_
,
d
evice
:=
range
valid
{
for
_
,
mountD
evice
:=
range
valid
{
_
,
found
:=
self
.
deviceMappings
[
d
evice
]
_
,
found
:=
self
.
deviceMappings
[
mountD
evice
]
if
!
found
{
if
!
found
{
chosen
=
d
evice
chosen
=
mountD
evice
break
break
}
}
}
}
...
@@ -928,7 +936,7 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a
...
@@ -928,7 +936,7 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a
return
chosen
,
false
,
nil
return
chosen
,
false
,
nil
}
}
func
(
self
*
awsInstance
)
releaseMountDevice
(
volumeID
string
,
mountDevice
string
)
{
func
(
self
*
awsInstance
)
releaseMountDevice
(
volumeID
string
,
mountDevice
mountDevice
)
{
self
.
mutex
.
Lock
()
self
.
mutex
.
Lock
()
defer
self
.
mutex
.
Unlock
()
defer
self
.
mutex
.
Unlock
()
...
@@ -1130,24 +1138,24 @@ func (c *AWSCloud) AttachDisk(instanceName string, diskName string, readOnly boo
...
@@ -1130,24 +1138,24 @@ func (c *AWSCloud) AttachDisk(instanceName string, diskName string, readOnly boo
return
""
,
errors
.
New
(
"AWS volumes cannot be mounted read-only"
)
return
""
,
errors
.
New
(
"AWS volumes cannot be mounted read-only"
)
}
}
mount
point
,
alreadyAttached
,
err
:=
awsInstance
.
assignMountpoint
(
disk
.
awsID
)
mount
Device
,
alreadyAttached
,
err
:=
awsInstance
.
getMountDevice
(
disk
.
awsID
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
// Inside the instance, the mountpoint always looks like /dev/xvdX (?)
// Inside the instance, the mountpoint always looks like /dev/xvdX (?)
hostDevice
:=
"/dev/xvd"
+
mountpoint
hostDevice
:=
"/dev/xvd"
+
string
(
mountDevice
)
// In the EC2 API, it is sometimes is /dev/sdX and sometimes /dev/xvdX
// In the EC2 API, it is sometimes is /dev/sdX and sometimes /dev/xvdX
// We are running on the node here, so we check if /dev/xvda exists to determine this
// We are running on the node here, so we check if /dev/xvda exists to determine this
ec2Device
:=
"/dev/xvd"
+
mountpoint
ec2Device
:=
"/dev/xvd"
+
string
(
mountDevice
)
if
_
,
err
:=
os
.
Stat
(
"/dev/xvda"
);
os
.
IsNotExist
(
err
)
{
if
_
,
err
:=
os
.
Stat
(
"/dev/xvda"
);
os
.
IsNotExist
(
err
)
{
ec2Device
=
"/dev/sd"
+
mountpoint
ec2Device
=
"/dev/sd"
+
string
(
mountDevice
)
}
}
attached
:=
false
attached
:=
false
defer
func
()
{
defer
func
()
{
if
!
attached
{
if
!
attached
{
awsInstance
.
releaseMountDevice
(
disk
.
awsID
,
mount
point
)
awsInstance
.
releaseMountDevice
(
disk
.
awsID
,
mount
Device
)
}
}
}()
}()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment