Skip to content

Commit

Permalink
fix db transaction bug
Browse files Browse the repository at this point in the history
Signed-off-by: Catherine <tuhongj@cn.ibm.com>
  • Loading branch information
Catherine2019 committed Dec 24, 2024
1 parent 9ac7a90 commit 2875705
Show file tree
Hide file tree
Showing 21 changed files with 150 additions and 188 deletions.
2 changes: 1 addition & 1 deletion scripts/cloudrc
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,5 @@ function get_uss_gateway()
{
uss_name=$(hostname -s | tr -s '-' '_')
uss_id=$(wds_curl GET "api/v2/wds/uss?name=$uss_name" | jq -r '.uss_gateways[0].id')
[ -z "$uss_id" ] && uss_id=$(wds_curl GET "api/v2/wds/uss" | jq --arg hname $(hostname -s) -r '.uss_gateways | .[] | select(.server_name == $hname) | .id')
[ -z "$uss_id" -o "$uss_id" = null ] && uss_id=$(wds_curl GET "api/v2/wds/uss" | jq --arg hname $(hostname -s) -r '.uss_gateways | .[] | select(.server_name == $hname) | .id')
}
3 changes: 2 additions & 1 deletion scripts/kvm/report_rc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function sync_instance()
boot_file=/proc/sys/kernel/random/boot_id
diff $flag_file $boot_file
[ $? -eq 0 ] && return
sudo iptables-restore </etc/iptables.rules
bridges=$(cat /proc/net/dev | grep br | awk -F: '{print $1}')
sudo iptables -N secgroup-chain && sudo iptables -A secgroup-chain -j ACCEPT
for bridge in $bridges; do
Expand Down Expand Up @@ -163,6 +164,6 @@ function calc_resource()
calc_resource
sync_instance
#probe_arp >/dev/null 2>&1
#inst_status
inst_status
#vlan_status
#router_status
2 changes: 1 addition & 1 deletion web/.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.0.0-102-gd16fa1a
v1.0.0-103-g9ac7a90
1 change: 1 addition & 0 deletions web/apitest/subnet_post.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ cat >tmp.json <<EOF
EOF

vpc_id=$(curl -k -XPOST -H "Authorization: bearer $token" -H "X-Resource-User: cathy" -H "X-Resource-Org: cathy" "$endpoint/api/v1/vpcs" -d @./tmp.json | jq -r .id)
echo vpc $vpc_id created

cat >tmp.json <<EOF
{
Expand Down
6 changes: 4 additions & 2 deletions web/apitest/tmp.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"instance": {
"id": "624132f5-8d20-48bc-917d-f59952b9ff31"
"name": "subnet-4260",
"network_cidr": "10.240.117.0/24",
"vpc": {
"id": "25c98d0d-6708-4f68-893a-97b318076233"
}
}
29 changes: 29 additions & 0 deletions web/src/common/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,32 @@ func GetContextDB(ctx context.Context) (context.Context, *gorm.DB) {
ctx = context.WithValue(ctx, contextDBKey, db)
return ctx, db
}

func SetContextDB(ctx context.Context, db *gorm.DB) (context.Context) {
ctx = context.WithValue(ctx, contextDBKey, db)
return ctx
}

func StartTransaction(ctx context.Context) (context.Context, *gorm.DB, bool) {
tx := ctx.Value(contextDBKey)
if tx != nil {
// returns old transaction
return ctx, tx.(*gorm.DB), false
}
db := DB().Begin()
ctx = context.WithValue(ctx, contextDBKey, db)
// returns new transaction
return ctx, db, true
}

func EndTransaction(ctx context.Context, err error) {
tx := ctx.Value(contextDBKey)
if tx != nil {
db := tx.(*gorm.DB)
if err != nil {
db.Rollback()
} else {
db.Commit()
}
}
}
22 changes: 7 additions & 15 deletions web/src/common/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,18 @@ type VlanInfo struct {
SecRules []*SecurityData `json:"security"`
}

func AllocateAddress(ctx context.Context, subnetID, ifaceID int64, ipaddr, addrType string) (address *model.Address, err error) {
func AllocateAddress(ctx context.Context, subnet *model.Subnet, ifaceID int64, ipaddr, addrType string) (address *model.Address, err error) {
var db *gorm.DB
ctx, db = GetContextDB(ctx)
subnet := &model.Subnet{Model: model.Model{ID: subnetID}}
err = db.Take(subnet).Error
if err != nil {
log.Println("Failed to query subnet", err)
return
}
address = &model.Address{Subnet: subnet}
address = &model.Address{}
if ipaddr == "" {
err = db.Set("gorm:query_option", "FOR UPDATE").Where("subnet_id = ? and allocated = ? and address != ?", subnetID, false, subnet.Gateway).Take(address).Error
err = db.Set("gorm:query_option", "FOR UPDATE").Where("subnet_id = ? and allocated = ? and address != ?", subnet.ID, false, subnet.Gateway).Take(address).Error
} else {
if !strings.Contains(ipaddr, "/") {
preSize, _ := net.IPMask(net.ParseIP(subnet.Netmask).To4()).Size()
ipaddr = fmt.Sprintf("%s/%d", ipaddr, preSize)
}
err = db.Set("gorm:query_option", "FOR UPDATE").Where("subnet_id = ? and allocated = ? and address = ?", subnetID, false, ipaddr).Take(address).Error
err = db.Set("gorm:query_option", "FOR UPDATE").Where("subnet_id = ? and allocated = ? and address = ?", subnet.ID, false, ipaddr).Take(address).Error
}
if err != nil {
log.Println("Failed to query address, %v", err)
Expand All @@ -77,8 +71,7 @@ func AllocateAddress(ctx context.Context, subnetID, ifaceID int64, ipaddr, addrT
}

func DeallocateAddress(ctx context.Context, ifaces []*model.Interface) (err error) {
var db *gorm.DB
ctx, db = GetContextDB(ctx)
ctx, db := GetContextDB(ctx)
where := ""
for i, iface := range ifaces {
if i == 0 {
Expand Down Expand Up @@ -144,7 +137,7 @@ func CreateInterface(ctx context.Context, subnet *model.Subnet, ID, owner int64,
log.Println("Failed to create interface, ", err)
return
}
iface.Address, err = AllocateAddress(ctx, subnet.ID, iface.ID, address, "native")
iface.Address, err = AllocateAddress(ctx, subnet, iface.ID, address, "native")
if err != nil {
log.Println("Failed to allocate address", err)
err2 := db.Delete(iface).Error
Expand All @@ -157,8 +150,7 @@ func CreateInterface(ctx context.Context, subnet *model.Subnet, ID, owner int64,
}

func DeleteInterfaces(ctx context.Context, masterID, subnetID int64, ifType string) (err error) {
var db *gorm.DB
ctx, db = GetContextDB(ctx)
ctx, db := GetContextDB(ctx)
ifaces := []*model.Interface{}
where := ""
if subnetID > 0 {
Expand Down
18 changes: 6 additions & 12 deletions web/src/routes/flavor.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,17 @@ type FlavorAdmin struct{}
type FlavorView struct{}

func (a *FlavorAdmin) Create(ctx context.Context, name string, cpu, memory, disk int32) (flavor *model.Flavor, err error) {
ctx, db := GetContextDB(ctx)
memberShip := GetMemberShip(ctx)
permit := memberShip.CheckPermission(model.Admin)
if !permit {
log.Println("Not authorized for this operation")
err = fmt.Errorf("Not authorized")
return
}
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
flavor = &model.Flavor{
Expand Down Expand Up @@ -92,13 +89,10 @@ func (a *FlavorAdmin) Delete(ctx context.Context, flavor *model.Flavor) (err err
err = fmt.Errorf("Not authorized")
return
}
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
if err = db.Delete(flavor).Error; err != nil {
Expand Down
27 changes: 9 additions & 18 deletions web/src/routes/floatingip.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@ func (a *FloatingIpAdmin) Create(ctx context.Context, instance *model.Instance,
err = fmt.Errorf("Subnet must be public")
return
}
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
floatingIp = &model.FloatingIp{Model: model.Model{Creater: memberShip.UserID}, Owner: memberShip.OrgID}
Expand Down Expand Up @@ -221,13 +218,10 @@ func (a *FloatingIpAdmin) GetFloatingIpByUUID(ctx context.Context, uuID string)
}

func (a *FloatingIpAdmin) Detach(ctx context.Context, floatingIp *model.FloatingIp) (err error) {
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
if floatingIp.Instance != nil {
Expand All @@ -251,13 +245,10 @@ func (a *FloatingIpAdmin) Detach(ctx context.Context, floatingIp *model.Floating
}

func (a *FloatingIpAdmin) Delete(ctx context.Context, floatingIp *model.FloatingIp) (err error) {
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, _, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
if floatingIp.Instance != nil {
Expand Down
18 changes: 6 additions & 12 deletions web/src/routes/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,10 @@ func FileExist(filename string) bool {

func (a *ImageAdmin) Create(ctx context.Context, name, osVersion, virtType, userName, url, architecture string, instID int64) (image *model.Image, err error) {
memberShip := GetMemberShip(ctx)
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
image = &model.Image{Model: model.Model{Creater: memberShip.UserID}, Owner: memberShip.OrgID, OsVersion: osVersion, VirtType: virtType, UserName: userName, Name: name, OSCode: name, Status: "creating", Architecture: architecture}
Expand Down Expand Up @@ -150,13 +147,10 @@ func (a *ImageAdmin) GetImage(ctx context.Context, reference *BaseReference) (im
}

func (a *ImageAdmin) Delete(ctx context.Context, image *model.Image) (err error) {
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
memberShip := GetMemberShip(ctx)
Expand Down
29 changes: 10 additions & 19 deletions web/src/routes/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,13 @@ func (a *InstanceAdmin) getHyperGroup(ctx context.Context, imageType string, zon
}

func (a *InstanceAdmin) Create(ctx context.Context, count int, prefix, userdata string, image *model.Image, flavor *model.Flavor, zone *model.Zone, routerID int64, primaryIface *InterfaceInfo, secondaryIfaces []*InterfaceInfo, keys []*model.Key, hyperID int) (instances []*model.Instance, err error) {
memberShip := GetMemberShip(ctx)
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
memberShip := GetMemberShip(ctx)
if image.Status != "available" {
err = fmt.Errorf("Image status not available")
log.Println("Image status not available")
Expand Down Expand Up @@ -237,13 +234,10 @@ func (a *InstanceAdmin) Update(ctx context.Context, instance *model.Instance, fl
return
}

ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
if hyperID != int(instance.Hyper) {
Expand Down Expand Up @@ -437,13 +431,10 @@ func (a *InstanceAdmin) buildMetadata(ctx context.Context, primaryIface *Interfa
}

func (a *InstanceAdmin) Delete(ctx context.Context, instance *model.Instance) (err error) {
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
memberShip := GetMemberShip(ctx)
Expand Down
7 changes: 6 additions & 1 deletion web/src/routes/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ type InterfaceAdmin struct{}
type InterfaceView struct{}

func (a *InterfaceAdmin) Update(ctx context.Context, id int64, name, pairs string, sgIDs []int64) (iface *model.Interface, err error) {
db := DB()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if newTransaction {
EndTransaction(ctx, err)
}
}()
iface = &model.Interface{Model: model.Model{ID: id}}
if err = db.Set("gorm:auto_preload", true).Take(iface).Error; err != nil {
log.Println("Failed to query interface ", err)
Expand Down
18 changes: 6 additions & 12 deletions web/src/routes/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,10 @@ func (a *KeyAdmin) Create(ctx context.Context, name, publicKey string) (key *mod
return
}
fingerPrint := ssh.FingerprintLegacyMD5(pub)
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
key = &model.Key{Model: model.Model{Creater: memberShip.UserID}, Owner: memberShip.OrgID, Name: name, PublicKey: publicKey, FingerPrint: fingerPrint}
Expand All @@ -97,13 +94,10 @@ func (a *KeyAdmin) Create(ctx context.Context, name, publicKey string) (key *mod
}

func (a *KeyAdmin) Delete(ctx context.Context, key *model.Key) (err error) {
ctx, db := GetContextDB(ctx)
db = db.Begin()
ctx, db, newTransaction := StartTransaction(ctx)
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
if newTransaction {
EndTransaction(ctx, err)
}
}()
memberShip := GetMemberShip(ctx)
Expand Down
Loading

0 comments on commit 2875705

Please sign in to comment.