Skip to content

Commit

Permalink
rework ntp faiure handling and display to user
Browse files Browse the repository at this point in the history
  • Loading branch information
MattDHill committed Oct 26, 2023
1 parent 9a545f1 commit a584645
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ <h3 style="color: #f8546a; font-weight: bold">Important!</h3>
<p>
Download your server's Root CA and
<a
href="https://docs.start9.com/latest/user-manual/connecting/connecting-lan"
href="https://docs.start9.com/0.3.5.x/user-manual/getting-started/connecting-lan"
target="_blank"
rel="noreferrer"
style="color: #6866cc; font-weight: bold; text-decoration: none"
Expand Down Expand Up @@ -104,7 +104,7 @@ <h2 style="font-variant-caps: all-small-caps">
<span style="font-weight: bold">Note:</span>
This address will only work from a Tor-enabled browser.
<a
href="https://docs.start9.com/latest/user-manual/connecting/connecting-tor"
href="https://docs.start9.com/0.3.5.x/user-manual/getting-started/connecting-tor"
target="_blank"
rel="noreferrer"
style="color: #6866cc; font-weight: bold; text-decoration: none"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ export function getErrorMessage(
} else if (e.code === 0) {
message =
'Request Error. Your browser blocked the request. This is usually caused by a corrupt browser cache or an overly aggressive ad blocker. Please clear your browser cache and/or adjust your ad blocker and try again'
link = 'https://docs.start9.com/0.3.5.x/support/common-issues#request-error'
} else if (!e.message) {
message = 'Unknown Error'
link = 'https://docs.start9.com/latest/support/faq'
} else {
message = e.message
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class CAWizardComponent {

instructions() {
this.windowRef.open(
'https://docs.start9.com/0.3.5.x/getting-started/trust-ca/#trust-root-ca',
'https://docs.start9.com/0.3.5.x/user-manual/getting-started/trust-ca/#trust-root-ca',
'_blank',
'noreferrer',
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<h2>
For a secure local connection and faster Tor experience,
<a
href="https://docs.start9.com/0.3.5.x/getting-started/connecting-lan"
href="https://docs.start9.com/0.3.5.x/user-manual/getting-started/connecting-lan"
target="_blank"
rel="noreferrer"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<ion-back-button defaultHref="system"></ion-back-button>
</ion-buttons>
<ion-title>Monitor</ion-title>
<ion-title slot="end"
><ion-spinner name="dots" class="fader"></ion-spinner
></ion-title>
<ion-title slot="end">
<ion-spinner name="dots" class="fader"></ion-spinner>
</ion-title>
</ion-toolbar>
</ion-header>

Expand All @@ -16,28 +16,51 @@
<div id="metricSection">
<ng-container *ngIf="!loading">
<ion-item-group>
<ion-item-divider>Time</ion-item-divider>
<ion-item>
<ion-label>System Time</ion-label>
<ion-note slot="end" class="metric-note">
<ion-text style="color: white"
>{{ systemTime$ | async | date:'MMMM d, y, h:mm a z':'UTC'
}}</ion-text
>
</ion-note>
<!-- <ion-item-divider>Time</ion-item-divider> -->
<ion-item *ngIf="now$ | async as now; else timeLoading">
<ion-label>
<h1>System Time</h1>
<h2>
<ion-text style="color: white">
<b>{{ now.value | date:'MMMM d, y, h:mm a z':'UTC' }}</b>
</ion-text>
</h2>
<p *ngIf="!now.synced">
<ion-text color="warning">
NTP not synced, time could be wrong
</ion-text>
</p>
</ion-label>
<ion-note slot="end" class="metric-note"></ion-note>
</ion-item>
<ng-template #timeLoading>
<ion-item>
<ion-label>
<h1>System Time</h1>
<p>Loading...</p>
</ion-label>
<ion-note slot="end" class="metric-note"></ion-note>
</ion-item>
</ng-template>

<ion-item>
<ion-label>System Uptime</ion-label>
<ion-note
*ngIf="systemUptime$ | async as uptime"
slot="end"
class="metric-note"
>
<ion-text style="color: white">
<b>{{ uptime.days }}</b> Days, <b>{{ uptime.hours }}</b> Hours,
<b>{{ uptime.minutes }}</b> Minutes
</ion-text>
</ion-note>
<ion-label>
<h1>System Uptime</h1>
<h2>
<ion-text style="color: white">
<ng-container *ngIf="uptime$ | async as uptime">
<b>{{ uptime.days }}</b>
Days,
<b>{{ uptime.hours }}</b>
Hours,
<b>{{ uptime.minutes }}</b>
Minutes,
<b>{{ uptime.seconds }}</b>
Seconds
</ng-container>
</ion-text>
</h2>
</ion-label>
</ion-item>
</ion-item-group>

Expand All @@ -50,9 +73,9 @@
>
<ion-label>{{ metric.key }}</ion-label>
<ion-note *ngIf="metric.value" slot="end" class="metric-note">
<ion-text style="color: white"
>{{ metric.value.value }} {{ metric.value.unit }}</ion-text
>
<ion-text style="color: white">
{{ metric.value.value }} {{ metric.value.unit }}
</ion-text>
</ion-note>
</ion-item>
</ion-item-group>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export class ServerMetricsPage {
going = false
metrics: Metrics = {}

readonly systemTime$ = this.timeService.systemTime$
readonly systemUptime$ = this.timeService.systemUptime$
readonly now$ = this.timeService.now$
readonly uptime$ = this.timeService.uptime$

constructor(
private readonly errToast: ErrorToastService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,32 @@

<!-- loaded -->
<ion-item-group *ngIf="server$ | async as server; else loading">
<ion-item *ngIf="isTorHttp" color="warning">
<ion-item
*ngIf="!server['ntp-synced']"
color="warning"
class="ion-margin-bottom"
>
<ion-icon slot="start" name="warning-outline"></ion-icon>
<ion-label>
<h2 style="font-weight: bold">Clock sync failure</h2>
<p style="font-weight: 600">
This will cause connectivity issues. Refer to the StartOS docs to
resolve the issue.
</p>
</ion-label>
<ion-button
slot="end"
color="light"
href="https://docs.start9.com/0.3.5.x/support/common-issues#clock-sync-failure"
target="_blank"
rel="noreferrer"
>
Open Docs
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-button>
</ion-item>

<ion-item *ngIf="isTorHttp" color="warning" class="ion-margin-bottom">
<ion-icon slot="start" name="warning-outline"></ion-icon>
<ion-label>
<h2 style="font-weight: bold">Http detected</h2>
Expand Down
5 changes: 4 additions & 1 deletion frontend/projects/ui/src/app/services/api/api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ export module RR {
export type EchoRes = string

export type GetSystemTimeReq = {} // server.time
export type GetSystemTimeRes = string
export type GetSystemTimeRes = {
now: string
uptime: number
}

export type GetServerLogsReq = ServerLogsReq // server.logs & server.kernel-logs
export type GetServerLogsRes = LogsRes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ export class MockApiService extends ApiService {
params: RR.GetSystemTimeReq,
): Promise<RR.GetSystemTimeRes> {
await pauseFor(2000)
return new Date().toUTCString()
return {
now: new Date().toUTCString(),
uptime: 1234567,
}
}

async getServerLogs(
Expand Down
2 changes: 1 addition & 1 deletion frontend/projects/ui/src/app/services/api/mock-patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const mockPatchData: DataModel = {
hostname: 'random-words',
pubkey: 'npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237lmu63q0uf63m',
'ca-fingerprint': 'SHA-256: 63 2B 11 99 44 40 17 DF 37 FC C3 DF 0F 3D 15',
'system-start-time': new Date(new Date().valueOf() - 360042).toUTCString(),
'ntp-synced': false,
zram: false,
platform: 'x86_64-nonfree',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export interface ServerInfo {
hostname: string
pubkey: string
'ca-fingerprint': string
'system-start-time': string
'ntp-synced': boolean
zram: boolean
platform: string
}
Expand Down
65 changes: 33 additions & 32 deletions frontend/projects/ui/src/app/services/time-service.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,55 @@
import { Injectable } from '@angular/core'
import {
map,
shareReplay,
startWith,
switchMap,
take,
tap,
} from 'rxjs/operators'
import { map, shareReplay, startWith, switchMap } from 'rxjs/operators'
import { PatchDB } from 'patch-db-client'
import { DataModel } from './patch-db/data-model'
import { ApiService } from './api/embassy-api.service'
import { combineLatest, from, timer } from 'rxjs'
import { combineLatest, from, interval } from 'rxjs'

@Injectable({
providedIn: 'root',
})
export class TimeService {
private readonly startTimeMs$ = this.patch
.watch$('server-info', 'system-start-time')
.pipe(map(startTime => new Date(startTime).valueOf()))

readonly systemTime$ = from(this.apiService.getSystemTime({})).pipe(
switchMap(utcStr => {
const dateObj = new Date(utcStr)
const msRemaining = (60 - dateObj.getSeconds()) * 1000
dateObj.setSeconds(0)
const current = dateObj.valueOf()
return timer(msRemaining, 60000).pipe(
private readonly time$ = from(this.apiService.getSystemTime({})).pipe(
switchMap(({ now, uptime }) => {
const current = new Date(now).valueOf()
return interval(1000).pipe(
map(index => {
const incremented = index + 1
const msToAdd = 60000 * incremented
return current + msToAdd
const msToAdd = 1000 * incremented
return {
now: current + msToAdd,
uptime: uptime + msToAdd,
}
}),
startWith({
now: current,
uptime,
}),
startWith(current),
)
}),
shareReplay({ bufferSize: 1, refCount: true }),
)

readonly systemUptime$ = combineLatest([
this.startTimeMs$,
this.systemTime$,
readonly now$ = combineLatest([
this.time$,
this.patch.watch$('server-info', 'ntp-synced'),
]).pipe(
map(([startTime, currentTime]) => {
const ms = currentTime - startTime
const days = Math.floor(ms / (24 * 60 * 60 * 1000))
const daysms = ms % (24 * 60 * 60 * 1000)
map(([time, synced]) => ({
value: time.now,
synced,
})),
)

readonly uptime$ = this.time$.pipe(
map(({ uptime }) => {
const days = Math.floor(uptime / (24 * 60 * 60 * 1000))
const daysms = uptime % (24 * 60 * 60 * 1000)
const hours = Math.floor(daysms / (60 * 60 * 1000))
const hoursms = ms % (60 * 60 * 1000)
const hoursms = uptime % (60 * 60 * 1000)
const minutes = Math.floor(hoursms / (60 * 1000))
return { days, hours, minutes }
const minutesms = uptime % (60 * 1000)
const seconds = Math.floor(minutesms / 1000)
return { days, hours, minutes, seconds }
}),
)

Expand Down

0 comments on commit a584645

Please sign in to comment.