Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
qbar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jens Nolte
qbar
Commits
1de37c12
Commit
1de37c12
authored
4 years ago
by
Mr. Snow Ball / projects
Browse files
Options
Downloads
Patches
Plain Diff
Add Producer for Qubes VM stats
parent
b50d2b96
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
load-all.ghci
+2
-1
2 additions, 1 deletion
load-all.ghci
package.yaml
+2
-0
2 additions, 0 deletions
package.yaml
src/QBar/Qubes/AdminAPI.hs
+120
-0
120 additions, 0 deletions
src/QBar/Qubes/AdminAPI.hs
with
124 additions
and
1 deletion
load-all.ghci
+
2
−
1
View file @
1de37c12
...
...
@@ -4,4 +4,5 @@
:load src/Prelude.hs
:set -XImplicitPrelude
:load src/QBar/Cli.hs
:load src/QBar/Cli.hs src/QBar/Qubes/AdminAPI.hs
:m QBar.Cli QBar.Qubes.AdminAPI
This diff is collapsed.
Click to expand it.
package.yaml
+
2
−
0
View file @
1de37c12
...
...
@@ -24,6 +24,7 @@ dependencies:
-
aeson
-
async
-
attoparsec
-
binary
-
bytestring
-
colour
-
concurrent-extra
...
...
@@ -31,6 +32,7 @@ dependencies:
-
dbus
-
directory
-
filepath
-
hostname
-
lens
-
mtl
-
network
...
...
This diff is collapsed.
Click to expand it.
src/QBar/Qubes/AdminAPI.hs
0 → 100644
+
120
−
0
View file @
1de37c12
module
QBar.Qubes.AdminAPI
where
import
Control.Monad
(
forM
)
import
Data.Binary
import
Data.Binary.Get
import
Data.Binary.Put
import
qualified
Data.ByteString
as
BS
import
qualified
Data.ByteString.Lazy
as
BL
import
qualified
Data.ByteString.Lazy.Char8
as
BLC
import
Network.HostName
import
Pipes
import
qualified
Pipes.Safe
as
P
import
System.IO
(
Handle
,
hSetBinaryMode
)
import
System.Process.Typed
data
QubesAdminReturn
=
Ok
{
okContent
::
BL
.
ByteString
}
|
Event
{
evSubject
::
BL
.
ByteString
,
evEvent
::
BL
.
ByteString
,
evProperties
::
[(
BL
.
ByteString
,
BL
.
ByteString
)]
}
|
Exception
{
excType
::
BL
.
ByteString
,
excTraceback
::
BL
.
ByteString
,
excFormatString
::
BL
.
ByteString
,
excFields
::
[
BL
.
ByteString
]
}
deriving
(
Eq
,
Ord
,
Show
,
Read
)
putLazyByteStringNul
x
=
do
when
(
0
`
BL
.
elem
`
x
)
$
error
"string mustn't contain any
\\
x00 bytes"
putLazyByteString
x
putWord8
0x00
instance
Binary
QubesAdminReturn
where
put
Ok
{
okContent
}
=
do
putWord8
0x30
>>
putWord8
0x00
putLazyByteString
okContent
put
Event
{
evSubject
,
evEvent
,
evProperties
}
=
do
putWord8
0x31
>>
putWord8
0x00
putLazyByteStringNul
evSubject
putLazyByteStringNul
evEvent
forM
evProperties
$
\
(
k
,
v
)
->
do
putLazyByteStringNul
k
putLazyByteStringNul
v
putWord8
0x00
put
Exception
{
excType
,
excTraceback
,
excFormatString
,
excFields
}
=
do
putWord8
0x32
>>
putWord8
0x00
putLazyByteStringNul
excType
putLazyByteStringNul
excTraceback
putLazyByteStringNul
excFormatString
forM
excFields
putLazyByteStringNul
putWord8
0x00
get
=
do
msgType
<-
getWord8
zero
<-
getWord8
case
(
msgType
,
zero
)
of
(
0x30
,
0x00
)
->
Ok
<$>
getRemainingLazyByteString
(
0x31
,
0x00
)
->
Event
<$>
getLazyByteStringNul
<*>
getLazyByteStringNul
<*>
getPairs
(
0x32
,
0x00
)
->
Exception
<$>
getLazyByteStringNul
<*>
getLazyByteStringNul
<*>
getLazyByteStringNul
<*>
getFields
_
->
fail
$
"unsupported message type "
<>
show
msgType
<>
", "
<>
show
zero
where
getPairs
=
untilZeroByte
$
(,)
<$>
getLazyByteStringNul
<*>
getLazyByteStringNul
getFields
=
untilZeroByte
getLazyByteStringNul
untilZeroByte
inner
=
lookAhead
getWord8
>>=
\
case
0x00
->
getWord8
>>
return
[]
_
->
inner
>>=
\
x
->
(
x
:
)
<$>
untilZeroByte
inner
qubesAdminConnect
::
String
->
IO
(
Process
()
Handle
()
)
qubesAdminConnect
serviceName
=
do
hostname
<-
getHostName
let
cmd
=
if
hostname
==
"dom0"
then
"qubesd-query dom0 "
<>
serviceName
<>
" dom0"
else
"qrexec-client-vm dom0 "
<>
serviceName
--NOTE qubesd-query and qrexec-client-vm don't like it if their input
-- is closed rather than empty.
-- hangs: qrexec-client-vm dom0 admin.vm.List <&-
-- works: qrexec-client-vm dom0 admin.vm.List </dev/null
let
processConfig
=
setStdin
nullStream
$
setStdout
createPipe
$
shell
cmd
startProcess
processConfig
qubesAdminCall
::
String
->
IO
QubesAdminReturn
qubesAdminCall
serviceName
=
do
process
<-
qubesAdminConnect
serviceName
let
stdout
=
getStdout
process
hSetBinaryMode
stdout
True
reply
<-
decode
<$>
BL
.
hGetContents
stdout
case
reply
of
Ok
{}
->
return
reply
Exception
{}
->
return
reply
Event
{}
->
fail
"service has returned events instead of a reply"
qubesAdminCallP
::
String
->
Producer
QubesAdminReturn
(
P
.
SafeT
IO
)
()
qubesAdminCallP
serviceName
=
do
process
<-
liftIO
$
qubesAdminConnect
serviceName
let
stdout
=
getStdout
process
liftIO
$
hSetBinaryMode
stdout
True
let
go
::
Decoder
QubesAdminReturn
->
Producer
QubesAdminReturn
(
P
.
SafeT
IO
)
()
go
=
\
case
Done
remainder
_
value
->
do
yield
value
go
$
pushChunk
(
runGetIncremental
get
)
remainder
d
@
(
Partial
_
)
->
do
chunk
<-
liftIO
$
BS
.
hGetSome
stdout
1024
if
not
(
BS
.
null
chunk
)
then
go
$
pushChunk
d
chunk
else
case
pushEndOfInput
d
of
Done
_
_
value
->
yield
value
_
->
return
()
Fail
_
_
msg
->
fail
$
"decoding reply from QubesAdmin failed: "
<>
msg
go
(
runGetIncremental
get
)
`
P
.
finally
`
stopProcess
process
qubesAdminEvents
::
String
->
Producer
QubesAdminReturn
(
P
.
SafeT
IO
)
()
qubesAdminEvents
serviceName
=
qubesAdminCallP
serviceName
>->
onlyEvents
where
onlyEvents
::
Pipe
QubesAdminReturn
QubesAdminReturn
(
P
.
SafeT
IO
)
()
onlyEvents
=
forever
$
await
>>=
\
reply
->
case
reply
of
Ok
{}
->
fail
"service has returned OK instead of events"
Exception
{}
->
fail
$
"service has returned an exception: "
++
show
reply
Event
{}
->
yield
reply
qubesVMStats
::
Producer
QubesAdminReturn
(
P
.
SafeT
IO
)
()
qubesVMStats
=
qubesAdminEvents
"admin.vm.Stats"
printEvents
::
Show
a
=>
Producer
a
(
P
.
SafeT
IO
)
()
->
IO
()
printEvents
prod
=
P
.
runSafeT
$
runEffect
$
prod
>->
(
forever
$
await
>>=
liftIO
.
print
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment