mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-01 19:46:41 +00:00
Add multiple nodes
This commit is contained in:
parent
19b6d194ea
commit
4cd8af904e
@ -42,27 +42,25 @@ interface FlagsDef {
|
|||||||
region?: string;
|
region?: string;
|
||||||
size?: string;
|
size?: string;
|
||||||
imageName?: string;
|
imageName?: string;
|
||||||
|
num?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class InstanceInitCmd extends Command {
|
export default class InstanceInitCmd extends Command {
|
||||||
public static description = stripIndent`
|
public static description = stripIndent`
|
||||||
Initialize an instance with balenaOS.
|
Initialize a new balenaOS device in the cloud.
|
||||||
|
|
||||||
Initialize a device by downloading the OS image of the specified fleet
|
This will upload a balenaOS image to your specific cloud provider (if it does not already exist), create a new cloud instance, and join it to the fleet with the provided config.json
|
||||||
and writing it to an SD Card.
|
|
||||||
|
|
||||||
If the --fleet option is omitted, it will be prompted for interactively.
|
Note: depending on the instance size this can take 5-15 minutes after image upload
|
||||||
|
|
||||||
${applicationIdInfo.split('\n').join('\n\t\t')}
|
${applicationIdInfo.split('\n').join('\n\t\t')}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
public static examples = [
|
public static examples = [
|
||||||
'$ balena instance init',
|
'$ balena instance init digitalocean config.json --apiKey <api key>',
|
||||||
'$ balena instance init --fleet MyFleet',
|
|
||||||
'$ balena instance init -f myorg/myfleet',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public static usage = 'instance init';
|
public static usage = 'instance init <provider> <config.json path>';
|
||||||
|
|
||||||
public static args: Array<IArg<any>> = [
|
public static args: Array<IArg<any>> = [
|
||||||
{
|
{
|
||||||
@ -89,6 +87,9 @@ export default class InstanceInitCmd extends Command {
|
|||||||
size: flags.string({
|
size: flags.string({
|
||||||
description: 'DigitalOcean droplet size',
|
description: 'DigitalOcean droplet size',
|
||||||
}),
|
}),
|
||||||
|
num: flags.integer({
|
||||||
|
description: 'Number of instances to create',
|
||||||
|
}),
|
||||||
imageName: flags.string({
|
imageName: flags.string({
|
||||||
description: 'custom image name',
|
description: 'custom image name',
|
||||||
})
|
})
|
||||||
@ -98,7 +99,7 @@ export default class InstanceInitCmd extends Command {
|
|||||||
|
|
||||||
public async run() {
|
public async run() {
|
||||||
const { args: params, flags: options } = this.parse<FlagsDef, { configFile: string, provider: string }>(InstanceInitCmd);
|
const { args: params, flags: options } = this.parse<FlagsDef, { configFile: string, provider: string }>(InstanceInitCmd);
|
||||||
|
|
||||||
if (!['do', 'digitalocean'].includes(params.provider)) {
|
if (!['do', 'digitalocean'].includes(params.provider)) {
|
||||||
console.error('Only DigitalOcean is supported as a provider, please use "do" or "digitalocean" as your provider positional argument.')
|
console.error('Only DigitalOcean is supported as a provider, please use "do" or "digitalocean" as your provider positional argument.')
|
||||||
return
|
return
|
||||||
@ -124,6 +125,7 @@ export default class InstanceInitCmd extends Command {
|
|||||||
let res
|
let res
|
||||||
let responseBody
|
let responseBody
|
||||||
let images = []
|
let images = []
|
||||||
|
const num = options.num || 1
|
||||||
|
|
||||||
do {
|
do {
|
||||||
res = await fetch(`https://api.digitalocean.com/v2/images?per_page=200&page=${page}`, {
|
res = await fetch(`https://api.digitalocean.com/v2/images?per_page=200&page=${page}`, {
|
||||||
@ -196,13 +198,16 @@ export default class InstanceInitCmd extends Command {
|
|||||||
responseBody = await res.json()
|
responseBody = await res.json()
|
||||||
|
|
||||||
const sshKeyID = responseBody.ssh_keys[0].id
|
const sshKeyID = responseBody.ssh_keys[0].id
|
||||||
const randomDropletID = randomName()
|
const dropletNames = []
|
||||||
|
|
||||||
console.log('Creating droplet...')
|
for (let i = 0; i < num; i++) {
|
||||||
|
dropletNames.push(randomName())
|
||||||
|
}
|
||||||
|
console.log('Creating droplets', dropletNames.join(', '))
|
||||||
res = await fetch('https://api.digitalocean.com/v2/droplets', {
|
res = await fetch('https://api.digitalocean.com/v2/droplets', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: randomDropletID,
|
names: dropletNames,
|
||||||
region: options.region || 'nyc1',
|
region: options.region || 'nyc1',
|
||||||
size: options.size || 's-2vcpu-4gb',
|
size: options.size || 's-2vcpu-4gb',
|
||||||
image: imageID,
|
image: imageID,
|
||||||
@ -218,24 +223,6 @@ export default class InstanceInitCmd extends Command {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
responseBody = await res.json()
|
|
||||||
const createURL = responseBody.links.actions.filter((action: any) => action.rel === 'create')[0]
|
|
||||||
if (!createURL) {
|
|
||||||
console.error('Failed to get a create check url! You will probably want to cleanup the image and droplet in your dashboard.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
console.log('Wait for droplet to be created...')
|
|
||||||
await new Promise((r) => setTimeout(() => r(null), 2000)) // Sleep for 2 seconds
|
|
||||||
res = await fetch(createURL.href, {
|
|
||||||
headers: {
|
|
||||||
authorization: `Bearer ${options.apiKey}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
responseBody = await res.json()
|
|
||||||
} while (responseBody.action.status !== 'completed')
|
|
||||||
|
|
||||||
console.log('Done! the device should show soon!')
|
console.log('Done! the device should show soon!')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user