Skip to content

Commit

Permalink
Merge pull request #34 from witnesschain-com/29-include-retires-and-s…
Browse files Browse the repository at this point in the history
…leep-timer-for-failed-mounting

feature : include retires and sleep timer for failed mounting (#34)
  • Loading branch information
adityakblock authored Jul 11, 2024
2 parents bd4acee + 7c1044a commit 32f5215
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 40 deletions.
16 changes: 9 additions & 7 deletions common/constants.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package wc_common

const (
DefaultAdminConfig string = "config/admin-config.json"
DefaultOpL1Config string = "config/l1-operator-config.json"
DefaultOpL2Config string = "config/l2-operator-config.json"
EncryptedDirName string = ".encrypted_keys"
DecryptedDirName string = ".decrypted_keys"
GoCryptFSConfigName string = EncryptedDirName + "/gocryptfs.conf"
MinEntropyBits float64 = 50
DefaultAdminConfig string = "config/admin-config.json"
DefaultOpL1Config string = "config/l1-operator-config.json"
DefaultOpL2Config string = "config/l2-operator-config.json"
EncryptedDirName string = ".encrypted_keys"
DecryptedDirName string = ".decrypted_keys"
GoCryptFSConfigName string = EncryptedDirName + "/gocryptfs.conf"
MinEntropyBits float64 = 50
MaxMountRetries int = 5
RetryPeriodInSeconds uint = 1
)
2 changes: 1 addition & 1 deletion common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
var (
ErrEmptyKeyName = errors.New("key name cannot be empty")
ErrKeyContainsWhitespaces = errors.New("key name cannot contain spaces")
ErrFileSystemNotMounted = errors.New("exit status 1")
ErrInvalidPassword = errors.New("invalid password")
ErrNotADirectory = errors.New("is not a directory")
ErrInvalidEncryptedDirectory = errors.New("invalid gocryptfs encrypted directory")
)
Expand Down
53 changes: 29 additions & 24 deletions common/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (
"github.com/urfave/cli/v2"
)

var useEncryptedKeys bool = false
var isFullPath bool = false
var EncryptedDir string = EncryptedDirName
var DecryptedDir string = DecryptedDirName
var GoCryptFSConfig string = GoCryptFSConfigName
var m_useEncryptedKeys bool = false
var m_isFullPath bool = false
var m_retryMounting bool = false
var m_encryptedDir string = EncryptedDirName
var m_decryptedDir string = DecryptedDirName
var m_goCryptFSConfig string = GoCryptFSConfigName

func KeysCmd() *cli.Command {
var keysCmd = &cli.Command{
Expand Down Expand Up @@ -99,12 +100,12 @@ func ListCmd() *cli.Command {
func InitKeyStore(cCtx *cli.Context) {
insecure := cCtx.Bool("insecure")

if !DirectoryExists(EncryptedDir) {
CreateDirectory(EncryptedDir)
if !DirectoryExists(m_encryptedDir) {
CreateDirectory(m_encryptedDir)
}

if !DirectoryExists(DecryptedDir) {
CreateDirectory(DecryptedDir)
if !DirectoryExists(m_decryptedDir) {
CreateDirectory(m_decryptedDir)
}

InitGocryptfs(insecure)
Expand All @@ -127,7 +128,7 @@ func DeleteKeyCmd(cCtx *cli.Context) {
}

func ListKeyCmd() {
dir, err := os.Open(DecryptedDir)
dir, err := os.Open(m_decryptedDir)
CheckError(err, "Error opening directory")
defer dir.Close()

Expand All @@ -147,7 +148,7 @@ func ListKeyCmd() {
}

func InitGocryptfs(insecure bool) {
initCmd := exec.Command("gocryptfs", "-init", "-plaintextnames", EncryptedDir)
initCmd := exec.Command("gocryptfs", "-init", "-plaintextnames", m_encryptedDir)

RunCommandWithPassword(initCmd, "init", insecure)
}
Expand All @@ -164,7 +165,7 @@ func ValidateKeyName(keyName string) error {
}

func CreateKey(keyName string) {
keyFile := DecryptedDir + "/" + keyName
keyFile := m_decryptedDir + "/" + keyName

_, err := os.Stat(keyFile)
if !os.IsNotExist(err) {
Expand All @@ -184,7 +185,7 @@ func CreateKey(keyName string) {
}

func DeleteKey(keyName string) {
keyFile := DecryptedDir + "/" + keyName
keyFile := m_decryptedDir + "/" + keyName
err := os.Remove(keyFile)
CheckError(err, "Error deleting key\n")

Expand All @@ -206,28 +207,32 @@ func CreateKeyFileAndStoreKey(keyFile string, privateKey string) {
}

func ValidEncryptedDir() bool {
_, err := os.Stat(GoCryptFSConfig)
_, err := os.Stat(m_goCryptFSConfig)

return !os.IsNotExist(err)
}

func GetPrivateKeyFromFile(keyName string) string {
keyFile := DecryptedDir + "/" + keyName
keyFile := m_decryptedDir + "/" + keyName
data, err := os.ReadFile(keyFile)
CheckError(err, "Error reading key file")
return string(data)
}

func UseEncryptedKeys() {
useEncryptedKeys = true
m_useEncryptedKeys = true
ValidateAndMount()
}

func RetryMounting() {
m_retryMounting = true
}

func ProcessConfigKeyPath(keyPath string) {
dir, file := filepath.Split(keyPath)

if file == keyPath && dir == "." {
fmt.Printf("Using the default key path : %s\n", EncryptedDir)
fmt.Printf("Using the default key path : %s\n", m_encryptedDir)
// this means they have given only the key name only,
// do nothing and use default path
return
Expand All @@ -236,18 +241,18 @@ func ProcessConfigKeyPath(keyPath string) {
// go to the grand parent directory of the key path to get the .encrypted_keys path
parentPath := filepath.Dir(filepath.Dir(dir))

EncryptedDir = filepath.Join(parentPath, EncryptedDirName)
DecryptedDir = filepath.Join(parentPath, DecryptedDirName)
GoCryptFSConfig = filepath.Join(parentPath, GoCryptFSConfigName)
isFullPath = true
m_encryptedDir = filepath.Join(parentPath, EncryptedDirName)
m_decryptedDir = filepath.Join(parentPath, DecryptedDirName)
m_goCryptFSConfig = filepath.Join(parentPath, GoCryptFSConfigName)
m_isFullPath = true

fmt.Printf("Using the key path : %s\n", EncryptedDir)
fmt.Printf("Using the key path : %s\n", m_encryptedDir)
}

func GetPrivateKey(key string) string {
if useEncryptedKeys {
if m_useEncryptedKeys {
keyName := key
if isFullPath {
if m_isFullPath {
_, keyName = filepath.Split(key)
}
return GetPrivateKeyFromFile(keyName)
Expand Down
71 changes: 63 additions & 8 deletions common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import (
"context"
"crypto/ecdsa"
"crypto/rand"
"encoding/json"
"fmt"
"math/big"
"os"
"os/exec"
"path/filepath"
"time"

"github.com/witnesschain-com/operator-cli/common/bindings/AvsDirectory"
"github.com/witnesschain-com/operator-cli/common/bindings/OperatorRegistry"
Expand All @@ -18,7 +21,15 @@ import (
"github.com/ethereum/go-ethereum/ethclient"
)

var isMounted bool = false
var m_isMounted bool = false

type Filesystem struct {
Target string `json:"target"`
}

type MountResult struct {
Filesystems []Filesystem `json:"filesystems"`
}

func ConnectToUrl(url string) *ethclient.Client {
client, err := ethclient.Dial(url)
Expand Down Expand Up @@ -89,31 +100,75 @@ func ValidateAndMount() {

if !ValidEncryptedDir() {
FatalErrorWithoutUnmount(fmt.Sprintf("%v: %s\n", ErrInvalidEncryptedDirectory,
" : check if "+GoCryptFSConfig+" exist. Or try initiating again after deleting those directories"))
" : check if "+m_goCryptFSConfig+" exist. Or try initiating again after deleting those directories"))
}

Mount()
if IsAlreadyMounted() {
if !m_retryMounting {
FatalErrorWithoutUnmount(m_decryptedDir + " already mounted")
}

fmt.Println("GoCryptFS filesystem already mounted")
for i := 0; i < MaxMountRetries; i++ {
fmt.Printf("Retrying in %v seconds\n", RetryPeriodInSeconds)

// RetryPeriodInSeconds
time.Sleep(time.Duration(RetryPeriodInSeconds * uint(time.Second)))
Mount()
if m_isMounted {
return
}
}
FatalErrorWithoutUnmount("Giving up, " + m_decryptedDir + " already mounted")
} else {
Mount()
}
}

func Mount() {
mountCmd := exec.Command("gocryptfs", EncryptedDir, DecryptedDir)
if IsAlreadyMounted() {
return
}

mountCmd := exec.Command("gocryptfs", m_encryptedDir, m_decryptedDir)
RunCommandWithPassword(mountCmd, "mount", true)

isMounted = true
m_isMounted = true
}

func Unmount() {
if !isMounted {
if !m_isMounted {
return
}

umountCmd := exec.Command("fusermount", "-u", DecryptedDir)
umountCmd := exec.Command("fusermount", "-u", m_decryptedDir)
err := umountCmd.Run()
if err != nil {
CheckErrorWithoutUnmount(err, "Error unmounting GoCryptFS filesystem")
}

isMounted = false
m_isMounted = false
}

func IsAlreadyMounted() bool {
cmd := exec.Command("findmnt", "-n", "-o", "TARGET", "--type", "fuse.gocryptfs", "-J")
output, err := cmd.CombinedOutput()
CheckError(err, "Error checking if filesystem is mounted. Output - "+string(output))

var mountResult MountResult
err = json.Unmarshal(output, &mountResult)

CheckError(err, "Error checking if filesystem is mounted. Output - "+string(output))

for _, fs := range mountResult.Filesystems {
absolutePath, err := filepath.Abs(m_decryptedDir)
CheckError(err, "Error getting absolute path")

if absolutePath == fs.Target {
return true
}
}
return false
}

func DirectoryExists(path string) bool {
Expand Down
1 change: 1 addition & 0 deletions watchtower-operator/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func GetConfigFromContext(cCtx *cli.Context) *OperatorConfig {
if config.UseEncryptedKeys {
// get the path from the first key, as others should be same
// will not work with different paths
wc_common.RetryMounting()
wc_common.ProcessConfigKeyPath(config.WatchtowerPrivateKeys[0])
wc_common.UseEncryptedKeys()
}
Expand Down

0 comments on commit 32f5215

Please sign in to comment.