sync

package
v1.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const CurrentSyncVersion = 4

CurrentSyncVersion is the version of the sync data format

View Source
const GroupTombstoneRetention = 90 * 24 * time.Hour

GroupTombstoneRetention is how long we retain deleted group tombstones for sync. After this window, tombstones may be garbage collected, and very stale devices may resurrect old groups.

View Source
const SyncFileName = "sshthing-hosts.json"

SyncFileName is the name of the sync data file in the repository

Variables

This section is empty.

Functions

func ExportDataToFile added in v1.0.3

func ExportDataToFile(data *SyncData, filePath string, password string) error

ExportDataToFile writes sync data to an encrypted JSON file at the specified path.

func ExportToFile

func ExportToFile(store *db.Store, filePath string, password string) error

ExportToFile exports sync data to an encrypted JSON file at the specified path.

Types

type GitManager

type GitManager struct {
	// contains filtered or unexported fields
}

GitManager handles Git operations for sync

func NewGitManager

func NewGitManager(repoPath, repoURL, branch, sshKeyPath string) *GitManager

NewGitManager creates a new Git manager

func (*GitManager) CommitChanges

func (gm *GitManager) CommitChanges(message string) error

CommitChanges stages and commits the sync file

func (*GitManager) GetSyncFilePath

func (gm *GitManager) GetSyncFilePath() string

GetSyncFilePath returns the path to the sync file in the repository

func (*GitManager) HasRemote

func (gm *GitManager) HasRemote() bool

HasRemote returns true if a remote is configured

func (*GitManager) Init

func (gm *GitManager) Init() error

Init initializes the local repository by either cloning or opening existing

func (*GitManager) Pull

func (gm *GitManager) Pull() error

Pull fetches and merges changes from the remote repository

func (*GitManager) Push

func (gm *GitManager) Push() error

Push pushes local changes to the remote repository

type ImportResult

type ImportResult struct {
	Added     int
	Updated   int
	Unchanged int
	Conflicts []SyncConflict
}

ImportResult contains the result of an import operation

func Import

func Import(store *db.Store, remote *SyncData, password string) (*ImportResult, error)

Import merges remote sync data into the local database. Uses "last write wins" strategy based on UpdatedAt timestamps. The store must already be opened with the correct master password. If the remote salt differs from local, keys are re-encrypted with the local salt.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager orchestrates sync operations

func NewManager

func NewManager(cfg *config.Config, store *db.Store, password string) (*Manager, error)

NewManager creates a new sync manager

func (*Manager) GetLastResult

func (m *Manager) GetLastResult() *SyncResult

GetLastResult returns the result of the last sync operation

func (*Manager) GetLastSync

func (m *Manager) GetLastSync() time.Time

GetLastSync returns the time of the last successful sync

func (*Manager) GetStatus

func (m *Manager) GetStatus() SyncStatus

GetStatus returns the current sync status

func (*Manager) Init

func (m *Manager) Init() error

Init initializes the sync manager and Git repository

func (*Manager) IsEnabled

func (m *Manager) IsEnabled() bool

IsEnabled returns true if sync is enabled

func (*Manager) StageString added in v1.0.3

func (m *Manager) StageString() string

StageString returns the current sync stage during an in-flight sync.

func (*Manager) StatusString

func (m *Manager) StatusString() string

StatusString returns a human-readable status string

func (*Manager) Sync

func (m *Manager) Sync() *SyncResult

Sync performs a full sync operation: pull -> import -> export -> commit -> push

type SyncConflict

type SyncConflict struct {
	HostID     int
	Hostname   string
	LocalTime  time.Time
	RemoteTime time.Time
	Resolution string // "local", "remote", or "skipped"
}

SyncConflict represents a conflict between local and remote host data

type SyncData

type SyncData struct {
	Version   int                      `json:"version"`
	Salt      string                   `json:"salt"` // Hex-encoded encryption salt from source database
	UpdatedAt time.Time                `json:"updated_at"`
	Groups    []SyncGroup              `json:"groups,omitempty"`
	Hosts     []SyncHost               `json:"hosts"`
	TokenDefs []authtoken.SyncTokenDef `json:"token_defs,omitempty"`
}

SyncData represents the portable format for syncing hosts across devices. The KeyData field in each host remains encrypted - we never export decrypted keys. The Salt field is required to re-encrypt keys when importing to a different database.

func Export

func Export(store *db.Store) (*SyncData, error)

Export reads all hosts from the database and returns them as SyncData. The key data remains encrypted - we do not decrypt keys during export. The salt is included so importing databases can re-encrypt with their own salt.

func LoadFromFile

func LoadFromFile(filePath string, password string) (*SyncData, error)

LoadFromFile reads sync data from a JSON file, supporting encrypted and legacy plaintext formats.

func Merge

func Merge(local, remote *SyncData) *SyncData

Merge combines local and remote data, returning the merged result. This is useful for preparing data to push after a pull.

type SyncFile added in v1.0.3

type SyncFile struct {
	Version   int       `json:"version"`
	UpdatedAt time.Time `json:"updated_at"`
	EncSalt   string    `json:"enc_salt,omitempty"`
	Data      string    `json:"data,omitempty"`

	// Legacy plaintext payload fields (v2 and older)
	Salt      string                   `json:"salt,omitempty"`
	Groups    []SyncGroup              `json:"groups,omitempty"`
	Hosts     []SyncHost               `json:"hosts,omitempty"`
	TokenDefs []authtoken.SyncTokenDef `json:"token_defs,omitempty"`
}

SyncFile is the on-disk sync file format. Version >= 3 stores encrypted payload in Data using EncSalt-derived key. Legacy plaintext payload fields are retained for automatic migration.

type SyncGroup added in v1.0.2

type SyncGroup struct {
	Name      string     `json:"name"`
	CreatedAt time.Time  `json:"created_at"`
	UpdatedAt time.Time  `json:"updated_at"`
	DeletedAt *time.Time `json:"deleted_at,omitempty"`
}

SyncGroup represents a named group entry in the sync file. Deleted groups are tombstoned via DeletedAt.

type SyncHost

type SyncHost struct {
	ID            int        `json:"id"`
	Label         string     `json:"label"`
	GroupName     string     `json:"group_name,omitempty"`
	Tags          []string   `json:"tags,omitempty"`
	Hostname      string     `json:"hostname"`
	Username      string     `json:"username"`
	Port          int        `json:"port"`
	KeyData       string     `json:"key_data"` // Encrypted blob (stays encrypted)
	KeyType       string     `json:"key_type"`
	CreatedAt     time.Time  `json:"created_at"`
	UpdatedAt     time.Time  `json:"updated_at"`
	LastConnected *time.Time `json:"last_connected,omitempty"`
}

SyncHost represents a host entry in the sync file. This mirrors db.HostModel but is designed for JSON serialization.

type SyncResult

type SyncResult struct {
	Success      bool
	Message      string
	HostsPulled  int
	HostsPushed  int
	HostsAdded   int
	HostsUpdated int
	HostsRemoved int
	Conflicts    []SyncConflict
	Error        error
	Timestamp    time.Time
}

SyncResult represents the outcome of a sync operation

type SyncStatus

type SyncStatus int

SyncStatus represents the current state of sync operations

const (
	SyncStatusDisabled SyncStatus = iota
	SyncStatusIdle
	SyncStatusSyncing
	SyncStatusError
	SyncStatusSuccess
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL