-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
494 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
packages/admin-ui/src/pages/system/components/Advanced/DockerUpgrade.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import React, { useState, useEffect } from "react"; | ||
import { ReqStatus } from "types"; | ||
import { api } from "api"; | ||
import { confirm } from "components/ConfirmDialog"; | ||
import Button from "components/Button"; | ||
import Ok from "components/Ok"; | ||
import ErrorView from "components/ErrorView"; | ||
import { withToast } from "components/toast/Toast"; | ||
import { DockerUpgradeRequirements } from "@dappnode/types"; | ||
import { gte, lt } from "semver"; | ||
import Card from "components/Card"; | ||
|
||
function RequirementsList({ items }: { items: DockerUpgradeRequirements }) { | ||
return ( | ||
<div> | ||
<Ok | ||
title="Docker in unattended upgrades" | ||
msg={ | ||
items.isDockerInUnattendedUpgrades | ||
? `Docker is in the unattended upgrades list. This means that it will be automatically updated by the system` | ||
: `Docker is not in the unattended upgrades list. This means that it will not be automatically updated by the system` | ||
} | ||
ok={items.isDockerInUnattendedUpgrades} | ||
/> | ||
<Ok | ||
title="Docker installed through apt" | ||
msg={ | ||
items.isDockerInstalledThroughApt | ||
? `Docker has been installed through the apt package manager. This is the recommended way to install docker in DAppNode so it can be automatically updated by unattended upgrades` | ||
: `Docker has not been installed through the apt package manager. This means that it will not be automatically updated by unattended upgrades` | ||
} | ||
ok={items.isDockerInstalledThroughApt} | ||
/> | ||
<Ok | ||
title="Docker is updated" | ||
msg={ | ||
items.isDockerInstalledThroughApt | ||
? `Docker host version ${items.dockerHostVersion}, Docker latest version ${items.dockerLatestVersion}` | ||
: `Docker host version ${items.dockerHostVersion}. Could not be determined the latest docker version available because docker is not installed through apt` | ||
} | ||
ok={ | ||
items.isDockerInstalledThroughApt && items.dockerLatestVersion | ||
? gte(items.dockerHostVersion, items.dockerLatestVersion) | ||
: false | ||
} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
export function DockerUpgrade() { | ||
const [updateReq, setUpdateReq] = useState<ReqStatus>({}); | ||
const [checkReq, setCheckReq] = useState< | ||
ReqStatus<DockerUpgradeRequirements> | ||
>({}); | ||
const [canUpdate, setCanUpdate] = useState<boolean>(false); | ||
|
||
useEffect(() => { | ||
if (checkReq.result) { | ||
const { | ||
isDockerInUnattendedUpgrades, | ||
isDockerInstalledThroughApt, | ||
dockerHostVersion, | ||
dockerLatestVersion | ||
} = checkReq.result; | ||
const canUpdate = | ||
!isDockerInUnattendedUpgrades || | ||
!isDockerInstalledThroughApt || | ||
Boolean( | ||
dockerLatestVersion && lt(dockerHostVersion, dockerLatestVersion) | ||
); | ||
setCanUpdate(canUpdate); | ||
} | ||
}, [checkReq.result]); | ||
|
||
async function dockerUpdateCheck() { | ||
try { | ||
setCheckReq({ loading: true }); | ||
const requirements = await api.dockerUpgradeCheck(); | ||
setCheckReq({ result: requirements }); | ||
} catch (e) { | ||
setCheckReq({ error: e }); | ||
} | ||
} | ||
|
||
async function dockerUpdate() { | ||
try { | ||
await new Promise<void>(resolve => { | ||
confirm({ | ||
title: `Docker update`, | ||
text: `Warning, you are about to update Docker . It is possible that the system will need to reboot. Make sure you can sustain some minutes of downtime and backup your most important data.`, | ||
label: "Update", | ||
onClick: resolve | ||
}); | ||
}); | ||
|
||
setUpdateReq({ loading: true }); | ||
await withToast(() => api.dockerUpgrade(), { | ||
message: "Updating Docker", | ||
onSuccess: "Updated Docker" | ||
}); | ||
setUpdateReq({ result: true }); | ||
// update the requirements after the update | ||
await dockerUpdateCheck(); | ||
} catch (e) { | ||
setUpdateReq({ error: e }); | ||
} | ||
} | ||
|
||
return ( | ||
<Card spacing> | ||
<p> | ||
Update docker to latest version, make sure its installed through the | ||
standard apt package manager and enable unattended upgrades for docker | ||
so you do not worry about updating docker anymore | ||
</p> | ||
|
||
{!canUpdate && ( | ||
<Button disabled={checkReq.loading} onClick={dockerUpdateCheck}> | ||
Check update requirements | ||
</Button> | ||
)} | ||
|
||
{checkReq.error ? ( | ||
<ErrorView error={checkReq.error} red hideIcon /> | ||
) : checkReq.loading ? ( | ||
<Ok msg={"Checking update requirements..."} loading={true} /> | ||
) : null} | ||
|
||
{checkReq.result && ( | ||
<> | ||
<RequirementsList items={checkReq.result} /> | ||
|
||
{canUpdate && ( | ||
<Button disabled={updateReq.loading} onClick={dockerUpdate}> | ||
Update docker | ||
</Button> | ||
)} | ||
|
||
{updateReq.result ? ( | ||
<Ok ok={true} msg={"Successfully updated docker"} /> | ||
) : updateReq.loading ? ( | ||
<Ok loading={true} msg={"Updating docker"} /> | ||
) : updateReq.error ? ( | ||
<ErrorView error={updateReq.error} red hideIcon /> | ||
) : null} | ||
</> | ||
)} | ||
</Card> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { | ||
dockerUpgradeService, | ||
dockerUpgradeCheck as _dockerUpgradeCheck | ||
} from "@dappnode/hostscriptsservices"; | ||
import { DockerUpgradeRequirements } from "@dappnode/types"; | ||
|
||
/** | ||
* Updates docker engine | ||
*/ | ||
export async function dockerUpgrade(): Promise<void> { | ||
await dockerUpgradeService(); | ||
} | ||
|
||
/** | ||
* Checks requirements to update docker | ||
*/ | ||
export async function dockerUpgradeCheck(): Promise<DockerUpgradeRequirements> { | ||
return await _dockerUpgradeCheck(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.