feat: curio: alertManager (#11926)

* add alert task

* maxbalance config, storage alert

* docs gen

* improve storage alert

* fix empty alert
This commit is contained in:
LexLuthr 2024-05-08 18:38:15 +05:30 committed by GitHub
parent 33876bf81c
commit 22ccaf91ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 1104 additions and 365 deletions

View File

@ -33,8 +33,6 @@ RUN set -eux; \
COPY ./ /opt/curio
WORKDIR /opt/curio
#RUN scripts/docker-git-state-check.sh
### make configurable filecoin-ffi build
ARG FFI_BUILD_FROM_SOURCE=0
ENV FFI_BUILD_FROM_SOURCE=${FFI_BUILD_FROM_SOURCE}

View File

@ -207,7 +207,7 @@ func (deps *Deps) PopulateRemainingDeps(ctx context.Context, cctx *cli.Context,
}
}
if deps.Cfg == nil {
if deps.DB == nil {
deps.DB, err = MakeDB(cctx)
if err != nil {
return err

View File

@ -250,7 +250,7 @@ func complete(d *MigrationData) {
func completeInit(d *MigrationData) {
stepCompleted(d, d.T("New Miner initialization complete."))
d.say(plain, "Try the web interface with %s for further guided improvements.", "--layers=gui")
d.say(plain, "Try the web interface with %s for further guided improvements.", code.Render("curio run --layers=gui"))
}
func configToDB(d *MigrationData) {

View File

@ -40,168 +40,173 @@ func init() {
}
var messageKeyToIndex = map[string]int{
"Aborting migration.": 45,
"Aborting migration.": 21,
"Aborting remaining steps.": 9,
"Aggregate-Anonymous: version, chain, and Miner power (bucketed).": 22,
"Cannot reach the DB: %s": 90,
"Cannot read the config.toml file in the provided directory, Error: %s": 65,
"Compare the configurations %s to %s. Changes between the miner IDs other than wallet addreses should be a new, minimal layer for runners that need it.": 116,
"Confidence epochs": 86,
"Confidence epochs: %d": 76,
"Configuration 'base' was created to resemble this lotus-miner's config.toml .": 117,
"Configuration 'base' was updated to include this miner's address": 99,
"Configuration 'base' was updated to include this miner's address (%s) and its wallet setup.": 115,
"Connected to Yugabyte": 59,
"Connected to Yugabyte. Schema is current.": 47,
"Continue to connect and update schema.": 109,
"Continue to verify the addresses and create a new miner actor.": 77,
"Could not create repo from directory: %s. Aborting migration": 66,
"Could not lock miner repo. Your miner must be stopped: %s\n Aborting migration": 67,
"Aggregate-Anonymous: version, chain, and Miner power (bucketed).": 26,
"Cannot reach the DB: %s": 93,
"Cannot read the config.toml file in the provided directory, Error: %s": 68,
"Compare the configurations %s to %s. Changes between the miner IDs other than wallet addreses should be a new, minimal layer for runners that need it.": 120,
"Confidence epochs": 89,
"Confidence epochs: %d": 79,
"Configuration 'base' was created to resemble this lotus-miner's config.toml .": 121,
"Configuration 'base' was updated to include this miner's address": 102,
"Configuration 'base' was updated to include this miner's address (%s) and its wallet setup.": 119,
"Connected to Yugabyte": 62,
"Connected to Yugabyte. Schema is current.": 50,
"Continue to connect and update schema.": 112,
"Continue to verify the addresses and create a new miner actor.": 80,
"Could not create repo from directory: %s. Aborting migration": 69,
"Could not lock miner repo. Your miner must be stopped: %s\n Aborting migration": 70,
"Create a new miner": 8,
"Ctrl+C pressed in Terminal": 5,
"Database config error occurred, abandoning migration: %s ": 110,
"Database: %s": 108,
"Documentation: ": 32,
"Database config error occurred, abandoning migration: %s ": 113,
"Database: %s": 111,
"Documentation: ": 36,
"Each step needs your confirmation and can be reversed. Press Ctrl+C to exit at any time.": 4,
"Enabling Sector Indexing in the database.": 48,
"Enter %s address": 82,
"Enter the Yugabyte database %s": 113,
"Enter the Yugabyte database host(s)": 111,
"Enter the info to connect to your Yugabyte database installation (https://download.yugabyte.com/)": 103,
"Enter the info to create a new miner": 71,
"Enter the owner address": 79,
"Enter the path to the configuration directory used by %s": 63,
"Enter the sector size": 83,
"Error closing backup file: %s": 56,
"Error connecting to Yugabyte database: %s": 114,
"Error connecting to full node API: %s": 91,
"Error creating backup file: %s": 53,
"Error encoding config.toml: %s": 49,
"Error expanding path: %s": 51,
"Enabling Sector Indexing in the database.": 51,
"Enter %s address": 85,
"Enter the Yugabyte database %s": 116,
"Enter the Yugabyte database host(s)": 114,
"Enter the info to connect to your Yugabyte database installation (https://download.yugabyte.com/)": 106,
"Enter the info to create a new miner": 74,
"Enter the owner address": 82,
"Enter the path to the configuration directory used by %s": 66,
"Enter the sector size": 86,
"Error closing backup file: %s": 59,
"Error connecting to Yugabyte database: %s": 117,
"Error connecting to full node API: %s": 94,
"Error creating backup file: %s": 56,
"Error encoding config.toml: %s": 52,
"Error expanding path: %s": 54,
"Error getting API: %s": 15,
"Error getting miner info: %s": 27,
"Error getting miner power: %s": 25,
"Error getting miner info: %s": 31,
"Error getting miner power: %s": 29,
"Error getting token: %s": 17,
"Error interpreting miner ID: %s: ID: %s": 40,
"Error marshalling message: %s": 26,
"Error reading config.toml: %s": 54,
"Error reading filemode of config.toml: %s": 52,
"Error saving config to layer: %s. Aborting Migration": 18,
"Error sending message: %s": 29,
"Error sending message: Status %s, Message: ": 30,
"Error signing message: %s": 28,
"Error verifying sectors: %s": 41,
"Error writing backup file: %s": 55,
"Error writing config.toml: %s": 57,
"Failed to create the miner actor: %s": 88,
"Failed to generate default config: %s": 97,
"Failed to generate random bytes for secret: %s": 93,
"Failed to get API info for FullNode: %w": 95,
"Failed to insert 'base' config layer in database: %s": 98,
"Failed to load base config from database: %s": 100,
"Failed to parse base config: %s": 101,
"Failed to parse confidence: %s": 87,
"Failed to parse sector size: %s": 85,
"Failed to parse the address: %s": 81,
"Failed to regenerate base config: %s": 102,
"Failed to verify the auth token from daemon node: %s": 96,
"Filecoin %s channels: %s and %s": 35,
"Hint: I am someone running Curio on whichever chain.": 23,
"Host: %s": 104,
"Error interpreting miner ID: %s: ID: %s": 44,
"Error marshalling message: %s": 30,
"Error reading config.toml: %s": 57,
"Error reading filemode of config.toml: %s": 55,
"Error saving config to layer: %s. Aborting Migration": 22,
"Error sending message: %s": 33,
"Error sending message: Status %s, Message: ": 34,
"Error signing message: %s": 32,
"Error verifying sectors: %s": 45,
"Error writing backup file: %s": 58,
"Error writing config.toml: %s": 60,
"Failed to create the miner actor: %s": 91,
"Failed to generate default config: %s": 100,
"Failed to generate random bytes for secret: %s": 96,
"Failed to get API info for FullNode: %w": 98,
"Failed to insert 'base' config layer in database: %s": 101,
"Failed to load base config from database: %s": 103,
"Failed to parse base config: %s": 104,
"Failed to parse confidence: %s": 90,
"Failed to parse sector size: %s": 88,
"Failed to parse the address: %s": 84,
"Failed to regenerate base config: %s": 105,
"Failed to verify the auth token from daemon node: %s": 99,
"Filecoin %s channels: %s and %s": 39,
"Hint: I am someone running Curio on whichever chain.": 27,
"Host: %s": 107,
"I want to:": 6,
"Increase reliability using redundancy: start multiple machines with at-least the post layer: 'curio run --layers=post'": 36,
"Individual Data: Miner ID, Curio version, chain (%s or %s). Signed.": 21,
"Initializing a new miner actor.": 70,
"Layer %s created. ": 118,
"Increase reliability using redundancy: start multiple machines with at-least the post layer: 'curio run --layers=post'": 40,
"Individual Data: Miner ID, Curio version, chain (%s or %s). Signed.": 25,
"Initializing a new miner actor.": 73,
"Layer %s created. ": 122,
"Lotus-Miner to Curio Migration.": 10,
"Message sent.": 31,
"Message sent.": 35,
"Migrate from existing Lotus-Miner": 7,
"Migrating lotus-miner config.toml to Curio in-database configuration.": 14,
"Miner %s created successfully": 89,
"Miner creation error occurred: %s ": 78,
"Migrating metadata for %d sectors.": 118,
"Miner %s created successfully": 92,
"Miner creation error occurred: %s ": 81,
"New Miner initialization complete.": 13,
"No address provided": 80,
"No host provided": 112,
"No path provided, abandoning migration ": 64,
"No value provided": 84,
"Nothing.": 24,
"Now shut down lotus-miner and lotus-worker and use run %s instead.": 43,
"One database can serve multiple miner IDs: Run a migration for each lotus-miner.": 37,
"Other": 62,
"Owner Address: %s": 72,
"Password: %s": 107,
"Please do not run guided-setup again as miner creation is not idempotent. You need to run 'curio config new-cluster %s' to finish the configuration": 94,
"Please start (or restart) %s now that database credentials are in %s.": 38,
"Port: %s": 105,
"Pre-initialization steps complete": 92,
"Press return to continue": 44,
"Press return to update %s with Yugabyte info. A Backup file will be written to that folder before changes are made.": 50,
"Read Miner Config": 68,
"Restart Lotus Miner. ": 58,
"Sector Size: %d": 75,
"Sectors verified. %d sector locations found.": 46,
"Select the location of your lotus-miner config directory?": 61,
"Select what you want to share with the Curio team.": 20,
"Sender Address: %s": 74,
"Step Complete: %s\n": 69,
"The '%s' layer stores common configuration. All curio instances can include it in their %s argument.": 33,
"The Curio team wants to improve the software you use. Tell the team you're using `%s`.": 19,
"The sectors are in the database. The database is ready for %s.": 42,
"No address provided": 83,
"No host provided": 115,
"No path provided, abandoning migration ": 67,
"No value provided": 87,
"No, abort": 20,
"Nothing.": 28,
"Now shut down lotus-miner and lotus-worker and use run %s instead.": 47,
"One database can serve multiple miner IDs: Run a migration for each lotus-miner.": 41,
"Other": 65,
"Owner Address: %s": 75,
"Password: %s": 110,
"Please do not run guided-setup again as miner creation is not idempotent. You need to run 'curio config new-cluster %s' to finish the configuration": 97,
"Please start (or restart) %s now that database credentials are in %s.": 42,
"Port: %s": 108,
"Pre-initialization steps complete": 95,
"Press return to continue": 48,
"Press return to update %s with Yugabyte info. A Backup file will be written to that folder before changes are made.": 53,
"Read Miner Config": 71,
"Restart Lotus Miner. ": 61,
"Sector Size: %d": 78,
"Sectors verified. %d sector locations found.": 49,
"Select the location of your lotus-miner config directory?": 64,
"Select what you want to share with the Curio team.": 24,
"Sender Address: %s": 77,
"Step Complete: %s\n": 72,
"The '%s' layer stores common configuration. All curio instances can include it in their %s argument.": 37,
"The Curio team wants to improve the software you use. Tell the team you're using `%s`.": 23,
"The sectors are in the database. The database is ready for %s.": 46,
"This interactive tool creates a new miner actor and creates the basic configuration layer for it.": 1,
"This interactive tool migrates lotus-miner to Curio in 5 minutes.": 3,
"This process is partially idempotent. Once a new miner actor has been created and subsequent steps fail, the user need to run 'curio config new-cluster < miner ID >' to finish the configuration.": 2,
"To run Curio: With machine or cgroup isolation, use the command (with example layer selection):": 120,
"To start, ensure your sealing pipeline is drained and shut-down lotus-miner.": 60,
"To work with the config: ": 119,
"To run Curio: With machine or cgroup isolation, use the command (with example layer selection):": 124,
"To start, ensure your sealing pipeline is drained and shut-down lotus-miner.": 63,
"To work with the config: ": 123,
"Try the web interface with %s for further guided improvements.": 11,
"Unmigratable sectors found. Do you want to continue?": 18,
"Use the arrow keys to navigate: ↓ ↑ → ← ": 0,
"Username: %s": 106,
"Waiting for %s to write sectors into Yugabyte.": 39,
"Worker Address: %s": 73,
"You can add other layers for per-machine configuration changes.": 34,
"Username: %s": 109,
"Waiting for %s to write sectors into Yugabyte.": 43,
"Worker Address: %s": 76,
"Yes, continue": 19,
"You can add other layers for per-machine configuration changes.": 38,
"You can now migrate your market node (%s), if applicable.": 12,
"could not get API info for FullNode: %w": 16,
}
var enIndex = []uint32{ // 122 elements
var enIndex = []uint32{ // 126 elements
// Entry 0 - 1F
0x00000000, 0x00000035, 0x00000097, 0x0000015a,
0x0000019c, 0x000001f5, 0x00000210, 0x0000021b,
0x0000023d, 0x00000250, 0x0000026a, 0x0000028a,
0x000002cc, 0x00000309, 0x0000032c, 0x00000372,
0x0000038b, 0x000003b6, 0x000003d1, 0x00000409,
0x00000463, 0x00000496, 0x000004e0, 0x00000521,
0x00000556, 0x0000055f, 0x00000580, 0x000005a1,
0x000005c1, 0x000005de, 0x000005fb, 0x0000062e,
0x0000038b, 0x000003b6, 0x000003d1, 0x00000406,
0x00000414, 0x0000041e, 0x00000432, 0x0000046a,
0x000004c4, 0x000004f7, 0x00000541, 0x00000582,
0x000005b7, 0x000005c0, 0x000005e1, 0x00000602,
// Entry 20 - 3F
0x0000063c, 0x00000650, 0x000006bb, 0x000006fb,
0x00000724, 0x0000079b, 0x000007ec, 0x00000838,
0x0000086a, 0x00000898, 0x000008b7, 0x000008f9,
0x0000093f, 0x00000958, 0x0000096c, 0x0000099c,
0x000009c6, 0x000009f0, 0x00000a12, 0x00000a89,
0x00000aa5, 0x00000ad2, 0x00000af4, 0x00000b15,
0x00000b36, 0x00000b57, 0x00000b78, 0x00000b92,
0x00000ba8, 0x00000bf5, 0x00000c2f, 0x00000c35,
0x00000622, 0x0000063f, 0x0000065c, 0x0000068f,
0x0000069d, 0x000006b1, 0x0000071c, 0x0000075c,
0x00000785, 0x000007fc, 0x0000084d, 0x00000899,
0x000008cb, 0x000008f9, 0x00000918, 0x0000095a,
0x000009a0, 0x000009b9, 0x000009e9, 0x00000a13,
0x00000a3d, 0x00000a5f, 0x00000ad6, 0x00000af2,
0x00000b1f, 0x00000b41, 0x00000b62, 0x00000b83,
0x00000ba4, 0x00000bc5, 0x00000bdf, 0x00000bf5,
// Entry 40 - 5F
0x00000c71, 0x00000c9d, 0x00000ce6, 0x00000d26,
0x00000d77, 0x00000d89, 0x00000da3, 0x00000dc3,
0x00000de8, 0x00000dfd, 0x00000e13, 0x00000e29,
0x00000e3c, 0x00000e55, 0x00000e94, 0x00000ebe,
0x00000ed6, 0x00000eea, 0x00000f0d, 0x00000f21,
0x00000f37, 0x00000f49, 0x00000f6c, 0x00000f7e,
0x00000fa0, 0x00000fc8, 0x00000fe9, 0x00001004,
0x0000102d, 0x0000104f, 0x00001081, 0x00001118,
0x00000c42, 0x00000c7c, 0x00000c82, 0x00000cbe,
0x00000cea, 0x00000d33, 0x00000d73, 0x00000dc4,
0x00000dd6, 0x00000df0, 0x00000e10, 0x00000e35,
0x00000e4a, 0x00000e60, 0x00000e76, 0x00000e89,
0x00000ea2, 0x00000ee1, 0x00000f0b, 0x00000f23,
0x00000f37, 0x00000f5a, 0x00000f6e, 0x00000f84,
0x00000f96, 0x00000fb9, 0x00000fcb, 0x00000fed,
0x00001015, 0x00001036, 0x00001051, 0x0000107a,
// Entry 60 - 7F
0x00001143, 0x0000117b, 0x000011a4, 0x000011dc,
0x0000121d, 0x0000124d, 0x00001270, 0x00001298,
0x000012fa, 0x00001306, 0x00001312, 0x00001322,
0x00001332, 0x00001342, 0x00001369, 0x000013aa,
0x000013ce, 0x000013df, 0x00001401, 0x0000142e,
0x0000148d, 0x0000152a, 0x00001578, 0x00001592,
0x000015b0, 0x00001610,
} // Size: 512 bytes
0x0000109c, 0x000010ce, 0x00001165, 0x00001190,
0x000011c8, 0x000011f1, 0x00001229, 0x0000126a,
0x0000129a, 0x000012bd, 0x000012e5, 0x00001347,
0x00001353, 0x0000135f, 0x0000136f, 0x0000137f,
0x0000138f, 0x000013b6, 0x000013f7, 0x0000141b,
0x0000142c, 0x0000144e, 0x0000147b, 0x000014a1,
0x00001500, 0x0000159d, 0x000015eb, 0x00001605,
0x00001623, 0x00001683,
} // Size: 528 bytes
const enData string = "" + // Size: 5648 bytes
const enData string = "" + // Size: 5763 bytes
"\x04\x00\x01 0\x02Use the arrow keys to navigate: ↓ ↑ → ←\x02This intera" +
"ctive tool creates a new miner actor and creates the basic configuration" +
" layer for it.\x02This process is partially idempotent. Once a new miner" +
@ -216,118 +221,120 @@ const enData string = "" + // Size: 5648 bytes
"e (%[1]s), if applicable.\x02New Miner initialization complete.\x02Migra" +
"ting lotus-miner config.toml to Curio in-database configuration.\x02Erro" +
"r getting API: %[1]s\x02could not get API info for FullNode: %[1]w\x02Er" +
"ror getting token: %[1]s\x02Error saving config to layer: %[1]s. Abortin" +
"g Migration\x02The Curio team wants to improve the software you use. Tel" +
"l the team you're using `%[1]s`.\x02Select what you want to share with t" +
"he Curio team.\x02Individual Data: Miner ID, Curio version, chain (%[1]s" +
" or %[2]s). Signed.\x02Aggregate-Anonymous: version, chain, and Miner po" +
"wer (bucketed).\x02Hint: I am someone running Curio on whichever chain." +
"\x02Nothing.\x02Error getting miner power: %[1]s\x02Error marshalling me" +
"ssage: %[1]s\x02Error getting miner info: %[1]s\x02Error signing message" +
": %[1]s\x02Error sending message: %[1]s\x04\x00\x01 .\x02Error sending m" +
"essage: Status %[1]s, Message:\x02Message sent.\x04\x00\x01 \x0f\x02Docu" +
"mentation:\x02The '%[1]s' layer stores common configuration. All curio i" +
"nstances can include it in their %[2]s argument.\x02You can add other la" +
"yers for per-machine configuration changes.\x02Filecoin %[1]s channels: " +
"%[2]s and %[3]s\x02Increase reliability using redundancy: start multiple" +
" machines with at-least the post layer: 'curio run --layers=post'\x02One" +
" database can serve multiple miner IDs: Run a migration for each lotus-m" +
"iner.\x02Please start (or restart) %[1]s now that database credentials a" +
"re in %[2]s.\x02Waiting for %[1]s to write sectors into Yugabyte.\x02Err" +
"or interpreting miner ID: %[1]s: ID: %[2]s\x02Error verifying sectors: %" +
"[1]s\x02The sectors are in the database. The database is ready for %[1]s" +
".\x02Now shut down lotus-miner and lotus-worker and use run %[1]s instea" +
"d.\x02Press return to continue\x02Aborting migration.\x02Sectors verifie" +
"d. %[1]d sector locations found.\x02Connected to Yugabyte. Schema is cur" +
"rent.\x02Enabling Sector Indexing in the database.\x02Error encoding con" +
"fig.toml: %[1]s\x02Press return to update %[1]s with Yugabyte info. A Ba" +
"ckup file will be written to that folder before changes are made.\x02Err" +
"or expanding path: %[1]s\x02Error reading filemode of config.toml: %[1]s" +
"\x02Error creating backup file: %[1]s\x02Error reading config.toml: %[1]" +
"s\x02Error writing backup file: %[1]s\x02Error closing backup file: %[1]" +
"s\x02Error writing config.toml: %[1]s\x04\x00\x01 \x15\x02Restart Lotus " +
"Miner.\x02Connected to Yugabyte\x02To start, ensure your sealing pipelin" +
"e is drained and shut-down lotus-miner.\x02Select the location of your l" +
"otus-miner config directory?\x02Other\x02Enter the path to the configura" +
"tion directory used by %[1]s\x04\x00\x01 '\x02No path provided, abandoni" +
"ng migration\x02Cannot read the config.toml file in the provided directo" +
"ry, Error: %[1]s\x02Could not create repo from directory: %[1]s. Abortin" +
"g migration\x02Could not lock miner repo. Your miner must be stopped: %[" +
"1]s\x0a Aborting migration\x02Read Miner Config\x04\x00\x01\x0a\x15\x02S" +
"tep Complete: %[1]s\x02Initializing a new miner actor.\x02Enter the info" +
" to create a new miner\x02Owner Address: %[1]s\x02Worker Address: %[1]s" +
"\x02Sender Address: %[1]s\x02Sector Size: %[1]d\x02Confidence epochs: %[" +
"1]d\x02Continue to verify the addresses and create a new miner actor." +
"\x04\x00\x01 %\x02Miner creation error occurred: %[1]s\x02Enter the owne" +
"r address\x02No address provided\x02Failed to parse the address: %[1]s" +
"\x02Enter %[1]s address\x02Enter the sector size\x02No value provided" +
"\x02Failed to parse sector size: %[1]s\x02Confidence epochs\x02Failed to" +
" parse confidence: %[1]s\x02Failed to create the miner actor: %[1]s\x02M" +
"iner %[1]s created successfully\x02Cannot reach the DB: %[1]s\x02Error c" +
"onnecting to full node API: %[1]s\x02Pre-initialization steps complete" +
"\x02Failed to generate random bytes for secret: %[1]s\x02Please do not r" +
"un guided-setup again as miner creation is not idempotent. You need to r" +
"un 'curio config new-cluster %[1]s' to finish the configuration\x02Faile" +
"d to get API info for FullNode: %[1]w\x02Failed to verify the auth token" +
" from daemon node: %[1]s\x02Failed to generate default config: %[1]s\x02" +
"Failed to insert 'base' config layer in database: %[1]s\x02Configuration" +
" 'base' was updated to include this miner's address\x02Failed to load ba" +
"se config from database: %[1]s\x02Failed to parse base config: %[1]s\x02" +
"Failed to regenerate base config: %[1]s\x02Enter the info to connect to " +
"your Yugabyte database installation (https://download.yugabyte.com/)\x02" +
"Host: %[1]s\x02Port: %[1]s\x02Username: %[1]s\x02Password: %[1]s\x02Data" +
"base: %[1]s\x02Continue to connect and update schema.\x04\x00\x01 <\x02D" +
"atabase config error occurred, abandoning migration: %[1]s\x02Enter the " +
"Yugabyte database host(s)\x02No host provided\x02Enter the Yugabyte data" +
"base %[1]s\x02Error connecting to Yugabyte database: %[1]s\x02Configurat" +
"ion 'base' was updated to include this miner's address (%[1]s) and its w" +
"allet setup.\x02Compare the configurations %[1]s to %[2]s. Changes betwe" +
"en the miner IDs other than wallet addreses should be a new, minimal lay" +
"er for runners that need it.\x02Configuration 'base' was created to rese" +
"mble this lotus-miner's config.toml .\x04\x00\x01 \x15\x02Layer %[1]s cr" +
"eated.\x04\x00\x01 \x19\x02To work with the config:\x02To run Curio: Wit" +
"h machine or cgroup isolation, use the command (with example layer selec" +
"tion):"
"ror getting token: %[1]s\x02Unmigratable sectors found. Do you want to c" +
"ontinue?\x02Yes, continue\x02No, abort\x02Aborting migration.\x02Error s" +
"aving config to layer: %[1]s. Aborting Migration\x02The Curio team wants" +
" to improve the software you use. Tell the team you're using `%[1]s`." +
"\x02Select what you want to share with the Curio team.\x02Individual Dat" +
"a: Miner ID, Curio version, chain (%[1]s or %[2]s). Signed.\x02Aggregate" +
"-Anonymous: version, chain, and Miner power (bucketed).\x02Hint: I am so" +
"meone running Curio on whichever chain.\x02Nothing.\x02Error getting min" +
"er power: %[1]s\x02Error marshalling message: %[1]s\x02Error getting min" +
"er info: %[1]s\x02Error signing message: %[1]s\x02Error sending message:" +
" %[1]s\x04\x00\x01 .\x02Error sending message: Status %[1]s, Message:" +
"\x02Message sent.\x04\x00\x01 \x0f\x02Documentation:\x02The '%[1]s' laye" +
"r stores common configuration. All curio instances can include it in the" +
"ir %[2]s argument.\x02You can add other layers for per-machine configura" +
"tion changes.\x02Filecoin %[1]s channels: %[2]s and %[3]s\x02Increase re" +
"liability using redundancy: start multiple machines with at-least the po" +
"st layer: 'curio run --layers=post'\x02One database can serve multiple m" +
"iner IDs: Run a migration for each lotus-miner.\x02Please start (or rest" +
"art) %[1]s now that database credentials are in %[2]s.\x02Waiting for %[" +
"1]s to write sectors into Yugabyte.\x02Error interpreting miner ID: %[1]" +
"s: ID: %[2]s\x02Error verifying sectors: %[1]s\x02The sectors are in the" +
" database. The database is ready for %[1]s.\x02Now shut down lotus-miner" +
" and lotus-worker and use run %[1]s instead.\x02Press return to continue" +
"\x02Sectors verified. %[1]d sector locations found.\x02Connected to Yuga" +
"byte. Schema is current.\x02Enabling Sector Indexing in the database." +
"\x02Error encoding config.toml: %[1]s\x02Press return to update %[1]s wi" +
"th Yugabyte info. A Backup file will be written to that folder before ch" +
"anges are made.\x02Error expanding path: %[1]s\x02Error reading filemode" +
" of config.toml: %[1]s\x02Error creating backup file: %[1]s\x02Error rea" +
"ding config.toml: %[1]s\x02Error writing backup file: %[1]s\x02Error clo" +
"sing backup file: %[1]s\x02Error writing config.toml: %[1]s\x04\x00\x01 " +
"\x15\x02Restart Lotus Miner.\x02Connected to Yugabyte\x02To start, ensur" +
"e your sealing pipeline is drained and shut-down lotus-miner.\x02Select " +
"the location of your lotus-miner config directory?\x02Other\x02Enter the" +
" path to the configuration directory used by %[1]s\x04\x00\x01 '\x02No p" +
"ath provided, abandoning migration\x02Cannot read the config.toml file i" +
"n the provided directory, Error: %[1]s\x02Could not create repo from dir" +
"ectory: %[1]s. Aborting migration\x02Could not lock miner repo. Your min" +
"er must be stopped: %[1]s\x0a Aborting migration\x02Read Miner Config" +
"\x04\x00\x01\x0a\x15\x02Step Complete: %[1]s\x02Initializing a new miner" +
" actor.\x02Enter the info to create a new miner\x02Owner Address: %[1]s" +
"\x02Worker Address: %[1]s\x02Sender Address: %[1]s\x02Sector Size: %[1]d" +
"\x02Confidence epochs: %[1]d\x02Continue to verify the addresses and cre" +
"ate a new miner actor.\x04\x00\x01 %\x02Miner creation error occurred: %" +
"[1]s\x02Enter the owner address\x02No address provided\x02Failed to pars" +
"e the address: %[1]s\x02Enter %[1]s address\x02Enter the sector size\x02" +
"No value provided\x02Failed to parse sector size: %[1]s\x02Confidence ep" +
"ochs\x02Failed to parse confidence: %[1]s\x02Failed to create the miner " +
"actor: %[1]s\x02Miner %[1]s created successfully\x02Cannot reach the DB:" +
" %[1]s\x02Error connecting to full node API: %[1]s\x02Pre-initialization" +
" steps complete\x02Failed to generate random bytes for secret: %[1]s\x02" +
"Please do not run guided-setup again as miner creation is not idempotent" +
". You need to run 'curio config new-cluster %[1]s' to finish the configu" +
"ration\x02Failed to get API info for FullNode: %[1]w\x02Failed to verify" +
" the auth token from daemon node: %[1]s\x02Failed to generate default co" +
"nfig: %[1]s\x02Failed to insert 'base' config layer in database: %[1]s" +
"\x02Configuration 'base' was updated to include this miner's address\x02" +
"Failed to load base config from database: %[1]s\x02Failed to parse base " +
"config: %[1]s\x02Failed to regenerate base config: %[1]s\x02Enter the in" +
"fo to connect to your Yugabyte database installation (https://download.y" +
"ugabyte.com/)\x02Host: %[1]s\x02Port: %[1]s\x02Username: %[1]s\x02Passwo" +
"rd: %[1]s\x02Database: %[1]s\x02Continue to connect and update schema." +
"\x04\x00\x01 <\x02Database config error occurred, abandoning migration: " +
"%[1]s\x02Enter the Yugabyte database host(s)\x02No host provided\x02Ente" +
"r the Yugabyte database %[1]s\x02Error connecting to Yugabyte database: " +
"%[1]s\x02Migrating metadata for %[1]d sectors.\x02Configuration 'base' w" +
"as updated to include this miner's address (%[1]s) and its wallet setup." +
"\x02Compare the configurations %[1]s to %[2]s. Changes between the miner" +
" IDs other than wallet addreses should be a new, minimal layer for runne" +
"rs that need it.\x02Configuration 'base' was created to resemble this lo" +
"tus-miner's config.toml .\x04\x00\x01 \x15\x02Layer %[1]s created.\x04" +
"\x00\x01 \x19\x02To work with the config:\x02To run Curio: With machine " +
"or cgroup isolation, use the command (with example layer selection):"
var koIndex = []uint32{ // 122 elements
var koIndex = []uint32{ // 126 elements
// Entry 0 - 1F
0x00000000, 0x00000044, 0x000000c1, 0x000001c1,
0x0000020e, 0x00000289, 0x000002aa, 0x000002bc,
0x000002e5, 0x00000300, 0x00000325, 0x00000348,
0x000003b2, 0x00000402, 0x00000428, 0x00000481,
0x000004a0, 0x000004dc, 0x0000050c, 0x00000564,
0x000005f0, 0x00000629, 0x0000067f, 0x000006bd,
0x0000070b, 0x00000726, 0x00000760, 0x00000793,
0x000007cd, 0x000007f7, 0x00000821, 0x00000863,
0x000004a0, 0x000004dc, 0x0000050c, 0x0000055c,
0x00000568, 0x0000057a, 0x00000595, 0x000005ed,
0x00000679, 0x000006b2, 0x00000708, 0x00000746,
0x00000794, 0x000007af, 0x000007e9, 0x0000081c,
// Entry 20 - 3F
0x00000887, 0x00000894, 0x0000091a, 0x0000096c,
0x00000993, 0x00000a2f, 0x00000ac1, 0x00000b3c,
0x00000b80, 0x00000bbe, 0x00000be5, 0x00000c50,
0x00000c9d, 0x00000cc4, 0x00000cdf, 0x00000d2e,
0x00000d6f, 0x00000daf, 0x00000df6, 0x00000e9c,
0x00000ecc, 0x00000f1b, 0x00000f3e, 0x00000f5f,
0x00000f82, 0x00000fa5, 0x00000fe3, 0x00001007,
0x0000101d, 0x00001088, 0x000010d7, 0x000010de,
0x00000856, 0x00000880, 0x000008aa, 0x000008ec,
0x00000910, 0x0000091d, 0x000009a3, 0x000009f5,
0x00000a1c, 0x00000ab8, 0x00000b4a, 0x00000bc5,
0x00000c09, 0x00000c47, 0x00000c6e, 0x00000cd9,
0x00000d26, 0x00000d4d, 0x00000d9c, 0x00000ddd,
0x00000e1d, 0x00000e64, 0x00000f0a, 0x00000f3a,
0x00000f89, 0x00000fac, 0x00000fcd, 0x00000ff0,
0x00001013, 0x00001051, 0x00001075, 0x0000108b,
// Entry 40 - 5F
0x00001126, 0x00001178, 0x000011d2, 0x0000123c,
0x000012cd, 0x000012e5, 0x000012ff, 0x00001323,
0x00001356, 0x0000136e, 0x00001386, 0x0000139e,
0x000013b3, 0x000013cb, 0x00001422, 0x0000144d,
0x00001465, 0x0000148c, 0x000014af, 0x000014c3,
0x000014d8, 0x000014fc, 0x00001526, 0x00001537,
0x0000155d, 0x00001583, 0x000015bc, 0x000015f4,
0x0000162c, 0x0000164b, 0x00001697, 0x00001755,
0x000010f6, 0x00001145, 0x0000114c, 0x00001194,
0x000011e6, 0x00001240, 0x000012aa, 0x0000133b,
0x00001353, 0x0000136d, 0x00001391, 0x000013c4,
0x000013dc, 0x000013f4, 0x0000140c, 0x00001421,
0x00001439, 0x00001490, 0x000014bb, 0x000014d3,
0x000014fa, 0x0000151d, 0x00001531, 0x00001546,
0x0000156a, 0x00001594, 0x000015a5, 0x000015cb,
0x000015f1, 0x0000162a, 0x00001662, 0x0000169a,
// Entry 60 - 7F
0x000017a1, 0x000017ef, 0x00001812, 0x0000186e,
0x000018be, 0x00001913, 0x00001956, 0x00001995,
0x00001a03, 0x00001a14, 0x00001a22, 0x00001a3a,
0x00001a4e, 0x00001a68, 0x00001a92, 0x00001af5,
0x00001b31, 0x00001b5b, 0x00001b93, 0x00001be7,
0x00001c60, 0x00001d1a, 0x00001d71, 0x00001da0,
0x00001dc7, 0x00001e53,
} // Size: 512 bytes
0x000016b9, 0x00001705, 0x000017c3, 0x0000180f,
0x0000185d, 0x00001880, 0x000018dc, 0x0000192c,
0x00001981, 0x000019c4, 0x00001a03, 0x00001a71,
0x00001a82, 0x00001a90, 0x00001aa8, 0x00001abc,
0x00001ad6, 0x00001b00, 0x00001b63, 0x00001b9f,
0x00001bc9, 0x00001c01, 0x00001c55, 0x00001c8d,
0x00001d06, 0x00001dc0, 0x00001e17, 0x00001e46,
0x00001e6d, 0x00001ef9,
} // Size: 528 bytes
const koData string = "" + // Size: 7763 bytes
const koData string = "" + // Size: 7929 bytes
"\x04\x00\x01 ?\x02화살표 키를 사용하여 이동하세요: ↓ ↑ → ←\x02이 대화형 도구는 새로운 채굴자 액터를 생성" +
"하고 그에 대한 기본 구성 레이어를 생성합니다.\x02이 프로세스는 부분적으로 항등원적입니다. 새로운 채굴자 액터가 생성되었고" +
" 후속 단계가 실패하는 경우 사용자는 구성을 완료하기 위해 'curio config new-cluster < 채굴자 ID >'를 " +
@ -337,98 +344,100 @@ const koData string = "" + // Size: 7763 bytes
"s-Miner에서 Curio로 이주.\x02%[1]s를 사용하여 웹 인터페이스를 시도하고 더 나은 안내된 개선을 진행하세요." +
"\x02해당하는 경우 이제 시장 노드를 이주할 수 있습니다 (%[1]s).\x02새로운 채굴자 초기화 완료.\x02lotus-mi" +
"ner config.toml을 Curio의 데이터베이스 구성으로 이전 중입니다.\x02API 가져오기 오류: %[1]s\x02Fu" +
"llNode의 API 정보를 가져올 수 없습니다: %[1]w\x02토큰을 가져오는 중 오류 발생: %[1]s\x02레이어에 구성을" +
" 저장하는 중 오류 발생: %[1]s. 마이그레이션 중단\x02Curio 팀은 당신이 사용하는 소프트웨어를 개선하고자 합니다. 팀" +
"에게 `%[1]s`를 사용 중이라고 알려주세요.\x02Curio 팀과 공유하고 싶은 것을 선택하세요.\x02개별 데이터: 채굴" +
"자 ID, Curio 버전, 체인 (%[1]s 또는 %[2]s). 서명됨.\x02집계-익명: 버전, 체인, 및 채굴자 파워 (" +
"버킷).\x02힌트: 나는 어떤 체인에서든 Curio를 실행 중인 사람입니다.\x02아무것도 없습니다.\x02마이너 파워를 가" +
"져오는 중 오류 발생: %[1]s\x02메시지를 마샬하는 중 오류 발생: %[1]s\x02마이너 정보를 가져오는 중 오류 발생" +
": %[1]s\x02메시지 서명 중 오류 발생: %[1]s\x02메시지 전송 중 오류 발생: %[1]s\x04\x00\x01 =" +
"\x02메시지 전송 중 오류 발생: 상태 %[1]s, 메시지:\x02메시지가 전송되었습니다.\x04\x00\x01 \x08\x02" +
"문서:\x02'%[1]s' 레이어에는 공통 구성이 저장됩니다. 모든 Curio 인스턴스는 %[2]s 인수에 포함시킬 수 있습니" +
"다.\x02기계별 구성 변경을 위해 다른 레이어를 추가할 수 있습니다.\x02Filecoin %[1]s 채널: %[2]s 및 " +
"%[3]s\x02신뢰성 향상을 위한 중복성 사용: 적어도 post 레이어를 사용하여 여러 대의 기계를 시작하십시오: 'curio " +
"run --layers=post'\x02한 개의 데이터베이스는 여러 광부 ID를 제공할 수 있습니다: 각 lotus-miner에 " +
"대해 마이그레이션을 실행하세요.\x02데이터베이스 자격 증명이 %[2]s에 입력되었으므로 지금 %[1]s을 시작하거나 다시 시" +
"작하세요.\x02%[1]s가 Yugabyte에 섹터를 기록하도록 대기 중입니다.\x02광부 ID를 해석하는 중 오류 발생: %" +
"[1]s: ID: %[2]s\x02섹터 확인 중 오류 발생: %[1]s\x02섹터가 데이터베이스에 있습니다. 데이터베이스가 %[1" +
"]s를 위해 준비되었습니다.\x02이제 lotus-miner와 lotus-worker를 종료하고 %[1]s을 실행하세요.\x02계" +
"속하려면 리턴을 누르세요\x02마이그레이션 중단.\x02섹터가 확인되었습니다. %[1]d개의 섹터 위치를 찾았습니다.\x02Y" +
"ugabyte에 연결되었습니다. 스키마가 현재입니다.\x02데이터베이스에서 Sector Indexing을 활성화합니다.\x02co" +
"nfig.toml을 인코딩하는 중 오류가 발생했습니다: %[1]s\x02%[1]s을 Yugabyte 정보로 업데이트하려면 리턴 키" +
"를 누르세요. 변경 사항을 적용하기 전에 해당 폴더에 백업 파일이 작성됩니다.\x02경로를 확장하는 중 오류 발생: %[1]s" +
"\x02config.toml의 파일 모드를 읽는 중 오류가 발생했습니다: %[1]s\x02백업 파일 생성 오류: %[1]s\x02" +
"config.toml 읽기 오류: %[1]s\x02백업 파일 쓰기 오류: %[1]s\x02백업 파일 닫기 오류: %[1]s\x02" +
"config.toml을 쓰는 중 오류가 발생했습니다: %[1]s\x04\x00\x01 \x1f\x02로터스 마이너 재시작.\x02" +
"Yugabyte에 연결됨\x02시작하려면 밀봉 파이프라인이 비어 있고 lotus-miner가 종료되었는지 확인하세요.\x02로터스" +
" 마이너 구성 디렉토리의 위치를 선택하시겠습니까?\x02기타\x02%[1]s에서 사용하는 구성 디렉터리 경로를 입력하세요.\x04" +
"\x00\x01 M\x02경로가 제공되지 않았으므로 마이그레이션을 포기합니다\x02제공된 디렉토리에서 config.toml 파일을" +
" 읽을 수 없습니다. 오류: %[1]s\x02디렉토리에서 저장소를 생성할 수 없습니다: %[1]s. 마이그레이션을 중단합니다." +
"\x02광부 저장소를 잠금 해제할 수 없습니다. 귀하의 광부를 중지해야 합니다: %[1]s\x0a 마이그레이션을 중단합니다." +
"\x02마이너 구성 읽기\x04\x00\x01\x0a\x15\x02단계 완료: %[1]s\x02새 채굴자 액터 초기화 중.\x02" +
"새 채굴자를 생성하기 위한 정보 입력\x02소유자 주소: %[1]s\x02작업자 주소: %[1]s\x02송신자 주소: %[1]" +
"s\x02섹터 크기: %[1]d\x02신뢰 에포크: %[1]d\x02주소를 확인하고 새 채굴자 액터를 생성하려면 계속 진행하세요." +
"\x04\x00\x01 &\x02채굴자 생성 오류 발생: %[1]s\x02소유자 주소 입력\x02주소가 제공되지 않았습니다\x02" +
"주소 구문 분석 실패: %[1]s\x02%[1]s 주소 입력\x02섹터 크기 입력\x02값이 제공되지 않았습니다\x02섹터 크" +
"기 구문 분석 실패: %[1]s\x02신뢰 에포크\x02신뢰도 구문 분석 실패: %[1]s\x02채굴자 액터 생성 실패: %[" +
"1]s\x02%[1]s 채굴자가 성공적으로 생성되었습니다\x02데이터베이스에 연결할 수 없습니다: %[1]s\x02풀 노드 API" +
"에 연결하는 중 오류 발생: %[1]s\x02사전 초기화 단계 완료\x02비밀번호를 위한 랜덤 바이트 생성에 실패했습니다: %" +
"[1]s\x02마이너 생성은 idempotent하지 않으므로 가이드 설정을 다시 실행하지 마십시오. 구성을 완료하려면 'curio" +
" config new-cluster %[1]s'를 실행해야 합니다.\x02FullNode에 대한 API 정보를 가져오는 데 실패했" +
"습니다: %[1]w\x02데몬 노드로부터 인증 토큰을 확인하는 중 오류 발생: %[1]s\x02기본 구성 생성 실패: %[1]" +
"s\x02데이터베이스에 'base' 구성 레이어를 삽입하는 데 실패했습니다: %[1]s\x02이 마이너 주소를 포함한 구성 'ba" +
"se'가 업데이트되었습니다.\x02데이터베이스에서 기본 구성을 로드하는 데 실패했습니다: %[1]s\x02기본 구성을 구문 분석하" +
"는 데 실패했습니다: %[1]s\x02기본 구성을 재생성하는 데 실패했습니다: %[1]s\x02Yugabyte 데이터베이스 설" +
"치에 연결할 정보를 입력하십시오 (https://download.yugabyte.com/)\x02호스트: %[1]s\x02포트" +
": %[1]s\x02사용자 이름: %[1]s\x02비밀번호: %[1]s\x02데이터베이스: %[1]s\x02계속 연결 및 스키마 " +
"업데이트.\x04\x00\x01 ^\x02데이터베이스 구성 오류가 발생하여 마이그레이션을 포기합니다: %[1]s\x02Yuga" +
"byte 데이터베이스 호스트를 입력하십시오\x02호스트가 제공되지 않았습니다\x02Yugabyte 데이터베이스 %[1]s을 입력하" +
"십시오\x02Yugabyte 데이터베이스에 연결하는 중 오류가 발생했습니다: %[1]s\x02기본 설정 'base'가 이 마이" +
"너의 주소(%[1]s) 및 지갑 설정을 포함하도록 업데이트되었습니다.\x02구성 %[1]s를 %[2]s과 비교하세요. 지갑 주" +
"소 이외의 마이너 ID 사이의 변경 사항은 필요한 실행자를 위한 새로운 최소한의 레이어여야 합니다.\x02'base' 설정이 " +
"이 lotus-miner의 config.toml과 유사하게 만들어졌습니다.\x04\x00\x01 *\x02레이어 %[1]s가 " +
"생성되었습니다.\x04\x00\x01 \x22\x02구성 파일을 사용하려면:\x02Curio를 실행하려면: 기계 또는 cgro" +
"up 격리를 사용하여 다음 명령을 사용하세요 (예제 레이어 선택과 함께):"
"llNode의 API 정보를 가져올 수 없습니다: %[1]w\x02토큰을 가져오는 중 오류 발생: %[1]s\x02이동할 수 없는" +
" 섹터가 발견되었습니다. 계속하시겠습니까?\x02예, 계속\x02아니오, 중단\x02마이그레이션 중단.\x02레이어에 구성을 저장" +
"하는 중 오류 발생: %[1]s. 마이그레이션 중단\x02Curio 팀은 당신이 사용하는 소프트웨어를 개선하고자 합니다. 팀에" +
"게 `%[1]s`를 사용 중이라고 알려주세요.\x02Curio 팀과 공유하고 싶은 것을 선택하세요.\x02개별 데이터: 채굴자" +
" ID, Curio 버전, 체인 (%[1]s 또는 %[2]s). 서명됨.\x02집계-익명: 버전, 체인, 및 채굴자 파워 (버킷)" +
".\x02힌트: 나는 어떤 체인에서든 Curio를 실행 중인 사람입니다.\x02아무것도 없습니다.\x02마이너 파워를 가져오는 중" +
" 오류 발생: %[1]s\x02메시지를 마샬하는 중 오류 발생: %[1]s\x02마이너 정보를 가져오는 중 오류 발생: %[1]s" +
"\x02메시지 서명 중 오류 발생: %[1]s\x02메시지 전송 중 오류 발생: %[1]s\x04\x00\x01 =\x02메시지 " +
"전송 중 오류 발생: 상태 %[1]s, 메시지:\x02메시지가 전송되었습니다.\x04\x00\x01 \x08\x02문서:" +
"\x02'%[1]s' 레이어에는 공통 구성이 저장됩니다. 모든 Curio 인스턴스는 %[2]s 인수에 포함시킬 수 있습니다." +
"\x02기계별 구성 변경을 위해 다른 레이어를 추가할 수 있습니다.\x02Filecoin %[1]s 채널: %[2]s 및 %[3]" +
"s\x02신뢰성 향상을 위한 중복성 사용: 적어도 post 레이어를 사용하여 여러 대의 기계를 시작하십시오: 'curio run " +
"--layers=post'\x02한 개의 데이터베이스는 여러 광부 ID를 제공할 수 있습니다: 각 lotus-miner에 대해 마" +
"이그레이션을 실행하세요.\x02데이터베이스 자격 증명이 %[2]s에 입력되었으므로 지금 %[1]s을 시작하거나 다시 시작하세요" +
".\x02%[1]s가 Yugabyte에 섹터를 기록하도록 대기 중입니다.\x02광부 ID를 해석하는 중 오류 발생: %[1]s: " +
"ID: %[2]s\x02섹터 확인 중 오류 발생: %[1]s\x02섹터가 데이터베이스에 있습니다. 데이터베이스가 %[1]s를 위해" +
" 준비되었습니다.\x02이제 lotus-miner와 lotus-worker를 종료하고 %[1]s을 실행하세요.\x02계속하려면 리" +
"턴을 누르세요\x02섹터가 확인되었습니다. %[1]d개의 섹터 위치를 찾았습니다.\x02Yugabyte에 연결되었습니다. 스키" +
"마가 현재입니다.\x02데이터베이스에서 Sector Indexing을 활성화합니다.\x02config.toml을 인코딩하는 중" +
" 오류가 발생했습니다: %[1]s\x02%[1]s을 Yugabyte 정보로 업데이트하려면 리턴 키를 누르세요. 변경 사항을 적용하" +
"기 전에 해당 폴더에 백업 파일이 작성됩니다.\x02경로를 확장하는 중 오류 발생: %[1]s\x02config.toml의 파" +
"일 모드를 읽는 중 오류가 발생했습니다: %[1]s\x02백업 파일 생성 오류: %[1]s\x02config.toml 읽기 오" +
"류: %[1]s\x02백업 파일 쓰기 오류: %[1]s\x02백업 파일 닫기 오류: %[1]s\x02config.toml을 쓰" +
"는 중 오류가 발생했습니다: %[1]s\x04\x00\x01 \x1f\x02로터스 마이너 재시작.\x02Yugabyte에 연결" +
"됨\x02시작하려면 밀봉 파이프라인이 비어 있고 lotus-miner가 종료되었는지 확인하세요.\x02로터스 마이너 구성 디렉" +
"토리의 위치를 선택하시겠습니까?\x02기타\x02%[1]s에서 사용하는 구성 디렉터리 경로를 입력하세요.\x04\x00\x01" +
" M\x02경로가 제공되지 않았으므로 마이그레이션을 포기합니다\x02제공된 디렉토리에서 config.toml 파일을 읽을 수 없습" +
"니다. 오류: %[1]s\x02디렉토리에서 저장소를 생성할 수 없습니다: %[1]s. 마이그레이션을 중단합니다.\x02광부 저" +
"장소를 잠금 해제할 수 없습니다. 귀하의 광부를 중지해야 합니다: %[1]s\x0a 마이그레이션을 중단합니다.\x02마이너 구" +
"성 읽기\x04\x00\x01\x0a\x15\x02단계 완료: %[1]s\x02새 채굴자 액터 초기화 중.\x02새 채굴자를 " +
"생성하기 위한 정보 입력\x02소유자 주소: %[1]s\x02작업자 주소: %[1]s\x02송신자 주소: %[1]s\x02섹터" +
" 크기: %[1]d\x02신뢰 에포크: %[1]d\x02주소를 확인하고 새 채굴자 액터를 생성하려면 계속 진행하세요.\x04" +
"\x00\x01 &\x02채굴자 생성 오류 발생: %[1]s\x02소유자 주소 입력\x02주소가 제공되지 않았습니다\x02주소 구" +
"문 분석 실패: %[1]s\x02%[1]s 주소 입력\x02섹터 크기 입력\x02값이 제공되지 않았습니다\x02섹터 크기 구문" +
" 분석 실패: %[1]s\x02신뢰 에포크\x02신뢰도 구문 분석 실패: %[1]s\x02채굴자 액터 생성 실패: %[1]s" +
"\x02%[1]s 채굴자가 성공적으로 생성되었습니다\x02데이터베이스에 연결할 수 없습니다: %[1]s\x02풀 노드 API에 연" +
"결하는 중 오류 발생: %[1]s\x02사전 초기화 단계 완료\x02비밀번호를 위한 랜덤 바이트 생성에 실패했습니다: %[1]" +
"s\x02마이너 생성은 idempotent하지 않으므로 가이드 설정을 다시 실행하지 마십시오. 구성을 완료하려면 'curio co" +
"nfig new-cluster %[1]s'를 실행해야 합니다.\x02FullNode에 대한 API 정보를 가져오는 데 실패했습니다" +
": %[1]w\x02데몬 노드로부터 인증 토큰을 확인하는 중 오류 발생: %[1]s\x02기본 구성 생성 실패: %[1]s\x02" +
"데이터베이스에 'base' 구성 레이어를 삽입하는 데 실패했습니다: %[1]s\x02이 마이너 주소를 포함한 구성 'base'" +
"가 업데이트되었습니다.\x02데이터베이스에서 기본 구성을 로드하는 데 실패했습니다: %[1]s\x02기본 구성을 구문 분석하는" +
" 데 실패했습니다: %[1]s\x02기본 구성을 재생성하는 데 실패했습니다: %[1]s\x02Yugabyte 데이터베이스 설치에 " +
"연결할 정보를 입력하십시오 (https://download.yugabyte.com/)\x02호스트: %[1]s\x02포트: %" +
"[1]s\x02사용자 이름: %[1]s\x02비밀번호: %[1]s\x02데이터베이스: %[1]s\x02계속 연결 및 스키마 업데이" +
"트.\x04\x00\x01 ^\x02데이터베이스 구성 오류가 발생하여 마이그레이션을 포기합니다: %[1]s\x02Yugabyt" +
"e 데이터베이스 호스트를 입력하십시오\x02호스트가 제공되지 않았습니다\x02Yugabyte 데이터베이스 %[1]s을 입력하십시오" +
"\x02Yugabyte 데이터베이스에 연결하는 중 오류가 발생했습니다: %[1]s\x02%[1]d 섹터의 메타데이터를 이동 중입니" +
"다.\x02기본 설정 'base'가 이 마이너의 주소(%[1]s) 및 지갑 설정을 포함하도록 업데이트되었습니다.\x02구성 %" +
"[1]s를 %[2]s과 비교하세요. 지갑 주소 이외의 마이너 ID 사이의 변경 사항은 필요한 실행자를 위한 새로운 최소한의 레이어" +
"여야 합니다.\x02'base' 설정이 이 lotus-miner의 config.toml과 유사하게 만들어졌습니다.\x04" +
"\x00\x01 *\x02레이어 %[1]s가 생성되었습니다.\x04\x00\x01 \x22\x02구성 파일을 사용하려면:\x02C" +
"urio를 실행하려면: 기계 또는 cgroup 격리를 사용하여 다음 명령을 사용하세요 (예제 레이어 선택과 함께):"
var zhIndex = []uint32{ // 122 elements
var zhIndex = []uint32{ // 126 elements
// Entry 0 - 1F
0x00000000, 0x00000033, 0x0000008b, 0x00000134,
0x0000017c, 0x000001cb, 0x000001e4, 0x000001f1,
0x00000211, 0x0000022a, 0x00000240, 0x0000025d,
0x000002a5, 0x000002e6, 0x00000302, 0x00000347,
0x00000364, 0x0000038d, 0x000003ab, 0x000003e4,
0x00000438, 0x00000465, 0x000004b4, 0x000004ef,
0x00000524, 0x0000052e, 0x00000552, 0x00000570,
0x00000594, 0x000005b2, 0x000005d0, 0x00000605,
0x00000364, 0x0000038d, 0x000003ab, 0x000003df,
0x000003ef, 0x000003fc, 0x0000040c, 0x00000445,
0x00000499, 0x000004c6, 0x00000515, 0x00000550,
0x00000585, 0x0000058f, 0x000005b3, 0x000005d1,
// Entry 20 - 3F
0x00000618, 0x00000627, 0x00000681, 0x000006be,
0x000006e6, 0x00000745, 0x00000795, 0x000007e8,
0x0000080e, 0x0000083b, 0x00000859, 0x00000895,
0x000008d9, 0x000008e9, 0x000008f9, 0x0000092c,
0x00000959, 0x0000097e, 0x000009a1, 0x00000a19,
0x00000a37, 0x00000a66, 0x00000a8a, 0x00000aaf,
0x00000ad3, 0x00000af7, 0x00000b1a, 0x00000b3a,
0x00000b4f, 0x00000b9a, 0x00000bca, 0x00000bd1,
0x000005f5, 0x00000613, 0x00000631, 0x00000666,
0x00000679, 0x00000688, 0x000006e2, 0x0000071f,
0x00000747, 0x000007a6, 0x000007f6, 0x00000849,
0x0000086f, 0x0000089c, 0x000008ba, 0x000008f6,
0x0000093a, 0x0000094a, 0x0000097d, 0x000009aa,
0x000009cf, 0x000009f2, 0x00000a6a, 0x00000a88,
0x00000ab7, 0x00000adb, 0x00000b00, 0x00000b24,
0x00000b48, 0x00000b6b, 0x00000b8b, 0x00000ba0,
// Entry 40 - 5F
0x00000bfb, 0x00000c1f, 0x00000c63, 0x00000c95,
0x00000cde, 0x00000cf1, 0x00000d0b, 0x00000d2a,
0x00000d4f, 0x00000d67, 0x00000d7c, 0x00000d94,
0x00000da8, 0x00000dbf, 0x00000df0, 0x00000e15,
0x00000e2b, 0x00000e3b, 0x00000e55, 0x00000e69,
0x00000e7c, 0x00000e89, 0x00000ea9, 0x00000eb9,
0x00000ed6, 0x00000ef6, 0x00000f10, 0x00000f2d,
0x00000f5e, 0x00000f77, 0x00000fa0, 0x0000102d,
0x00000beb, 0x00000c1b, 0x00000c22, 0x00000c4c,
0x00000c70, 0x00000cb4, 0x00000ce6, 0x00000d2f,
0x00000d42, 0x00000d5c, 0x00000d7b, 0x00000da0,
0x00000db8, 0x00000dcd, 0x00000de5, 0x00000df9,
0x00000e10, 0x00000e41, 0x00000e66, 0x00000e7c,
0x00000e8c, 0x00000ea6, 0x00000eba, 0x00000ecd,
0x00000eda, 0x00000efa, 0x00000f0a, 0x00000f27,
0x00000f47, 0x00000f61, 0x00000f7e, 0x00000faf,
// Entry 60 - 7F
0x00001059, 0x00001094, 0x000010b4, 0x000010e5,
0x00001118, 0x00001145, 0x00001166, 0x0000118c,
0x000011e6, 0x000011f5, 0x00001204, 0x00001216,
0x00001225, 0x00001237, 0x00001256, 0x0000128e,
0x000012b3, 0x000012c3, 0x000012e1, 0x0000130d,
0x0000135e, 0x000013e0, 0x00001427, 0x00001441,
0x00001459, 0x000014b0,
} // Size: 512 bytes
0x00000fc8, 0x00000ff1, 0x0000107e, 0x000010aa,
0x000010e5, 0x00001105, 0x00001136, 0x00001169,
0x00001196, 0x000011b7, 0x000011dd, 0x00001237,
0x00001246, 0x00001255, 0x00001267, 0x00001276,
0x00001288, 0x000012a7, 0x000012df, 0x00001304,
0x00001314, 0x00001332, 0x0000135e, 0x00001388,
0x000013d9, 0x0000145b, 0x000014a2, 0x000014bc,
0x000014d4, 0x0000152b,
} // Size: 528 bytes
const zhData string = "" + // Size: 5296 bytes
const zhData string = "" + // Size: 5419 bytes
"\x04\x00\x01 .\x02使用箭头键进行导航↓ ↑ → ←\x02此交互式工具将创建一个新的矿工角色并为其创建基本配置层。\x02" +
"该过程部分幂等。一旦创建了新的矿工角色,并且随后的步骤失败,用户需要运行 'curio config new-cluster < 矿工 ID" +
" >' 来完成配置。\x02这个交互式工具可以在5分钟内将lotus-miner迁移到Curio。\x02每一步都需要您的确认并且可以撤销。随" +
@ -436,41 +445,42 @@ const zhData string = "" + // Size: 5296 bytes
"\x02中止剩余步骤。\x02Lotus-Miner到Curio迁移。\x02尝试使用%[1]s的网络界面进行更进一步的指导性改进。\x02如果" +
"适用,您现在可以迁移您的市场节点(%[1]s)。\x02新矿工初始化完成。\x02将 lotus-miner config.toml 迁移到" +
" Curio 的数据库配置中。\x02获取 API 时出错:%[1]s\x02无法获取FullNode的API信息%[1]w\x02获取令牌时" +
"出错:%[1]s\x02保存配置到层时出错%[1]s。正在中止迁移\x02Curio 团队希望改进您使用的软件。告诉团队您正在使用 `%[" +
"1]s`。\x02选择您想与Curio团队分享的内容。\x02个人数据矿工 IDCurio 版本,链(%[1]s 或 %[2]s。签名。" +
"\x02聚合-匿名:版本,链和矿工算力(分桶)。\x02提示我是在任何链上运行 Curio 的人。\x02没有。\x02获取矿工功率时出错%" +
"[1]s\x02整理消息时出错%[1]s\x02获取矿工信息时出错%[1]s\x02签署消息时出错%[1]s\x02发送消息时出错%[1" +
"]s\x04\x00\x01 0\x02发送消息时出错状态%[1]s消息\x02消息已发送。\x04\x00\x01 \x0a\x02文档" +
"\x02'%[1]s'层存储通用配置。所有Curio实例都可以在其%[2]s参数中包含它。\x02您可以添加其他层进行每台机器的配置更改。" +
"\x02Filecoin %[1]s 频道:%[2]s 和 %[3]s\x02通过冗余增加可靠性使用至少后层启动多台机器'curio run" +
" --layers=post'\x02一个数据库可以服务多个矿工ID为每个lotus-miner运行迁移。\x02请立即启动或重新启动%[" +
"1]s因为数据库凭据已在%[2]s中。\x02等待%[1]s将扇区写入Yugabyte。\x02解释矿工ID时出错%[1]sID%[2]" +
"s\x02验证扇区时出错%[1]s\x02扇区在数据库中。数据库已准备好用于%[1]s。\x02现在关闭lotus-miner和lotus-w" +
"orker改为使用%[1]s运行。\x02按回车继续\x02中止迁移。\x02扇区已验证。发现了%[1]d个扇区位置。\x02已连接到Yuga" +
"byte。模式是当前的。\x02在数据库中启用扇区索引。\x02编码config.toml时出错%[1]s\x02按回车键更新 %[1]s 以" +
"包含 Yugabyte 信息。在进行更改之前,将在该文件夹中写入备份文件。\x02扩展路径时出错%[1]s\x02读取config.tom" +
"l文件模式时出错%[1]s\x02创建备份文件时出错%[1]s\x02读取 config.toml 时出错:%[1]s\x02写入备份文件时" +
"出错:%[1]s\x02关闭备份文件时出错%[1]s\x02写入config.toml时出错%[1]s\x04\x00\x01 \x1b" +
"\x02重新启动Lotus Miner。\x02已连接到Yugabyte\x02开始之前请确保您的密封管道已排空并关闭lotus-miner。" +
"\x02选择您的lotus-miner配置目录的位置\x02其他\x02输入%[1]s使用的配置目录的路径\x04\x00\x01 \x1f" +
"\x02未提供路径放弃迁移\x02无法读取提供的目录中的config.toml文件错误%[1]s\x02无法从目录创建repo%[1]s" +
"。 中止迁移\x02无法锁定矿工repo。 您的矿工必须停止:%[1]s\x0a 中止迁移\x02读取矿工配置\x04\x00\x01" +
"\x0a\x15\x02步骤完成%[1]s\x02初始化新的矿工角色。\x02输入创建新矿工所需的信息\x02所有者地址%[1]s\x02工" +
"作地址:%[1]s\x02发送者地址%[1]s\x02扇区大小: %[1]d\x02置信度时期: %[1]d\x02继续验证地址并创建新的" +
"矿工角色。\x04\x00\x01 \x02矿工创建错误发生: %[1]s\x02输入所有者地址\x02未提供地址\x02解析地址失败: " +
"%[1]s\x02输入 %[1]s 地址\x02输入扇区大小\x02未提供值\x02解析扇区大小失败: %[1]s\x02置信度时期\x02解析" +
"置信度失败: %[1]s\x02创建矿工角色失败: %[1]s\x02矿工 %[1]s 创建成功\x02无法访问数据库: %[1]s\x02" +
"连接到完整节点 API 时发生错误: %[1]s\x02预初始化步骤完成\x02生成密码的随机字节失败: %[1]s\x02请不要再次运行引" +
"导设置,因为矿工创建不是幂等的。 您需要运行 'curio config new-cluster %[1]s' 来完成配置。\x02无法获取" +
" FullNode 的 API 信息: %[1]w\x02无法验证来自守护进程节点的授权令牌: %[1]s\x02无法生成默认配置: %[1]s" +
"\x02无法将 'base' 配置层插入数据库: %[1]s\x02配置 'base' 已更新以包含此矿工的地址\x02从数据库加载基本配置失败" +
"%[1]s\x02解析基本配置失败%[1]s\x02重新生成基本配置失败: %[1]s\x02输入连接到您的Yugabyte数据库安装的" +
"信息https://download.yugabyte.com/\x02主机%[1]s\x02端口%[1]s\x02用户名%[1]" +
"s\x02密码%[1]s\x02数据库%[1]s\x02继续连接和更新架构。\x04\x00\x01 3\x02发生数据库配置错误放弃迁移" +
"%[1]s\x02输入Yugabyte数据库主机S\x02未提供主机\x02输入Yugabyte数据库 %[1]s\x02连接到Yug" +
"abyte数据库时出错%[1]s\x02'base'配置已更新,包括该矿工的地址(%[1]s及其钱包设置。\x02比较配置%[1]s和%[2" +
"]s。矿工ID之间除了钱包地址的变化应该是需要的运行者的一个新的、最小的层。\x02'base'配置已创建以类似于这个lotus-miner的" +
"config.toml。\x04\x00\x01 \x15\x02层%[1]s已创建。\x04\x00\x01 \x13\x02要使用配置" +
"\x02运行Curio使用机器或cgroup隔离使用命令附带示例层选择"
"出错:%[1]s\x02发现无法迁移的扇区。您想要继续吗\x02是的继续\x02不中止\x02中止迁移。\x02保存配置到层时出错%" +
"[1]s。正在中止迁移\x02Curio 团队希望改进您使用的软件。告诉团队您正在使用 `%[1]s`。\x02选择您想与Curio团队分享的内" +
"容。\x02个人数据矿工 IDCurio 版本,链(%[1]s 或 %[2]s。签名。\x02聚合-匿名:版本,链和矿工算力(分桶)。" +
"\x02提示我是在任何链上运行 Curio 的人。\x02没有。\x02获取矿工功率时出错%[1]s\x02整理消息时出错%[1]s" +
"\x02获取矿工信息时出错%[1]s\x02签署消息时出错%[1]s\x02发送消息时出错%[1]s\x04\x00\x01 0\x02发" +
"送消息时出错:状态%[1]s消息\x02消息已发送。\x04\x00\x01 \x0a\x02文档\x02'%[1]s'层存储通用配置" +
"。所有Curio实例都可以在其%[2]s参数中包含它。\x02您可以添加其他层进行每台机器的配置更改。\x02Filecoin %[1]s " +
"频道:%[2]s 和 %[3]s\x02通过冗余增加可靠性使用至少后层启动多台机器'curio run --layers=post'" +
"\x02一个数据库可以服务多个矿工ID为每个lotus-miner运行迁移。\x02请立即启动或重新启动%[1]s因为数据库凭据已在%[" +
"2]s中。\x02等待%[1]s将扇区写入Yugabyte。\x02解释矿工ID时出错%[1]sID%[2]s\x02验证扇区时出错%[" +
"1]s\x02扇区在数据库中。数据库已准备好用于%[1]s。\x02现在关闭lotus-miner和lotus-worker改为使用%[1]s" +
"运行。\x02按回车继续\x02扇区已验证。发现了%[1]d个扇区位置。\x02已连接到Yugabyte。模式是当前的。\x02在数据库中启" +
"用扇区索引。\x02编码config.toml时出错%[1]s\x02按回车键更新 %[1]s 以包含 Yugabyte 信息。在进行更改" +
"之前,将在该文件夹中写入备份文件。\x02扩展路径时出错%[1]s\x02读取config.toml文件模式时出错%[1]s\x02创建" +
"备份文件时出错:%[1]s\x02读取 config.toml 时出错:%[1]s\x02写入备份文件时出错%[1]s\x02关闭备份文件" +
"时出错:%[1]s\x02写入config.toml时出错%[1]s\x04\x00\x01 \x1b\x02重新启动Lotus Mine" +
"r。\x02已连接到Yugabyte\x02开始之前请确保您的密封管道已排空并关闭lotus-miner。\x02选择您的lotus-mine" +
"r配置目录的位置\x02其他\x02输入%[1]s使用的配置目录的路径\x04\x00\x01 \x1f\x02未提供路径放弃迁移\x02无" +
"法读取提供的目录中的config.toml文件错误%[1]s\x02无法从目录创建repo%[1]s。 中止迁移\x02无法锁定矿工r" +
"epo。 您的矿工必须停止:%[1]s\x0a 中止迁移\x02读取矿工配置\x04\x00\x01\x0a\x15\x02步骤完成%[1]s" +
"\x02初始化新的矿工角色。\x02输入创建新矿工所需的信息\x02所有者地址%[1]s\x02工作地址%[1]s\x02发送者地址%[1" +
"]s\x02扇区大小: %[1]d\x02置信度时期: %[1]d\x02继续验证地址并创建新的矿工角色。\x04\x00\x01 \x02矿" +
"工创建错误发生: %[1]s\x02输入所有者地址\x02未提供地址\x02解析地址失败: %[1]s\x02输入 %[1]s 地址\x02" +
"输入扇区大小\x02未提供值\x02解析扇区大小失败: %[1]s\x02置信度时期\x02解析置信度失败: %[1]s\x02创建矿工角色" +
"失败: %[1]s\x02矿工 %[1]s 创建成功\x02无法访问数据库: %[1]s\x02连接到完整节点 API 时发生错误: %[1" +
"]s\x02预初始化步骤完成\x02生成密码的随机字节失败: %[1]s\x02请不要再次运行引导设置因为矿工创建不是幂等的。 您需要运行 '" +
"curio config new-cluster %[1]s' 来完成配置。\x02无法获取 FullNode 的 API 信息: %[1]w" +
"\x02无法验证来自守护进程节点的授权令牌: %[1]s\x02无法生成默认配置: %[1]s\x02无法将 'base' 配置层插入数据库: " +
"%[1]s\x02配置 'base' 已更新以包含此矿工的地址\x02从数据库加载基本配置失败%[1]s\x02解析基本配置失败%[1]s" +
"\x02重新生成基本配置失败: %[1]s\x02输入连接到您的Yugabyte数据库安装的信息https://download.yugaby" +
"te.com/\x02主机%[1]s\x02端口%[1]s\x02用户名%[1]s\x02密码%[1]s\x02数据库%[1]s" +
"\x02继续连接和更新架构。\x04\x00\x01 3\x02发生数据库配置错误放弃迁移%[1]s\x02输入Yugabyte数据库主机" +
"S\x02未提供主机\x02输入Yugabyte数据库 %[1]s\x02连接到Yugabyte数据库时出错%[1]s\x02正在迁移%[1" +
"]d个扇区的元数据。\x02'base'配置已更新,包括该矿工的地址(%[1]s及其钱包设置。\x02比较配置%[1]s和%[2]s。矿工ID" +
"之间除了钱包地址的变化应该是需要的运行者的一个新的、最小的层。\x02'base'配置已创建以类似于这个lotus-miner的confi" +
"g.toml。\x04\x00\x01 \x15\x02层%[1]s已创建。\x04\x00\x01 \x13\x02要使用配置\x02运行C" +
"urio使用机器或cgroup隔离使用命令附带示例层选择"
// Total table size 20243 bytes (19KiB); checksum: AB52E150
// Total table size 20695 bytes (20KiB); checksum: BB5CCE20

View File

@ -187,6 +187,44 @@
],
"fuzzy": true
},
{
"id": "Unmigratable sectors found. Do you want to continue?",
"message": "Unmigratable sectors found. Do you want to continue?",
"translation": "Unmigratable sectors found. Do you want to continue?",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Yes, continue",
"message": "Yes, continue",
"translation": "Yes, continue",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "No, abort",
"message": "No, abort",
"translation": "No, abort",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Aborting migration.",
"message": "Aborting migration.",
"translation": "Aborting migration.",
"translatorComment": "Copied from source.",
"placeholders": [
{
"id": "Error",
"string": "%[1]v",
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "err.Error()"
}
],
"fuzzy": true
},
{
"id": "Error saving config to layer: {Error}. Aborting Migration",
"message": "Error saving config to layer: {Error}. Aborting Migration",
@ -602,13 +640,6 @@
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Aborting migration.",
"message": "Aborting migration.",
"translation": "Aborting migration.",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "Sectors verified. {I} sector locations found.",
"message": "Sectors verified. {I} sector locations found.",
@ -1552,6 +1583,23 @@
],
"fuzzy": true
},
{
"id": "Migrating metadata for {NSectors} sectors.",
"message": "Migrating metadata for {NSectors} sectors.",
"translation": "Migrating metadata for {NSectors} sectors.",
"translatorComment": "Copied from source.",
"placeholders": [
{
"id": "NSectors",
"string": "%[1]d",
"type": "int",
"underlyingType": "int",
"argNum": 1,
"expr": "nSectors"
}
],
"fuzzy": true
},
{
"id": "Configuration 'base' was updated to include this miner's address ({MinerAddress}) and its wallet setup.",
"message": "Configuration 'base' was updated to include this miner's address ({MinerAddress}) and its wallet setup.",

View File

@ -1101,6 +1101,30 @@
"translation": "'base' 설정이 이 lotus-miner의 config.toml과 유사하게 만들어졌습니다.",
"message": "Configuration 'base' was created to resemble this lotus-miner's config.toml .",
"placeholder": null
},
{
"id": "Unmigratable sectors found. Do you want to continue?",
"translation": "이동할 수 없는 섹터가 발견되었습니다. 계속하시겠습니까?",
"message": "Unmigratable sectors found. Do you want to continue?",
"placeholder": null
},
{
"id": "Yes, continue",
"translation": "예, 계속",
"message": "Yes, continue",
"placeholder": null
},
{
"id": "No, abort",
"translation": "아니오, 중단",
"message": "No, abort",
"placeholder": null
},
{
"id": "Migrating metadata for {NSectors} sectors.",
"translation": "{NSectors} 섹터의 메타데이터를 이동 중입니다.",
"message": "Migrating metadata for {NSectors} sectors.",
"placeholder": null
}
]
}

View File

@ -1071,6 +1071,30 @@
"translation": "'base'配置已创建以类似于这个lotus-miner的config.toml。",
"message": "Configuration 'base' was created to resemble this lotus-miner's config.toml .",
"placeholder": null
},
{
"id": "Unmigratable sectors found. Do you want to continue?",
"translation": "发现无法迁移的扇区。您想要继续吗?",
"message": "Unmigratable sectors found. Do you want to continue?",
"placeholder": null
},
{
"id": "Yes, continue",
"translation": "是的,继续",
"message": "Yes, continue",
"placeholder": null
},
{
"id": "No, abort",
"translation": "不,中止",
"message": "No, abort",
"placeholder": null
},
{
"id": "Migrating metadata for {NSectors} sectors.",
"translation": "正在迁移{NSectors}个扇区的元数据。",
"message": "Migrating metadata for {NSectors} sectors.",
"placeholder": null
}
]
}

View File

@ -16,6 +16,7 @@ import (
"github.com/filecoin-project/lotus/cmd/curio/deps"
curio "github.com/filecoin-project/lotus/curiosrc"
"github.com/filecoin-project/lotus/curiosrc/alertmanager"
"github.com/filecoin-project/lotus/curiosrc/chainsched"
"github.com/filecoin-project/lotus/curiosrc/ffi"
"github.com/filecoin-project/lotus/curiosrc/gc"
@ -144,6 +145,9 @@ func StartTasks(ctx context.Context, dependencies *deps.Deps) (*harmonytask.Task
activeTasks = append(activeTasks, storageEndpointGcTask)
}
amTask := alertmanager.NewAlertTask(full, db, cfg.Alerting)
activeTasks = append(activeTasks, amTask)
if needProofParams {
for spt := range dependencies.ProofTypes {
if err := modules.GetParams(true)(spt); err != nil {

View File

@ -0,0 +1,332 @@
package alertmanager
import (
"database/sql"
"fmt"
"strings"
"github.com/BurntSushi/toml"
"github.com/dustin/go-humanize"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/node/config"
)
// balanceCheck retrieves the machine details from the database and performs balance checks on unique addresses.
// It populates the alert map with any errors encountered during the process and with any alerts related to low wallet balance and missing wallets.
// The alert map key is "Balance Check".
// It queries the database for the configuration of each layer and decodes it using the toml.Decode function.
// It then iterates over the addresses in the configuration and curates a list of unique addresses.
// If an address is not found in the chain node, it adds an alert to the alert map.
// If the balance of an address is below MinimumWalletBalance, it adds an alert to the alert map.
// If there are any errors encountered during the process, the err field of the alert map is populated.
func balanceCheck(al *alerts) {
Name := "Balance Check"
al.alertMap[Name] = &alertOut{}
var ret string
uniqueAddrs, _, err := al.getAddresses()
if err != nil {
al.alertMap[Name].err = err
return
}
for _, addrStr := range uniqueAddrs {
addr, err := address.NewFromString(addrStr)
if err != nil {
al.alertMap[Name].err = xerrors.Errorf("failed to parse address: %w", err)
return
}
has, err := al.api.WalletHas(al.ctx, addr)
if err != nil {
al.alertMap[Name].err = err
return
}
if !has {
ret += fmt.Sprintf("Wallet %s was not found in chain node. ", addrStr)
}
balance, err := al.api.WalletBalance(al.ctx, addr)
if err != nil {
al.alertMap[Name].err = err
}
if abi.TokenAmount(al.cfg.MinimumWalletBalance).GreaterThanEqual(balance) {
ret += fmt.Sprintf("Balance for wallet %s is below 5 Fil. ", addrStr)
}
}
if ret != "" {
al.alertMap[Name].alertString = ret
}
return
}
// taskFailureCheck retrieves the task failure counts from the database for a specific time period.
// It then checks for specific sealing tasks and tasks with more than 5 failures to generate alerts.
func taskFailureCheck(al *alerts) {
Name := "TaskFailures"
al.alertMap[Name] = &alertOut{}
type taskFailure struct {
Machine string `db:"completed_by_host_and_port"`
Name string `db:"name"`
Failures int `db:"failed_tasks_count"`
}
var taskFailures []taskFailure
err := al.db.Select(al.ctx, &taskFailures, `
SELECT completed_by_host_and_port, name, COUNT(*) AS failed_count
FROM harmony_task_history
WHERE result = FALSE
AND work_end >= NOW() - $1::interval
GROUP BY completed_by_host_and_port, name
ORDER BY completed_by_host_and_port, name;`, fmt.Sprintf("%f Minutes", AlertMangerInterval.Minutes()))
if err != nil {
al.alertMap[Name].err = xerrors.Errorf("getting failed task count: %w", err)
return
}
mmap := make(map[string]int)
tmap := make(map[string]int)
if len(taskFailures) > 0 {
for _, tf := range taskFailures {
_, ok := tmap[tf.Name]
if !ok {
tmap[tf.Name] = tf.Failures
} else {
tmap[tf.Name] += tf.Failures
}
_, ok = mmap[tf.Machine]
if !ok {
mmap[tf.Machine] = tf.Failures
} else {
mmap[tf.Machine] += tf.Failures
}
}
}
sealingTasks := []string{"SDR", "TreeD", "TreeRC", "PreCommitSubmit", "PoRep", "Finalize", "MoveStorage", "CommitSubmit", "WdPost", "ParkPiece"}
contains := func(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
// Alerts for any sealing pipeline failures. Other tasks should have at least 5 failures for an alert
for name, count := range tmap {
if contains(sealingTasks, name) {
al.alertMap[Name].alertString += fmt.Sprintf("Task: %s, Failures: %d. ", name, count)
}
if count > 5 {
al.alertMap[Name].alertString += fmt.Sprintf("Task: %s, Failures: %d. ", name, count)
}
}
// Alert if a machine failed more than 5 tasks
for name, count := range tmap {
if count > 5 {
al.alertMap[Name].alertString += fmt.Sprintf("Machine: %s, Failures: %d. ", name, count)
}
}
return
}
// permanentStorageCheck retrieves the storage details from the database and checks if there is sufficient space for sealing sectors.
// It queries the database for the available storage for all storage paths that can store data.
// It queries the database for sectors being sealed that have not been finalized yet.
// For each sector, it calculates the required space for sealing based on the sector size.
// It checks if there is enough available storage for each sector and updates the sectorMap accordingly.
// If any sectors are unaccounted for, it calculates the total missing space and adds an alert to the alert map.
func permanentStorageCheck(al *alerts) {
Name := "PermanentStorageSpace"
// Get all storage path for permanent storages
type storage struct {
ID string `db:"storage_id"`
Available int64 `db:"available"`
}
var storages []storage
err := al.db.Select(al.ctx, &storages, `
SELECT storage_id, available
FROM storage_path
WHERE can_store = TRUE;`)
if err != nil {
al.alertMap[Name].err = xerrors.Errorf("getting storage details: %w", err)
return
}
type sector struct {
Miner abi.ActorID `db:"sp_id"`
Number abi.SectorNumber `db:"sector_number"`
Proof abi.RegisteredSealProof `db:"reg_seal_proof"`
}
var sectors []sector
err = al.db.Select(al.ctx, &sectors, `
SELECT sp_id, sector_number, reg_seal_proof
FROM sectors_sdr_pipeline
WHERE after_move_storage = FALSE;`)
if err != nil {
al.alertMap[Name].err = xerrors.Errorf("getting sectors being sealed: %w", err)
return
}
type sm struct {
s sector
size int64
}
sectorMap := make(map[sm]bool)
for _, sec := range sectors {
space := int64(0)
sec := sec
sectorSize, err := sec.Proof.SectorSize()
if err != nil {
space = int64(64<<30)*2 + int64(200<<20) // Assume 64 GiB sector
} else {
space = int64(sectorSize)*2 + int64(200<<20) // sealed + unsealed + cache
}
key := sm{s: sec, size: space}
sectorMap[key] = false
for _, strg := range storages {
if space > strg.Available {
strg.Available -= space
sectorMap[key] = true
}
}
}
missingSpace := big.NewInt(0)
for sec, accounted := range sectorMap {
if !accounted {
big.Add(missingSpace, big.NewInt(sec.size))
}
}
if missingSpace.GreaterThan(big.NewInt(0)) {
al.alertMap[Name].alertString = fmt.Sprintf("Insufficient storage space for sealing sectors. Additional %s required.", humanize.Bytes(missingSpace.Uint64()))
}
}
// getAddresses retrieves machine details from the database, stores them in an array and compares layers for uniqueness.
// It employs addrMap to handle unique addresses, and generated slices for configuration fields and MinerAddresses.
// The function iterates over layers, storing decoded configuration and verifying address existence in addrMap.
// It ends by returning unique addresses and miner slices.
func (al *alerts) getAddresses() ([]string, []string, error) {
// MachineDetails represents the structure of data received from the SQL query.
type machineDetail struct {
ID int
HostAndPort string
Layers string
}
var machineDetails []machineDetail
// Get all layers in use
err := al.db.Select(al.ctx, &machineDetails, `
SELECT m.id, m.host_and_port, d.layers
FROM harmony_machines m
LEFT JOIN harmony_machine_details d ON m.id = d.machine_id;`)
if err != nil {
return nil, nil, xerrors.Errorf("getting config layers for all machines: %w", err)
}
// UniqueLayers takes an array of MachineDetails and returns a slice of unique layers.
layerMap := make(map[string]bool)
var uniqueLayers []string
// Get unique layers in use
for _, machine := range machineDetails {
machine := machine
// Split the Layers field into individual layers
layers := strings.Split(machine.Layers, ",")
for _, layer := range layers {
layer = strings.TrimSpace(layer)
if _, exists := layerMap[layer]; !exists && layer != "" {
layerMap[layer] = true
uniqueLayers = append(uniqueLayers, layer)
}
}
}
addrMap := make(map[string]bool)
var uniqueAddrs []string
var miners []string
// Get all unique addresses
for _, layer := range uniqueLayers {
text := ""
cfg := config.DefaultCurioConfig()
err := al.db.QueryRow(al.ctx, `SELECT config FROM harmony_config WHERE title=$1`, layer).Scan(&text)
if err != nil {
if strings.Contains(err.Error(), sql.ErrNoRows.Error()) {
return nil, nil, xerrors.Errorf("missing layer '%s' ", layer)
}
return nil, nil, fmt.Errorf("could not read layer '%s': %w", layer, err)
}
_, err = toml.Decode(text, cfg)
if err != nil {
return nil, nil, fmt.Errorf("could not read layer, bad toml %s: %w", layer, err)
}
for i := range cfg.Addresses {
prec := cfg.Addresses[i].PreCommitControl
com := cfg.Addresses[i].CommitControl
term := cfg.Addresses[i].TerminateControl
miner := cfg.Addresses[i].MinerAddresses
if prec != nil {
for j := range prec {
if _, ok := addrMap[prec[j]]; !ok && prec[j] != "" {
addrMap[prec[j]] = true
uniqueAddrs = append(uniqueAddrs, prec[j])
}
}
}
if com != nil {
for j := range com {
if _, ok := addrMap[com[j]]; !ok && com[j] != "" {
addrMap[com[j]] = true
uniqueAddrs = append(uniqueAddrs, com[j])
}
}
}
if term != nil {
for j := range term {
if _, ok := addrMap[term[j]]; !ok && term[j] != "" {
addrMap[term[j]] = true
uniqueAddrs = append(uniqueAddrs, term[j])
}
}
}
if miner != nil {
for j := range miner {
if _, ok := addrMap[miner[j]]; !ok && miner[j] != "" {
addrMap[miner[j]] = true
miners = append(miners, miner[j])
}
}
}
}
}
return uniqueAddrs, miners, nil
}

View File

@ -0,0 +1,227 @@
// Nobody associated with this software's development has any business relationship to pagerduty.
// This is provided as a convenient trampoline to SP's alert system of choice.
package alertmanager
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
logging "github.com/ipfs/go-log/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/harmony/harmonydb"
"github.com/filecoin-project/lotus/lib/harmony/harmonytask"
"github.com/filecoin-project/lotus/lib/harmony/resources"
"github.com/filecoin-project/lotus/node/config"
"github.com/filecoin-project/lotus/storage/ctladdr"
)
const AlertMangerInterval = time.Hour
var log = logging.Logger("curio/alertmanager")
type AlertAPI interface {
ctladdr.NodeApi
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error)
}
type AlertTask struct {
api AlertAPI
cfg config.CurioAlerting
db *harmonydb.DB
}
type alertOut struct {
err error
alertString string
}
type alerts struct {
ctx context.Context
api AlertAPI
db *harmonydb.DB
cfg config.CurioAlerting
alertMap map[string]*alertOut
}
type pdPayload struct {
Summary string `json:"summary"`
Severity string `json:"severity"`
Source string `json:"source"`
Component string `json:"component,omitempty"`
Group string `json:"group,omitempty"`
Class string `json:"class,omitempty"`
CustomDetails interface{} `json:"custom_details,omitempty"`
}
type alertFunc func(al *alerts)
var alertFuncs = []alertFunc{
balanceCheck,
taskFailureCheck,
permanentStorageCheck,
}
func NewAlertTask(api AlertAPI, db *harmonydb.DB, alertingCfg config.CurioAlerting) *AlertTask {
return &AlertTask{
api: api,
db: db,
cfg: alertingCfg,
}
}
func (a *AlertTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done bool, err error) {
if a.cfg.PageDutyIntegrationKey == "" {
log.Warnf("PageDutyIntegrationKey is empty, not sending an alert")
return true, nil
}
ctx := context.Background()
alMap := make(map[string]*alertOut)
altrs := &alerts{
ctx: ctx,
api: a.api,
db: a.db,
cfg: a.cfg,
alertMap: alMap,
}
for _, al := range alertFuncs {
al(altrs)
}
details := make(map[string]interface{})
for k, v := range altrs.alertMap {
if v != nil {
if v.err != nil {
details[k] = v.err.Error()
continue
}
if v.alertString != "" {
details[k] = v.alertString
}
}
}
// Alert only if required
if len(details) > 0 {
payloadData := &pdPayload{
Summary: "Curio Alert",
Severity: "critical",
CustomDetails: details,
Source: "Curio Cluster",
}
err = a.sendAlert(payloadData)
if err != nil {
return false, err
}
}
return true, nil
}
func (a *AlertTask) CanAccept(ids []harmonytask.TaskID, engine *harmonytask.TaskEngine) (*harmonytask.TaskID, error) {
id := ids[0]
return &id, nil
}
func (a *AlertTask) TypeDetails() harmonytask.TaskTypeDetails {
return harmonytask.TaskTypeDetails{
Max: 1,
Name: "AlertManager",
Cost: resources.Resources{
Cpu: 1,
Ram: 64 << 20,
Gpu: 0,
},
IAmBored: harmonytask.SingletonTaskAdder(AlertMangerInterval, a),
}
}
func (a *AlertTask) Adder(taskFunc harmonytask.AddTaskFunc) {
return
}
var _ harmonytask.TaskInterface = &AlertTask{}
// sendAlert sends an alert to PagerDuty with the provided payload data.
// It creates a PDData struct with the provided routing key, event action and payload.
// It creates an HTTP POST request with the PagerDuty event URL as the endpoint and the marshaled JSON data as the request body.
// It sends the request using an HTTP client with a maximum of 5 retries for network errors with exponential backoff before each retry.
// It handles different HTTP response status codes and returns an error based on the status code().
// If all retries fail, it returns an error indicating the last network error encountered.
func (a *AlertTask) sendAlert(data *pdPayload) error {
type pdData struct {
RoutingKey string `json:"routing_key"`
EventAction string `json:"event_action"`
Payload *pdPayload `json:"payload"`
}
payload := &pdData{
RoutingKey: a.cfg.PageDutyIntegrationKey,
EventAction: "trigger",
Payload: data,
}
jsonData, err := json.Marshal(payload)
if err != nil {
return fmt.Errorf("error marshaling JSON: %w", err)
}
req, err := http.NewRequest("POST", a.cfg.PagerDutyEventURL, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
var resp *http.Response
for i := 0; i < 5; i++ { // Maximum of 5 retries
resp, err = client.Do(req)
if err != nil {
time.Sleep(time.Duration(2*i) * time.Second) // Exponential backoff
continue
}
defer func() { _ = resp.Body.Close() }()
switch resp.StatusCode {
case 202:
log.Debug("Accepted: The event has been accepted by PagerDuty.")
return nil
case 400:
bd, rerr := io.ReadAll(resp.Body)
if rerr != nil {
return xerrors.Errorf("Bad request: payload JSON is invalid. Failed to read the body: %w", err)
}
return xerrors.Errorf("Bad request: payload JSON is invalid %s", string(bd))
case 429:
log.Debug("Too many API calls, retrying after backoff...")
time.Sleep(time.Duration(5*i) * time.Second) // Exponential backoff
case 500, 501, 502, 503, 504:
log.Debug("Server error, retrying after backoff...")
time.Sleep(time.Duration(5*i) * time.Second) // Exponential backoff
default:
log.Errorw("Response status:", resp.Status)
return xerrors.Errorf("Unexpected HTTP response: %s", resp.Status)
}
}
return fmt.Errorf("after retries, last error: %w", err)
}

View File

@ -364,3 +364,24 @@
# type: string
#StorageRPCSecret = ""
[Alerting]
# PagerDutyEventURL is URL for PagerDuty.com Events API v2 URL. Events sent to this API URL are ultimately
# routed to a PagerDuty.com service and processed.
# The default is sufficient for integration with the stock commercial PagerDuty.com company's service.
#
# type: string
#PagerDutyEventURL = "https://events.pagerduty.com/v2/enqueue"
# PageDutyIntegrationKey is the integration key for a PagerDuty.com service. You can find this unique service
# identifier in the integration page for the service.
#
# type: string
#PageDutyIntegrationKey = ""
# MinimumWalletBalance is the minimum balance all active wallets. If the balance is below this value, an
# alerts will be triggered for the wallet
#
# type: types.FIL
#MinimumWalletBalance = "5 FIL"

View File

@ -368,5 +368,10 @@ func DefaultCurioConfig() *CurioConfig {
MaxQueueTrees: 0, // default don't use this limit
MaxQueuePoRep: 0, // default don't use this limit
},
Alerting: CurioAlerting{
PagerDutyEventURL: "https://events.pagerduty.com/v2/enqueue",
PageDutyIntegrationKey: "",
MinimumWalletBalance: types.MustParseFIL("5"),
},
}
}

View File

@ -183,6 +183,30 @@ over the worker address if this flag is set.`,
Comment: `MinerAddresses are the addresses of the miner actors to use for sending messages`,
},
},
"CurioAlerting": {
{
Name: "PagerDutyEventURL",
Type: "string",
Comment: `PagerDutyEventURL is URL for PagerDuty.com Events API v2 URL. Events sent to this API URL are ultimately
routed to a PagerDuty.com service and processed.
The default is sufficient for integration with the stock commercial PagerDuty.com company's service.`,
},
{
Name: "PageDutyIntegrationKey",
Type: "string",
Comment: `PageDutyIntegrationKey is the integration key for a PagerDuty.com service. You can find this unique service
identifier in the integration page for the service.`,
},
{
Name: "MinimumWalletBalance",
Type: "types.FIL",
Comment: `MinimumWalletBalance is the minimum balance all active wallets. If the balance is below this value, an
alerts will be triggered for the wallet`,
},
},
"CurioConfig": {
{
Name: "Subsystems",
@ -224,6 +248,12 @@ over the worker address if this flag is set.`,
Name: "Apis",
Type: "ApisConfig",
Comment: ``,
},
{
Name: "Alerting",
Type: "CurioAlerting",
Comment: ``,
},
},

View File

@ -77,6 +77,7 @@ type CurioConfig struct {
Ingest CurioIngestConfig
Journal JournalConfig
Apis ApisConfig
Alerting CurioAlerting
}
type ApisConfig struct {
@ -1109,3 +1110,18 @@ type FaultReporterConfig struct {
// rewards. This address should have adequate funds to cover gas fees.
ConsensusFaultReporterAddress string
}
type CurioAlerting struct {
// PagerDutyEventURL is URL for PagerDuty.com Events API v2 URL. Events sent to this API URL are ultimately
// routed to a PagerDuty.com service and processed.
// The default is sufficient for integration with the stock commercial PagerDuty.com company's service.
PagerDutyEventURL string
// PageDutyIntegrationKey is the integration key for a PagerDuty.com service. You can find this unique service
// identifier in the integration page for the service.
PageDutyIntegrationKey string
// MinimumWalletBalance is the minimum balance all active wallets. If the balance is below this value, an
// alerts will be triggered for the wallet
MinimumWalletBalance types.FIL
}