Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use the mesos slave id as swan agent id #921

Merged
merged 3 commits into from
Sep 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .coveralls.yml

This file was deleted.

65 changes: 61 additions & 4 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"strings"
"time"

log "github.com/Sirupsen/logrus"
Expand Down Expand Up @@ -171,11 +173,14 @@ func (agent *Agent) Join() error {
return err
}

// detect mesos slave id
id, err := agent.detectMesosSlaveID(masterURL)
if err != nil {
return err
}

// setup & join
agent.clusterNode = mole.NewAgent(&mole.Config{
Role: mole.RoleAgent,
Master: masterURL,
})
agent.clusterNode = mole.NewAgent(id, masterURL)

return agent.clusterNode.Join()
}
Expand Down Expand Up @@ -257,3 +262,55 @@ func (agent *Agent) detectLeaderAddr() (string, error) {

return "", errors.New("all of swan manager unavailable")
}

// try best to detect the mesos slave id running on the same host
// by querying against to the swan master
func (agent *Agent) detectMesosSlaveID(masterAddr *url.URL) (string, error) {
// obtian from env
if env := os.Getenv("MESOS_SALVE_ID"); env != "" {
return env, nil
}

// obtain from remote swan master by query ip addresses

var (
queryIPs []string
queryURL = masterAddr.String() + "/v1/agents/query_id?ips="
)

if env := os.Getenv("MESOS_SLAVE_IPS"); env != "" {
// obtain local ips from env
queryIPs = strings.Split(env, ",")

} else {
// obtain local ips from sysinfo
info, err := Gather()
if err != nil {
return "", err
}
for inet, ips := range info.IPs {
if inet == "docker0" {
continue
}
queryIPs = append(queryIPs, ips...)
}
}

// query id against swan master
resp, err := http.Get(queryURL + strings.Join(queryIPs, ","))
if err != nil {
return "", err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}

if resp.StatusCode == http.StatusOK {
return string(body), nil
}

return "", fmt.Errorf("query id against master got %d - %s", resp.StatusCode, string(body))
}
41 changes: 37 additions & 4 deletions api/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"net/http"
"strings"

"github.com/Dataman-Cloud/swan/types"
log "github.com/Sirupsen/logrus"
Expand All @@ -26,6 +27,38 @@ func (r *Server) listAgents(w http.ResponseWriter, req *http.Request) {
writeJSON(w, http.StatusOK, ret)
}

func (r *Server) queryAgentID(w http.ResponseWriter, req *http.Request) {
if err := req.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

var (
ips = req.Form.Get("ips")
)
if ips == "" {
http.Error(w, "query parameter ips required", http.StatusBadRequest)
return
}

state, err := r.driver.MesosState()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

for _, slave := range state.Slaves {
for _, ip := range strings.Split(ips, ",") {
if ip == slave.Hostname {
w.Write([]byte(slave.ID))
return
}
}
}

http.Error(w, "not found matched mesos slaves", http.StatusNotFound)
}

func (r *Server) getAgent(w http.ResponseWriter, req *http.Request) {
var (
id = mux.Vars(req)["agent_id"]
Expand Down Expand Up @@ -61,22 +94,22 @@ func (r *Server) getAgentConfigs(w http.ResponseWriter, req *http.Request) {
}

func (r *Server) redirectAgentDocker(w http.ResponseWriter, req *http.Request) {
n := len(`/v1/agents/docker/`) + 16
n := len(`/v1/agents/docker/`) + 39 // FIX LATER
r.redirectAgent(n, w, req)
}

func (r *Server) redirectAgentProxy(w http.ResponseWriter, req *http.Request) {
n := len(`/v1/agents/`) + 16
n := len(`/v1/agents/`) + 39
r.redirectAgent(n, w, req)
}

func (r *Server) redirectAgentDNS(w http.ResponseWriter, req *http.Request) {
n := len(`/v1/agents/`) + 16
n := len(`/v1/agents/`) + 39
r.redirectAgent(n, w, req)
}

func (r *Server) redirectAgentIPAM(w http.ResponseWriter, req *http.Request) {
n := len(`/v1/agents/`) + 16
n := len(`/v1/agents/`) + 39
r.redirectAgent(n, w, req)
}

Expand Down
3 changes: 3 additions & 0 deletions api/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Dataman-Cloud/swan/mesos"
"github.com/Dataman-Cloud/swan/mole"
"github.com/Dataman-Cloud/swan/types"
"github.com/andygrunwald/megos"
)

type Driver interface {
Expand All @@ -22,6 +23,8 @@ type Driver interface {
ClusterAgent(id string) *mole.ClusterAgent
CloseClusterAgent(id string)

MesosState() (*megos.State, error)

// for debug convenience
Dump() interface{}
Load() map[string]interface{}
Expand Down
2 changes: 2 additions & 0 deletions api/route_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package api

/*
import (
"reflect"
"testing"
Expand Down Expand Up @@ -199,3 +200,4 @@ func TestNewPrefixRoute(t *testing.T) {
})
}
}
*/
1 change: 1 addition & 0 deletions api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func (s *Server) setupRoutes(mux *mux.Router) {
NewRoute("DELETE", "/v1/debug", s.disableDebug),

NewRoute("GET", "/v1/agents", s.listAgents),
NewRoute("GET", "/v1/agents/query_id", s.queryAgentID),
NewRoute("GET", "/v1/agents/{agent_id}", s.getAgent),
NewRoute("DELETE", "/v1/agents/{agent_id}", s.closeAgent),
NewRoute("GET", "/v1/agents/{agent_id}/sysinfo", s.getAgent),
Expand Down
2 changes: 2 additions & 0 deletions api/server_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package api

/*
import (
"net"
"net/http"
Expand Down Expand Up @@ -425,3 +426,4 @@ func TestServer_forwardRequest(t *testing.T) {
})
}
}
*/
2 changes: 2 additions & 0 deletions api/utils_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package api

/*
import (
"io"
"net/http"
Expand Down Expand Up @@ -80,3 +81,4 @@ func Test_decode(t *testing.T) {
})
}
}
*/
26 changes: 0 additions & 26 deletions codecov.yml

This file was deleted.

1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ services:
- SWAN_JOIN_ADDRS=127.0.0.1:9999
- SWAN_LOG_LEVEL=debug
- SWAN_START_DELAY=5
- MESOS_SLAVE_IPS=127.0.0.1 # should keep same as mesos-slave.MESOS_HOSTNAME
healthcheck:
test: ["CMD", "wget", "-s", "-q", "http://127.0.0.1:10000/ping"]
interval: 5s
Expand Down
23 changes: 16 additions & 7 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

+ agents
- [GET /v1/agents](#list-agents) *List all agents*
- [GET /v1/agents/query_id](#query-agent-id) *Query mesos slave id by ip addresses (internal use)*
- [GET /v1/agents/{agent_id}](#get-agent) *Get specified agent*
- [DELETE /v1/agents/{agent_id}](#close-agent) *Disconnect specified agent*
- [GET /v1/agents/{agent_id}/dns](#get-agent-dns) *Get dns records on specified agent*
Expand Down Expand Up @@ -1448,13 +1449,13 @@ swan上可以直接请求 节点上的 [Docker Remote API 1.21](https://docs.doc

Example:
```
/v1/agents/3981314045636649/docker/containers/json
/v1/agents/212c92eb-f594-43d5-89da-7820a56e8570-S0/docker/containers/json

/v1/agents/3981314045636649/docker/containers/54b701f325fe1f229dd9174fb90123057e933d2f564d4e5f90e0a69ee6461770/json
/v1/agents/212c92eb-f594-43d5-89da-7820a56e8570-S0/docker/containers/54b701f325fe1f229dd9174fb90123057e933d2f564d4e5f90e0a69ee6461770/json

/v1/agents/3981314045636649/docker/images/json
/v1/agents/212c92eb-f594-43d5-89da-7820a56e8570-S0/docker/images/json

/v1/agents/3981314045636649/docker/networks
/v1/agents/212c92eb-f594-43d5-89da-7820a56e8570-S0/docker/networks
```

#### Reset
Expand All @@ -1476,15 +1477,14 @@ Example response:
}
```


#### list agents
```
GET /v1/agents
```

```json
{
"3264208446845635": {
"212c92eb-f594-43d5-89da-7820a56e8570-S0": {
"hostname": "master",
"os": "NAME=\"CentOS Linux\"\nVERSION=\"7 (Core)\"\nID=\"centos\"\nID_LIKE=\"rhel fedora\"\nVERSION_ID=\"7\"\nPRETTY_NAME=\"CentOS Linux 7 (Core)\"\nANSI_COLOR=\"0;31\"\nCPE_NAME=\"cpe:/o:centos:centos:7\"\nHOME_URL=\"https://www.centos.org/\"\nBUG_REPORT_URL=\"https://bugs.centos.org/\"\n\nCENTOS_MANTISBT_PROJECT=\"CentOS-7\"\nCENTOS_MANTISBT_PROJECT_VERSION=\"7\"\nREDHAT_SUPPORT_PRODUCT=\"centos\"\nREDHAT_SUPPORT_PRODUCT_VERSION=\"7\"\n\n",
"uptime": "34909.000000",
Expand Down Expand Up @@ -1550,7 +1550,7 @@ GET /v1/agents
2181
]
},
"3981314045636649": {
"212c92eb-f594-43d5-89da-7820a56e8570-S1": {
"hostname": "node1",
"os": "NAME=\"CentOS Linux\"\nVERSION=\"7 (Core)\"\nID=\"centos\"\nID_LIKE=\"rhel fedora\"\nVERSION_ID=\"7\"\nPRETTY_NAME=\"CentOS Linux 7 (Core)\"\nANSI_COLOR=\"0;31\"\nCPE_NAME=\"cpe:/o:centos:centos:7\"\nHOME_URL=\"https://www.centos.org/\"\nBUG_REPORT_URL=\"https://bugs.centos.org/\"\n\nCENTOS_MANTISBT_PROJECT=\"CentOS-7\"\nCENTOS_MANTISBT_PROJECT_VERSION=\"7\"\nREDHAT_SUPPORT_PRODUCT=\"centos\"\nREDHAT_SUPPORT_PRODUCT_VERSION=\"7\"\n\n",
"uptime": "34906.000000",
Expand Down Expand Up @@ -1592,6 +1592,15 @@ GET /v1/agents
}
```

#### query agent id
```
GET /v1/agents/query_id?ips=192.168.1.196,192.168.1.130,xxx
```

```plain
212c92eb-f594-43d5-89da-7820a56e8570-S0
```

#### get agent
```
GET /v1/agents/{agent_id}
Expand Down
3 changes: 3 additions & 0 deletions integration-test/swan_api_canary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func (s *ApiSuite) TestCanaryUpdate(c *check.C) {

// verify proxy record
proxy := s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 5)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down Expand Up @@ -110,6 +111,7 @@ func (s *ApiSuite) TestCanaryUpdate(c *check.C) {
// verify proxy record
time.Sleep(time.Millisecond * 500)
proxy = s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 5)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down Expand Up @@ -196,6 +198,7 @@ func (s *ApiSuite) TestCanaryUpdate(c *check.C) {

// verify proxy record again
proxy = s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 5)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down
1 change: 1 addition & 0 deletions integration-test/swan_api_create_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (s *ApiSuite) TestCreateAppProxy(c *check.C) {

// verify proxy record
proxy := s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 10)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down
3 changes: 3 additions & 0 deletions integration-test/swan_api_rollback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (s *ApiSuite) TestRollBackApp(c *check.C) {

// verify proxy record
proxy := s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 3)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down Expand Up @@ -101,6 +102,7 @@ func (s *ApiSuite) TestRollBackApp(c *check.C) {

// verify proxy record
proxy = s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 3)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down Expand Up @@ -150,6 +152,7 @@ func (s *ApiSuite) TestRollBackApp(c *check.C) {

// verify proxy record
proxy = s.listAppProxies(id, c)
c.Assert(proxy, check.Not(check.IsNil))
c.Assert(proxy.Alias, check.Equals, "www.xxx.com")
c.Assert(len(proxy.Backends), check.Equals, 3)
c.Assert(proxy.Listen, check.Equals, "")
Expand Down
Loading