Skip to content

Commit 1a3f137

Browse files
committed
Allow private network dir to exist if it is empty.
In order to run private networks in docker, it is convenient to mount the data directory. By disallowing the network directory to exist it is not possible to mount the node directory.
1 parent 452af1c commit 1a3f137

File tree

5 files changed

+64
-5
lines changed

5 files changed

+64
-5
lines changed

cmd/goal/messages.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ const (
131131
loggingNotEnabled = "Remote logging is current disabled"
132132
loggingEnabled = "Remote logging is enabled. Node = %s, Guid = %s"
133133

134-
infoNetworkAlreadyExists = "Network Root Directory '%s' already exists"
134+
infoNetworkAlreadyExists = "Network Root Directory '%s' already exists and is not empty"
135135
errorCreateNetwork = "Error creating private network: %s"
136136
infoNetworkCreated = "Network %s created under %s"
137137
errorLoadingNetwork = "Error loading deployed network: %s"

cmd/goal/network.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,8 @@ var networkCreateCmd = &cobra.Command{
8585
if err != nil {
8686
panic(err)
8787
}
88-
// Make sure target directory doesn't already exist
89-
exists := util.FileExists(networkRootDir)
90-
if exists {
88+
// Make sure target directory does not exist or is empty
89+
if util.FileExists(networkRootDir) && !util.IsEmpty(networkRootDir) {
9190
reportErrorf(infoNetworkAlreadyExists, networkRootDir)
9291
}
9392

netdeploy/networkTemplate.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,15 @@ func (t NetworkTemplate) createNodeDirectories(targetFolder string, binDir strin
7474
nodeDir := filepath.Join(targetFolder, cfg.Name)
7575
err = os.Mkdir(nodeDir, os.ModePerm)
7676
if err != nil {
77-
return
77+
if os.IsExist(err) {
78+
// allow some flexibility around pre-existing directories to support docker and pre-mounted volumes.
79+
if !util.IsEmpty(nodeDir) {
80+
err = fmt.Errorf("duplicate node directory detected: %w", err)
81+
return
82+
}
83+
} else {
84+
return
85+
}
7886
}
7987

8088
_, err = util.CopyFile(genesisFile, filepath.Join(nodeDir, genesisFileName))

util/io.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ func FileExists(filePath string) bool {
5959
return fileExists
6060
}
6161

62+
// IsEmpty recursively check path for files and returns true if there are none.
63+
func IsEmpty(path string) bool {
64+
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
65+
if info.IsDir() {
66+
return nil
67+
}
68+
return os.ErrExist
69+
})
70+
return err == nil
71+
}
72+
6273
// ExeDir returns the absolute path to the current executing binary (not including the filename)
6374
func ExeDir() (string, error) {
6475
ex, err := os.Executable()

util/io_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (C) 2019-2022 Algorand, Inc.
2+
// This file is part of go-algorand
3+
//
4+
// go-algorand is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// go-algorand is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package util
18+
19+
import (
20+
"os"
21+
"path"
22+
"testing"
23+
24+
"github.com/stretchr/testify/assert"
25+
26+
"github.com/algorand/go-algorand/test/partitiontest"
27+
)
28+
29+
func TestIsEmpty(t *testing.T) {
30+
partitiontest.PartitionTest(t)
31+
32+
testPath := path.Join(os.TempDir(), "this", "is", "a", "long", "path")
33+
err := os.MkdirAll(testPath, os.ModePerm)
34+
assert.NoError(t, err)
35+
defer os.RemoveAll(testPath)
36+
assert.True(t, IsEmpty(testPath))
37+
38+
_, err = os.Create(path.Join(testPath, "file.txt"))
39+
assert.NoError(t, err)
40+
assert.False(t, IsEmpty(testPath))
41+
}

0 commit comments

Comments
 (0)