mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-28 04:46:42 -04:00
Remove old device ID from server in DeviceIDGen
This commit is contained in:
@@ -2,6 +2,7 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
@@ -49,6 +50,18 @@ func ParseConfig(valuesRequested [][2]string, missingValueError string) []string
|
|||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenDeviceIDList returns a pointer to a slice of all registered device IDs.
|
||||||
|
// Requires: errorOnFail (set to true to throw an error if the device ID list cannot be generated)
|
||||||
|
func GenDeviceIDList(errorOnFail bool) *[]fs.DirEntry {
|
||||||
|
// create a slice of all registered devices
|
||||||
|
deviceIDList, err := os.ReadDir(ConfigDir + PathSeparator + "devices")
|
||||||
|
if err != nil && errorOnFail {
|
||||||
|
fmt.Println(AnsiError + "Failed to read the devices directory: " + err.Error() + AnsiReset)
|
||||||
|
os.Exit(101)
|
||||||
|
}
|
||||||
|
return &deviceIDList
|
||||||
|
}
|
||||||
|
|
||||||
// WriteConfig writes the provided key-value pairs under the specified section headers in the libmutton.ini file.
|
// WriteConfig writes the provided key-value pairs under the specified section headers in the libmutton.ini file.
|
||||||
// Requires: valuesToWrite (a slice of length 3 arrays each containing a section, a key name, and a value).
|
// Requires: valuesToWrite (a slice of length 3 arrays each containing a section, a key name, and a value).
|
||||||
func WriteConfig(valuesToWrite [][3]string, append bool) {
|
func WriteConfig(valuesToWrite [][3]string, append bool) {
|
||||||
|
|||||||
+7
-1
@@ -53,7 +53,8 @@ func GpgKeyGen() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DirInit creates the libmutton directories.
|
// DirInit creates the libmutton directories.
|
||||||
func DirInit(preserveOldConfigDir bool) {
|
// Returns: oldDeviceID (before from before the directory reset).
|
||||||
|
func DirInit(preserveOldConfigDir bool) string {
|
||||||
// create EntryRoot
|
// create EntryRoot
|
||||||
err := os.MkdirAll(EntryRoot, 0700)
|
err := os.MkdirAll(EntryRoot, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -61,6 +62,9 @@ func DirInit(preserveOldConfigDir bool) {
|
|||||||
os.Exit(102)
|
os.Exit(102)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get old device ID before its potential removal
|
||||||
|
oldDeviceID := (*GenDeviceIDList(false))[0].Name() // errorOnFail set to false to ignore error if device ID directory does not exist (error non-critical for this function)
|
||||||
|
|
||||||
// remove existing config directory (if it exists and not in append mode)
|
// remove existing config directory (if it exists and not in append mode)
|
||||||
if !preserveOldConfigDir {
|
if !preserveOldConfigDir {
|
||||||
_, isAccessible := TargetIsFile(ConfigDir, false, 1)
|
_, isAccessible := TargetIsFile(ConfigDir, false, 1)
|
||||||
@@ -79,4 +83,6 @@ func DirInit(preserveOldConfigDir bool) {
|
|||||||
fmt.Println(AnsiError + "Failed to create \"" + ConfigDir + "\": " + err.Error() + AnsiReset)
|
fmt.Println(AnsiError + "Failed to create \"" + ConfigDir + "\": " + err.Error() + AnsiReset)
|
||||||
os.Exit(102)
|
os.Exit(102)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return oldDeviceID
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -56,7 +56,9 @@ func main() {
|
|||||||
case "register":
|
case "register":
|
||||||
// register a new device ID
|
// register a new device ID
|
||||||
// stdin[0] is expected to be the device ID
|
// stdin[0] is expected to be the device ID
|
||||||
_, _ = os.Create(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + stdin[0]) // error ignored; failure unlikely to occur if init was successful; "register" is not a user-facing argument and thus the error would not be visible
|
// stdin[1] is expected to be the old device ID (for removal)
|
||||||
|
_, _ = os.Create(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + stdin[0]) // errors ignored; failure unlikely to occur if init was successful; "register" is not a user-facing argument and thus the error would not be visible
|
||||||
|
_ = os.RemoveAll(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + stdin[1])
|
||||||
// print EntryRoot and bool indicating OS type to stdout for client to store in config
|
// print EntryRoot and bool indicating OS type to stdout for client to store in config
|
||||||
fmt.Print(core.EntryRoot + sync.FSSpace + strconv.FormatBool(core.IsWindows))
|
fmt.Print(core.EntryRoot + sync.FSSpace + strconv.FormatBool(core.IsWindows))
|
||||||
case "init":
|
case "init":
|
||||||
|
|||||||
+4
-4
@@ -129,8 +129,8 @@ func GetSSHOutput(sshClient *ssh.Client, cmd, stdin string) string {
|
|||||||
// getRemoteDataFromClient returns a map of remote entries to their modification times, a list of remote folders, a list of queued deletions, and the current server&client times as UNIX timestamps.
|
// getRemoteDataFromClient returns a map of remote entries to their modification times, a list of remote folders, a list of queued deletions, and the current server&client times as UNIX timestamps.
|
||||||
func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string]int64, []string, []string, int64, int64) {
|
func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string]int64, []string, []string, int64, int64) {
|
||||||
// get remote output over SSH
|
// get remote output over SSH
|
||||||
clientDeviceID, _ := os.ReadDir(core.ConfigDir + core.PathSeparator + "devices")
|
deviceIDList := core.GenDeviceIDList(true)
|
||||||
if len(clientDeviceID) == 0 {
|
if len(*deviceIDList) == 0 {
|
||||||
if manualSync {
|
if manualSync {
|
||||||
fmt.Println(joinErrorWithEXE("Sync failed - No device ID found; run \"", " init\" to generate a device ID"))
|
fmt.Println(joinErrorWithEXE("Sync failed - No device ID found; run \"", " init\" to generate a device ID"))
|
||||||
os.Exit(105)
|
os.Exit(105)
|
||||||
@@ -139,7 +139,7 @@ func getRemoteDataFromClient(sshClient *ssh.Client, manualSync bool) (map[string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
clientTime := time.Now().Unix() // get client time now to avoid accuracy issues caused by unpredictable sync time
|
clientTime := time.Now().Unix() // get client time now to avoid accuracy issues caused by unpredictable sync time
|
||||||
output := GetSSHOutput(sshClient, "libmuttonserver fetch", clientDeviceID[0].Name())
|
output := GetSSHOutput(sshClient, "libmuttonserver fetch", (*deviceIDList)[0].Name())
|
||||||
|
|
||||||
// split output into slice based on occurrences of FSSpace
|
// split output into slice based on occurrences of FSSpace
|
||||||
outputSlice := strings.Split(output, FSSpace)
|
outputSlice := strings.Split(output, FSSpace)
|
||||||
@@ -409,7 +409,7 @@ func ShearRemoteFromClient(sshClient *ssh.Client, targetLocationIncomplete strin
|
|||||||
func RenameRemoteFromClient(sshClient *ssh.Client, oldLocationIncomplete, newLocationIncomplete string) {
|
func RenameRemoteFromClient(sshClient *ssh.Client, oldLocationIncomplete, newLocationIncomplete string) {
|
||||||
RenameLocal(oldLocationIncomplete, newLocationIncomplete, false) // move the target on the local system
|
RenameLocal(oldLocationIncomplete, newLocationIncomplete, false) // move the target on the local system
|
||||||
|
|
||||||
deviceIDList := genDeviceIDList()
|
deviceIDList := core.GenDeviceIDList(true)
|
||||||
if len(*deviceIDList) > 0 { // ensure a device ID exists (online mode)
|
if len(*deviceIDList) > 0 { // ensure a device ID exists (online mode)
|
||||||
// call the server to move the target on the remote system and add the old target to the deletions list
|
// call the server to move the target on the remote system and add the old target to the deletions list
|
||||||
GetSSHOutput(sshClient, "libmuttonserver rename",
|
GetSSHOutput(sshClient, "libmuttonserver rename",
|
||||||
|
|||||||
+1
-13
@@ -2,7 +2,6 @@ package sync
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -20,17 +19,6 @@ func getModTimes(entryList []string) []int64 {
|
|||||||
return modList
|
return modList
|
||||||
}
|
}
|
||||||
|
|
||||||
// genDeviceIDList returns a pointer to a slice of all registered device IDs.
|
|
||||||
func genDeviceIDList() *[]fs.DirEntry {
|
|
||||||
// create a slice of all registered devices
|
|
||||||
deviceIDList, err := os.ReadDir(core.ConfigDir + core.PathSeparator + "devices")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(core.AnsiError + "Failed to read the devices directory: " + err.Error() + core.AnsiReset)
|
|
||||||
os.Exit(101)
|
|
||||||
}
|
|
||||||
return &deviceIDList
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShearLocal removes the target file or directory from the local system.
|
// ShearLocal removes the target file or directory from the local system.
|
||||||
// Returns: deviceID (only on client; for use in ShearRemoteFromClient).
|
// Returns: deviceID (only on client; for use in ShearRemoteFromClient).
|
||||||
// If the local system is a server, it will also add the target to the deletions list for all clients (except the requesting client).
|
// If the local system is a server, it will also add the target to the deletions list for all clients (except the requesting client).
|
||||||
@@ -42,7 +30,7 @@ func ShearLocal(targetLocationIncomplete, clientDeviceID string) string {
|
|||||||
onServer = true
|
onServer = true
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceIDList := genDeviceIDList()
|
deviceIDList := core.GenDeviceIDList(true)
|
||||||
|
|
||||||
// add the sheared target (incomplete, vanity) to the deletions list (if running on a server)
|
// add the sheared target (incomplete, vanity) to the deletions list (if running on a server)
|
||||||
if onServer {
|
if onServer {
|
||||||
|
|||||||
+20
-7
@@ -9,25 +9,38 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rwinkhart/libmutton/core"
|
"github.com/rwinkhart/libmutton/core"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeviceIDGen generates a new client device ID and registers it with the server.
|
// DeviceIDGen generates a new client device ID and registers it with the server (will replace existing one).
|
||||||
// Device IDs are only needed for online synchronization.
|
// Device IDs are only needed for online synchronization.
|
||||||
// Device IDs are guaranteed unique as the current UNIX time is appended to them.
|
// Device IDs are guaranteed unique as the current UNIX time is appended to them.
|
||||||
// Returns: the remote EntryRoot and OS type indicator.
|
// Returns: the remote EntryRoot and OS type indicator.
|
||||||
func DeviceIDGen() (string, string) {
|
func DeviceIDGen(oldDeviceID string) (string, string) {
|
||||||
|
// generate new device ID
|
||||||
deviceIDPrefix, _ := os.Hostname()
|
deviceIDPrefix, _ := os.Hostname()
|
||||||
deviceIDSuffix := core.StringGen(rand.Intn(32)+48, true, 0.2, true) + "-" + strconv.FormatInt(time.Now().Unix(), 10)
|
deviceIDSuffix := core.StringGen(rand.Intn(32)+48, true, 0.2, true) + "-" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
deviceID := deviceIDPrefix + "-" + deviceIDSuffix
|
newDeviceID := deviceIDPrefix + "-" + deviceIDSuffix
|
||||||
_, err := os.Create(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + deviceID) // TODO remove existing device ID file if it exists (from both client and server)
|
|
||||||
|
// create new device ID file (locally)
|
||||||
|
_, err := os.Create(core.ConfigDir + core.PathSeparator + "devices" + core.PathSeparator + newDeviceID) // TODO remove existing device ID file if it exists (from both client and server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(core.AnsiError + "Failed to create local device ID file: " + err.Error() + core.AnsiReset)
|
fmt.Println(core.AnsiError + "Failed to create local device ID file: " + err.Error() + core.AnsiReset)
|
||||||
|
os.Exit(102)
|
||||||
}
|
}
|
||||||
|
|
||||||
// register device ID with server and fetch remote EntryRoot and OS type
|
// register new device ID with server and fetch remote EntryRoot and OS type
|
||||||
//manualSync is true so the user is alerted if device ID registration fails
|
// also removes the old device ID file (remotely)
|
||||||
|
// manualSync is true so the user is alerted if device ID registration fails
|
||||||
sshClient, _, _ := GetSSHClient(true)
|
sshClient, _, _ := GetSSHClient(true)
|
||||||
sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput(sshClient, "libmuttonserver register", deviceID), FSSpace)
|
defer func(sshClient *ssh.Client) {
|
||||||
|
err = sshClient.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(core.AnsiError + "Init failed - Unable to close SSH client: " + err.Error() + core.AnsiReset)
|
||||||
|
os.Exit(104)
|
||||||
|
}
|
||||||
|
}(sshClient)
|
||||||
|
sshEntryRootSSHIsWindows := strings.Split(GetSSHOutput(sshClient, "libmuttonserver register", newDeviceID+"\n"+oldDeviceID), FSSpace)
|
||||||
|
|
||||||
return sshEntryRootSSHIsWindows[0], sshEntryRootSSHIsWindows[1]
|
return sshEntryRootSSHIsWindows[0], sshEntryRootSSHIsWindows[1]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user