Merge: Win travis build
* commit '6503bab1aaa27ff43175d069413630a420093be0': *: added cross-env to npm scripts run npm build on windows *: added more logging -: fix autohosts tests on Windows -: fix qlog test on Windows *: fix nvs script *: travis - use nvs on Windows *: travis-win -- try nvm *(global): travis: choco install nodejs +(global): windows travis build
This commit is contained in:
commit
215e3eeaf6
55
.travis.yml
55
.travis.yml
|
@ -7,14 +7,41 @@ go:
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
- windows
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- nvm install node
|
- |-
|
||||||
- npm install -g npm
|
case $TRAVIS_OS_NAME in
|
||||||
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.23.8
|
linux | osx)
|
||||||
|
nvm install node
|
||||||
|
npm install -g npm
|
||||||
|
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.23.8
|
||||||
|
;;
|
||||||
|
windows)
|
||||||
|
# Using NVS for managing Node.js versions on Windows
|
||||||
|
NVS_HOME="C:\ProgramData\nvs"
|
||||||
|
git clone --single-branch https://github.com/jasongin/nvs $NVS_HOME
|
||||||
|
source $NVS_HOME/nvs.sh
|
||||||
|
nvs add latest
|
||||||
|
nvs use latest
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- npm --prefix client ci
|
- |-
|
||||||
|
case $TRAVIS_OS_NAME in
|
||||||
|
linux | osx)
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
npm --prefix client ci
|
||||||
|
;;
|
||||||
|
windows)
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
nvs --version
|
||||||
|
npm --prefix client ci
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
|
@ -23,10 +50,24 @@ cache:
|
||||||
- $HOME/Library/Caches/go-build
|
- $HOME/Library/Caches/go-build
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- /bin/bash ci.sh
|
- |-
|
||||||
|
case $TRAVIS_OS_NAME in
|
||||||
|
linux | osx)
|
||||||
|
/bin/bash ci.sh
|
||||||
|
;;
|
||||||
|
windows)
|
||||||
|
npm --prefix client run build-prod
|
||||||
|
go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
- |-
|
||||||
|
case $TRAVIS_OS_NAME in
|
||||||
|
linux)
|
||||||
|
bash <(curl -s https://codecov.io/bash)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
slack: performix:yXTihlSzsLFSZiqbXMNzvTSX
|
slack: performix:yXTihlSzsLFSZiqbXMNzvTSX
|
||||||
|
@ -60,6 +101,8 @@ matrix:
|
||||||
file_glob: true
|
file_glob: true
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
|
|
||||||
|
# Docker build configuration
|
||||||
|
- if: repo = AdguardTeam/AdGuardHome
|
||||||
- name: docker
|
- name: docker
|
||||||
if: type != pull_request AND (branch = master OR tag IS present) AND repo = AdguardTeam/AdGuardHome
|
if: type != pull_request AND (branch = master OR tag IS present) AND repo = AdguardTeam/AdGuardHome
|
||||||
go:
|
go:
|
||||||
|
|
|
@ -3522,6 +3522,58 @@
|
||||||
"gud": "^1.0.0"
|
"gud": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cross-env": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"cross-spawn": "^7.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build-dev": "NODE_ENV=development ./node_modules/.bin/webpack --config webpack.dev.js",
|
"build-dev": "cross-env NODE_ENV=development webpack --config webpack.dev.js",
|
||||||
"watch": "NODE_ENV=development ./node_modules/.bin/webpack --config webpack.dev.js --watch",
|
"watch": "cross-env NODE_ENV=development webpack --config webpack.dev.js --watch",
|
||||||
"build-prod": "NODE_ENV=production ./node_modules/.bin/webpack --config webpack.prod.js",
|
"build-prod": "cross-env NODE_ENV=production webpack --config webpack.prod.js",
|
||||||
"lint": "eslint client/"
|
"lint": "eslint client/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -49,6 +49,7 @@
|
||||||
"clean-webpack-plugin": "^0.1.19",
|
"clean-webpack-plugin": "^0.1.19",
|
||||||
"compression-webpack-plugin": "^1.1.11",
|
"compression-webpack-plugin": "^1.1.11",
|
||||||
"copy-webpack-plugin": "^4.6.0",
|
"copy-webpack-plugin": "^4.6.0",
|
||||||
|
"cross-env": "^7.0.2",
|
||||||
"css-loader": "^2.1.1",
|
"css-loader": "^2.1.1",
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
"eslint-config-airbnb-base": "^12.1.0",
|
"eslint-config-airbnb-base": "^12.1.0",
|
||||||
|
@ -70,11 +71,11 @@
|
||||||
"style-loader": "^0.21.0",
|
"style-loader": "^0.21.0",
|
||||||
"stylelint": "^9.10.1",
|
"stylelint": "^9.10.1",
|
||||||
"stylelint-webpack-plugin": "0.10.4",
|
"stylelint-webpack-plugin": "0.10.4",
|
||||||
|
"svg-url-loader": "^2.3.2",
|
||||||
"uglifyjs-webpack-plugin": "^1.2.7",
|
"uglifyjs-webpack-plugin": "^1.2.7",
|
||||||
"url-loader": "^1.0.1",
|
"url-loader": "^1.0.1",
|
||||||
"webpack": "3.8.1",
|
"webpack": "3.8.1",
|
||||||
"webpack-dev-server": "^3.1.14",
|
"webpack-dev-server": "^3.1.14",
|
||||||
"webpack-merge": "^4.1.3",
|
"webpack-merge": "^4.1.3"
|
||||||
"svg-url-loader": "^2.3.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ type User struct {
|
||||||
|
|
||||||
// InitAuth - create a global object
|
// InitAuth - create a global object
|
||||||
func InitAuth(dbFilename string, users []User, sessionTTL uint32) *Auth {
|
func InitAuth(dbFilename string, users []User, sessionTTL uint32) *Auth {
|
||||||
|
log.Info("Initializing auth module: %s", dbFilename)
|
||||||
|
|
||||||
a := Auth{}
|
a := Auth{}
|
||||||
a.sessionTTL = sessionTTL
|
a.sessionTTL = sessionTTL
|
||||||
a.sessions = make(map[string]*session)
|
a.sessions = make(map[string]*session)
|
||||||
|
@ -83,7 +85,7 @@ func InitAuth(dbFilename string, users []User, sessionTTL uint32) *Auth {
|
||||||
}
|
}
|
||||||
a.loadSessions()
|
a.loadSessions()
|
||||||
a.users = users
|
a.users = users
|
||||||
log.Debug("Auth: initialized. users:%d sessions:%d", len(a.users), len(a.sessions))
|
log.Info("Auth: initialized. users:%d sessions:%d", len(a.users), len(a.sessions))
|
||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
home/home.go
15
home/home.go
|
@ -43,10 +43,10 @@ const (
|
||||||
|
|
||||||
// Update-related variables
|
// Update-related variables
|
||||||
var (
|
var (
|
||||||
versionString string
|
versionString = "dev"
|
||||||
updateChannel string
|
updateChannel = "none"
|
||||||
versionCheckURL string
|
versionCheckURL = ""
|
||||||
ARMVersion string
|
ARMVersion = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
const versionCheckPeriod = time.Hour * 8
|
const versionCheckPeriod = time.Hour * 8
|
||||||
|
@ -155,11 +155,11 @@ func run(args options) {
|
||||||
configureLogger(args)
|
configureLogger(args)
|
||||||
|
|
||||||
// print the first message after logger is configured
|
// print the first message after logger is configured
|
||||||
msg := "AdGuard Home, version %s, channel %s\n, arch %s %s"
|
msg := "AdGuard Home, version %s, channel %s, arch %s %s"
|
||||||
if ARMVersion != "" {
|
if ARMVersion != "" {
|
||||||
msg = msg + " v" + ARMVersion
|
msg = msg + " v" + ARMVersion
|
||||||
}
|
}
|
||||||
log.Printf(msg, versionString, updateChannel, runtime.GOOS, runtime.GOARCH, ARMVersion)
|
log.Printf(msg, versionString, updateChannel, runtime.GOOS, runtime.GOARCH)
|
||||||
log.Debug("Current working directory is %s", Context.workDir)
|
log.Debug("Current working directory is %s", Context.workDir)
|
||||||
if args.runningAsService {
|
if args.runningAsService {
|
||||||
log.Info("AdGuard Home is running as a service")
|
log.Info("AdGuard Home is running as a service")
|
||||||
|
@ -169,6 +169,7 @@ func run(args options) {
|
||||||
|
|
||||||
Context.firstRun = detectFirstRun()
|
Context.firstRun = detectFirstRun()
|
||||||
if Context.firstRun {
|
if Context.firstRun {
|
||||||
|
log.Info("This is the first time AdGuard Home is launched")
|
||||||
requireAdminRights()
|
requireAdminRights()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +198,7 @@ func run(args options) {
|
||||||
|
|
||||||
err = parseConfig()
|
err = parseConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error("Failed to parse configuration, exiting")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +213,7 @@ func run(args options) {
|
||||||
config.DHCP.ConfigModified = onConfigModified
|
config.DHCP.ConfigModified = onConfigModified
|
||||||
Context.dhcpServer = dhcpd.Create(config.DHCP)
|
Context.dhcpServer = dhcpd.Create(config.DHCP)
|
||||||
if Context.dhcpServer == nil {
|
if Context.dhcpServer == nil {
|
||||||
|
log.Error("Failed to initialize DHCP server, exiting")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
Context.autoHosts.Init("")
|
Context.autoHosts.Init("")
|
||||||
|
|
|
@ -107,14 +107,14 @@ schema_version: 5
|
||||||
// . Wait until the filters are downloaded
|
// . Wait until the filters are downloaded
|
||||||
// . Stop and cleanup
|
// . Stop and cleanup
|
||||||
func TestHome(t *testing.T) {
|
func TestHome(t *testing.T) {
|
||||||
// Reinit context
|
// Init new context
|
||||||
Context = homeContext{}
|
Context = homeContext{}
|
||||||
|
|
||||||
dir := prepareTestDir()
|
dir := prepareTestDir()
|
||||||
defer func() { _ = os.RemoveAll(dir) }()
|
defer func() { _ = os.RemoveAll(dir) }()
|
||||||
_ = os.MkdirAll(filepath.Join(Context.getDataDir(), filterDir), 0755)
|
|
||||||
fn := filepath.Join(dir, "AdGuardHome.yaml")
|
fn := filepath.Join(dir, "AdGuardHome.yaml")
|
||||||
|
|
||||||
|
// Prepare the test config
|
||||||
assert.True(t, ioutil.WriteFile(fn, []byte(yamlConf), 0644) == nil)
|
assert.True(t, ioutil.WriteFile(fn, []byte(yamlConf), 0644) == nil)
|
||||||
fn, _ = filepath.Abs(fn)
|
fn, _ = filepath.Abs(fn)
|
||||||
|
|
||||||
|
@ -135,11 +135,11 @@ func TestHome(t *testing.T) {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
assert.Truef(t, err == nil, "%s", err)
|
assert.Truef(t, err == nil, "%s", err)
|
||||||
assert.Equal(t, 200, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
resp, err = h.Get("http://127.0.0.1:3000/control/status")
|
resp, err = h.Get("http://127.0.0.1:3000/control/status")
|
||||||
assert.Truef(t, err == nil, "%s", err)
|
assert.Truef(t, err == nil, "%s", err)
|
||||||
assert.Equal(t, 200, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
|
|
||||||
// test DNS over UDP
|
// test DNS over UDP
|
||||||
r := upstream.NewResolver("127.0.0.1:5354", 3*time.Second)
|
r := upstream.NewResolver("127.0.0.1:5354", 3*time.Second)
|
||||||
|
|
|
@ -42,6 +42,8 @@ type Web struct {
|
||||||
|
|
||||||
// CreateWeb - create module
|
// CreateWeb - create module
|
||||||
func CreateWeb(conf *WebConfig) *Web {
|
func CreateWeb(conf *WebConfig) *Web {
|
||||||
|
log.Info("Initialize web module")
|
||||||
|
|
||||||
w := Web{}
|
w := Web{}
|
||||||
w.conf = conf
|
w.conf = conf
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,9 @@ func (l *queryLog) getData(params getDataParams) map[string]interface{} {
|
||||||
fileEntries, oldest, total := l.searchFiles(params)
|
fileEntries, oldest, total := l.searchFiles(params)
|
||||||
|
|
||||||
if params.OlderThan.IsZero() {
|
if params.OlderThan.IsZero() {
|
||||||
params.OlderThan = now
|
// In case if the timer is not precise (for instance, on Windows)
|
||||||
|
// We really want to get all records including those added just before the call
|
||||||
|
params.OlderThan = now.Add(time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add from memory buffer
|
// add from memory buffer
|
||||||
|
|
|
@ -23,7 +23,7 @@ type AutoHosts struct {
|
||||||
hostsFn string // path to the main hosts-file
|
hostsFn string // path to the main hosts-file
|
||||||
hostsDirs []string // paths to OS-specific directories with hosts-files
|
hostsDirs []string // paths to OS-specific directories with hosts-files
|
||||||
watcher *fsnotify.Watcher // file and directory watcher object
|
watcher *fsnotify.Watcher // file and directory watcher object
|
||||||
updateChan chan bool // signal for 'update' goroutine
|
updateChan chan bool // signal for 'updateLoop' goroutine
|
||||||
|
|
||||||
onChanged onChangedT // notification to other modules
|
onChanged onChangedT // notification to other modules
|
||||||
}
|
}
|
||||||
|
@ -68,20 +68,22 @@ func (a *AutoHosts) Init(hostsFn string) {
|
||||||
|
|
||||||
// Start - start module
|
// Start - start module
|
||||||
func (a *AutoHosts) Start() {
|
func (a *AutoHosts) Start() {
|
||||||
go a.update()
|
log.Debug("Start AutoHosts module")
|
||||||
|
|
||||||
|
go a.updateLoop()
|
||||||
a.updateChan <- true
|
a.updateChan <- true
|
||||||
|
|
||||||
go a.watcherLoop()
|
go a.watcherLoop()
|
||||||
|
|
||||||
err := a.watcher.Add(a.hostsFn)
|
err := a.watcher.Add(a.hostsFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("AutoHosts: %s", err)
|
log.Error("Error while initializing watcher for a file %s: %s", a.hostsFn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dir := range a.hostsDirs {
|
for _, dir := range a.hostsDirs {
|
||||||
err = a.watcher.Add(dir)
|
err = a.watcher.Add(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("AutoHosts: %s", err)
|
log.Error("Error while initializing watcher for a directory %s: %s", dir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +91,8 @@ func (a *AutoHosts) Start() {
|
||||||
// Close - close module
|
// Close - close module
|
||||||
func (a *AutoHosts) Close() {
|
func (a *AutoHosts) Close() {
|
||||||
a.updateChan <- false
|
a.updateChan <- false
|
||||||
a.watcher.Close()
|
close(a.updateChan)
|
||||||
|
_ = a.watcher.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read IP-hostname pairs from file
|
// Read IP-hostname pairs from file
|
||||||
|
@ -174,7 +177,7 @@ func (a *AutoHosts) watcherLoop() {
|
||||||
log.Debug("AutoHosts: modified: %s", event.Name)
|
log.Debug("AutoHosts: modified: %s", event.Name)
|
||||||
select {
|
select {
|
||||||
case a.updateChan <- true:
|
case a.updateChan <- true:
|
||||||
// sent a signal to 'update' goroutine
|
// sent a signal to 'updateLoop' goroutine
|
||||||
default:
|
default:
|
||||||
// queue is full
|
// queue is full
|
||||||
}
|
}
|
||||||
|
@ -189,41 +192,48 @@ func (a *AutoHosts) watcherLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read static hosts from system files
|
// updateLoop - read static hosts from system files
|
||||||
func (a *AutoHosts) update() {
|
func (a *AutoHosts) updateLoop() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case ok := <-a.updateChan:
|
case ok := <-a.updateChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
|
log.Debug("Finished AutoHosts update loop")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
table := make(map[string][]net.IP)
|
a.updateHosts()
|
||||||
|
|
||||||
a.load(table, a.hostsFn)
|
|
||||||
|
|
||||||
for _, dir := range a.hostsDirs {
|
|
||||||
fis, err := ioutil.ReadDir(dir)
|
|
||||||
if err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
log.Error("AutoHosts: Opening directory: %s: %s", dir, err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fi := range fis {
|
|
||||||
a.load(table, dir+"/"+fi.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a.lock.Lock()
|
|
||||||
a.table = table
|
|
||||||
a.lock.Unlock()
|
|
||||||
a.notify()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateHosts - loads system hosts
|
||||||
|
func (a *AutoHosts) updateHosts() {
|
||||||
|
table := make(map[string][]net.IP)
|
||||||
|
|
||||||
|
a.load(table, a.hostsFn)
|
||||||
|
|
||||||
|
for _, dir := range a.hostsDirs {
|
||||||
|
fis, err := ioutil.ReadDir(dir)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
log.Error("AutoHosts: Opening directory: %s: %s", dir, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fi := range fis {
|
||||||
|
a.load(table, dir+"/"+fi.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.lock.Lock()
|
||||||
|
a.table = table
|
||||||
|
a.lock.Unlock()
|
||||||
|
|
||||||
|
a.notify()
|
||||||
|
}
|
||||||
|
|
||||||
// Process - get the list of IP addresses for the hostname
|
// Process - get the list of IP addresses for the hostname
|
||||||
// Return nil if not found
|
// Return nil if not found
|
||||||
func (a *AutoHosts) Process(host string) []net.IP {
|
func (a *AutoHosts) Process(host string) []net.IP {
|
||||||
|
|
|
@ -17,38 +17,73 @@ func prepareTestDir() string {
|
||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAutoHosts(t *testing.T) {
|
func TestAutoHostsResolution(t *testing.T) {
|
||||||
ah := AutoHosts{}
|
ah := AutoHosts{}
|
||||||
|
|
||||||
dir := prepareTestDir()
|
dir := prepareTestDir()
|
||||||
defer func() { _ = os.RemoveAll(dir) }()
|
defer func() { _ = os.RemoveAll(dir) }()
|
||||||
|
|
||||||
f, _ := ioutil.TempFile(dir, "")
|
f, _ := ioutil.TempFile(dir, "")
|
||||||
defer os.Remove(f.Name())
|
defer func() { _ = os.Remove(f.Name()) }()
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
_, _ = f.WriteString(" 127.0.0.1 host localhost \n")
|
_, _ = f.WriteString(" 127.0.0.1 host localhost \n")
|
||||||
|
|
||||||
ah.Init(f.Name())
|
ah.Init(f.Name())
|
||||||
ah.Start()
|
|
||||||
// wait until we parse the file
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
|
|
||||||
|
// Update from the hosts file
|
||||||
|
ah.updateHosts()
|
||||||
|
|
||||||
|
// Existing host
|
||||||
ips := ah.Process("localhost")
|
ips := ah.Process("localhost")
|
||||||
assert.True(t, ips[0].Equal(net.ParseIP("127.0.0.1")))
|
assert.NotNil(t, ips)
|
||||||
ips = ah.Process("newhost")
|
assert.Equal(t, 1, len(ips))
|
||||||
assert.True(t, ips == nil)
|
assert.Equal(t, net.ParseIP("127.0.0.1"), ips[0])
|
||||||
|
|
||||||
|
// Unknown host
|
||||||
|
ips = ah.Process("newhost")
|
||||||
|
assert.Nil(t, ips)
|
||||||
|
|
||||||
|
// Test hosts file
|
||||||
table := ah.List()
|
table := ah.List()
|
||||||
ips, _ = table["host"]
|
ips, _ = table["host"]
|
||||||
assert.True(t, ips[0].String() == "127.0.0.1")
|
assert.NotNil(t, ips)
|
||||||
|
assert.Equal(t, 1, len(ips))
|
||||||
|
assert.Equal(t, "127.0.0.1", ips[0].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAutoHostsFSNotify(t *testing.T) {
|
||||||
|
ah := AutoHosts{}
|
||||||
|
|
||||||
|
dir := prepareTestDir()
|
||||||
|
defer func() { _ = os.RemoveAll(dir) }()
|
||||||
|
|
||||||
|
f, _ := ioutil.TempFile(dir, "")
|
||||||
|
defer func() { _ = os.Remove(f.Name()) }()
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
// Init
|
||||||
|
_, _ = f.WriteString(" 127.0.0.1 host localhost \n")
|
||||||
|
ah.Init(f.Name())
|
||||||
|
ah.updateHosts()
|
||||||
|
|
||||||
|
// Unknown host
|
||||||
|
ips := ah.Process("newhost")
|
||||||
|
assert.Nil(t, ips)
|
||||||
|
|
||||||
|
// Stat monitoring for changes
|
||||||
|
ah.Start()
|
||||||
|
defer ah.Close()
|
||||||
|
|
||||||
|
// Update file
|
||||||
_, _ = f.WriteString("127.0.0.2 newhost\n")
|
_, _ = f.WriteString("127.0.0.2 newhost\n")
|
||||||
|
_ = f.Sync()
|
||||||
|
|
||||||
// wait until fsnotify has triggerred and processed the file-modification event
|
// wait until fsnotify has triggerred and processed the file-modification event
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
// Check if we are notified about changes
|
||||||
ips = ah.Process("newhost")
|
ips = ah.Process("newhost")
|
||||||
assert.True(t, ips[0].Equal(net.ParseIP("127.0.0.2")))
|
assert.NotNil(t, ips)
|
||||||
|
assert.Equal(t, 1, len(ips))
|
||||||
ah.Close()
|
assert.Equal(t, "127.0.0.2", ips[0].String())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ func SetRlimit(val uint) {
|
||||||
|
|
||||||
func HaveAdminRights() (bool, error) {
|
func HaveAdminRights() (bool, error) {
|
||||||
var token windows.Token
|
var token windows.Token
|
||||||
h, _ := windows.GetCurrentProcess()
|
h := windows.CurrentProcess()
|
||||||
err := windows.OpenProcessToken(h, windows.TOKEN_QUERY, &token)
|
err := windows.OpenProcessToken(h, windows.TOKEN_QUERY, &token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
Loading…
Reference in New Issue