Skip to content
This repository was archived by the owner on Jun 23, 2020. It is now read-only.

Commit 845aba5

Browse files
author
Harvey Lowndes
committed
Restructure workspace and driver packages
1 parent 605d7d5 commit 845aba5

File tree

9 files changed

+266
-254
lines changed

9 files changed

+266
-254
lines changed

pkg/oci/driver/block/block_driver.go

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
// Copyright 2017 Oracle and/or its affiliates. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package block
16+
17+
import (
18+
"fmt"
19+
"log"
20+
"os"
21+
22+
"github.com/oracle/oci-flexvolume-driver/pkg/flexvolume"
23+
"github.com/oracle/oci-flexvolume-driver/pkg/iscsi"
24+
"github.com/oracle/oci-flexvolume-driver/pkg/oci/client"
25+
"github.com/oracle/oci-flexvolume-driver/pkg/oci/driver"
26+
27+
"github.com/oracle/oci-go-sdk/core"
28+
)
29+
30+
const (
31+
// FIXME: Assume lun 1 for now?? Can we get the LUN via the API?
32+
diskIDByPathTemplate = "/dev/disk/by-path/ip-%s:%d-iscsi-%s-lun-1"
33+
)
34+
35+
// OCIFlexvolumeDriver implements the flexvolume.Driver interface for OCI.
36+
type OCIFlexvolumeDriver struct{}
37+
38+
func init() {
39+
driver.RegisterDriver("oci-bvs", &OCIFlexvolumeDriver{})
40+
}
41+
42+
// Init checks that we have the appropriate credentials and metadata API access
43+
// on driver initialisation.
44+
func (d OCIFlexvolumeDriver) Init() flexvolume.DriverStatus {
45+
configPath := driver.GetConfigPath()
46+
47+
if _, err := os.Stat(configPath); !os.IsNotExist(err) {
48+
_, err = client.New(configPath)
49+
if err != nil {
50+
return flexvolume.Fail(err)
51+
}
52+
} else {
53+
log.Printf("Config file %q does not exist. Assuming worker node.", configPath)
54+
}
55+
56+
return flexvolume.Succeed()
57+
}
58+
59+
// Attach initiates the attachment of the given OCI volume to the k8s worker
60+
// node.
61+
func (d OCIFlexvolumeDriver) Attach(opts flexvolume.Options, nodeName string) flexvolume.DriverStatus {
62+
c, err := client.New(driver.GetConfigPath())
63+
if err != nil {
64+
return flexvolume.Fail(err)
65+
}
66+
67+
instance, err := c.GetInstanceByNodeName(nodeName)
68+
if err != nil {
69+
return flexvolume.Fail(err)
70+
}
71+
72+
volumeOCID := driver.DeriveVolumeOCID(c.GetConfig().Auth.RegionKey, opts["kubernetes.io/pvOrVolumeName"])
73+
74+
log.Printf("Attaching volume %s -> instance %s", volumeOCID, *instance.Id)
75+
76+
attachment, statusCode, err := c.AttachVolume(*instance.Id, volumeOCID)
77+
if err != nil {
78+
if statusCode != 409 {
79+
log.Printf("AttachVolume: %+v", err)
80+
return flexvolume.Fail(err)
81+
}
82+
// If we get a 409 conflict response when attaching we
83+
// presume that the device is already attached.
84+
log.Printf("Attach(): Volume %q already attached.", volumeOCID)
85+
attachment, err = c.FindVolumeAttachment(volumeOCID)
86+
if err != nil {
87+
return flexvolume.Fail(err)
88+
}
89+
if *attachment.GetInstanceId() != *instance.Id {
90+
return flexvolume.Fail("Already attached to instance: ", *instance.Id)
91+
}
92+
}
93+
94+
attachment, err = c.WaitForVolumeAttached(*attachment.GetId())
95+
if err != nil {
96+
return flexvolume.Fail(err)
97+
}
98+
99+
log.Printf("attach: %s attached", *attachment.GetId())
100+
iscsiAttachment, ok := attachment.(core.IScsiVolumeAttachment)
101+
if !ok {
102+
return flexvolume.Fail("Only ISCSI volume attachments are currently supported")
103+
}
104+
105+
return flexvolume.DriverStatus{
106+
Status: flexvolume.StatusSuccess,
107+
Device: fmt.Sprintf(diskIDByPathTemplate, *iscsiAttachment.Ipv4, *iscsiAttachment.Port, *iscsiAttachment.Iqn),
108+
}
109+
}
110+
111+
// Detach detaches the volume from the worker node.
112+
func (d OCIFlexvolumeDriver) Detach(pvOrVolumeName, nodeName string) flexvolume.DriverStatus {
113+
c, err := client.New(driver.GetConfigPath())
114+
if err != nil {
115+
return flexvolume.Fail(err)
116+
}
117+
118+
volumeOCID := driver.DeriveVolumeOCID(c.GetConfig().Auth.RegionKey, pvOrVolumeName)
119+
attachment, err := c.FindVolumeAttachment(volumeOCID)
120+
if err != nil {
121+
return flexvolume.Fail(err)
122+
}
123+
124+
err = c.DetachVolume(*attachment.GetId())
125+
if err != nil {
126+
return flexvolume.Fail(err)
127+
}
128+
129+
err = c.WaitForVolumeDetached(*attachment.GetId())
130+
if err != nil {
131+
return flexvolume.Fail(err)
132+
}
133+
return flexvolume.Succeed()
134+
}
135+
136+
// WaitForAttach searches for the the volume attachment created by Attach() and
137+
// waits for its life cycle state to reach ATTACHED.
138+
func (d OCIFlexvolumeDriver) WaitForAttach(mountDevice string, _ flexvolume.Options) flexvolume.DriverStatus {
139+
return flexvolume.DriverStatus{
140+
Status: flexvolume.StatusSuccess,
141+
Device: mountDevice,
142+
}
143+
}
144+
145+
// IsAttached checks whether the volume is attached to the host.
146+
// TODO(apryde): The documentation states that this is called from the Kubelet
147+
// and KCM. Implementation requries credentials which won't be present on nodes
148+
// but I've only ever seen it called by the KCM.
149+
func (d OCIFlexvolumeDriver) IsAttached(opts flexvolume.Options, nodeName string) flexvolume.DriverStatus {
150+
c, err := client.New(driver.GetConfigPath())
151+
if err != nil {
152+
return flexvolume.Fail(err)
153+
}
154+
155+
volumeOCID := driver.DeriveVolumeOCID(c.GetConfig().Auth.RegionKey, opts["kubernetes.io/pvOrVolumeName"])
156+
attachment, err := c.FindVolumeAttachment(volumeOCID)
157+
if err != nil {
158+
return flexvolume.DriverStatus{
159+
Status: flexvolume.StatusSuccess,
160+
Message: err.Error(),
161+
Attached: false,
162+
}
163+
}
164+
165+
log.Printf("attach: found volume attachment %s", *attachment.GetId())
166+
167+
return flexvolume.DriverStatus{
168+
Status: flexvolume.StatusSuccess,
169+
Attached: true,
170+
}
171+
}
172+
173+
// MountDevice connects the iSCSI target on the k8s worker node before mounting
174+
// and (if necessary) formatting the disk.
175+
func (d OCIFlexvolumeDriver) MountDevice(mountDir, mountDevice string, opts flexvolume.Options) flexvolume.DriverStatus {
176+
iSCSIMounter, err := iscsi.NewFromDevicePath(mountDevice)
177+
if err != nil {
178+
return flexvolume.Fail(err)
179+
}
180+
181+
if isMounted, oErr := iSCSIMounter.DeviceOpened(mountDevice); oErr != nil {
182+
return flexvolume.Fail(oErr)
183+
} else if isMounted {
184+
return flexvolume.Succeed("Device already mounted. Nothing to do.")
185+
}
186+
187+
if err = iSCSIMounter.AddToDB(); err != nil {
188+
return flexvolume.Fail(err)
189+
}
190+
if err = iSCSIMounter.SetAutomaticLogin(); err != nil {
191+
return flexvolume.Fail(err)
192+
}
193+
if err = iSCSIMounter.Login(); err != nil {
194+
return flexvolume.Fail(err)
195+
}
196+
197+
if !waitForPathToExist(mountDevice, 20) {
198+
return flexvolume.Fail("Failed waiting for device to exist: ", mountDevice)
199+
}
200+
201+
options := []string{}
202+
if opts[flexvolume.OptionReadWrite] == "ro" {
203+
options = []string{"ro"}
204+
}
205+
err = iSCSIMounter.FormatAndMount(mountDevice, mountDir, opts[flexvolume.OptionFSType], options)
206+
if err != nil {
207+
return flexvolume.Fail(err)
208+
}
209+
210+
return flexvolume.Succeed()
211+
}
212+
213+
// UnmountDevice unmounts the disk, logs out the iscsi target, and deletes the
214+
// iscsi node record.
215+
func (d OCIFlexvolumeDriver) UnmountDevice(mountPath string) flexvolume.DriverStatus {
216+
iSCSIMounter, err := iscsi.NewFromMountPointPath(mountPath)
217+
if err != nil {
218+
if err == iscsi.ErrMountPointNotFound {
219+
return flexvolume.Succeed("Mount point not found. Nothing to do.")
220+
}
221+
return flexvolume.Fail(err)
222+
}
223+
224+
if err = iSCSIMounter.UnmountPath(mountPath); err != nil {
225+
return flexvolume.Fail(err)
226+
}
227+
if err = iSCSIMounter.Logout(); err != nil {
228+
return flexvolume.Fail(err)
229+
}
230+
if err = iSCSIMounter.RemoveFromDB(); err != nil {
231+
return flexvolume.Fail(err)
232+
}
233+
234+
return flexvolume.Succeed()
235+
}
236+
237+
// Mount is unimplemented as we use the --enable-controller-attach-detach flow
238+
// and as such mount the drive in MountDevice().
239+
func (d OCIFlexvolumeDriver) Mount(mountDir string, opts flexvolume.Options) flexvolume.DriverStatus {
240+
return flexvolume.NotSupported()
241+
}
242+
243+
// Unmount is unimplemented as we use the --enable-controller-attach-detach flow
244+
// and as such unmount the drive in UnmountDevice().
245+
func (d OCIFlexvolumeDriver) Unmount(mountDir string) flexvolume.DriverStatus {
246+
return flexvolume.NotSupported()
247+
}

pkg/oci/driver/utils.go renamed to pkg/oci/driver/block/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
package driver
15+
package block
1616

1717
import (
1818
"os"

0 commit comments

Comments
 (0)