Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
e9720ff
feat!: initial vue 3 commit
jacdavi Jun 30, 2025
50b154e
Adding timeout
causand22 Jun 28, 2025
f77bf42
add missing dotfiles; fix App.vue variables
jacdavi Jul 1, 2025
967fc23
update env file and vite config
jacdavi Jul 1, 2025
6bcf711
fix: handle VITE_BASE_PATH correctly; handle undefined VITE_AUTH
jacdavi Jul 1, 2025
50c2766
fixing formatting
causand22 Jul 1, 2025
2abc22a
fixing redoc cli
causand22 Jul 1, 2025
786695f
general file reorg and cleanup
jacdavi Jul 1, 2025
3fc9f25
async loading the terminal
causand22 Jul 1, 2025
7ff4411
remove eventbus; confirm nav/reload in config editor
jacdavi Jul 1, 2025
6a3b0bd
renaming
causand22 Jul 1, 2025
edad068
fix disks on StoppedExperiment; rename experiment views
jacdavi Jul 1, 2025
7e53081
add different favicon for dev mode
jacdavi Jul 1, 2025
c646f59
fixing b-modal
causand22 Jul 3, 2025
6b491d9
undo makefile changes; add back known_policy
jacdavi Jul 8, 2025
fa42120
fix: update docker images for vue3
jacdavi Jul 9, 2025
e2f83fc
trigger gh actions
jacdavi Jul 9, 2025
1e1a029
fix: fix docs build in jit image
jacdavi Jul 9, 2025
918ca5f
fix: fix calls to @input and :on-cancel not working as expected
jacdavi Jul 10, 2025
c1f1bee
fix: update readme and clean up some code
jacdavi Jul 10, 2025
964d29c
add nvm use 22 in readme
causand22 Jul 10, 2025
97a23e9
fix: add back rbac tests
jacdavi Jul 10, 2025
06400d5
Merge branch 'feat/vue3' of https://github.com/causand22/sceptre-phen…
jacdavi Jul 10, 2025
1db4f7e
updating settings page
causand22 Jul 10, 2025
2f79229
run format
jacdavi Jul 10, 2025
5411fac
adding session storage so refresh doesn't log out
causand22 Jul 11, 2025
b804c85
updating search bars
causand22 Jul 11, 2025
dc9289d
adding tooltips to table action buttons
causand22 Jul 11, 2025
183f6b0
placeholder darker
causand22 Jul 11, 2025
77f38c5
fixing search bug
causand22 Jul 11, 2025
25e498a
fixing search clear
causand22 Jul 11, 2025
ece0f73
fixing text color
causand22 Jul 11, 2025
1c2c253
fixes disks download path
causand22 Jul 11, 2025
72b789a
removing old store / http
causand22 Jul 11, 2025
e894789
fix: minor fixes for config editor
jacdavi Jul 11, 2025
552e27f
Merge branch 'feat/vue3' of https://github.com/causand22/sceptre-phen…
jacdavi Jul 11, 2025
fd3392d
console log updates
jacdavi Jul 15, 2025
01ef57e
adding backend disk check
causand22 Jul 15, 2025
e68bc65
fixing log css, running format
causand22 Jul 16, 2025
c848499
fixing lodash bug
causand22 Jul 16, 2025
fe03318
bugfixing with labels'
causand22 Jul 16, 2025
5c162d8
Merge branch 'sandialabs:main' into feat/vue3
causand22 Jul 16, 2025
bd79389
fixing token creation
causand22 Jul 16, 2025
7908b0e
adding password reqs, oops
causand22 Jul 16, 2025
d2fece2
pushing all timeout settings
causand22 Jul 16, 2025
b9f5e46
Merge branch 'feat/vue3' of https://github.com/causand22/sceptre-phen…
jacdavi Jul 16, 2025
76fb845
footer on bottom
causand22 Jul 16, 2025
6a7bf3a
fix: add disabled user page
jacdavi Jul 16, 2025
6519a54
fix: create user flow, sign in on success, leave modal open on error
jacdavi Jul 16, 2025
54efdb1
fix: leave icons enabled on experiments page
jacdavi Jul 16, 2025
7de7b91
fix: fix experiment page not loading from other navigation paths
jacdavi Jul 16, 2025
094987f
fix: exception in SOH when filtering to empty list
jacdavi Jul 17, 2025
f2a5d6b
fix: Experiments table layout responsiveness
jacdavi Jul 17, 2025
d4a92f3
fix: adjust size of network volume graph
jacdavi Jul 17, 2025
ad171d9
fix: don't close create user modal on error
jacdavi Jul 17, 2025
32718bc
fix: update disk upload progress indicator
jacdavi Jul 17, 2025
ff0a3c1
fix: reset websocket on dev hot reload
jacdavi Jul 18, 2025
f9d4e9e
fix: users table didn't show role assigned for created user
jacdavi Jul 18, 2025
187b372
adding front end validation
causand22 Jul 18, 2025
59604cf
fixing file download
causand22 Jul 18, 2025
ec10d1b
removing token argument, not used
causand22 Jul 18, 2025
e90560a
reverting token, turns out it's needed
causand22 Jul 18, 2025
2e63c60
npm run format
causand22 Jul 18, 2025
ad966fe
commenting out analyzer
causand22 Jul 18, 2025
f96bf03
mini fix to error notification
causand22 Aug 2, 2025
e77e632
turning full page loading into just body -- so users can still nav
causand22 Aug 2, 2025
5256349
fix: cleanup js console logs; sign user out if invalid signature error
jacdavi Aug 3, 2025
940ee27
fix: add backoff for reconnecting websocket
jacdavi Aug 3, 2025
93d8d9b
fmt: npm run format
jacdavi Aug 3, 2025
28ec6b4
fix(jit): install vite in dockerfile
jacdavi Aug 7, 2025
0615443
fix(jit): install vite at build time via npm install
jacdavi Aug 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Welcome to `phenix`!
## Building

### Local build
To build locally, you will need Golang v1.18, Node v14.2, Yarn 1.22, and Protoc 3.14 installed.
To build locally, you will need Golang v1.20, Node 22, and Protoc 3.14 installed.

Once installed (if not already), simply run:
```bash
Expand Down
13 changes: 6 additions & 7 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FROM ghcr.io/sandia-minimega/minimega:${MM_MIN_REV} AS minimega


# ** jsbuilder **
FROM node:14.21.3 AS jsbuilder
FROM node:22 AS jsbuilder

ARG INSTALL_CERTS=
RUN ["/bin/bash", "-c", "if [ -n $INSTALL_CERTS ]; then \
Expand All @@ -15,10 +15,9 @@ RUN ["/bin/bash", "-c", "if [ -n $INSTALL_CERTS ]; then \
wget ${arr[$i]} -e use_proxy=no \
-O /usr/local/share/ca-certificates/custom$i.crt; \
done && \
update-ca-certificates; \
yarn config set cafile /etc/ssl/certs/ca-certificates.crt; fi"]
update-ca-certificates; fi"]

RUN npm install -g @vue/cli redoc-cli
RUN npm install -g @redocly/cli

COPY ./src/js /phenix/src/js

Expand All @@ -27,16 +26,16 @@ WORKDIR /phenix/src/js
ARG PHENIX_WEB_AUTH=disabled
ARG PHENIX_BASE_PATH=/

ENV VUE_APP_AUTH ${PHENIX_WEB_AUTH}
ENV VUE_BASE_PATH ${PHENIX_BASE_PATH}
ENV VITE_AUTH ${PHENIX_WEB_AUTH}
ENV VITE_BASE_PATH ${PHENIX_BASE_PATH}

RUN make dist/index.html

COPY ./src/go/web/public/docs/openapi.yml /phenix/src/go/web/public/docs/openapi.yml

WORKDIR /phenix/src/go/web/public/docs

RUN npx redoc-cli build openapi.yml -o index.html --title 'phenix API'
RUN npx @redocly/cli build-docs openapi.yml -o index.html --title 'phenix API'


# ** gobuilder **
Expand Down
7 changes: 3 additions & 4 deletions docker/jit/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ FROM $PHENIX_IMG
ARG PHENIX_REPO
ARG PHENIX_BRANCH

ENV NODE_VERSION 14.21.3
ENV NODE_VERSION 22.17.0

RUN wget -O node.txz https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz \
&& tar -xJf node.txz -C /usr/local --strip-components=1 --no-same-owner && rm node.txz \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs

RUN npm install -g @vue/cli redoc-cli yarn
RUN npm install -g @redocly/cli
RUN git clone --branch ${PHENIX_BRANCH} https://github.com/${PHENIX_REPO}.git /usr/local/src/phenix \
&& mkdir -p /opt/phenix/web \
&& cp -a /usr/local/src/phenix/src/go/web/public /opt/phenix/web

WORKDIR /usr/local/src/phenix/src/js
RUN yarn install
WORKDIR /opt/phenix/web/public
RUN npx redoc-cli build docs/openapi.yml -o docs/index.html --title 'phenix API'
RUN npx @redocly/cli build-docs docs/openapi.yml -o docs/index.html --title 'phenix API'

COPY phenix-ui-entrypoint.sh /phenix-ui-entrypoint.sh
RUN chmod +x /phenix-ui-entrypoint.sh
Expand Down
3 changes: 2 additions & 1 deletion docker/jit/phenix-ui-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ echo "building phenix UI (this could take a while...)"
start_time=$(date +%s)

pushd /usr/local/src/phenix/src/js &> /dev/null
VUE_BASE_PATH=$base VUE_APP_AUTH=$auth npm run build &> /tmp/phenix-ui-build.log
npm install &> /tmp/phenix-ui-build.log
VITE_BASE_PATH=$base VITE_AUTH=$auth npm run build &> /tmp/phenix-ui-build.log
res=$?

if [ $res -ne 0 ]; then
Expand Down
33 changes: 20 additions & 13 deletions hack/build/docker-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,18 @@ fi


docker build -t phenix:builder -f - . <<EOF
FROM ubuntu:20.04

FROM node:22

SHELL ["/bin/bash", "-c"]

RUN ["/bin/bash", "-c", "if (( $USER_UID != 0 )); then \
groupadd --gid $USER_UID $USERNAME \
&& useradd -s /bin/bash --uid $USER_UID --gid $USER_UID -m $USERNAME; fi"]

RUN apt update && apt install -y curl gnupg2 make protobuf-compiler wget xz-utils
RUN apt update && apt install -y curl gnupg2 make protobuf-compiler wget xz-utils git

ENV GOLANG_VERSION 1.18.5
ENV GOLANG_VERSION 1.20.14

RUN wget -O go.tgz https://golang.org/dl/go\${GOLANG_VERSION}.linux-amd64.tar.gz \
&& tar -C /usr/local -xzf go.tgz && rm go.tgz
Expand All @@ -85,17 +88,21 @@ ENV PATH \$GOPATH/bin:/usr/local/go/bin:\$PATH
RUN mkdir -p \$GOPATH/src \$GOPATH/bin \
&& chmod -R 777 \$GOPATH

ENV NODE_VERSION 12.18.3
# use full version name here (e.g., 22.17.0 instead of 22)
# ENV NVM_DIR /root/.nvm

# RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# RUN source \$NVM_DIR/nvm.sh \
# && nvm install \$NODE_VERSION \
# && nvm alias default \$NODE_VERSION \
# && nvm use default

RUN wget -O node.txz https://nodejs.org/dist/v\${NODE_VERSION}/node-v\${NODE_VERSION}-linux-x64.tar.xz \
&& tar -xJf node.txz -C /usr/local --strip-components=1 --no-same-owner && rm node.txz \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
# RUN chmod a+x \$NVM_DIR/nvm.sh
RUN npm install -g @redocly/cli
# ENTRYPOINT ["bash", "-c", "source \$NVM_DIR/nvm.sh && exec \"$@\"", "--"]

RUN npm install -g @vue/cli redoc-cli
# CMD []

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
&& apt update && apt install -y yarn
EOF


Expand All @@ -111,8 +118,8 @@ docker run -it --rm \
-v $ROOT_DIR:/phenix \
-w /phenix \
-u $USERNAME \
-e VUE_APP_AUTH=$auth \
-e VUE_BASE_PATH=$base \
-e VITE_AUTH=$auth \
-e VITE_BASE_PATH=$base \
-e TAG=$tag \
-e COMMIT=$commit \
phenix:builder make bin/phenix
Expand Down
12 changes: 6 additions & 6 deletions podman/Containerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM docker.io/library/node:12.18.3 AS jsbuilder
FROM docker.io/library/node:22 AS jsbuilder

RUN npm install -g @vue/cli redoc-cli
RUN npm install -g @redocly/cli

COPY ./src/js /phenix/src/js

Expand All @@ -9,8 +9,8 @@ WORKDIR /phenix/src/js
ARG PHENIX_WEB_AUTH=disabled
ARG PHENIX_BASE_PATH=/

ENV VUE_APP_AUTH ${PHENIX_WEB_AUTH}
ENV VUE_BASE_PATH ${PHENIX_BASE_PATH}
ENV VITE_AUTH ${PHENIX_WEB_AUTH}
ENV VITE_BASE_PATH ${PHENIX_BASE_PATH}

RUN npm install \
&& npm run build
Expand All @@ -19,10 +19,10 @@ COPY ./src/go/web/public/docs/openapi.yml /phenix/src/go/web/public/docs/openapi

WORKDIR /phenix/src/go/web/public/docs

RUN npx redoc-cli bundle openapi.yml -o index.html --title 'phenix API'
RUN npx build-docs bundle openapi.yml -o index.html --title 'phenix API'


FROM docker.io/library/golang:1.17.2 AS gobuilder
FROM docker.io/library/golang:1.24.1 AS gobuilder

RUN apt update \
&& apt install -y protobuf-compiler xz-utils
Expand Down
2 changes: 1 addition & 1 deletion src/go/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ bindata.go
mock.go

web/public/assets
web/public/favicon.ico
web/public/favicon*.ico
web/public/index.html
web/public/docs/index.html
4 changes: 2 additions & 2 deletions src/go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ clean:
$(RM) web/bindata.go
$(RM) web/proto/*.pb.go
$(RM) web/public/docs/index.html
$(RM) web/public/favicon.ico
$(RM) web/public/favicon*.ico
$(RM) web/public/index.html
$(RM) -r web/public/assets
$(RM) web/rbac/known_policy.go
Expand Down Expand Up @@ -68,7 +68,7 @@ tmpl/bindata.go: $(TEMPLATES) bin/go-bindata
$(GOBIN)/go-bindata -pkg tmpl -prefix tmpl/templates -o tmpl/bindata.go tmpl/templates/...

web/public/docs/index.html: web/public/docs/openapi.yml
npx redoc-cli build web/public/docs/openapi.yml -o web/public/docs/index.html --title 'phenix API'
npx @redocly/cli build-docs web/public/docs/openapi.yml -o web/public/docs/index.html --title 'phenix API'

web/bindata.go: web/public/docs/index.html web/public/index.html web/public/vnc.html bin/go-bindata
$(GOBIN)/go-bindata -pkg web -prefix web/public -o web/bindata.go web/public/...
Expand Down
9 changes: 8 additions & 1 deletion src/go/api/disk/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package disk
import (
"fmt"
"path/filepath"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -41,6 +42,12 @@ func (MMDiskFiles) RebaseDisk(src, dst string, unsafe bool) error {

func (MMDiskFiles) ResizeDisk(src, size string) error {
cmd := mmcli.NewCommand()

re := regexp.MustCompile(`[+-]?\d+[KMGTPE]`)
if !re.MatchString(size) {
return fmt.Errorf("provided size does not match valid pattern")
}

cmd.Command = fmt.Sprintf("disk resize %s %s", src, size)
_, err := mmcli.SingleDataResponse(mmcli.Run(cmd))
return err
Expand Down Expand Up @@ -176,7 +183,7 @@ func resolveImage(path string) []Details {
}
}
if !knownFormat {
plog.Debug(plog.TypeSystem, "file didn't match know image extensions: %s", "path", path)
plog.Debug(plog.TypeSystem, "file didn't match known image extensions: %s", "path", path)
return imageDetails
}

Expand Down
4 changes: 4 additions & 0 deletions src/go/api/settings/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ var DEFAULT_SETTINGS = []v2.Setting{
{Category: "Password", Name: "UppercaseReq", Type: v2.SettingValueBool, Value: strconv.FormatBool(false)},
{Category: "Password", Name: "MinLength", Type: v2.SettingValueInt, Value: formatInt(8)},

{Category: "Timeout", Name: "Enabled", Type: v2.SettingValueBool, Value: strconv.FormatBool(false)},
{Category: "Timeout", Name: "TimeoutMin", Type: v2.SettingValueFloat, Value: formatFloat(30)},
{Category: "Timeout", Name: "WarningMin", Type: v2.SettingValueFloat, Value: formatFloat(3)},

{Category: "Logging", Name: "MaxFileRotations", Type: v2.SettingValueInt, Value: formatInt(0)},
{Category: "Logging", Name: "MaxFileSize", Type: v2.SettingValueInt, Value: formatInt(100)},
{Category: "Logging", Name: "MaxFileAge", Type: v2.SettingValueInt, Value: formatInt(90)},
Expand Down
9 changes: 8 additions & 1 deletion src/go/api/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Adding a new setting:
type Settings struct {
PasswordSettings PasswordSettings `json:"password_settings"`
LoggingSettings LoggingSettings `json:"logging_settings"`

TimeoutSettings TimeoutSettings `json:"timeout_settings"`
}

func GetSettings() (*Settings, error) {
Expand All @@ -52,6 +52,10 @@ func GetSettings() (*Settings, error) {
return nil, fmt.Errorf("Error getting logging settings: %v", err)
}

settings.TimeoutSettings, err = GetTimeoutSettingsFromList(settingList)
if err != nil {
return nil, fmt.Errorf("Error getting timeout settings: %v", err)
}

return settings, nil
}
Expand All @@ -67,6 +71,9 @@ func UpdateAllSettings(newSettings Settings) error {
return fmt.Errorf("Error updating logging settings: %w", err)
}

if err := UpdateTimeoutSettings(newSettings.TimeoutSettings); err != nil {
return fmt.Errorf("Error updating timeout settings: %w", err)
}

return nil
}
Expand Down
73 changes: 73 additions & 0 deletions src/go/api/settings/timeout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package settings

import (
"fmt"
"phenix/types"
"strconv"
)

type TimeoutSettings struct {
Enabled bool `json:"enabled"`
TimeoutMin float64 `json:"timeout_min"`
WarningMin float64 `json:"warning_min"`
}

func GetTimeoutSettings() (TimeoutSettings, error) {
settings, err := List()
if err != nil {
return TimeoutSettings{}, fmt.Errorf("Error listing settings; %w", err)
}

return GetTimeoutSettingsFromList(settings)
}

func GetTimeoutSettingsFromList(settings []types.Setting) (TimeoutSettings, error) {
timeout := TimeoutSettings{}
var err error

for _, setting := range settings {
category := setting.Spec.Category
name := setting.Spec.Name
if category != "Timeout" {
continue
}

switch name {
case "Enabled":
timeout.Enabled, err = strconv.ParseBool(setting.Spec.Value)
if err != nil {
return timeout, fmt.Errorf("Error parsing %s.%s setting: %w", category, name, err)
}
case "TimeoutMin":
timeout.TimeoutMin, err = parseFloat(setting.Spec.Value)
if err != nil {
return timeout, fmt.Errorf("Error parsing %s.%s setting: %w", category, name, err)
}
case "WarningMin":
timeout.WarningMin, err = parseFloat(setting.Spec.Value)
if err != nil {
return timeout, fmt.Errorf("Error parsing %s.%s setting: %w", category, name, err)
}
}
}

return timeout, nil
}

func UpdateTimeoutSettings(newSettings TimeoutSettings) error {
var err error

_, err = Update("Timeout", "Enabled", strconv.FormatBool(newSettings.Enabled))
if err != nil {
return fmt.Errorf("Error updating Timeout.Enabled: %w", err)
}
_, err = Update("Timeout", "TimeoutMin", formatFloat(newSettings.TimeoutMin))
if err != nil {
return fmt.Errorf("Error updating Timeout.Delay: %w", err)
}
_, err = Update("Timeout", "WarningMin", formatFloat(newSettings.WarningMin))
if err != nil {
return fmt.Errorf("Error updating Timeout.Delay: %w", err)
}
return nil
}
21 changes: 21 additions & 0 deletions src/go/web/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3090,3 +3090,24 @@ func GetPasswordRequirements(w http.ResponseWriter, r *http.Request) {
}
w.Write(body)
}

func GetTimeoutSettings(w http.ResponseWriter, r *http.Request) {
plog.Debug("HTTP handler called", "handler", "GetTimeoutSettings")
settings.SetDefaults()

timeoutReqs, err := settings.GetTimeoutSettings()
if err != nil {
plog.Error("Getting password settings:", "err", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
body, err := json.Marshal(timeoutReqs)
if err != nil {
plog.Error(plog.TypeSystem, "Marshalling timeout reqs:", "err", err)
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
w.Write(body)
}
2 changes: 1 addition & 1 deletion src/go/web/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,13 @@ func Start(opts ...ServerOption) error {
api.HandleFunc("/settings", GetSettings).Methods("GET", "OPTIONS")
api.HandleFunc("/settings", SetSettings).Methods("POST", "OPTIONS")
api.HandleFunc("/settings/password", GetPasswordRequirements).Methods("GET", "OPTIONS")
api.HandleFunc("/settings/timeout", GetTimeoutSettings).Methods("GET", "OPTIONS")

workflowRoutes := []route{
{"/workflow/apply/{branch}", weberror.ErrorHandler(ApplyWorkflow), []string{"POST"}},
{"/workflow/configs/{branch}", weberror.ErrorHandler(WorkflowUpsertConfig), []string{"POST"}},
}


optionRoutes := []route{
{"/options", weberror.ErrorHandler(GetOptions), []string{"GET"}},
}
Expand Down
3 changes: 0 additions & 3 deletions src/js/.browserslistrc

This file was deleted.

Loading