@ -49,12 +49,12 @@ func initCLI() *portainer.CLIFlags {
var cliService portainer . CLIService = & cli . Service { }
var cliService portainer . CLIService = & cli . Service { }
flags , err := cliService . ParseFlags ( portainer . APIVersion )
flags , err := cliService . ParseFlags ( portainer . APIVersion )
if err != nil {
if err != nil {
log . Fatalf ( "Failed parsing flags: %v" , err )
log rus . Fatalf ( "Failed parsing flags: %v" , err )
}
}
err = cliService . ValidateFlags ( flags )
err = cliService . ValidateFlags ( flags )
if err != nil {
if err != nil {
log . Fatalf ( "Failed validating flags:%v" , err )
log rus . Fatalf ( "Failed validating flags:%v" , err )
}
}
return flags
return flags
}
}
@ -62,7 +62,7 @@ func initCLI() *portainer.CLIFlags {
func initFileService ( dataStorePath string ) portainer . FileService {
func initFileService ( dataStorePath string ) portainer . FileService {
fileService , err := filesystem . NewService ( dataStorePath , "" )
fileService , err := filesystem . NewService ( dataStorePath , "" )
if err != nil {
if err != nil {
log . Fatalf ( "Failed creating file service: %v" , err )
log rus . Fatalf ( "Failed creating file service: %v" , err )
}
}
return fileService
return fileService
}
}
@ -70,7 +70,7 @@ func initFileService(dataStorePath string) portainer.FileService {
func initDataStore ( flags * portainer . CLIFlags , secretKey [ ] byte , fileService portainer . FileService , shutdownCtx context . Context ) dataservices . DataStore {
func initDataStore ( flags * portainer . CLIFlags , secretKey [ ] byte , fileService portainer . FileService , shutdownCtx context . Context ) dataservices . DataStore {
connection , err := database . NewDatabase ( "boltdb" , * flags . Data , secretKey )
connection , err := database . NewDatabase ( "boltdb" , * flags . Data , secretKey )
if err != nil {
if err != nil {
log . Fatalf ( "failed creating database connection: %s" , err )
log rus . Fatalf ( "failed creating database connection: %s" , err )
}
}
if bconn , ok := connection . ( * boltdb . DbConnection ) ; ok {
if bconn , ok := connection . ( * boltdb . DbConnection ) ; ok {
@ -78,22 +78,22 @@ func initDataStore(flags *portainer.CLIFlags, secretKey []byte, fileService port
bconn . MaxBatchDelay = * flags . MaxBatchDelay
bconn . MaxBatchDelay = * flags . MaxBatchDelay
bconn . InitialMmapSize = * flags . InitialMmapSize
bconn . InitialMmapSize = * flags . InitialMmapSize
} else {
} else {
log . Fatalf ( "failed creating database connection: expecting a boltdb database type but a different one was received" )
log rus . Fatalf ( "failed creating database connection: expecting a boltdb database type but a different one was received" )
}
}
store := datastore . NewStore ( * flags . Data , fileService , connection )
store := datastore . NewStore ( * flags . Data , fileService , connection )
isNew , err := store . Open ( )
isNew , err := store . Open ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed opening store: %v" , err )
log rus . Fatalf ( "Failed opening store: %v" , err )
}
}
if * flags . Rollback {
if * flags . Rollback {
err := store . Rollback ( false )
err := store . Rollback ( false )
if err != nil {
if err != nil {
log . Fatalf ( "Failed rolling back: %v" , err )
log rus . Fatalf ( "Failed rolling back: %v" , err )
}
}
log . Println ( "Exiting rollback" )
log rus . Println ( "Exiting rollback" )
os . Exit ( 0 )
os . Exit ( 0 )
return nil
return nil
}
}
@ -101,21 +101,26 @@ func initDataStore(flags *portainer.CLIFlags, secretKey []byte, fileService port
// Init sets some defaults - it's basically a migration
// Init sets some defaults - it's basically a migration
err = store . Init ( )
err = store . Init ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing data store: %v" , err )
log rus . Fatalf ( "Failed initializing data store: %v" , err )
}
}
if isNew {
if isNew {
// from MigrateData
// from MigrateData
store . VersionService . StoreDBVersion ( portainer . DBVersion )
store . VersionService . StoreDBVersion ( portainer . DBVersion )
err := updateSettingsFromFlags ( store , flags )
if err != nil {
logrus . Fatalf ( "Failed updating settings from flags: %v" , err )
}
} else {
} else {
storedVersion , err := store . VersionService . DBVersion ( )
storedVersion , err := store . VersionService . DBVersion ( )
if err != nil {
if err != nil {
log . Fatalf ( "Something Failed during creation of new database: %v" , err )
log rus . Fatalf ( "Something Failed during creation of new database: %v" , err )
}
}
if storedVersion != portainer . DBVersion {
if storedVersion != portainer . DBVersion {
err = store . MigrateData ( )
err = store . MigrateData ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed migration: %v" , err )
log rus . Fatalf ( "Failed migration: %v" , err )
}
}
}
}
}
}
@ -146,7 +151,7 @@ func initDataStore(flags *portainer.CLIFlags, secretKey []byte, fileService port
func initComposeStackManager ( assetsPath string , configPath string , reverseTunnelService portainer . ReverseTunnelService , proxyManager * proxy . Manager ) portainer . ComposeStackManager {
func initComposeStackManager ( assetsPath string , configPath string , reverseTunnelService portainer . ReverseTunnelService , proxyManager * proxy . Manager ) portainer . ComposeStackManager {
composeWrapper , err := exec . NewComposeStackManager ( assetsPath , configPath , proxyManager )
composeWrapper , err := exec . NewComposeStackManager ( assetsPath , configPath , proxyManager )
if err != nil {
if err != nil {
log . Fatalf ( "Failed creating compose manager: %v" , err )
log rus . Fatalf ( "Failed creating compose manager: %v" , err )
}
}
return composeWrapper
return composeWrapper
@ -329,9 +334,9 @@ func enableFeaturesFromFlags(dataStore dataservices.DataStore, flags *portainer.
}
}
if featureState {
if featureState {
log . Printf ( "Feature %v : on" , * correspondingFeature )
log rus . Printf ( "Feature %v : on" , * correspondingFeature )
} else {
} else {
log . Printf ( "Feature %v : off" , * correspondingFeature )
log rus . Printf ( "Feature %v : off" , * correspondingFeature )
}
}
settings . FeatureFlagSettings [ * correspondingFeature ] = featureState
settings . FeatureFlagSettings [ * correspondingFeature ] = featureState
@ -360,7 +365,7 @@ func generateAndStoreKeyPair(fileService portainer.FileService, signatureService
func initKeyPair ( fileService portainer . FileService , signatureService portainer . DigitalSignatureService ) error {
func initKeyPair ( fileService portainer . FileService , signatureService portainer . DigitalSignatureService ) error {
existingKeyPair , err := fileService . KeyPairFilesExist ( )
existingKeyPair , err := fileService . KeyPairFilesExist ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed checking for existing key pair: %v" , err )
log rus . Fatalf ( "Failed checking for existing key pair: %v" , err )
}
}
if existingKeyPair {
if existingKeyPair {
@ -431,7 +436,7 @@ func createTLSSecuredEndpoint(flags *portainer.CLIFlags, dataStore dataservices.
err := snapshotService . SnapshotEndpoint ( endpoint )
err := snapshotService . SnapshotEndpoint ( endpoint )
if err != nil {
if err != nil {
log . Printf ( "http error: environment snapshot error (environment=%s, URL=%s) (err=%s)\n" , endpoint . Name , endpoint . URL , err )
log rus . Printf ( "http error: environment snapshot error (environment=%s, URL=%s) (err=%s)\n" , endpoint . Name , endpoint . URL , err )
}
}
return dataStore . Endpoint ( ) . Create ( endpoint )
return dataStore . Endpoint ( ) . Create ( endpoint )
@ -477,7 +482,7 @@ func createUnsecuredEndpoint(endpointURL string, dataStore dataservices.DataStor
err := snapshotService . SnapshotEndpoint ( endpoint )
err := snapshotService . SnapshotEndpoint ( endpoint )
if err != nil {
if err != nil {
log . Printf ( "http error: environment snapshot error (environment=%s, URL=%s) (err=%s)\n" , endpoint . Name , endpoint . URL , err )
log rus . Printf ( "http error: environment snapshot error (environment=%s, URL=%s) (err=%s)\n" , endpoint . Name , endpoint . URL , err )
}
}
return dataStore . Endpoint ( ) . Create ( endpoint )
return dataStore . Endpoint ( ) . Create ( endpoint )
@ -494,7 +499,7 @@ func initEndpoint(flags *portainer.CLIFlags, dataStore dataservices.DataStore, s
}
}
if len ( endpoints ) > 0 {
if len ( endpoints ) > 0 {
log . Println ( "Instance already has defined environments. Skipping the environment defined via CLI." )
log rus . Println ( "Instance already has defined environments. Skipping the environment defined via CLI." )
return nil
return nil
}
}
@ -508,9 +513,9 @@ func loadEncryptionSecretKey(keyfilename string) []byte {
content , err := os . ReadFile ( path . Join ( "/run/secrets" , keyfilename ) )
content , err := os . ReadFile ( path . Join ( "/run/secrets" , keyfilename ) )
if err != nil {
if err != nil {
if os . IsNotExist ( err ) {
if os . IsNotExist ( err ) {
log . Printf ( "Encryption key file `%s` not present" , keyfilename )
log rus . Printf ( "Encryption key file `%s` not present" , keyfilename )
} else {
} else {
log . Printf ( "Error reading encryption key file: %v" , err )
log rus . Printf ( "Error reading encryption key file: %v" , err )
}
}
return nil
return nil
@ -527,33 +532,33 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
fileService := initFileService ( * flags . Data )
fileService := initFileService ( * flags . Data )
encryptionKey := loadEncryptionSecretKey ( * flags . SecretKeyName )
encryptionKey := loadEncryptionSecretKey ( * flags . SecretKeyName )
if encryptionKey == nil {
if encryptionKey == nil {
log . Println ( "p roceeding without encryption key")
log rus. Println ( "P roceeding without encryption key")
}
}
dataStore := initDataStore ( flags , encryptionKey , fileService , shutdownCtx )
dataStore := initDataStore ( flags , encryptionKey , fileService , shutdownCtx )
if err := dataStore . CheckCurrentEdition ( ) ; err != nil {
if err := dataStore . CheckCurrentEdition ( ) ; err != nil {
log . Fatal ( err )
log rus . Fatal ( err )
}
}
instanceID , err := dataStore . Version ( ) . InstanceID ( )
instanceID , err := dataStore . Version ( ) . InstanceID ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed getting instance id: %v" , err )
log rus . Fatalf ( "Failed getting instance id: %v" , err )
}
}
apiKeyService := initAPIKeyService ( dataStore )
apiKeyService := initAPIKeyService ( dataStore )
settings , err := dataStore . Settings ( ) . Settings ( )
settings , err := dataStore . Settings ( ) . Settings ( )
if err != nil {
if err != nil {
log . Fatal ( err )
log rus . Fatal ( err )
}
}
jwtService , err := initJWTService ( settings . UserSessionTimeout , dataStore )
jwtService , err := initJWTService ( settings . UserSessionTimeout , dataStore )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing JWT service: %v" , err )
log rus . Fatalf ( "Failed initializing JWT service: %v" , err )
}
}
err = enableFeaturesFromFlags ( dataStore , flags )
err = enableFeaturesFromFlags ( dataStore , flags )
if err != nil {
if err != nil {
log . Fatalf ( "Failed enabling feature flag: %v" , err )
log rus . Fatalf ( "Failed enabling feature flag: %v" , err )
}
}
ldapService := initLDAPService ( )
ldapService := initLDAPService ( )
@ -567,17 +572,17 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
sslService , err := initSSLService ( * flags . AddrHTTPS , * flags . Data , * flags . SSLCert , * flags . SSLKey , fileService , dataStore , shutdownTrigger )
sslService , err := initSSLService ( * flags . AddrHTTPS , * flags . Data , * flags . SSLCert , * flags . SSLKey , fileService , dataStore , shutdownTrigger )
if err != nil {
if err != nil {
log . Fatal ( err )
log rus . Fatal ( err )
}
}
sslSettings , err := sslService . GetSSLSettings ( )
sslSettings , err := sslService . GetSSLSettings ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed to get ssl settings: %s" , err )
log rus . Fatalf ( "Failed to get ssl settings: %s" , err )
}
}
err = initKeyPair ( fileService , digitalSignatureService )
err = initKeyPair ( fileService , digitalSignatureService )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing key pair: %v" , err )
log rus . Fatalf ( "Failed initializing key pair: %v" , err )
}
}
reverseTunnelService := chisel . NewService ( dataStore , shutdownCtx )
reverseTunnelService := chisel . NewService ( dataStore , shutdownCtx )
@ -587,7 +592,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
snapshotService , err := initSnapshotService ( * flags . SnapshotInterval , dataStore , dockerClientFactory , kubernetesClientFactory , shutdownCtx )
snapshotService , err := initSnapshotService ( * flags . SnapshotInterval , dataStore , dockerClientFactory , kubernetesClientFactory , shutdownCtx )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing snapshot service: %v" , err )
log rus . Fatalf ( "Failed initializing snapshot service: %v" , err )
}
}
snapshotService . Start ( )
snapshotService . Start ( )
@ -608,37 +613,37 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
swarmStackManager , err := initSwarmStackManager ( * flags . Assets , dockerConfigPath , digitalSignatureService , fileService , reverseTunnelService , dataStore )
swarmStackManager , err := initSwarmStackManager ( * flags . Assets , dockerConfigPath , digitalSignatureService , fileService , reverseTunnelService , dataStore )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing swarm stack manager: %v" , err )
log rus . Fatalf ( "Failed initializing swarm stack manager: %v" , err )
}
}
kubernetesDeployer := initKubernetesDeployer ( kubernetesTokenCacheManager , kubernetesClientFactory , dataStore , reverseTunnelService , digitalSignatureService , proxyManager , * flags . Assets )
kubernetesDeployer := initKubernetesDeployer ( kubernetesTokenCacheManager , kubernetesClientFactory , dataStore , reverseTunnelService , digitalSignatureService , proxyManager , * flags . Assets )
helmPackageManager , err := initHelmPackageManager ( * flags . Assets )
helmPackageManager , err := initHelmPackageManager ( * flags . Assets )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing helm package manager: %v" , err )
log rus . Fatalf ( "Failed initializing helm package manager: %v" , err )
}
}
err = edge . LoadEdgeJobs ( dataStore , reverseTunnelService )
err = edge . LoadEdgeJobs ( dataStore , reverseTunnelService )
if err != nil {
if err != nil {
log . Fatalf ( "Failed loading edge jobs from database: %v" , err )
log rus . Fatalf ( "Failed loading edge jobs from database: %v" , err )
}
}
applicationStatus := initStatus ( instanceID )
applicationStatus := initStatus ( instanceID )
err = initEndpoint ( flags , dataStore , snapshotService )
err = initEndpoint ( flags , dataStore , snapshotService )
if err != nil {
if err != nil {
log . Fatalf ( "Failed initializing environment: %v" , err )
log rus . Fatalf ( "Failed initializing environment: %v" , err )
}
}
adminPasswordHash := ""
adminPasswordHash := ""
if * flags . AdminPasswordFile != "" {
if * flags . AdminPasswordFile != "" {
content , err := fileService . GetFileContent ( * flags . AdminPasswordFile , "" )
content , err := fileService . GetFileContent ( * flags . AdminPasswordFile , "" )
if err != nil {
if err != nil {
log . Fatalf ( "Failed getting admin password file: %v" , err )
log rus . Fatalf ( "Failed getting admin password file: %v" , err )
}
}
adminPasswordHash , err = cryptoService . Hash ( strings . TrimSuffix ( string ( content ) , "\n" ) )
adminPasswordHash , err = cryptoService . Hash ( strings . TrimSuffix ( string ( content ) , "\n" ) )
if err != nil {
if err != nil {
log . Fatalf ( "Failed hashing admin password: %v" , err )
log rus . Fatalf ( "Failed hashing admin password: %v" , err )
}
}
} else if * flags . AdminPassword != "" {
} else if * flags . AdminPassword != "" {
adminPasswordHash = * flags . AdminPassword
adminPasswordHash = * flags . AdminPassword
@ -647,11 +652,11 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
if adminPasswordHash != "" {
if adminPasswordHash != "" {
users , err := dataStore . User ( ) . UsersByRole ( portainer . AdministratorRole )
users , err := dataStore . User ( ) . UsersByRole ( portainer . AdministratorRole )
if err != nil {
if err != nil {
log . Fatalf ( "Failed getting admin user: %v" , err )
log rus . Fatalf ( "Failed getting admin user: %v" , err )
}
}
if len ( users ) == 0 {
if len ( users ) == 0 {
log . Println ( "Created admin user with the given password." )
log rus . Println ( "Created admin user with the given password." )
user := & portainer . User {
user := & portainer . User {
Username : "admin" ,
Username : "admin" ,
Role : portainer . AdministratorRole ,
Role : portainer . AdministratorRole ,
@ -659,21 +664,21 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
}
}
err := dataStore . User ( ) . Create ( user )
err := dataStore . User ( ) . Create ( user )
if err != nil {
if err != nil {
log . Fatalf ( "Failed creating admin user: %v" , err )
log rus . Fatalf ( "Failed creating admin user: %v" , err )
}
}
} else {
} else {
log . Println ( "Instance already has an administrator user defined. Skipping admin password related flags." )
log rus . Println ( "Instance already has an administrator user defined. Skipping admin password related flags." )
}
}
}
}
err = reverseTunnelService . StartTunnelServer ( * flags . TunnelAddr , * flags . TunnelPort , snapshotService )
err = reverseTunnelService . StartTunnelServer ( * flags . TunnelAddr , * flags . TunnelPort , snapshotService )
if err != nil {
if err != nil {
log . Fatalf ( "Failed starting tunnel server: %v" , err )
log rus . Fatalf ( "Failed starting tunnel server: %v" , err )
}
}
sslDBSettings , err := dataStore . SSLSettings ( ) . Settings ( )
sslDBSettings , err := dataStore . SSLSettings ( ) . Settings ( )
if err != nil {
if err != nil {
log . Fatalf ( "Failed to fetch ssl settings from DB" )
log rus . Fatalf ( "Failed to fetch ssl settings from DB" )
}
}
scheduler := scheduler . NewScheduler ( shutdownCtx )
scheduler := scheduler . NewScheduler ( shutdownCtx )
@ -724,8 +729,8 @@ func main() {
for {
for {
server := buildServer ( flags )
server := buildServer ( flags )
log . Printf ( "[INFO] [cmd,main] Starting Portainer version %s\n" , portainer . APIVersion )
log rus . Printf ( "[INFO] [cmd,main] Starting Portainer version %s\n" , portainer . APIVersion )
err := server . Start ( )
err := server . Start ( )
log . Printf ( "[INFO] [cmd,main] Http server exited: %v\n" , err )
log rus . Printf ( "[INFO] [cmd,main] Http server exited: %v\n" , err )
}
}
}
}