mirror of
https://github.com/stake-house/wagyu-installer.git
synced 2026-01-09 13:18:04 -05:00
Compare commits
25 Commits
v0.6.0
...
cs/install
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
410df9c1be | ||
|
|
a904442c55 | ||
|
|
9c444bca35 | ||
|
|
f9d9b75b1b | ||
|
|
4dbe342a91 | ||
|
|
04dd67cd88 | ||
|
|
e08a38221e | ||
|
|
d3302cf08e | ||
|
|
937a70fc79 | ||
|
|
3787fd0217 | ||
|
|
996049e3d7 | ||
|
|
e29a377df4 | ||
|
|
6e501d0798 | ||
|
|
aa2c997afd | ||
|
|
81dfb46a18 | ||
|
|
0ad9ef976d | ||
|
|
ef4ce6ab92 | ||
|
|
7ea6d5aae8 | ||
|
|
424ab11755 | ||
|
|
19abe323b8 | ||
|
|
001bebe9c4 | ||
|
|
efe3cbc586 | ||
|
|
1b87ce9ee5 | ||
|
|
e00783b692 | ||
|
|
7d61a20517 |
@@ -29,7 +29,6 @@
|
||||
"@rauschma/stringio": "^1.4.0",
|
||||
"html-webpack-plugin": "^5.2.0",
|
||||
"js-yaml": "^4.0.0",
|
||||
"node-docker-api": "^1.1.22",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-router-dom": "^5.2.0",
|
||||
|
||||
@@ -26,15 +26,15 @@ const executeCommandAsync = async (cmd: string): Promise<any> => {
|
||||
});
|
||||
}
|
||||
|
||||
const executeCommandInNewTerminal = (cmd: string): number => {
|
||||
return executeCommandSync(UBUNTU_TERMINAL_COMMAND + " -- bash -c '" + cmd + "'");
|
||||
const executeCommandInNewTerminal = (cmd: string, title: string): number => {
|
||||
return executeCommandSync(UBUNTU_TERMINAL_COMMAND + " --title=\"" + title + "\" -- bash -c '" + cmd + "'");
|
||||
}
|
||||
|
||||
const executeCommandSync = (cmd: string): number => {
|
||||
console.log("running command sync with: " + cmd);
|
||||
|
||||
try {
|
||||
execSync(cmd);
|
||||
execSync(cmd, {stdio: 'inherit'});
|
||||
return 0;
|
||||
}
|
||||
catch (error) {
|
||||
@@ -92,6 +92,7 @@ const syncWait = (ms: number) => {
|
||||
}
|
||||
|
||||
async function writeToWritable(writable: Writable, responses: string[]) {
|
||||
syncWait(1000);
|
||||
for (const response of responses) {
|
||||
console.log("writing '" + response + "'");
|
||||
await streamWrite(writable, response);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { doesFileExist, readlink } from "./BashUtils";
|
||||
import { executeCommandAsync, executeCommandInNewTerminal, executeCommandSync, executeCommandSyncReturnStdout, executeCommandWithPromptsAsync } from "./ExecuteCommand";
|
||||
import { executeCommandInNewTerminal, executeCommandSync, executeCommandSyncReturnStdout, executeCommandWithPromptsAsync } from "./ExecuteCommand";
|
||||
|
||||
import { Container } from 'node-docker-api/lib/container';
|
||||
import { Docker } from "node-docker-api";
|
||||
import fs from "fs";
|
||||
import yaml from "js-yaml";
|
||||
|
||||
const ASKPASS_PATH = "src/scripts/askpass.sh";
|
||||
|
||||
const ROCKET_POOL_EXECUTABLE = "~/bin/rocketpool";
|
||||
const ROCKET_POOL_DIR = "~/.rocketpool"
|
||||
const ROCKET_POOL_INSTALL_COMMAND = "curl -L https://github.com/rocket-pool/smartnode-install/releases/latest/download/rocketpool-cli-linux-amd64 --create-dirs -o " + ROCKET_POOL_EXECUTABLE + " && chmod +x " + ROCKET_POOL_EXECUTABLE;
|
||||
@@ -21,7 +21,9 @@ const GETH_PEERS_DOCKER_CMD = "docker exec rocketpool_eth1 geth --exec 'admin.pe
|
||||
type Callback = (success: boolean) => void;
|
||||
type NodeStatusCallback = (status: number) => void;
|
||||
|
||||
const docker = new Docker({ socketPath: '/var/run/docker.sock' });
|
||||
const wrapCommandInDockerGroup = (command: string) => {
|
||||
return "sg docker \"" + command + "\"";
|
||||
}
|
||||
|
||||
// TODO: make this better, it is pretty brittle and peeks into the RP settings implementation
|
||||
// this is required because we select the client at random, so we need to show the user what is running
|
||||
@@ -37,7 +39,15 @@ const getEth2ClientName = (): string => {
|
||||
}
|
||||
}
|
||||
|
||||
const installAndStartRocketPool = async (password: string, callback: Callback) => {
|
||||
const installAndStartRocketPool = async (callback: Callback) => {
|
||||
// cache sudo credentials to be used for install later
|
||||
const passwordRc = executeCommandSync("export SUDO_ASKPASS='" + ASKPASS_PATH + "' && sudo -A echo 'Authentication successful.'");
|
||||
if (passwordRc != 0) {
|
||||
console.log("password failed");
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const cliRc = executeCommandSync(ROCKET_POOL_INSTALL_COMMAND);
|
||||
if (cliRc != 0) {
|
||||
console.log("cli failed to install");
|
||||
@@ -45,19 +55,19 @@ const installAndStartRocketPool = async (password: string, callback: Callback) =
|
||||
return;
|
||||
}
|
||||
|
||||
const serviceRc = executeCommandSync(ROCKET_POOL_EXECUTABLE + " service install --yes --network pyrmont")
|
||||
if (serviceRc != 0) {
|
||||
console.log("service install failed");
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// For some reason executeCommandWithPromptsAsync needs the full path, so fetching it here
|
||||
const rocketPoolExecutableFullPath = readlink(ROCKET_POOL_EXECUTABLE);
|
||||
console.log("full path");
|
||||
console.log(rocketPoolExecutableFullPath);
|
||||
|
||||
const serviceRc = await executeCommandAsync("echo " + password + " | sudo -S " + rocketPoolExecutableFullPath + " --allow-root service install --yes --network pyrmont");
|
||||
if (serviceRc != 0) {
|
||||
console.log("service install failed to install");
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const promptRepsonses = [
|
||||
const promptResponses = [
|
||||
"1\n", // which eth1 client? 1 geth, 2 infura, 3 custom
|
||||
"\n", // ethstats label
|
||||
"\n", // ethstats login
|
||||
@@ -65,7 +75,7 @@ const installAndStartRocketPool = async (password: string, callback: Callback) =
|
||||
"\n" // graffiti
|
||||
]
|
||||
|
||||
const serviceConfigRc = await executeCommandWithPromptsAsync(rocketPoolExecutableFullPath, ["service", "config"], promptRepsonses);
|
||||
const serviceConfigRc = await executeCommandWithPromptsAsync(rocketPoolExecutableFullPath, ["service", "config"], promptResponses);
|
||||
if (serviceConfigRc != 0) {
|
||||
console.log("service config failed");
|
||||
callback(false);
|
||||
@@ -93,7 +103,7 @@ const isRocketPoolInstalled = (): boolean => {
|
||||
}
|
||||
|
||||
const openEth1Logs = () => {
|
||||
const openEth1LogsRc = executeCommandInNewTerminal(ROCKET_POOL_EXECUTABLE + " service logs eth1");
|
||||
const openEth1LogsRc = executeCommandInNewTerminal(wrapCommandInDockerGroup("docker container logs -f rocketpool_eth1"), "eth1 (geth) logs");
|
||||
if (openEth1LogsRc != 0) {
|
||||
console.log("failed to open eth1 logs");
|
||||
return;
|
||||
@@ -101,7 +111,7 @@ const openEth1Logs = () => {
|
||||
}
|
||||
|
||||
const openEth2BeaconLogs = () => {
|
||||
const openEth2BeaconLogsRc = executeCommandInNewTerminal(ROCKET_POOL_EXECUTABLE + " service logs eth2");
|
||||
const openEth2BeaconLogsRc = executeCommandInNewTerminal(wrapCommandInDockerGroup("docker container logs -f rocketpool_eth2"), "eth2 beacon node (" + getEth2ClientName() + ") logs");
|
||||
if (openEth2BeaconLogsRc != 0) {
|
||||
console.log("failed to open eth2 beacon logs");
|
||||
return;
|
||||
@@ -109,7 +119,7 @@ const openEth2BeaconLogs = () => {
|
||||
}
|
||||
|
||||
const openEth2ValidatorLogs = () => {
|
||||
const openEth2ValidatorLogsRc = executeCommandInNewTerminal(ROCKET_POOL_EXECUTABLE + " service logs validator");
|
||||
const openEth2ValidatorLogsRc = executeCommandInNewTerminal(wrapCommandInDockerGroup("docker container logs -f rocketpool_validator"), "eth2 validator (" + getEth2ClientName() + ") logs");
|
||||
if (openEth2ValidatorLogsRc != 0) {
|
||||
console.log("failed to open eth2 validator logs");
|
||||
return;
|
||||
@@ -117,15 +127,15 @@ const openEth2ValidatorLogs = () => {
|
||||
}
|
||||
|
||||
const startNodes = (): number => {
|
||||
return executeCommandSync(ROCKET_POOL_EXECUTABLE + " service start");
|
||||
return executeCommandSync(wrapCommandInDockerGroup(ROCKET_POOL_EXECUTABLE + " service start"));
|
||||
}
|
||||
|
||||
const stopNodes = (): number => {
|
||||
return executeCommandSync(ROCKET_POOL_EXECUTABLE + " service stop -y");
|
||||
return executeCommandSync(wrapCommandInDockerGroup(ROCKET_POOL_EXECUTABLE + " service stop -y"));
|
||||
}
|
||||
|
||||
const queryEth1PeerCount = (): number => {
|
||||
const numPeers = executeCommandSyncReturnStdout(GETH_PEERS_DOCKER_CMD);
|
||||
const numPeers = executeCommandSyncReturnStdout(wrapCommandInDockerGroup(GETH_PEERS_DOCKER_CMD));
|
||||
const numPeersNumber = parseInt(numPeers.trim());
|
||||
return isNaN(numPeersNumber) ? 0 : numPeersNumber;
|
||||
}
|
||||
@@ -135,7 +145,7 @@ const queryEth1Status = (nodeStatusCallback: NodeStatusCallback) => {
|
||||
}
|
||||
|
||||
const queryEth1Syncing = (): boolean => {
|
||||
const syncValue = executeCommandSyncReturnStdout(GETH_SYNC_STATUS_DOCKER_CMD);
|
||||
const syncValue = executeCommandSyncReturnStdout(wrapCommandInDockerGroup(GETH_SYNC_STATUS_DOCKER_CMD));
|
||||
return !syncValue.includes("false");
|
||||
}
|
||||
|
||||
@@ -147,29 +157,14 @@ const queryEth2ValidatorStatus = (nodeStatusCallback: NodeStatusCallback) => {
|
||||
dockerContainerStatus("rocketpool_validator", nodeStatusCallback);
|
||||
}
|
||||
|
||||
// TODO: make this better - it is very fragile
|
||||
const dockerContainerStatus = async (containerName: string, nodeStatusCallback: NodeStatusCallback) => {
|
||||
docker.container.list().then(
|
||||
(containers: Container[]) => {
|
||||
const filteredContainers = containers.filter((container => {
|
||||
const data: any = container.data;
|
||||
return data["Names"][0].includes(containerName);
|
||||
}))
|
||||
const containerId = executeCommandSyncReturnStdout(wrapCommandInDockerGroup("docker ps -q -f name=" + containerName));
|
||||
|
||||
if (filteredContainers.length == 0) {
|
||||
nodeStatusCallback(2); // offline
|
||||
} else {
|
||||
const containerData: any = filteredContainers[0].data;
|
||||
const containerState: string = containerData["State"];
|
||||
if (containerState.includes("running")) {
|
||||
nodeStatusCallback(0); // online
|
||||
} else {
|
||||
nodeStatusCallback(2); // offline
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
nodeStatusCallback(2); // offline
|
||||
})
|
||||
if (containerId.trim()) {
|
||||
nodeStatusCallback(0); // online
|
||||
} else {
|
||||
nodeStatusCallback(2); // offline
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
MainContent
|
||||
} from "../colors";
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import styled, { keyframes } from "styled-components";
|
||||
|
||||
import { History } from "history";
|
||||
@@ -38,10 +38,6 @@ const Content = styled.div`
|
||||
flex-grow: 6;
|
||||
`;
|
||||
|
||||
const StyledInput = styled.input`
|
||||
width: 100px;
|
||||
`;
|
||||
|
||||
const rotate = keyframes`
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
@@ -57,99 +53,19 @@ const LoadingSpinner = styled.div`
|
||||
border: 16px solid #f3f3f3; /* Light grey */
|
||||
border-top: 16px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
margin-top: 30px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
animation: ${rotate} 2s linear infinite;
|
||||
`;
|
||||
|
||||
const FooterContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-self: flex-end;
|
||||
height: 70;
|
||||
flex-grow:1;
|
||||
min-width:100vw;
|
||||
`;
|
||||
|
||||
const InputContainer = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const ContinueButton = styled.div`
|
||||
color: ${Black};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-self:flex-end;
|
||||
height: 24;
|
||||
background-color: ${Button};
|
||||
padding: 16 24;
|
||||
border-radius: 10%;
|
||||
text-decoration: none;
|
||||
|
||||
transition: 250ms background-color ease;
|
||||
cursor: pointer;
|
||||
margin: 60;
|
||||
|
||||
&:hover {
|
||||
background-color: ${ButtonHover};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButton = styled(Link)`
|
||||
color: ${Black};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-self:flex-end;
|
||||
height: 24;
|
||||
background-color: ${Button};
|
||||
padding: 16 24;
|
||||
border-radius: 10%;
|
||||
text-decoration: none;
|
||||
|
||||
transition: 250ms background-color ease;
|
||||
cursor: pointer;
|
||||
margin: 60;
|
||||
|
||||
&:hover {
|
||||
background-color: ${ButtonHover};
|
||||
}
|
||||
`;
|
||||
|
||||
const Installing = ({ history }: {history: History}) => {
|
||||
const [password, setPassword] = useState("");
|
||||
const [installInProgress, setInstallInProgress] = useState(false);
|
||||
|
||||
const handleChangePassword = (event: { target: { value: React.SetStateAction<string>; }; }) => {
|
||||
setPassword(event.target.value);
|
||||
}
|
||||
|
||||
const handleKeyPressed = (event: { keyCode: any; which: any; }) => {
|
||||
var code = event.keyCode || event.which;
|
||||
if(code === ENTER_KEYCODE) {
|
||||
handleSubmitPassword();
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmitPassword = () => {
|
||||
// TODO: handle wrong password
|
||||
// TODO: handle empty password
|
||||
|
||||
setInstallInProgress(true);
|
||||
|
||||
// Without this setTimeout, there was a pause before the screen would update saying Installing...
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
installAndStartRocketPool(password, installCallback);
|
||||
}, 2000);
|
||||
}
|
||||
installAndStartRocketPool(installCallback);
|
||||
}, 1000);
|
||||
}, [])
|
||||
|
||||
const installCallback = (success: boolean) => {
|
||||
if (success) {
|
||||
@@ -168,36 +84,15 @@ const Installing = ({ history }: {history: History}) => {
|
||||
return (
|
||||
<Container>
|
||||
<LandingHeader>Install</LandingHeader>
|
||||
|
||||
{ installInProgress ?
|
||||
<Content>
|
||||
Installing...
|
||||
<br />
|
||||
<br />
|
||||
May take up to 2 minutes.
|
||||
May take 2-4 minutes depending on internet speed.
|
||||
<SpinnerContainer>
|
||||
<LoadingSpinner />
|
||||
</SpinnerContainer>
|
||||
</Content> :
|
||||
<Content>
|
||||
In order to download the necessary software, we must have admin access to your computer.
|
||||
<br />
|
||||
<br />
|
||||
Please enter you computer login password* below. Don't worry, we'll keep it safe.
|
||||
<br />
|
||||
<br />
|
||||
<InputContainer>
|
||||
<StyledInput type="password" value={password} onChange={handleChangePassword} onKeyPress={handleKeyPressed} />
|
||||
</InputContainer>
|
||||
<br />
|
||||
<br />
|
||||
*Note: at this stage we cannot handle password retries, so please get it right ;)
|
||||
</Content>
|
||||
}
|
||||
<FooterContainer>
|
||||
<StyledButton to="/systemcheck">Back</StyledButton>
|
||||
<ContinueButton onClick={handleSubmitPassword}>Continue</ContinueButton>
|
||||
</FooterContainer>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -80,24 +80,27 @@ const LogsButton = styled.button`
|
||||
const NodeStatus: [string, string, string][] = [
|
||||
["Online", "\u2B24", "green"], // 0
|
||||
["Syncing", "\u2B24", "yellow"], // 1
|
||||
["Offline", "\u2B24", "red"] // 2
|
||||
["Offline", "\u2B24", "red"], // 2
|
||||
["Loading...", "", ""] // 3
|
||||
]
|
||||
|
||||
// TODO: right after install, while nodes are starting up, this page says everything is "online"
|
||||
// while things are looking for peers. Need to improve that logic.
|
||||
|
||||
const Status = () => {
|
||||
const [eth1ContainerStatus, setEth1ContainerStatus] = useState(2);
|
||||
const [eth1ContainerStatus, setEth1ContainerStatus] = useState(3);
|
||||
const [eth1PeerCount, setEth1PeerCount] = useState(0);
|
||||
const [eth1Syncing, setEth1Syncing] = useState(false);
|
||||
const [eth2ClientName, setEth2ClientName] = useState("");
|
||||
const [eth2BeaconContainerStatus, setEth2BeaconContainerStatus] = useState(2);
|
||||
const [eth2ValidatorContainerStatus, setEth2ValidatorContainerStatus] = useState(2);
|
||||
const [eth2BeaconContainerStatus, setEth2BeaconContainerStatus] = useState(3);
|
||||
const [eth2ValidatorContainerStatus, setEth2ValidatorContainerStatus] = useState(3);
|
||||
|
||||
useEffect(() => {
|
||||
queryStatuses();
|
||||
setEth2ClientName(getEth2ClientName());
|
||||
setInterval(queryStatuses, 5000);
|
||||
setTimeout(() => {
|
||||
queryStatuses();
|
||||
setEth2ClientName(getEth2ClientName());
|
||||
setInterval(queryStatuses, 5000);
|
||||
}, 500)
|
||||
}, []);
|
||||
|
||||
const queryStatuses = () => {
|
||||
@@ -119,7 +122,9 @@ const Status = () => {
|
||||
}
|
||||
|
||||
const computeEth1Status = (): number => {
|
||||
if (eth1ContainerStatus == 2) {
|
||||
if (eth1ContainerStatus == 3) {
|
||||
return 3;
|
||||
} else if (eth1ContainerStatus == 2) {
|
||||
return 2;
|
||||
} else if (eth1Syncing) {
|
||||
return 1;
|
||||
@@ -149,19 +154,19 @@ const Status = () => {
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Eth1 Node</td>
|
||||
<td>Eth1 Node - geth</td>
|
||||
<td>{formatStatusIcon(computeEth1Status())} {NodeStatus[computeEth1Status()][0]}</td>
|
||||
<td>{eth1PeerCount}</td>
|
||||
<td><LogsButton onClick={openEth1Logs} disabled={eth1ContainerStatus == 2}>View Logs</LogsButton></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Eth2 Beacon Node</td>
|
||||
<td>Eth2 Beacon Node - {eth2ClientName}</td>
|
||||
<td>{formatStatusIcon(computeEth2BeaconStatus())} {NodeStatus[computeEth2BeaconStatus()][0]}</td>
|
||||
<td>-</td>
|
||||
<td><LogsButton onClick={openEth2BeaconLogs} disabled={eth2BeaconContainerStatus == 2}>View Logs</LogsButton></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Eth2 Validator</td>
|
||||
<td>Eth2 Validator - {eth2ClientName}</td>
|
||||
<td>{formatStatusIcon(computeEth2ValidatorStatus())} {NodeStatus[computeEth2ValidatorStatus()][0]}</td>
|
||||
<td>-</td>
|
||||
<td><LogsButton onClick={openEth2ValidatorLogs} disabled={eth2ValidatorContainerStatus == 2}>View Logs</LogsButton></td>
|
||||
@@ -231,8 +236,6 @@ const Status = () => {
|
||||
<Content>
|
||||
{ renderNodeStatusTable() }
|
||||
<br />
|
||||
Eth2 client: {eth2ClientName}
|
||||
<br />
|
||||
<br />
|
||||
*Note: "Syncing" state is only supported for Eth1. Eth1 Beacon/Validator statuses are set based on docker status.
|
||||
<br />
|
||||
|
||||
2
src/scripts/askpass.sh
Executable file
2
src/scripts/askpass.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
zenity --password --title=Authentication
|
||||
65
yarn.lock
65
yarn.lock
@@ -508,14 +508,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
||||
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
||||
|
||||
JSONStream@0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-0.10.0.tgz#74349d0d89522b71f30f0a03ff9bd20ca6f12ac0"
|
||||
integrity sha1-dDSdDYlSK3HzDwoD/5vSDKbxKsA=
|
||||
dependencies:
|
||||
jsonparse "0.0.5"
|
||||
through ">=2.2.7 <3"
|
||||
|
||||
accepts@^1.3.5:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
||||
@@ -1026,7 +1018,7 @@ debug@*, debug@^4.1.0, debug@^4.1.1:
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
||||
debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||
@@ -1142,16 +1134,6 @@ dir-glob@^3.0.1:
|
||||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
docker-modem@^0.3.1:
|
||||
version "0.3.7"
|
||||
resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-0.3.7.tgz#3f510d09f5d334dc2134228f92bd344671227df4"
|
||||
integrity sha1-P1ENCfXTNNwhNCKPkr00RnEiffQ=
|
||||
dependencies:
|
||||
JSONStream "0.10.0"
|
||||
debug "^2.6.0"
|
||||
readable-stream "~1.0.26-4"
|
||||
split-ca "^1.0.0"
|
||||
|
||||
dom-converter@^0.2:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
|
||||
@@ -1888,7 +1870,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
|
||||
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@@ -2141,11 +2123,6 @@ jsonfile@^4.0.0:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonparse@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-0.0.5.tgz#330542ad3f0a654665b778f3eb2d9a9fa507ac64"
|
||||
integrity sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=
|
||||
|
||||
keygrip@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
|
||||
@@ -2397,11 +2374,6 @@ memory-fs@^0.5.0:
|
||||
errno "^0.1.3"
|
||||
readable-stream "^2.0.1"
|
||||
|
||||
memorystream@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
|
||||
integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI=
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||
@@ -2556,14 +2528,6 @@ no-case@^3.0.4:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-docker-api@^1.1.22:
|
||||
version "1.1.22"
|
||||
resolved "https://registry.yarnpkg.com/node-docker-api/-/node-docker-api-1.1.22.tgz#230327efd309a6ec7302bf3f404ab760040a5806"
|
||||
integrity sha1-IwMn79MJpuxzAr8/QEq3YAQKWAY=
|
||||
dependencies:
|
||||
docker-modem "^0.3.1"
|
||||
memorystream "^0.3.1"
|
||||
|
||||
node-releases@^1.1.70:
|
||||
version "1.1.71"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
|
||||
@@ -3005,16 +2969,6 @@ readable-stream@^3.1.1:
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@~1.0.26-4:
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
|
||||
integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
rechoir@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca"
|
||||
@@ -3381,11 +3335,6 @@ spdx-license-ids@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
|
||||
integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==
|
||||
|
||||
split-ca@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6"
|
||||
integrity sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=
|
||||
|
||||
split-string@^3.0.1, split-string@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
|
||||
@@ -3418,11 +3367,6 @@ string_decoder@^1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
@@ -3536,11 +3480,6 @@ terser@^5.5.1:
|
||||
source-map "~0.7.2"
|
||||
source-map-support "~0.5.19"
|
||||
|
||||
"through@>=2.2.7 <3":
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
tiny-invariant@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
|
||||
|
||||
Reference in New Issue
Block a user