using memorysize fact in manifests

3,527 views
Skip to first unread message

Andreas Kuntzagk

unread,
Jun 30, 2011, 3:36:00 AM6/30/11
to puppet...@googlegroups.com
Hi,

I want some config depending on memorysize.

What I tried was
if ($memorysize >= 256 * 1024*1024) {
...
}

But this fails because $memorysize is a string (and contains a "G") and can't be
compared to an int.

Are all facts strings? How do I work with numbers?

regards, Andreas

--
Andreas Kuntzagk
SystemAdministrator
MDC Berlin / BIMSB
Tel.: +49 30 9406 2997

Matthias Saou

unread,
Jun 30, 2011, 5:20:18 AM6/30/11
to puppet...@googlegroups.com
Andreas Kuntzagk <andreas....@mdc-berlin.de> wrote:

> I want some config depending on memorysize.
>
> What I tried was
> if ($memorysize >= 256 * 1024*1024) {
> ...
> }
>
> But this fails because $memorysize is a string (and contains a "G")
> and can't be compared to an int.
>
> Are all facts strings? How do I work with numbers?

Typical problem. Not to mention that you happen to have "G" but that
could very easily be "M". Here's my workaround for that, which I use
for calculations to then set some sysctl.conf values accordingly :

# This is ugly, but very useful to get a standard kiB total RAM
# to base further calculations upon. Note that we get a string
$mem = inline_template("<%
mem,unit = scope.lookupvar('::memorysize').split
mem = mem.to_f
# Normalize mem to KiB
case unit
when nil: mem *= (1<<0)
when 'kB': mem *= (1<<10)
when 'MB': mem *= (1<<20)
when 'GB': mem *= (1<<30)
when 'TB': mem *= (1<<40)
end
%><%= mem.to_i %>")

Here's an example of how I then use it :

# kernel.shmmax
if $shmmax {
$shmmax_final = $shmmax
} else {
if $oracle {
# For non-shm half the RAM for <= 4G, 2G otherwise
if $mem <= 4294967296 {
$shmmax_final = $mem / 2
} else {
$shmmax_final = $mem - 2147483648
}
} else {
$shmmax_final = $mem
}
}

HTH,
Matthias

Martijn Grendelman

unread,
Jun 30, 2011, 8:00:57 AM6/30/11
to puppet...@googlegroups.com

I use a custom fact, that returns the amount of system memory in
megabytes. This is, however, Linux-only, since it uses /proc/meminfo:

$ cat modules/common/lib/facter/memorysize_mb.rb


require 'facter'

Facter.add("memorysize_mb") do
confine :kernel => :Linux

ram = 0

# Steal linux's meminfo
File.open( "/proc/meminfo" , 'r' ) do |f|
f.grep( /^MemTotal:/ ) { |mem|
ram = mem.split( / +/ )[1].to_i / 1024
}
end

setcode do
ram
end
end


> Here's an example of how I then use it :
>
> # kernel.shmmax
> if $shmmax {
> $shmmax_final = $shmmax
> } else {
> if $oracle {
> # For non-shm half the RAM for <= 4G, 2G otherwise
> if $mem <= 4294967296 {
> $shmmax_final = $mem / 2
> } else {
> $shmmax_final = $mem - 2147483648
> }
> } else {
> $shmmax_final = $mem
> }
> }


Best regards,
Martijn Grendelman

Chris Phillips

unread,
Jun 30, 2011, 8:29:22 AM6/30/11
to puppet...@googlegroups.com

Well that's odd, I was looking at the exact same issue this morning for sysctl.conf / oracle stuff.

But why are people writing new facts?? Why not just take a copy of the original function and simply not run the function that normalizes the number? It seems very odd to make a more limited version of the function when it's already there.

Is it not possible to copy the code directly from utils/memory.rb  in facter?

Chris


--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.


Chris Phillips

unread,
Jun 30, 2011, 8:56:58 AM6/30/11
to puppet...@googlegroups.com
Further to this, this is the normal memory code condensed with normalization removed to give "raw" versions of the facts.

require 'facter'

{   :MemorySizeRaw => "MemTotal",
    :MemoryFreeRaw => "MemFree",
    :SwapSizeRaw   => "SwapTotal",
    :SwapFreeRaw   => "SwapFree"
}.each do |fact, name|
    Facter.add(fact) do
        confine :kernel => :linux
        setcode do
            memsize_raw = ""
            Thread::exclusive do
                File.readlines("/proc/meminfo").each do |l|
                    memsize_raw = $1.to_i if l =~ /^#{name}:\s+(\d+)\s+\S+/
                    # MemoryFree == memfree + cached + buffers
                    #  (assume scales are all the same as memfree)
                    if name == "MemFree" &&
                        l =~ /^(?:Buffers|Cached):\s+(\d+)\s+\S+/
                        memsize_raw += $1.to_i
                    end
                end
            end
            memsize_raw
        end
    end
end

Thanks

Chris
Reply all
Reply to author
Forward
0 new messages