Skip to content

Commit

Permalink
update - testnet restart instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
POPPIN-FUMI committed Jan 16, 2025
1 parent 3a3d031 commit a7a0237
Show file tree
Hide file tree
Showing 73 changed files with 1,918 additions and 705 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,7 @@ Input the IP address of the server.
### Set RSA Key for SSH
※ Please set the path to your RSA key. The default path is `~/.ssh/id_rsa`. ※
Currently, only the default path is supported.Please set the path to your RSA
key. The default path is `~/.ssh/id_rsa`.
※ Please set the path to your RSA key. The default path is `~/.ssh/id_rsa`.
```bash
? What's the path to your RSA key? (~/.ssh/id_rsa) › ~/.ssh/id_rsa
Expand Down
2 changes: 1 addition & 1 deletion cli/deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@slv/cli",
"version": "0.3.4",
"version": "0.4.0",
"exports": "./dist/exe",
"publish": {
"include": ["src"],
Expand Down
2 changes: 1 addition & 1 deletion cli/lib/addInventory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const addInventory = async (
const findIdentity = Object.keys(inventory[inventoryType].hosts).find(
(key) => String(key) === identityAccount,
)
console.log(`✔ Identity account: ${findIdentity}`)

if (findIdentity) {
console.log(
colors.yellow(`⚠️ The same Identity already exists
Expand Down
1 change: 1 addition & 0 deletions cli/lib/runAnsible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const runAnsilbe = async (
if (debug) {
cmd += ' -vvv'
}
console.log(`🚀 Running ansible: ${cmd}`)
const result = await spawnSync(cmd)
if (!result.success) {
console.error(
Expand Down
144 changes: 141 additions & 3 deletions cli/src/validator/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Command } from '@cliffy'
import { init } from '/src/validator/init/init.ts'
import { deployValidatorTestnet } from '/src/validator/deploy/deployValidatorTestnet.ts'
import { prompt, Select } from '@cliffy/prompt'
import { Confirm, prompt, Select } from '@cliffy/prompt'
import { colors } from '@cliffy/colors'
import { listValidators } from '/src/validator/listValidators.ts'
import { getIPByIdentityKey } from '/lib/getIPByIdentityKey.ts'
import { getTemplatePath } from '/lib/getTemplatePath.ts'
import { runAnsilbe } from '/lib/runAnsible.ts'
import type { InventoryType, NetworkType } from '@cmn/types/config.ts'
import { genOrReadInventory } from '/lib/genOrReadInventory.ts'
import { parse } from 'https://deno.land/[email protected]/yaml/parse.ts'
import { addInventory } from '/lib/addInventory.ts'
import type { SSHConnection } from '@cmn/prompt/checkSshConnection.ts'
import { homeDir } from '@cmn/constants/path.ts'
import { updateInventory } from '/lib/updateInventory.ts'
import { VERSION_SOLANA_TESTNET } from '@cmn/constants/version.ts'

export const validatorCmd = new Command()
.description('Manage Solana Validator Nodes')
Expand Down Expand Up @@ -73,8 +78,12 @@ validatorCmd.command('set:identity')
: 'testnet_validators'

const templateRoot = getTemplatePath()
const inventory = await genOrReadInventory(inventoryType)
const playbook =
`${templateRoot}/ansible/testnet-validator/change_identity_and_restart.yml`
inventory[inventoryType].hosts[options.pubkey].validator_type ===
'firedancer'
? `${templateRoot}/ansible/testnet-validator/change_identity_and_restart.yml`
: `${templateRoot}/ansible/testnet-validator/set_identity_to_active.yml`
const result = await runAnsilbe(playbook, inventoryType, options.pubkey)
if (result) {
console.log(colors.white('✅ Successfully Set Validator Identity'))
Expand Down Expand Up @@ -141,3 +150,132 @@ validatorCmd.command('restart')
return
}
})

validatorCmd.command('setup:agave')
.description('Setup Agave Validator')
.option('--pubkey <pubkey>', 'Public Key of Validator')
.action(async (options) => {
if (!options.pubkey) {
console.log(colors.yellow('⚠️ Public Key is required'))
return
}
const inventoryType: InventoryType = 'testnet_validators'
const templateRoot = getTemplatePath()
const playbook = `${templateRoot}/ansible/testnet-validator/setup_agave.yml`
const result = await runAnsilbe(playbook, inventoryType, options.pubkey)
await updateInventory(options.pubkey, inventoryType, {
validator_type: 'agave',
version: VERSION_SOLANA_TESTNET,
})
if (result) {
console.log(colors.white('✅ Successfully Setup Agave Validator'))
return
}
})

// validatorCmd.command('update:version')
// .description('Update Validator Version')
// .option('--pubkey <pubkey>', 'Public Key of Validator')
// .option('-n, --network <network>', 'Network to deploy validators', {
// default: 'testnet',
// })
// .action(async (options) => {
// if (!options.pubkey) {
// console.log(colors.yellow('⚠️ Public Key is required'))
// return
// }
// const inventoryType: InventoryType = options.network === 'mainnet'
// ? 'mainnet_validators'
// : 'testnet_validators'
// })

validatorCmd.command('apply')
.description('Apply Ansiible Playbook')
.option('-y, --yml <yml>', 'Playbook Yml File Path to Apply')
.option('-p, --pubkey <pubkey>', 'Public Key of Validator')
.option('-n, --network <network>', 'Network to deploy validators', {
default: 'testnet',
})
.action(async (options) => {
if (!options.yml) {
console.log(colors.yellow('⚠️ Yml File is required'))
return
}
if (!options.pubkey) {
console.log(colors.yellow('⚠️ Public Key is required'))
return
}
const inventoryType: InventoryType = options.network === 'mainnet'
? 'mainnet_validators'
: 'testnet_validators'
const result = await runAnsilbe(options.yml, inventoryType, options.pubkey)
if (result) {
console.log(colors.white('✅ Successfully Applied Playbook'))
return
}
})

validatorCmd.command('codebot')
.description('CodeBot Validator Config')
.action(async () => {
const confirm = await prompt([{
type: Confirm,
name: 'continue',
message: 'Do you want to migrate to new inventory?',
default: true,
}])
if (!confirm.continue) {
console.log(colors.blue('Cancelled...🌝'))
return
}
interface Validator {
identity_account: string
vote_account: string
authority_account: string
username: string
ip: string
rsa_key_path: string
solana_cli: string
solana_version: string
validator_type: string
version: string
}

interface Config {
validators: Validator[]
}
const inventoryType: InventoryType = 'testnet_validators'
const oldConfigPath = homeDir + '/.slv/config.validator.testnet.yml'
let fileContent = ''
try {
fileContent = await Deno.readTextFile(oldConfigPath)
} catch (_error) {
console.log(`No file found at ${oldConfigPath}`)
console.log(colors.white('Looks good...🌝'))
return
}
const config = parse(fileContent) as Config
for (const validator of config.validators) {
const sshConnection: SSHConnection = {
username: validator.username,
ip: validator.ip,
rsa_key_path: validator.rsa_key_path,
}
await addInventory(
validator.identity_account,
sshConnection,
inventoryType,
)
await updateInventory(
validator.identity_account,
inventoryType,
{
vote_account: validator.vote_account,
authority_account: validator.authority_account,
validator_type: validator.validator_type,
version: validator.version,
},
)
}
console.log(colors.white('✅ Successfully Migrated to New Inventory'))
})
8 changes: 6 additions & 2 deletions cli/src/validator/init/copyKeys.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { runAnsilbe } from '/lib/runAnsible.ts'
import { getTemplatePath } from '/lib/getTemplatePath.ts'
import { colors } from '@cliffy/colors'
import type { InventoryType } from '@cmn/types/config.ts'

const copyKeys = async (limit: string) => {
const copyKeys = async (
inventoryType: InventoryType,
identityAccount: string,
) => {
const templateRoot = getTemplatePath()
const createUserYml =
`${templateRoot}/ansible/testnet-validator/copy_keys.yml`
const result = await runAnsilbe(createUserYml, limit)
const result = await runAnsilbe(createUserYml, inventoryType, identityAccount)
if (result) {
console.log(colors.white('🔑 Keys copied successfully'))
}
Expand Down
27 changes: 24 additions & 3 deletions cli/src/validator/init/initTestnetConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,29 @@ import { exec } from '@elsoul/child-process'
import denoJson from '/deno.json' with { type: 'json' }
import { copyKeys } from '/src/validator/init/copyKeys.ts'
import { updateInventory } from '/lib/updateInventory.ts'
import { prompt, Select } from '@cliffy/prompt'
import { testnetValidatorConfigDir } from '@cmn/constants/path.ts'

const initTestnetConfig = async (sshConnection: SSHConnection) => {
try {
await Deno.stat(testnetValidatorConfigDir)
} catch (_error) {
await exec(
`cp -r ${configRoot}/template/${denoJson.version}/jinja/testnet-validator ${configRoot}`,
)
}
const { validatorType } = await prompt([
{
name: 'validatorType',
message: 'Select Validator Type',
type: Select,
options: ['firedancer', 'agave'],
default: 'agave',
},
])
if (!validatorType) {
return
}
const inventoryType = 'testnet_validators' as InventoryType
// Check if testnet-validator Template exists
try {
Expand All @@ -35,20 +56,20 @@ const initTestnetConfig = async (sshConnection: SSHConnection) => {
return
}
// Create solv User on Ubuntu Server
await genSolvUser(sshConnection.ip, inventoryType)
await genSolvUser(identityAccount, inventoryType)
// Generate Vote Key
const { voteAccount, authAccount } = await genVoteKey(identityAccount)
const configTestnet: Partial<HostData> = {
vote_account: voteAccount,
authority_account: authAccount,
validator_type: 'firedancer',
validator_type: validatorType,
}
await updateInventory(identityAccount, inventoryType, configTestnet)

console.log(
`✔︎ Validator testnet config saved to ${inventoryPath}`,
)
await copyKeys('testnet_validators')
await copyKeys(inventoryType, identityAccount)
console.log(colors.white(`Now you can deploy with:
$ slv v deploy -n testnet
Expand Down
11 changes: 10 additions & 1 deletion cli/src/validator/listValidators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ const listValidators = async (network: NetworkType) => {
'Version',
]
console.log(colors.white('Your Testnet Validators Settings:'))
for (const validator of Object.values(inventory.testnet_validators.hosts)) {
if (!inventory.testnet_validators || !inventory.testnet_validators.hosts) {
console.log(colors.yellow('⚠️ No validators found\n\n $ slv v init'))
return
}
const validators = Object.values(inventory.testnet_validators.hosts)
if (!validators) {
console.log(colors.yellow('⚠️ No validators found\n\n $ slv v init'))
return
}
for (const validator of validators) {
const table = new Table()
table
.body([
Expand Down
2 changes: 1 addition & 1 deletion cmn/constants/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const homeDir = Deno.env.get('HOME')
export const configRoot = homeDir
? join(homeDir, '.slv')
: join(Deno.cwd(), '.slv')

export const testnetValidatorConfigDir = join(configRoot, 'testnet-validator')
export const getInventoryPath = (
inventoryType: InventoryType,
) => {
Expand Down
8 changes: 4 additions & 4 deletions cmn/constants/version.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Description: Version constants for the application.
// e.g.: VERSION + SOLANA CLI NAME + NETWORK = '0.0.1' only numbers and dots
export const VERSION_SOLANA_TESTNET = '2.1.6'
export const VERSION_SOLANA_TESTNET = '2.0.22'
export const VERSION_SOLANA_MAINNET = '2.0.19'
export const VERSION_JITO_TESTNET = '2.1.6'
export const VERSION_JITO_TESTNET = '2.0.22'
export const VERSION_JITO_MAINNET = '2.0.19'
export const VERSION_FIREDANCER_TESTNET = '0.302.20104'
export const VERSION_FIREDANCER_MAINNET = '0.302.20104'
export const VERSION_FIREDANCER_TESTNET = '0.304.20106'
export const VERSION_FIREDANCER_MAINNET = '0.304.20106'
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"build:mac": "deno compile -A --target x86_64-apple-darwin --no-check --output dist/slv-x86_64-apple-darwin-exe cli/src/index.ts && tar -czvf dist/slv-x86_64-apple-darwin-exe.tar.gz dist/slv-x86_64-apple-darwin-exe",
"upload:script": "cd ./sh/ && aws --endpoint-url=https://278a7109e511280594fe6a2ebb778333.r2.cloudflarestorage.com/slv s3 cp install s3://slv/ --content-disposition 'attachment; filename=install'",
"upload:exe": "deno run -A cli/uploadExe.ts",
"upload:template": "tar -czf dist/template.tar.gz ./template/0.3.4 && deno run -A cli/uploadTemplate.ts",
"upload:template": "tar -czf dist/template.tar.gz ./template/0.4.0 && deno run -A cli/uploadTemplate.ts",
"purge:cache": "deno run -A cmn/lib/purgeR2Cache.ts",
"slv-dev": "npm run --prefix website/slv-dev"
},
Expand Down
Empty file removed sh/0.1.0/install
Empty file.
Loading

0 comments on commit a7a0237

Please sign in to comment.