Skip to content
This repository has been archived by the owner on Jul 16, 2020. It is now read-only.

Commit

Permalink
Merge pull request #761 from rbradford/ephemeral-boot-from-volume
Browse files Browse the repository at this point in the history
Ephemeral boot from volume
  • Loading branch information
markdryan authored Nov 9, 2016
2 parents ea0035b + dbcfffb commit 3c0cf66
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 20 deletions.
22 changes: 22 additions & 0 deletions ciao-controller/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ func (client *ssntpClient) CommandNotify(command ssntp.Command, frame *ssntp.Fra
glog.V(1).Info(string(payload))
}

func (client *ssntpClient) deleteEphemeralStorage(instanceID string) {
attachments, _ := client.ctl.ds.GetStorageAttachments(instanceID)
for _, attachment := range attachments {
if !attachment.Ephemeral {
continue
}
err := client.ctl.ds.DeleteStorageAttachment(attachment.ID)
if err != nil {
glog.Warningf("Error deleting attachment from datastore: %v", err)
}
err = client.ctl.ds.DeleteBlockDevice(attachment.BlockID)
if err != nil {
glog.Warningf("Error deleting block device from datastore: %v", err)
}
err = client.ctl.DeleteBlockDevice(attachment.BlockID)
if err != nil {
glog.Warningf("Error deleting block device: %v", err)
}
}
}

func (client *ssntpClient) EventNotify(event ssntp.Event, frame *ssntp.Frame) {
payload := frame.Payload

Expand All @@ -73,6 +94,7 @@ func (client *ssntpClient) EventNotify(event ssntp.Event, frame *ssntp.Frame) {
glog.Warning("Error unmarshalling InstanceDeleted")
return
}
client.deleteEphemeralStorage(event.InstanceDeleted.InstanceUUID)
client.ctl.ds.DeleteInstance(event.InstanceDeleted.InstanceUUID)
case ssntp.ConcentratorInstanceAdded:
var event payloads.EventConcentratorInstanceAdded
Expand Down
70 changes: 68 additions & 2 deletions ciao-controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,59 @@ func testStartWorkloadLaunchCNCI(t *testing.T, num int) (*testutil.SsntpTestClie
return netClient, instances
}

func TestGetStorage(t *testing.T) {
func TestGetStorageForVolume(t *testing.T) {
tenant, err := addTestTenant()
if err != nil {
t.Fatal(err)
}

sourceVolume := addTestBlockDevice(t, tenant.ID)
defer ctl.DeleteBlockDevice(sourceVolume.ID)

// a temporary in memory filesystem?
s := &types.StorageResource{
ID: "",
Bootable: true,
Persistent: true,
SourceType: types.VolumeService,
SourceID: sourceVolume.ID,
}

wl := &types.Workload{
ID: "validID",
ImageID: uuid.Generate().String(),
Storage: s,
}

pl, err := getStorage(ctl, wl, tenant.ID, "")
if err != nil {
t.Fatal(err)
}

if pl.ID == "" {
t.Errorf("storage ID does not exist")
}

if pl.Bootable != true {
t.Errorf("bootable flag not correct")
}

if pl.Ephemeral != false {
t.Errorf("ephemeral flag not correct")
}

createdVolume, err := ctl.ds.GetBlockDevice(pl.ID)

if err != nil {
t.Fatal(err)
}

if len(createdVolume.Name) == 0 {
t.Errorf("block device name not set")
}
}

func TestGetStorageForImage(t *testing.T) {
tenant, err := addTestTenant()
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -1113,7 +1165,7 @@ func TestGetStorage(t *testing.T) {
Storage: s,
}

pl, err := getStorage(ctl, wl, tenant.ID)
pl, err := getStorage(ctl, wl, tenant.ID, "")
if err != nil {
t.Fatal(err)
}
Expand All @@ -1125,6 +1177,20 @@ func TestGetStorage(t *testing.T) {
if pl.Bootable != true {
t.Errorf("bootable flag not correct")
}

if pl.Ephemeral != true {
t.Errorf("ephemeral flag not correct")
}

createdVolume, err := ctl.ds.GetBlockDevice(pl.ID)

if err != nil {
t.Fatal(err)
}

if len(createdVolume.Name) == 0 {
t.Errorf("block device name not set")
}
}

func TestStorageConfig(t *testing.T) {
Expand Down
16 changes: 13 additions & 3 deletions ciao-controller/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ func (i *instance) Add() error {
if i.CNCI == false {
ds := i.ctl.ds
ds.AddInstance(&i.Instance)
storage := i.newConfig.sc.Start.Storage
if (storage != payloads.StorageResources{}) {
_, err := ds.CreateStorageAttachment(i.Instance.ID, storage.ID, storage.Ephemeral)
if err != nil {
glog.Error(err)
}
}
} else {
i.ctl.ds.AddTenantCNCI(i.TenantID, i.ID, i.MACAddress)
}
Expand Down Expand Up @@ -146,7 +153,7 @@ func (c *config) GetResources() map[string]int {
return resources
}

func getStorage(c *controller, wl *types.Workload, tenant string) (payloads.StorageResources, error) {
func getStorage(c *controller, wl *types.Workload, tenant string, instanceID string) (payloads.StorageResources, error) {
s := wl.Storage

// storage already exists, use preexisting definition.
Expand Down Expand Up @@ -199,6 +206,7 @@ func getStorage(c *controller, wl *types.Workload, tenant string) (payloads.Stor
Size: s.Size,
CreateTime: time.Now(),
TenantID: tenant,
Name: fmt.Sprintf("Storage for instance: %s", instanceID),
}

err = c.ds.AddBlockDevice(data)
Expand All @@ -207,7 +215,7 @@ func getStorage(c *controller, wl *types.Workload, tenant string) (payloads.Stor
return payloads.StorageResources{}, err
}

return payloads.StorageResources{ID: data.ID, Bootable: s.Bootable}, nil
return payloads.StorageResources{ID: data.ID, Bootable: s.Bootable, Ephemeral: true}, nil
case types.VolumeService:
device, err := c.CopyBlockDevice(s.SourceID)
if err != nil {
Expand All @@ -221,6 +229,7 @@ func getStorage(c *controller, wl *types.Workload, tenant string) (payloads.Stor
Size: s.Size,
CreateTime: time.Now(),
TenantID: tenant,
Name: fmt.Sprintf("Storage for instance: %s", instanceID),
}

err = c.ds.AddBlockDevice(data)
Expand All @@ -244,6 +253,7 @@ func getStorage(c *controller, wl *types.Workload, tenant string) (payloads.Stor
Size: s.Size,
CreateTime: time.Now(),
TenantID: tenant,
Name: fmt.Sprintf("Storage for instance: %s", instanceID),
}

err = c.ds.AddBlockDevice(data)
Expand Down Expand Up @@ -316,7 +326,7 @@ func newConfig(ctl *controller, wl *types.Workload, instanceID string, tenantID

// handle storage resources
if wl.Storage != nil {
storage, err = getStorage(ctl, wl, tenantID)
storage, err = getStorage(ctl, wl, tenantID, instanceID)
if err != nil {
return config, err
}
Expand Down
9 changes: 7 additions & 2 deletions ciao-controller/internal/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,9 @@ func (ds *Datastore) UpdateBlockDevice(data types.BlockData) error {
return ds.AddBlockDevice(data)
}

func (ds *Datastore) createStorageAttachment(instanceID string, blockID string) (types.StorageAttachment, error) {
// CreateStorageAttachment will associate an instance with a block device in
// the datastore
func (ds *Datastore) CreateStorageAttachment(instanceID string, blockID string, ephemeral bool) (types.StorageAttachment, error) {
link := attachment{
instanceID: instanceID,
volumeID: blockID,
Expand All @@ -1498,6 +1500,7 @@ func (ds *Datastore) createStorageAttachment(instanceID string, blockID string)
InstanceID: instanceID,
ID: uuid.Generate().String(),
BlockID: blockID,
Ephemeral: ephemeral,
}

// add it to our links map
Expand Down Expand Up @@ -1639,7 +1642,9 @@ func (ds *Datastore) getStorageAttachment(instanceID string, volumeID string) (t
return a, nil
}

func (ds *Datastore) deleteStorageAttachment(ID string) error {
// DeleteStorageAttachment will delete the attachment with the associated ID
// from the datastore.
func (ds *Datastore) DeleteStorageAttachment(ID string) error {
ds.attachLock.Lock()
a, ok := ds.attachments[ID]
if ok {
Expand Down
20 changes: 10 additions & 10 deletions ciao-controller/internal/datastore/datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,7 @@ func TestCreateStorageAttachment(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1875,7 +1875,7 @@ func TestUpdateStorageAttachmentExisting(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1982,7 +1982,7 @@ func TestUpdateStorageAttachmentDeleted(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -2032,7 +2032,7 @@ func TestGetStorageAttachment(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -2127,7 +2127,7 @@ func TestDeleteStorageAttachment(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand All @@ -2141,7 +2141,7 @@ func TestDeleteStorageAttachment(t *testing.T) {
t.Fatal(err)
}

err = ds.deleteStorageAttachment(a.ID)
err = ds.DeleteStorageAttachment(a.ID)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -2189,7 +2189,7 @@ func TestDeleteStorageAttachmentError(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand All @@ -2203,7 +2203,7 @@ func TestDeleteStorageAttachmentError(t *testing.T) {
t.Fatal(err)
}

err = ds.deleteStorageAttachment(a.ID)
err = ds.DeleteStorageAttachment(a.ID)
if err != nil {
t.Fatal(err)
}
Expand All @@ -2213,7 +2213,7 @@ func TestDeleteStorageAttachmentError(t *testing.T) {
t.Fatal(err)
}

err = ds.deleteStorageAttachment(a.ID)
err = ds.DeleteStorageAttachment(a.ID)
if err != ErrNoStorageAttachment {
t.Fatal(err)
}
Expand Down Expand Up @@ -2256,7 +2256,7 @@ func TestGetVolumeAttachments(t *testing.T) {
t.Fatal(err)
}

_, err = ds.createStorageAttachment(instance.ID, data.ID)
_, err = ds.CreateStorageAttachment(instance.ID, data.ID, false)
if err != nil {
t.Fatal(err)
}
Expand Down
27 changes: 24 additions & 3 deletions ciao-controller/internal/datastore/sqlite3db.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ func (d attachments) Init() error {
id string primary key,
instance_id string,
block_id string,
ephemeral int,
foreign key(instance_id) references instances(id),
foreign key(block_id) references block_data(id)
);`
Expand Down Expand Up @@ -555,6 +556,8 @@ func (ds *sqliteDB) exec(db *sql.DB, cmd string) error {
return err
}

// This function is deprecated and will be removed soon. It should not be used
// for newly written or updated code.
func (ds *sqliteDB) create(tableName string, record ...interface{}) error {
// get database location of this table
db := ds.getTableDB(tableName)
Expand Down Expand Up @@ -2304,8 +2307,25 @@ func (ds *sqliteDB) deleteBlockData(ID string) error {
}

func (ds *sqliteDB) createStorageAttachment(a types.StorageAttachment) error {
datastore := ds.getTableDB("attachments")

ds.dbLock.Lock()
err := ds.create("attachments", a.ID, a.InstanceID, a.BlockID)

tx, err := datastore.Begin()
if err != nil {
ds.dbLock.Unlock()
return err
}

_, err = tx.Exec("INSERT INTO attachments (id, instance_id, block_id, ephemeral) VALUES (?, ?, ?, ?)", a.ID, a.InstanceID, a.BlockID, a.Ephemeral)
if err != nil {
tx.Rollback()
ds.dbLock.Unlock()
return err
}

tx.Commit()

ds.dbLock.Unlock()
return err
}
Expand All @@ -2317,7 +2337,8 @@ func (ds *sqliteDB) getAllStorageAttachments() (map[string]types.StorageAttachme

query := `SELECT attachments.id,
attachments.instance_id,
attachments.block_id
attachments.block_id,
attachments.ephemeral
FROM attachments `

rows, err := datastore.Query(query)
Expand All @@ -2329,7 +2350,7 @@ func (ds *sqliteDB) getAllStorageAttachments() (map[string]types.StorageAttachme
for rows.Next() {
var a types.StorageAttachment

err = rows.Scan(&a.ID, &a.InstanceID, &a.BlockID)
err = rows.Scan(&a.ID, &a.InstanceID, &a.BlockID, &a.Ephemeral)
if err != nil {
continue
}
Expand Down
Loading

0 comments on commit 3c0cf66

Please sign in to comment.