e89a8bc8612b64a3041dd9e66ec14c874b18bba7 — Louis Solofrizzo 7 months ago ad52a41
Api: Add temporary status for instance creation and deletion

Before this patch, one could create a multiple numbers of instances with
the same name, because we did not commit the instance to the database
before the actual LXD creation. It is now fixed, the instance is
committed to the database much faster, with an "Allocating" status,
which is removed with the real status on actual instance creation. The
same behavior applies to deletion.

Signed-off-by: Louis Solofrizzo <lsolofrizzo@online.net>
2 files changed, 34 insertions(+), 13 deletions(-)

M api/database.go
M api/instance.go
M api/database.go => api/database.go +1 -0
@@ 47,6 47,7 @@ Architecture string
  	User         uint
  	Type         string
+ 	Status       string
  }
  
  type DbIpv4 struct {

M api/instance.go => api/instance.go +33 -13
@@ 21,23 21,31 @@   	for _, instance := range entries {
  		var ipv4 DbIpv4
+ 		var status string
  		ipv6 = ""
  
  		DB.Find(&ipv4, "instance = ?", instance.Uuid)
- 		inst, _, err := Context.LXD.GetInstanceState("LF" + instance.Uuid)
  
- 		if err != nil {
- 			APIError(ctx, 500, err.Error())
- 			return
- 		}
+ 		if instance.Status == "LXD" {
+ 			inst, _, err := Context.LXD.GetInstanceState("LF" + instance.Uuid)
+ 
+ 			if err != nil {
+ 				APIError(ctx, 500, err.Error())
+ 				return
+ 			}
  
- 		for _, net := range inst.Network {
- 			for _, addr := range net.Addresses {
- 				if addr.Family == "inet6" && !strings.HasPrefix(addr.Address, "fe80") && addr.Scope != "local" {
- 					ipv6 = addr.Address
- 					break
+ 			for _, net := range inst.Network {
+ 				for _, addr := range net.Addresses {
+ 					if addr.Family == "inet6" && !strings.HasPrefix(addr.Address, "fe80") && addr.Scope != "local" {
+ 						ipv6 = addr.Address
+ 						break
+ 					}
  				}
  			}
+ 
+ 			status = inst.Status
+ 		} else {
+ 			status = instance.Status
  		}
  
  		result = append(result, cisco.Instance{


@@ 47,7 55,7 @@ OS:           instance.OS,
  			Architecture: instance.Architecture,
  			Ipv4:         ipv4.IP,
- 			Status:       inst.Status,
+ 			Status:       status,
  			Ipv6:         ipv6,
  			Type:         instance.Type,
  		})


@@ 60,6 68,7 @@ var entry DbInstance
  	var result cisco.Instance
  	var ipv6 string
+ 	var status string
  
  	user := ctx.Values().Get("User")
  	instance := ctx.Params().Get("name")


@@ 76,13 85,19 @@ }
  	}
  
+ 	if entry.Status == "LXD" {
+ 		status = inst.Status
+ 	} else {
+ 		status = entry.Status
+ 	}
+ 
  	result = cisco.Instance{
  		Uuid:         entry.Uuid,
  		Name:         entry.Name,
  		Size:         entry.Size,
  		OS:           entry.OS,
  		Architecture: entry.Architecture,
- 		Status:       inst.Status,
+ 		Status:       status,
  		Ipv6:         ipv6,
  		Type:         entry.Type,
  	}


@@ 225,13 240,16 @@ entry.Type = instance.Type
  	entry.OS = instance.OS
  	entry.User, _ = ctx.Values().GetUint("User")
+ 	entry.Status = "Allocating"
+ 	DB.Create(&entry)
  
  	if createBackendInstance(entry) != nil {
  		APIError(ctx, 500, "Cannot create instance")
+ 		DB.Delete(&entry)
  		return
  	}
  
- 	DB.Create(&entry)
+ 	DB.Model(&entry).Update("status", "LXD")
  	ctx.StatusCode(iris.StatusCreated)
  }
  


@@ 341,6 359,8 @@ }
  	}
  
+ 	DB.Model(&entry).Update("status", "Deleting")
+ 
  	op, err := Context.LXD.DeleteContainer("LF" + entry.Uuid)
  	if err != nil {
  		APIError(ctx, 503, "Error: "+err.Error())