mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-24 07:46:39 +00:00
Initial version of command
This commit is contained in:
parent
f635f648da
commit
e10a974a9f
49
lib/commands/instance/index.ts
Normal file
49
lib/commands/instance/index.ts
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016-2020 Balena Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { flags } from '@oclif/command';
|
||||
import Command from '../../command';
|
||||
import * as cf from '../../utils/common-flags';
|
||||
import { stripIndent } from '../../utils/lazy';
|
||||
|
||||
interface FlagsDef {
|
||||
help: void;
|
||||
v13: boolean;
|
||||
}
|
||||
|
||||
export default class InstanceCmd extends Command {
|
||||
public static description = stripIndent`
|
||||
Initialize a new cloud instance running balenaOS
|
||||
|
||||
A config.json must first be generated using the 'balena config generate' command
|
||||
`;
|
||||
public static examples = ['$ balena instance init'];
|
||||
|
||||
public static usage = 'instance [COMMAND]';
|
||||
|
||||
public static flags: flags.Input<FlagsDef> = {
|
||||
help: cf.help,
|
||||
v13: cf.v13,
|
||||
};
|
||||
|
||||
public static authenticated = true;
|
||||
public static primary = true;
|
||||
|
||||
public async run() {
|
||||
|
||||
}
|
||||
}
|
175
lib/commands/instance/init.ts
Normal file
175
lib/commands/instance/init.ts
Normal file
@ -0,0 +1,175 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016-2020 Balena Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { IArg } from '@oclif/parser/lib/args';
|
||||
import Command from '../../command';
|
||||
import { stripIndent } from '../../utils/lazy';
|
||||
import {
|
||||
applicationIdInfo,
|
||||
} from '../../utils/messages';
|
||||
|
||||
import * as fs from 'fs'
|
||||
import * as fetch from 'isomorphic-fetch'
|
||||
import * as cf from '../../utils/common-flags';
|
||||
import { flags } from '@oclif/command';
|
||||
import { uniqueId } from 'lodash';
|
||||
import { json } from 'body-parser';
|
||||
|
||||
interface FlagsDef {
|
||||
help: void;
|
||||
v13: boolean;
|
||||
apiKey?: string;
|
||||
}
|
||||
|
||||
export default class InstanceInitCmd extends Command {
|
||||
public static description = stripIndent`
|
||||
Initialize an instance with balenaOS.
|
||||
|
||||
Initialize a device by downloading the OS image of the specified fleet
|
||||
and writing it to an SD Card.
|
||||
|
||||
If the --fleet option is omitted, it will be prompted for interactively.
|
||||
|
||||
${applicationIdInfo.split('\n').join('\n\t\t')}
|
||||
`;
|
||||
|
||||
public static examples = [
|
||||
'$ balena instance init',
|
||||
'$ balena instance init --fleet MyFleet',
|
||||
'$ balena instance init -f myorg/myfleet',
|
||||
];
|
||||
|
||||
public static usage = 'instance init';
|
||||
|
||||
public static args: Array<IArg<any>> = [
|
||||
{
|
||||
name: 'configFile',
|
||||
description: 'the config.json file path',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
public static flags: flags.Input<FlagsDef> = {
|
||||
help: cf.help,
|
||||
v13: cf.v13,
|
||||
apiKey: flags.string({
|
||||
description: 'digitalocean api key',
|
||||
}),
|
||||
};
|
||||
|
||||
public static authenticated = true;
|
||||
|
||||
public async run() {
|
||||
const { args: params, flags: options } = this.parse<FlagsDef, { configFile: string }>(InstanceInitCmd);
|
||||
|
||||
// Check if the config file exists
|
||||
console.log('Reading config file')
|
||||
const exists = fs.existsSync(params.configFile)
|
||||
if (!exists) {
|
||||
console.log('Config file does not exist, exiting...')
|
||||
return
|
||||
}
|
||||
|
||||
const configFile = JSON.parse(fs.readFileSync(params.configFile).toString())
|
||||
|
||||
console.log('Creating digitalocean image')
|
||||
|
||||
if (!options.apiKey) {
|
||||
console.log('Missing digitalocean api key, please provide with --apiKey <api_key>')
|
||||
}
|
||||
|
||||
console.log('Uploading image...')
|
||||
let res = await fetch('https://api.digitalocean.com/v2/images', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
authorization: `Bearer ${options.apiKey}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: 'balenaOS',
|
||||
url: `https://api.balena-cloud.com/download?fileType=.gz&appId=${configFile.applicationID}&deviceType=qemux86-64`,
|
||||
distribution: 'Unknown',
|
||||
region: 'nyc1',
|
||||
description: 'balenaOS',
|
||||
tags: [
|
||||
'balenaOS'
|
||||
]
|
||||
})
|
||||
})
|
||||
console.log('Image sent.')
|
||||
|
||||
let responseBody = await res.json()
|
||||
const imageID = responseBody.image.id
|
||||
do {
|
||||
console.log('Checking image status...')
|
||||
await new Promise((r) => setTimeout(() => r(null), 2000)) // Sleep for 2 seconds
|
||||
res = await fetch(`https://api.digitalocean.com/v2/images/${imageID}`, {
|
||||
headers: {
|
||||
authorization: `Bearer ${options.apiKey}`
|
||||
}
|
||||
})
|
||||
responseBody = await res.json()
|
||||
} while (responseBody.image.status !== 'available')
|
||||
console.log('Image available.')
|
||||
|
||||
console.log('Getting ssh key info')
|
||||
res = await fetch('https://api.digitalocean.com/v2/account/keys', {
|
||||
headers: {
|
||||
authorization: `Bearer ${options.apiKey}`
|
||||
}
|
||||
})
|
||||
responseBody = await res.json()
|
||||
|
||||
const sshKeyID = responseBody.ssh_keys[0].id
|
||||
|
||||
console.log('Creating droplet...')
|
||||
res = await fetch('https://api.digitalocean.com/v2/droplets', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: uniqueId(),
|
||||
region: 'nyc1',
|
||||
size: 's-2vcpu-4gb',
|
||||
image: imageID,
|
||||
ssh_keys: [sshKeyID],
|
||||
user_data: JSON.stringify(configFile),
|
||||
tags: [
|
||||
'balenaOS'
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
responseBody = await res.json()
|
||||
const createURL = responseBody.links.actions.filter((link: any) => link.rel === 'created')[0]
|
||||
if (!createURL) {
|
||||
console.error('Failed to get a create url!')
|
||||
}
|
||||
|
||||
do {
|
||||
console.log('Checking droplet creation status...')
|
||||
await new Promise((r) => setTimeout(() => r(null), 2000)) // Sleep for 2 seconds
|
||||
res = await fetch(createURL, {
|
||||
headers: {
|
||||
authorization: `Bearer ${options.apiKey}`
|
||||
}
|
||||
})
|
||||
responseBody = await res.json()
|
||||
} while (responseBody.action.status !== 'completed')
|
||||
|
||||
console.log('Done! the device should show soon!')
|
||||
|
||||
}
|
||||
}
|
@ -232,5 +232,6 @@ See: https://git.io/JRHUW#deprecation-policy`,
|
||||
'join',
|
||||
'leave',
|
||||
'scan',
|
||||
'instance',
|
||||
];
|
||||
}
|
||||
|
20
npm-shrinkwrap.json
generated
20
npm-shrinkwrap.json
generated
@ -2583,6 +2583,12 @@
|
||||
"is-root": "*"
|
||||
}
|
||||
},
|
||||
"@types/isomorphic-fetch": {
|
||||
"version": "0.0.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.35.tgz",
|
||||
"integrity": "sha512-DaZNUvLDCAnCTjgwxgiL1eQdxIKEpNLOlTNtAgnZc50bG2copGhRrFN9/PxPBuJe+tZVLCbQ7ls0xveXVRPkvw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/js-yaml": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.2.tgz",
|
||||
@ -10365,6 +10371,15 @@
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||
},
|
||||
"isomorphic-fetch": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
|
||||
"integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
|
||||
"requires": {
|
||||
"node-fetch": "^2.6.1",
|
||||
"whatwg-fetch": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
@ -18492,6 +18507,11 @@
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.1.1.tgz",
|
||||
"integrity": "sha512-Czi3fG883e96T4DLEPRvufrF2ydhOOW1+1a6c3gNjH2aIh50DNFBdfwh2AKoOf1rXvpvavAoA11Qdq9+BKjE0Q=="
|
||||
},
|
||||
"whatwg-fetch": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
|
||||
"integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
@ -135,6 +135,7 @@
|
||||
"@types/http-proxy": "^1.17.7",
|
||||
"@types/intercept-stdout": "^0.1.0",
|
||||
"@types/is-root": "^2.1.2",
|
||||
"@types/isomorphic-fetch": "0.0.35",
|
||||
"@types/js-yaml": "^4.0.2",
|
||||
"@types/jsonwebtoken": "^8.5.4",
|
||||
"@types/klaw": "^3.0.2",
|
||||
@ -244,6 +245,7 @@
|
||||
"inquirer": "^7.3.3",
|
||||
"is-elevated": "^3.0.0",
|
||||
"is-root": "^2.1.0",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"js-yaml": "^4.0.0",
|
||||
"klaw": "^3.0.0",
|
||||
"livepush": "^3.5.0",
|
||||
|
Loading…
Reference in New Issue
Block a user