Skip to content

Commit b102382

Browse files
committed
Add ipmi support
1 parent c6f3d6e commit b102382

File tree

7 files changed

+60
-8
lines changed

7 files changed

+60
-8
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
[submodule "ocaml-variorum"]
2-
path = ocaml-variorum
3-
url = https://github.com/patricoferris/ocaml-variorum

clarke.opam

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ doc: "https://patricoferris.github.io/clarke/"
1111
build: ["dune" "build" "-p" name "-j" jobs]
1212
depends: [
1313
"dune" {>= "2.0"}
14-
"eio_main" {>= "0.5"}
14+
"eio_luv"
1515
"variorum"
1616
"ptime"
1717
"cmdliner"
18-
]
18+
]
19+
pin-depends: [
20+
[ "hwloc.dev" "git+https://github.com/patricoferris/ocaml-hwloc#3447dc5c40f0d868529aafcc84b5d2d971062b30" ]
21+
[ "jansson.dev" "git+https://github.com/patricoferris/ocaml-jansson#42cb429e722ec64807d75ae401758eb666c9d189" ]
22+
[ "eio.dev" "git+https://github.com/patricoferris/eio#e22946a7e8de7094f15753cc9084beb1c06dd43b" ]
23+
[ "eio_luv.dev" "git+https://github.com/patricoferris/eio#e22946a7e8de7094f15753cc9084beb1c06dd43b" ]
24+
[ "variorum.dev" "git+https://github.com/patricoferris/ocaml-variorum#9128770e9df08ca7a90f317acc08b9cd49da6766" ]
25+
]

dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
(vendored_dirs ocaml-variorum ocaml-ipmi)
1+
(vendored_dirs ocaml-variorum eio)

ocaml-variorum

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/bin/main.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ module Specs = struct
4343

4444
let meter_of_meter_spec ~clock = function
4545
| `Const f -> Models.const ~clock f
46+
| `Ipmi -> S.Meter ((module Clarke.Ipmi), { clock })
4647
| `Variorum -> S.Meter ((module Clarke.Variorum), { clock })
4748

4849
let meter_spec_of_string s =
4950
match String.lowercase_ascii s with
5051
| "variorum" -> Ok `Variorum
52+
| "ipmi" -> Ok `Ipmi
5153
| v -> (
5254
match String.split_on_char ':' v with
5355
| [ "const"; f ] -> (

src/lib/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
(library
22
(name clarke)
33
(public_name clarke)
4-
(libraries eio ptime variorum ezjsonm))
4+
(libraries eio_luv eio.unix ptime variorum ezjsonm))

src/lib/ipmi.ml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
(* Ipmi-based monitor *)
2+
open Eio
3+
open Eio_luv.Low_level
4+
5+
module Ipmi = struct
6+
let ipmi args = ("sudo", "sudo" :: "ipmitool" :: args)
7+
let power_consumption = ipmi [ "sensor"; "reading"; "Pwr Consumption"; "-c" ]
8+
9+
let parse_power_consumption s =
10+
match String.split_on_char ',' (String.trim s) with
11+
| "Pwr Consumption" :: watts :: _ -> int_of_string watts
12+
| _ -> failwith "Couldn't parse the power consumption"
13+
end
14+
15+
type t = { clock : Eio.Time.clock }
16+
17+
let supported = true
18+
19+
let read_all handle buf =
20+
let rec read acc =
21+
try
22+
let i = Eio_luv.Low_level.Stream.read_into handle buf in
23+
read (acc + i)
24+
with End_of_file -> acc
25+
in
26+
read 0
27+
28+
let get_power_consumption () =
29+
let cmd, args = Ipmi.power_consumption in
30+
let parent_pipe = Eio_luv.Low_level.Pipe.init () in
31+
Switch.run @@ fun sw ->
32+
let handle = Eio_luv.Low_level.Pipe.to_handle ~sw parent_pipe in
33+
let buf = Luv.Buffer.create 64 in
34+
let redirect =
35+
Eio_luv.Low_level.Process.
36+
[ to_parent_pipe ~fd:Luv.Process.stdout ~parent_pipe () ]
37+
in
38+
let t = Process.spawn ~redirect cmd args in
39+
let _ = Process.await_exit t in
40+
let read = read_all handle buf in
41+
Luv.Buffer.to_string (Luv.Buffer.sub buf ~offset:0 ~length:read)
42+
43+
let collect t =
44+
let pc =
45+
get_power_consumption () |> Ipmi.parse_power_consumption |> float_of_int
46+
in
47+
Info.v (Option.get (Ptime.of_float_s @@ Time.now t.clock)) pc

0 commit comments

Comments
 (0)