Skip to content

Commit

Permalink
feat: support deletion of files in disk images
Browse files Browse the repository at this point in the history
In addition to injecting files present on the phenix head node into a
disk image, this capability adds support for deleting files already
present inside a disk image using a new `deletions` key in the topology
node schema.

Relies on a minimega feature added in sandia-minimega/minimega@9f867b3
  • Loading branch information
glattercj authored and activeshadow committed Feb 20, 2025
1 parent bb4d18e commit 5322e7c
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
context: .
file: docker/Dockerfile
build-args: |
MM_MIN_REV=da0b90c
MM_MIN_REV=9f867b3
PHENIX_COMMIT=${{ env.sha }}
PHENIX_TAG=${{ env.branch }}
APPS_REPO=github.com/${{ github.event_name == 'repository_dispatch' && github.event.client_payload.repo || 'sandialabs/sceptre-phenix-apps' }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/minimega.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ jobs:
context: docker
file: docker/Dockerfile.minimega
build-args: |
MM_REV=da0b90c
MM_REV=9f867b3
PHENIX_REVISION=${{ env.sha }}
push: true
tags: |
ghcr.io/${{ github.repository }}/minimega:da0b90c
ghcr.io/${{ github.repository }}/minimega:9f867b3
ghcr.io/${{ github.repository }}/minimega:${{ env.sha }}
ghcr.io/${{ github.repository }}/minimega:${{ env.branch }}
4 changes: 2 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Update GitHub workflow config to change the minimum version of minimega
# required for use with phenix. This build stage is needed for making sure the
# latest version of the minimega Python module is installed.
ARG MM_MIN_REV=c8e20a3
ARG MM_MIN_REV=9f867b3
FROM ghcr.io/activeshadow/minimega/minimega:${MM_MIN_REV} AS minimega


Expand Down Expand Up @@ -170,7 +170,7 @@ COPY --from=gobuilder /phenix/src/go/bin/phenix-tunneler-* /opt/phenix/downloads

# Update GitHub workflow config to change the minimum version of minimega
# required for use with phenix.
ARG MM_MIN_REV=c8e20a3
ARG MM_MIN_REV=9f867b3
LABEL gov.sandia.phenix.minimega-min-revision="ghcr.io/sandialabs/sceptre-phenix/minimega:${MM_MIN_REV}"

WORKDIR /opt/phenix
Expand Down
4 changes: 2 additions & 2 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services:
context: ../
dockerfile: docker/Dockerfile
args:
MM_MIN_REV: da0b90c
MM_MIN_REV: 9f867b3
PHENIX_WEB_AUTH: disabled
APPS_REPO: github.com/activeshadow/phenix-apps
APPS_BRANCH: caldera
Expand Down Expand Up @@ -46,7 +46,7 @@ services:
context: .
dockerfile: Dockerfile.minimega
args:
MM_REV: da0b90c
MM_REV: 9f867b3
image: minimega
container_name: minimega
privileged: true
Expand Down
7 changes: 5 additions & 2 deletions src/go/tmpl/templates/minimega_script.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ ns add-host localhost
## DoNotBoot: {{ derefBool .General.DoNotBoot }} ##
{{- else }}
{{- if (derefBool .General.Snapshot) -}}
{{ $firstDrive := index .Hardware.Drives 0 }}
disk snapshot {{ $firstDrive.Image }} {{ $.SnapshotName .General.Hostname }}
{{ $firstDrive := index .Hardware.Drives 0 }}
disk snapshot {{ $firstDrive.Image }} {{ $.SnapshotName .General.Hostname }}
{{- if gt (len .Injections) 0 }}
disk inject {{ $.SnapshotName .General.Hostname }}:{{ $firstDrive.GetInjectPartition }} files {{ .FileInjects $basedir }}
{{- end }}
{{- if gt (len .Deletions) 0 }}
disk inject {{ $.SnapshotName .General.Hostname }}:{{ $firstDrive.GetInjectPartition }} delete files {{ .FileDeletions }}
{{- end }}
{{- end }}
clear vm config
{{- if ne (index $.Schedules .General.Hostname) "" }}
Expand Down
8 changes: 8 additions & 0 deletions src/go/types/interfaces/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ type NodeSpec interface {
Hardware() NodeHardware
Network() NodeNetwork
Injections() []NodeInjection
Deletions() []NodeDeletion
Delay() NodeDelay
Advanced() map[string]string
Overrides() map[string]string
Commands() []string
External() bool

SetInjections([]NodeInjection)
SetDeletions([]NodeDeletion)
SetType(string)
SetLabels(map[string]string)

Expand Down Expand Up @@ -87,6 +89,7 @@ type NodeSpec interface {
// - network: 75.75.0.0/16
AddNetworkOSPF(routerID string, dead, hello, retrans int, areas map[int][]string)
AddInject(string, string, string, string)
AddDeletion(string, string)

SetAdvanced(map[string]string)
AddAdvanced(string, string)
Expand Down Expand Up @@ -254,6 +257,11 @@ type NodeInjection interface {
Permissions() string
}

type NodeDeletion interface {
Path() string
Description() string
}

type NodeDelay interface {
Timer() time.Duration
User() bool
Expand Down
55 changes: 52 additions & 3 deletions src/go/types/version/v0/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Node struct {
HardwareF *Hardware `json:"hardware" yaml:"hardware" structs:"hardware" mapstructure:"hardware"`
NetworkF *Network `json:"network" yaml:"network" structs:"network" mapstructure:"network"`
InjectionsF []*Injection `json:"injections" yaml:"injections" structs:"injections" mapstructure:"injections"`

DeletionsF []*Deletion `json:"deletions" yaml:"deletions" structs:"deletions" mapstructure:"deletions"`
}

func (this Node) Annotations() map[string]interface{} {
Expand Down Expand Up @@ -55,6 +55,16 @@ func (this Node) Injections() []ifaces.NodeInjection {
return injects
}

func (this Node) Deletions() []ifaces.NodeDeletion {
deletions := make([]ifaces.NodeDeletion, len(this.DeletionsF))

for i, j := range this.DeletionsF {
deletions[i] = j
}

return deletions
}

func (this Node) Delay() ifaces.NodeDelay {
return new(Delay)
}
Expand Down Expand Up @@ -85,6 +95,16 @@ func (this *Node) SetInjections(injections []ifaces.NodeInjection) {
this.InjectionsF = injects
}

func (this *Node) SetDeletions(deletions []ifaces.NodeDeletion) {
deletionList := make([]*Deletion, len(deletions))

for i, j := range deletions {
deletionList[i] = j.(*Deletion)
}

this.DeletionsF = deletionList
}

func (this *Node) SetType(t string) {
this.TypeF = t
}
Expand Down Expand Up @@ -182,6 +202,13 @@ func (this *Node) AddInject(src, dst, perms, desc string) {
})
}

func (this *Node) AddDeletion(path, desc string) {
this.DeletionsF = append(this.DeletionsF, &Deletion{
PathF: path,
DescriptionF: desc,
})
}

func (Node) SetAdvanced(map[string]string) {}
func (Node) AddAdvanced(string, string) {}
func (Node) AddOverride(string, string) {}
Expand Down Expand Up @@ -211,7 +238,6 @@ type General struct {
VMTypeF string `json:"vm_type" yaml:"vm_type" structs:"vm_type" mapstructure:"vm_type"`
SnapshotF *bool `json:"snapshot" yaml:"snapshot" structs:"snapshot" mapstructure:"snapshot"`
DoNotBootF *bool `json:"do_not_boot" yaml:"do_not_boot" structs:"do_not_boot" mapstructure:"do_not_boot"`

}

func (this General) Hostname() string {
Expand All @@ -229,7 +255,7 @@ func (this General) VMType() string {
func (this General) Snapshot() *bool {
return this.SnapshotF
}
func (this *General) SetSnapshot(b bool) {
func (this *General) SetSnapshot(b bool) {
this.SnapshotF = &b
}

Expand Down Expand Up @@ -353,6 +379,19 @@ func (this Injection) Permissions() string {
return this.PermissionsF
}

type Deletion struct {
PathF string `json:"path" yaml:"path" structs:"path" mapstructure:"path"`
DescriptionF string `json:"description" yaml:"description" structs:"description" mapstructure:"description"`
}

func (this Deletion) Path() string {
return this.PathF
}

func (this Deletion) Description() string {
return this.DescriptionF
}

type Delay struct{}

func (this Delay) Timer() time.Duration {
Expand Down Expand Up @@ -423,6 +462,16 @@ func (this Node) FileInjects(baseDir string) string {
return strings.Join(injects, " ")
}

func (this Node) FileDeletions() string {
deletions := make([]string, len(this.DeletionsF))

for i, deletion := range this.DeletionsF {
deletions[i] = fmt.Sprintf(`"%s"`, deletion.PathF)
}

return strings.Join(deletions, ",")
}

func (this Node) RouterName() string {
if !strings.EqualFold(this.TypeF, "router") {
return this.GeneralF.HostnameF
Expand Down
68 changes: 68 additions & 0 deletions src/go/types/version/v1/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Node struct {
HardwareF *Hardware `json:"hardware" yaml:"hardware" structs:"hardware" mapstructure:"hardware"`
NetworkF *Network `json:"network" yaml:"network" structs:"network" mapstructure:"network"`
InjectionsF []*Injection `json:"injections" yaml:"injections" structs:"injections" mapstructure:"injections"`
DeletionsF []*Deletion `json:"deletions" yaml:"deletions" structs:"deletions" mapstructure:"deletions"`
AdvancedF map[string]string `json:"advanced" yaml:"advanced" structs:"advanced" mapstructure:"advanced"`
OverridesF map[string]string `json:"overrides" yaml:"overrides" structs:"overrides" mapstructure:"overrides"`
DelayF *Delay `json:"delay" yaml:"delay" structs:"delay" mapstructure:"delay"`
Expand Down Expand Up @@ -59,6 +60,16 @@ func (this Node) Injections() []ifaces.NodeInjection {
return injects
}

func (this Node) Deletions() []ifaces.NodeDeletion {
deletions := make([]ifaces.NodeDeletion, len(this.DeletionsF))

for i, j := range this.DeletionsF {
deletions[i] = j
}

return deletions
}

func (this Node) Delay() ifaces.NodeDelay {
if this.DelayF == nil {
return new(Delay)
Expand Down Expand Up @@ -102,6 +113,16 @@ func (this *Node) SetInjections(injections []ifaces.NodeInjection) {
this.InjectionsF = injects
}

func (this *Node) SetDeletions(deletions []ifaces.NodeDeletion) {
deletionList := make([]*Deletion, len(deletions))

for i, j := range deletions {
deletionList[i] = j.(*Deletion)
}

this.DeletionsF = deletionList
}

func (this *Node) SetType(t string) {
this.TypeF = t
}
Expand Down Expand Up @@ -243,6 +264,30 @@ func (this *Node) AddInject(src, dst, perms, desc string) {
}
}

func (this *Node) AddDeletion(path, desc string) {
if _, ok := this.LabelsF["disable-injects"]; ok {
return
}

var exists bool

for _, deletion := range this.DeletionsF {
if deletion.PathF == path {
deletion.DescriptionF = desc

exists = true
break
}
}

if !exists {
this.DeletionsF = append(this.DeletionsF, &Deletion{
PathF: path,
DescriptionF: desc,
})
}
}

func (this *Node) SetAdvanced(adv map[string]string) {
this.AdvancedF = adv
}
Expand Down Expand Up @@ -512,6 +557,19 @@ func (this Injection) Permissions() string {
return this.PermissionsF
}

type Deletion struct {
PathF string `json:"path" yaml:"path" structs:"path" mapstructure:"path"`
DescriptionF string `json:"description" yaml:"description" structs:"description" mapstructure:"description"`
}

func (this Deletion) Path() string {
return this.PathF
}

func (this Deletion) Description() string {
return this.DescriptionF
}

func (this Node) validate() error {
if this.ExternalF == nil {
return nil
Expand Down Expand Up @@ -636,6 +694,16 @@ func (this Node) FileInjects(baseDir string) string {
return strings.Join(injects, " ")
}

func (this Node) FileDeletions() string {
deletions := make([]string, len(this.DeletionsF))

for i, deletion := range this.DeletionsF {
deletions[i] = fmt.Sprintf(`"%s"`, deletion.PathF)
}

return strings.Join(deletions, ",")
}

func (this Node) RouterName() string {
if !strings.EqualFold(this.TypeF, "router") {
return this.GeneralF.HostnameF
Expand Down

0 comments on commit 5322e7c

Please sign in to comment.