Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release-merge #128

Merged
merged 41 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
52185ca
[none working] implemented tracepoint for syscall write
der-whity Nov 20, 2024
6fcd0c4
refactor: use source sets instead of runtime checks
luca-dot-sh Nov 20, 2024
94bb0b7
refactor: additional renaming suggestions and more from PR
luca-dot-sh Nov 20, 2024
41d8555
Merge pull request #99 from amosproj/refactor_frontend
fhilgers Nov 22, 2024
b2a787c
fixed: filepointer instead of filedeskriptor
der-whity Nov 22, 2024
b6a7e50
implemented Tracepoint for sendmsg
der-whity Nov 23, 2024
0968eb1
refactored vfs_write and sendmsg
der-whity Nov 23, 2024
6c8737f
created REEADME for eBPF programs
der-whity Nov 23, 2024
71296d8
feat: add apps to processes, configuration menu, per process configur…
luca-dot-sh Nov 22, 2024
7ec4463
[None working] Changed proto files and started to redesign ebpf_utils
Mr-Kanister Nov 24, 2024
aad8641
Merge pull request #103 from amosproj/per_process_config
luca-dot-sh Nov 24, 2024
7b84f2f
Merge pull request #102 from amosproj/TraceSendMsg
der-whity Nov 24, 2024
2eab9dc
[none working] add error bubbling
Mr-Kanister Nov 24, 2024
2ef0ca4
Split create, destroy into create, destroy, attach, detach
Mr-Kanister Nov 25, 2024
e82e22f
chore(eBPF): added tracking the syscall-duration in mikroseconds
der-whity Nov 25, 2024
77c3091
feat: add ebpf logger
fhilgers Nov 25, 2024
9faae66
fix: load programs at startup
fhilgers Nov 25, 2024
11a5467
feat: implement collecting and sending of vfs write events
fhilgers Nov 25, 2024
7cedf11
feat: adapt client for init_stream
fhilgers Nov 25, 2024
5e5a95c
feat: adapt bindings for init_stream
fhilgers Nov 25, 2024
bb00a1e
Add state struct, integrate changes into server.rs
Mr-Kanister Nov 25, 2024
258b295
Merge pull request #105 from amosproj/88-vfs-write-new
fhilgers Nov 25, 2024
07b5a61
Merge branch 'dev' into 80-sendmsg
fhilgers Nov 25, 2024
12b0f29
Outsource features in seperate file
Mr-Kanister Nov 25, 2024
d3aa32c
Merge pull request #104 from amosproj/80-sendmsg
BenediktZinn Nov 25, 2024
72efb8f
Merge branch 'dev' into config-rework
Mr-Kanister Nov 25, 2024
6cbbd05
Fix reuse
Mr-Kanister Nov 25, 2024
dc02279
created Map for pids to track
der-whity Nov 25, 2024
cb7741e
Merge pull request #107 from amosproj/80-sendmsgConfigure
fhilgers Nov 25, 2024
50626ec
fix: make frontend work with config-rework
fhilgers Nov 26, 2024
62ed97a
Merge branch 'dev' into config-rework
fhilgers Nov 26, 2024
e341301
Merge pull request #106 from amosproj/config-rework
ffranzgitHub Nov 26, 2024
6aefa46
feat: sendmsg collection and config
fhilgers Nov 26, 2024
72e2a70
Merge pull request #108 from amosproj/sendmsg-setup
BenediktZinn Nov 26, 2024
aaa1185
feat: implement demo program for sendmsg
fhilgers Nov 25, 2024
0e6dc2b
Merge pull request #125 from amosproj/sendmsg-demo
fhilgers Nov 26, 2024
5cbf62b
feat: add configuration screen with working metric selection and even…
luca-dot-sh Nov 25, 2024
5a7a9b2
fix: Remove old timestamps from map
fhilgers Nov 26, 2024
5709aa4
Merge pull request #126 from amosproj/vis_metrics_updated
fhilgers Nov 27, 2024
1228133
chore: sprint-06 deliverables
fhilgers Nov 27, 2024
0a94d76
Merge pull request #127 from amosproj/sprint-06-deliverables
alinawlo Nov 27, 2024
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
Binary file added Deliverables/sprint-06/build-documentation.pdf
Binary file not shown.
Binary file added Deliverables/sprint-06/design-documentation.pdf
Binary file not shown.
Binary file added Deliverables/sprint-06/feature-board.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions Deliverables/sprint-06/feature-board.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Title URL Assignees Status Estimated size Real size
Identify Running State https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/75 Awaiting Review 3
EPIC: analyze unix domain sockets https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/80 BenediktZinn, der-whity, ffranzgitHub, fhilgers, luca-dot-sh, Mr-Kanister Awaiting Review 5
Unix Domain Socket: Daemon Collector https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/113 BenediktZinn, ffranzgitHub, fhilgers Awaiting Review 2
Unix Domain Socket: Configuration https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/112 ffranzgitHub, Mr-Kanister Awaiting Review 2
Unix Domain Socket: Frontend https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/114 luca-dot-sh Awaiting Review 3
Unix Domain Socket: Ebpf https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/111 der-whity Awaiting Review 2
Plaintext architecture document https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/34 fhilgers, Mr-Kanister Awaiting Review 3
EPIC: uprobe https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/19 Sprint Backlog 8
Define metric for the visualisation screen https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/46 Sprint Backlog 3
internal: implement client library and export to kotlin for load and list programs https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/60 BenediktZinn, fhilgers Feature Archive 2 1
Display running processes in UI https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/73 luca-dot-sh Feature Archive 2 2
User eBPF programm Selection https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/41 ffranzgitHub, fhilgers, Mr-Kanister Feature Archive 5 -1
internal: define kotlin interface for frontend loading and listing programs https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/58 fhilgers Feature Archive 1 1
internal: implement loading/unloading of ebpf functions in daemon https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/77 der-whity, ffranzgitHub, Mr-Kanister Feature Archive 2 3
Retrieve running processes List https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/72 Mr-Kanister Feature Archive 3 3
Home Screen and Navigation Drawer https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/43 luca-dot-sh Feature Archive 2 3
EBPF Program extension https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/54 der-whity Feature Archive 3 3
Bugfix: Manage Sbom generation through nix https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/55 Mr-Kanister Feature Archive 1 1
Communcation between Android side and Rust side https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/42 fhilgers Feature Archive 5 5
scope(ebpf) unix domain socket traffic analysis (research) https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/22 fhilgers Feature Archive 5 3
Create a prototype for the visualisation screen https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/47 luca-dot-sh Feature Archive 3 3
internal: implement frontend load and list programs https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/62 luca-dot-sh Feature Archive 2 2
internal: implement test cli client load and list programs https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/59 BenediktZinn, ffranzgitHub, Mr-Kanister Feature Archive 3 2
Preparation of CI https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/6 fhilgers Feature Archive 3 3
scope(ui) find timeseries visualization library (research) https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/21 clabrous, luca-dot-sh Feature Archive 2 2
Generation of sboms doesn't include kotlin https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/39 Feature Archive 1 1
Manage Sbom generation through nix https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/30 Mr-Kanister Feature Archive 2 1
scope(daemon) get information about android processes to list/find/search them (research) https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/20 der-whity, ffranzgitHub Feature Archive 3 1
License and Copyright Agreement https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/18 fhilgers Feature Archive 2 2
Preperation of Kotlin https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/7 clabrous, luca-dot-sh Feature Archive 3 3
Docker Container https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/11 fhilgers Feature Archive 3 3
scope(build) aarch64 als target https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/23 fhilgers Feature Archive 1 1
scope(build) android 13 instead of 15 https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/24 fhilgers Feature Archive 1 1
Team Decision https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/8 BenediktZinn, clabrous, der-whity, ffranzgitHub, fhilgers, luca-dot-sh, Mr-Kanister Feature Archive 1 1
architecture document https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/10 fhilgers Feature Archive 3 5
bill of materials https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/9 BenediktZinn, der-whity, Mr-Kanister Feature Archive 3 3
Brain Storming Architecture https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/3 Feature Archive 3 1
Define the time intervals / time delay between each data point https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/45 Product Backlog
UI Filter for System and User Applications https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/76 Product Backlog
Distinguish between System vs. User Applications https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/74 Product Backlog 3
Display Installed Applications in UI https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/25 Product Backlog -1
Brain Storming eBPF Use Cases https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/1 Product Backlog 2
Uprobe Analysis: Setup https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/115 Product Backlog
Uprobe Analysis: Finding Symbols from shared libraries https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/116 Product Backlog
Uprobe Analysis: Finding Symbols from Dex/Oat https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/117 Product Backlog
Uprobe Analysis: Setup ebpf uprobes https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/118 Product Backlog
Uprobe Analysis: Collect Uprobe events https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/119 Product Backlog
Uprobe Analysis: Config https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/120 Product Backlog
Uprobe Analysis: Frontend Show Symbols https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/121 Product Backlog
Uprobe Analysis: Frontend Show Uprobe Events https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/122 Product Backlog
Refactor: Collection of events in Daemon https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/123 Product Backlog
Refactor: Configuration API https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/124 Product Backlog
Create kprobe to Track Blocking vfs_write Call https://github.com/amosproj/amos2024ws03-android-zero-instrumentation/issues/88 der-whity Feature Archive 3 3
Binary file added Deliverables/sprint-06/imp-squared-backlog.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions Deliverables/sprint-06/imp-squared-backlog.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Title Assignees Status
Note: All of the Items have a more detailed description pls. click them to see. (this is not an item) Todo
Tech: Streamline testing proces Todo
Team: Completing Task Quicker (earlier PR) Todo
Team: Rotating the deliverable creation Todo
Tech: Split Backlog Items (PR and Creation) Todo
Team: Assist in creating team processes (Sinatra Doctrine, this is ongoing) In Progress
Team: Load balancing inside the dev team In Progress
Team: Making sure all tasks in a sprint are being finished In Progress
Tech: Repository coordination In Progress
Team collaboration (between dev and po) Done
Gain Independence from the IP Done
Lifting the collective mood Done
Creating a Template for backlog item suggestions by the IP Done
Solving dissatisfaction among the team Done
Focus on IP (and PO relations) Done
Ensuring that everyone has work to do Done
Backlog Item creation procedure Done
Helping Coordinate the team meeting Done
Helping to set up the first IP meeting Done
Supporting team in understanding the amos workflow (e.g importance of the team meeting) Done
Creating Sub-Teams to streamline development Done
Establishing a continuouse release cycle with the team Done
Improving time management in the Team meeting Done
Ensuring a continuous backlog items flow Done
Binary file added Deliverables/sprint-06/planning-documents.pdf
Binary file not shown.
Binary file added Deliverables/sprint-06/user-documentation.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ SPDX-License-Identifier: MIT
The resulting APKs for release/debug build types can then be found under `frontend/app/build/outputs/apk`.

### Installing the app:
`./gradlew installRealBackendDebug` or `./gradlew iRBD` for installing a version with a **real** backend <br/>
`./gradlew installMockBackendDebug` or `./gradlew iMBD` for installing a version with a **mocked** backend <br/>
`./gradlew installRealDebug` or `./gradlew iRD` for installing a version with a **real** backend <br/>
`./gradlew installMockDebug` or `./gradlew iMD` for installing a version with a **mocked** backend <br/>

### Generating the report for the bill of materials (BOM)
To generate a BOM of all *release runtime dependencies*, the following Gradle task can be run: <br/>
Expand Down
14 changes: 8 additions & 6 deletions frontend/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ android {
}
}

flavorDimensions += "environment"
// Flavors and build types needs to match the library
flavorDimensions += "version"
productFlavors {
create("realBackend") {
dimension = "environment"
create("real") {
dimension = "version"
}
create("mockedBackend") {
dimension = "environment"
versionNameSuffix = ".mocked" // Optional
create("mock") {
dimension = "version"
versionNameSuffix = ".mock" // Optional
}
}
}
Expand All @@ -99,6 +100,7 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.accompanist.drawablepainter)

implementation(project(":client"))

Expand Down
4 changes: 4 additions & 0 deletions frontend/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ SPDX-License-Identifier: MIT
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<!-- not a problem since we are not publishing to Play Store -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />

<application
android:name=".ZiofaApplication"
android:allowBackup="true"
Expand Down
25 changes: 15 additions & 10 deletions frontend/app/src/main/java/de/amosproj3/ziofa/ZiofaApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
package de.amosproj3.ziofa

import android.app.Application
import android.content.Context
import android.content.pm.PackageManager
import de.amosproj3.ziofa.api.ConfigurationAccess
import de.amosproj3.ziofa.api.DataStreamProvider
import de.amosproj3.ziofa.api.ProcessListAccess
import de.amosproj3.ziofa.bl.ConfigurationManager
import de.amosproj3.ziofa.bl.DataStreamManager
import de.amosproj3.ziofa.bl.PackageInformationProvider
import de.amosproj3.ziofa.client.ClientFactory
import de.amosproj3.ziofa.client.RustClientFactory
import de.amosproj3.ziofa.client.mocks.MockClientFactory
import de.amosproj3.ziofa.ui.configuration.ConfigurationViewModel
import de.amosproj3.ziofa.ui.processes.ProcessesViewModel
import de.amosproj3.ziofa.ui.visualization.VisualizationViewModel
Expand All @@ -25,18 +29,19 @@ import timber.log.Timber
class ZiofaApplication : Application() {

val appModule = module {
single<ClientFactory> {
if (BuildConfig.FLAVOR == "mockedBackend") {
MockClientFactory()
} else {
RustClientFactory("http://[::1]:50051")
}
}
single<PackageManager> { get<Context>().packageManager }
single<PackageInformationProvider> { PackageInformationProvider(get()) }
single<ClientFactory> { RustClientFactory("http://[::1]:50051") }
single<DataStreamProvider> { DataStreamManager(get()) }
single { ConfigurationManager(clientFactory = get()) } binds
arrayOf(ConfigurationAccess::class, ProcessListAccess::class)
viewModel { ConfigurationViewModel(configurationAccess = get()) }
viewModel { ProcessesViewModel(processListAccess = get()) }
viewModel { VisualizationViewModel(clientFactory = get()) }
viewModel {
ProcessesViewModel(processListAccess = get(), packageInformationProvider = get())
}
viewModel {
VisualizationViewModel(configurationManager = get(), dataStreamProvider = get())
}
}

override fun onCreate() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ package de.amosproj3.ziofa.api
import uniffi.shared.Configuration

sealed class ConfigurationUpdate {
data class OK(val configuration: Configuration) : ConfigurationUpdate()
data class Valid(val configuration: Configuration) : ConfigurationUpdate()

data class NOK(val error: Throwable) : ConfigurationUpdate()
data class Invalid(val error: Throwable) : ConfigurationUpdate()

data object UNKNOWN : ConfigurationUpdate()
data object Unknown : ConfigurationUpdate()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT

package de.amosproj3.ziofa.api

import kotlinx.coroutines.flow.Flow

interface DataStreamProvider {
suspend fun counter(ebpfProgramName: String): Flow<UInt>

suspend fun vfsWriteEvents(pids: List<UInt>): Flow<WriteEvent.VfsWriteEvent>

suspend fun sendMessageEvents(pids: List<UInt>): Flow<WriteEvent.SendMessageEvent>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT

package de.amosproj3.ziofa.api

import android.graphics.drawable.Drawable

data class InstalledPackageInfo(val displayName: String, val icon: Drawable)
28 changes: 28 additions & 0 deletions frontend/app/src/main/java/de/amosproj3/ziofa/api/WriteEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT

package de.amosproj3.ziofa.api

sealed class WriteEvent(
val fileDescriptor: ULong,
val processId: UInt,
val startTimestamp: ULong,
val durationOrSize: ULong,
) {

data class VfsWriteEvent(
val fd: ULong,
val pid: UInt,
val size: ULong,
val timestampMillis: ULong, // unix time
) : WriteEvent(fd, pid, timestampMillis, size)

data class SendMessageEvent(
val fd: ULong,
val pid: UInt,
val tid: UInt,
val beginTimestamp: ULong,
val durationMicros: ULong,
) : WriteEvent(fd, pid, beginTimestamp, durationMicros)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// SPDX-FileCopyrightText: 2024 Felix Hilgers <[email protected]>
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT
Expand Down Expand Up @@ -28,7 +29,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :

override val processesList = MutableStateFlow<List<Process>>(listOf())
override val configuration: MutableStateFlow<ConfigurationUpdate> =
MutableStateFlow(ConfigurationUpdate.UNKNOWN)
MutableStateFlow(ConfigurationUpdate.Unknown)

override fun submitConfiguration(configuration: Configuration) {
coroutineScope.launch {
Expand All @@ -45,7 +46,7 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
initializeConfigurationState()
startProcessListUpdates()
} catch (e: ClientException) {
configuration.update { ConfigurationUpdate.NOK(e) }
configuration.update { ConfigurationUpdate.Invalid(e) }
}
}
}
Expand All @@ -56,10 +57,12 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
client!!.getConfiguration()
} catch (e: ClientException) {
// TODO this should be handled on the backend
client!!.setConfiguration(Configuration(listOf()))
client!!.setConfiguration(
Configuration(vfsWrite = null, sysSendmsg = null, uprobes = listOf())
)
client!!.getConfiguration()
}
configuration.update { ConfigurationUpdate.OK(initializedConfiguration) }
configuration.update { ConfigurationUpdate.Valid(initializedConfiguration) }
}

private suspend fun startProcessListUpdates() {
Expand All @@ -73,11 +76,11 @@ class ConfigurationManager(val clientFactory: ClientFactory) :
private suspend fun getAndUpdateConfiguration() {
configuration.update {
try {
(client?.getConfiguration()?.let { ConfigurationUpdate.OK(it) }
?: ConfigurationUpdate.UNKNOWN)
(client?.getConfiguration()?.let { ConfigurationUpdate.Valid(it) }
?: ConfigurationUpdate.Unknown)
.also { Timber.i("Received config $it") }
} catch (e: Exception) {
ConfigurationUpdate.NOK(e)
ConfigurationUpdate.Invalid(e)
}
}
}
Expand Down
Loading
Loading