func (l *DeployLock) Lock() error { if l.locked { return nil } // check if we can lock by checking if any thing in the lock file is a prefix to us path := helper.GetBaseLockPath("deploy") mutex := zookeeper.NewMutex(Zk.Conn, path) if err := mutex.Lock(); err != nil { return err } defer mutex.Unlock() lockedPaths, err := getLockedPaths(path) if err != nil { return err } if allID, ok := lockedPaths[allPath]; ok && allID != "" { return LockConflictError(allID) } for p, conflictID := range lockedPaths { if strings.HasPrefix(l.path, p) { return LockConflictError(conflictID) } } // if no conflicts, register our lock lockedPaths[l.path] = l.id if err := setJson(path, lockedPaths); err != nil { return err } l.locked = true return nil }
func (s *DatamodelSuite) TestReserveRouterPortAndUpdateTrie(c *C) { Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(true)) Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(false)) Zk.RecursiveDelete(helper.GetBaseLockPath()) Zk.RecursiveDelete("/atlantis/router") CreateRouterPaths() CreateRouterPortsPaths() CreateLockPaths() MinRouterPort = uint16(65533) MaxRouterPort = uint16(65535) helper.SetRouterRoot(true) port, created, err := ReserveRouterPortAndUpdateTrie(true, "app", "sha", "env") c.Assert(err, IsNil) c.Assert(created, Equals, true) c.Assert(port, Equals, "65533") trie, err := routerzk.GetTrie(Zk.Conn, helper.GetAppEnvTrieName("app", "env")) c.Assert(err, IsNil) c.Assert(len(trie.Rules), Equals, 1) port, created, err = ReserveRouterPortAndUpdateTrie(true, "app", "sha2", "env") c.Assert(err, IsNil) c.Assert(created, Equals, false) c.Assert(port, Equals, "65533") trie, err = routerzk.GetTrie(Zk.Conn, helper.GetAppEnvTrieName("app", "env")) c.Assert(err, IsNil) c.Assert(len(trie.Rules), Equals, 2) }
func (l *RouterPortsLock) Lock() error { var path string if l.locked { return nil } if l.internal { path = helper.GetBaseLockPath("router_ports_internal") } else { path = helper.GetBaseLockPath("router_ports_external") } l.mutex = zookeeper.NewMutex(Zk.Conn, path) if err := l.mutex.Lock(); err != nil { return err } l.locked = true return nil }
func (s *DatamodelSuite) TestDeployAndTeardownLocking(c *C) { Zk.RecursiveDelete(helper.GetBaseLockPath("deploy")) CreateLockPaths() // Fire off a bunch of deploys dl0 := NewDeployLock("dl0", "app0", "sha0", "env0") c.Assert(dl0.Lock(), IsNil) dl1 := NewDeployLock("dl1", "app1", "sha1", "env1") c.Assert(dl1.Lock(), IsNil) dl2 := NewDeployLock("dl2", "app1", "sha2", "env1") c.Assert(dl2.Lock(), IsNil) dl3 := NewDeployLock("dl3", "app1", "sha1", "env2") c.Assert(dl3.Lock(), IsNil) dl4 := NewDeployLock("dl4", "app1", "sha1", "env2") err := dl4.Lock() c.Assert(err, Not(IsNil)) c.Assert(err, FitsTypeOf, LockConflictError("dl3")) c.Assert(err, Equals, LockConflictError("dl3")) // Unlock and try to lock through previously failed one c.Assert(dl3.Unlock(), IsNil) c.Assert(dl4.Lock(), IsNil) // Try some Teardowns tl0 := NewTeardownLock("tl0", "app2", "sha2", "env2") c.Assert(tl0.Lock(), IsNil) tl1 := NewTeardownLock("tl1", "app0", "sha0", "env0") err = tl1.Lock() c.Assert(err, Not(IsNil)) c.Assert(err, FitsTypeOf, LockConflictError("dl0")) c.Assert(err, Equals, LockConflictError("dl0")) tl2 := NewTeardownLock("tl2", "app0", "sha1") c.Assert(tl2.Lock(), IsNil) tl3 := NewTeardownLock("tl3", "app3") c.Assert(tl3.Lock(), IsNil) tl4 := NewTeardownLock("tl4", "app0") err = tl4.Lock() c.Assert(err, Not(IsNil)) c.Assert(err, FitsTypeOf, LockConflictError("dl0")) c.Assert(err, Equals, LockConflictError("dl0")) tl5 := NewTeardownLock("tl5") err = tl5.Lock() c.Assert(err, Not(IsNil)) c.Assert(err, FitsTypeOf, LockConflictError("dl0")) // Try a deploy while tearing down dl5 := NewDeployLock("dl5", "app3", "sha3", "env3") err = dl5.Lock() c.Assert(err, Not(IsNil)) c.Assert(err, FitsTypeOf, LockConflictError("tl3")) c.Assert(err, Equals, LockConflictError("tl3")) }
func (l *DeployLock) Unlock() error { if !l.locked { return nil } // remove ourselves from the lock file path := helper.GetBaseLockPath("deploy") mutex := zookeeper.NewMutex(Zk.Conn, path) if err := mutex.Lock(); err != nil { return err } defer mutex.Unlock() lockedPaths, err := getLockedPaths(path) if err != nil { return err } delete(lockedPaths, l.path) if err := setJson(path, lockedPaths); err != nil { return err } l.locked = false return nil }
func CreateLockPaths() { Zk.Touch(helper.GetBaseLockPath("deploy")) Zk.Touch(helper.GetBaseLockPath("router_ports_internal")) Zk.Touch(helper.GetBaseLockPath("router_ports_external")) }
func (s *DatamodelSuite) TestRouterPorts(c *C) { // test internal Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(true)) Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(false)) Zk.RecursiveDelete(helper.GetBaseLockPath()) CreateRouterPortsPaths() CreateLockPaths() MinRouterPort = uint16(65533) MaxRouterPort = uint16(65535) c.Assert(HasRouterPortForAppEnv(true, "app", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(false, "app", "env"), Equals, false) appPort, err := reserveRouterPort(true, "app", "env") c.Assert(err, IsNil) appPort2, err := reserveRouterPort(true, "app", "env") c.Assert(err, IsNil) c.Assert(appPort, Equals, appPort2) c.Assert(HasRouterPortForAppEnv(true, "app", "env"), Equals, true) c.Assert(HasRouterPortForAppEnv(false, "app", "env"), Equals, false) app2Port, err := reserveRouterPort(true, "app2", "env") c.Assert(err, IsNil) c.Assert(appPort, Not(Equals), app2Port) c.Assert(HasRouterPortForAppEnv(true, "app2", "env"), Equals, true) c.Assert(HasRouterPortForAppEnv(false, "app2", "env"), Equals, false) _, err = reserveRouterPort(true, "app3", "env2") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(true, "app3", "env2"), Equals, true) c.Assert(HasRouterPortForAppEnv(false, "app3", "env2"), Equals, false) _, err = reserveRouterPort(true, "app4", "env3") c.Assert(err, Not(IsNil)) err = ReclaimRouterPortsForEnv(true, "env") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(true, "app", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(true, "app2", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(true, "app3", "env2"), Equals, true) err = ReclaimRouterPortsForApp(true, "app3") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(true, "app", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(true, "app2", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(true, "app3", "env2"), Equals, false) _, err = reserveRouterPort(true, "app4", "env2") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(true, "app4", "env2"), Equals, true) c.Assert(HasRouterPortForAppEnv(false, "app4", "env2"), Equals, false) // test external Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(true)) Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(false)) Zk.RecursiveDelete(helper.GetBaseLockPath()) CreateRouterPortsPaths() CreateLockPaths() MinRouterPort = uint16(65533) MaxRouterPort = uint16(65535) c.Assert(HasRouterPortForAppEnv(true, "app", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(false, "app", "env"), Equals, false) appPort, err = reserveRouterPort(false, "app", "env") c.Assert(err, IsNil) appPort2, err = reserveRouterPort(false, "app", "env") c.Assert(err, IsNil) c.Assert(appPort, Equals, appPort2) c.Assert(HasRouterPortForAppEnv(false, "app", "env"), Equals, true) c.Assert(HasRouterPortForAppEnv(true, "app", "env"), Equals, false) app2Port, err = reserveRouterPort(false, "app2", "env") c.Assert(err, IsNil) c.Assert(appPort, Not(Equals), app2Port) c.Assert(HasRouterPortForAppEnv(false, "app2", "env"), Equals, true) c.Assert(HasRouterPortForAppEnv(true, "app2", "env"), Equals, false) _, err = reserveRouterPort(false, "app3", "env2") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(false, "app3", "env2"), Equals, true) c.Assert(HasRouterPortForAppEnv(true, "app3", "env2"), Equals, false) _, err = reserveRouterPort(false, "app4", "env3") c.Assert(err, Not(IsNil)) err = ReclaimRouterPortsForEnv(false, "env") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(false, "app", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(false, "app2", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(false, "app3", "env2"), Equals, true) err = ReclaimRouterPortsForApp(false, "app3") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(false, "app", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(false, "app2", "env"), Equals, false) c.Assert(HasRouterPortForAppEnv(false, "app3", "env2"), Equals, false) _, err = reserveRouterPort(false, "app4", "env2") c.Assert(err, IsNil) c.Assert(HasRouterPortForAppEnv(false, "app4", "env2"), Equals, true) c.Assert(HasRouterPortForAppEnv(true, "app4", "env2"), Equals, false) }