Azure / nxtools

Azure Automanage Machine Configuration Linux DSC resources
Other
13 stars 13 forks source link

nxscript support for bash #27

Closed didayal-msft closed 5 months ago

didayal-msft commented 1 year ago

Description

Existing users using the nx module nxscript resource are using bash scipts and not powershell. During migration from azure automation DSC for linux, the urgent need would be to find a dsc v3 compatible resource that allows the bash script capability. Since the released nxscript resource only supports powershell, we should release a resource that supports bash scripts as well.

Proposed properties

Special considerations or limitations

eehret commented 1 year ago

I couldn't agree more.

I have been trying to get this to work in a couple of different ways so far...

I've tried invoking simple bash commands directly from the powershell nxScript blocks - this seems to work sometimes, depending on the content of the script. I've also tried using here-strings to embed the desired bash script into the nxScript and call it using bash -c , but this sometimes seems to fail for unknown reasons as well.

Overall this has been quite painful and the thought of rewriting all those bash scripts in powershell is daunting to say the least.

eehret commented 1 year ago

For anyone else struggling to find a way to do something similar, I did manage to get this to work:

      SetScript = {
        $BashScript = @'
fstabHasTmpEntry=$(grep -E '\s/tmp\s' /etc/fstab | grep -E -v '^\s*#')

if [ -n "$fstabHasTmpEntry" ]; then
    awk '!/^#/ && ($2 == "/tmp") { if(!match($4, /nodev/)) $4=$4",nodev" } 1' /etc/fstab > /tmp/fstab
    mv /tmp/fstab /etc/fstab
    mount -o remount /tmp
fi
'@
        $BashScript | Out-File -FilePath '/tmp/tmp_nodev_configured_set.sh'
        $null = Invoke-NativeCommand -Executable 'bash' -Parameters @('/tmp/tmp_nodev_configured_set.sh')
      }

I tried passing the $BashScript here-string directly to bash using parameters like so but it did not work

Invoke-NativeCommand -Executable 'bash' -Parameters @('-c', $BashString)

Something always seems to happen to the parameters that makes the end result incorrect.

Executing the file after writing the here-string to disk works though... I will use this workaround for now, in order to reduce the effort in converting all of my existing DSC scripts (which contain bash code)

Ram1622 commented 1 year ago

@gaelcolas @gurrajatwal, Could you please help us to fix this issue?

gaelcolas commented 1 year ago

Afraid I'm no longer under MSFT contract and that resource was written by @gurrajatwal .

The way it's written is using scriptblocks and invoking them directly which is the way to go for PS. I'd recommend at least parsing the get/set/test scripts first line for shebang, and if found just write to file, +x, and execute. For results just expects some JSON to get results & reasons.

eehret commented 1 year ago

@gaelcolas Thank you so much. I really appreciate you providing suggestions despite not being under contract with MSFT at the moment!

didayal-msft commented 1 year ago

For anyone else struggling to find a way to do something similar, I did manage to get this to work:

      SetScript = {
        $BashScript = @'
fstabHasTmpEntry=$(grep -E '\s/tmp\s' /etc/fstab | grep -E -v '^\s*#')

if [ -n "$fstabHasTmpEntry" ]; then
    awk '!/^#/ && ($2 == "/tmp") { if(!match($4, /nodev/)) $4=$4",nodev" } 1' /etc/fstab > /tmp/fstab
    mv /tmp/fstab /etc/fstab
    mount -o remount /tmp
fi
'@
        $BashScript | Out-File -FilePath '/tmp/tmp_nodev_configured_set.sh'
        $null = Invoke-NativeCommand -Executable 'bash' -Parameters @('/tmp/tmp_nodev_configured_set.sh')
      }

I tried passing the $BashScript here-string directly to bash using parameters like so but it did not work

Invoke-NativeCommand -Executable 'bash' -Parameters @('-c', $BashString)

Something always seems to happen to the parameters that makes the end result incorrect.

Executing the file after writing the here-string to disk works though... I will use this workaround for now, in order to reduce the effort in converting all of my existing DSC scripts (which contain bash code)

@eehret Can you confirm if your method works for multiple policies applied to a VM? we observed most policies get stuck at running the testscript which keeps returning false compliance but the set script never gets launched

eehret commented 1 year ago

@didayal-msft Yes, it works for multiple. I am ensuring that the scripts are named uniquely, since I write them all to /tmp.


From: Divyadeep Dayal @.> Sent: Thursday, September 28, 2023 12:48:44 AM To: Azure/nxtools @.> Cc: Eric Ehret @.>; Comment @.> Subject: Re: [Azure/nxtools] nxscript support for bash (Issue #27)

For anyone else struggling to find a way to do something similar, I did manage to get this to work:

  SetScript = {
    $BashScript = @'

fstabHasTmpEntry=$(grep -E '\s/tmp\s' /etc/fstab | grep -E -v '^\s*#')

if [ -n "$fstabHasTmpEntry" ]; then awk '!/^#/ && ($2 == "/tmp") { if(!match($4, /nodev/)) $4=$4",nodev" } 1' /etc/fstab > /tmp/fstab mv /tmp/fstab /etc/fstab mount -o remount /tmp fi '@ $BashScript | Out-File -FilePath '/tmp/tmp_nodev_configured_set.sh' $null = Invoke-NativeCommand -Executable 'bash' -Parameters @('/tmp/tmp_nodev_configured_set.sh') }

I tried passing the $BashScript here-string directly to bash using parameters like so but it did not work

Invoke-NativeCommand -Executable 'bash' -Parameters @('-c', $BashString)

Something always seems to happen to the parameters that makes the end result incorrect.

Executing the file after writing the here-string to disk works though... I will use this workaround for now, in order to reduce the effort in converting all of my existing DSC scripts (which contain bash code)

Can you confirm if your method works for multiple policies applied to a VM? we observed most policies get stuck at running the testscript which keeps returning false compliance but the set script never gets launched

— Reply to this email directly, view it on GitHubhttps://github.com/Azure/nxtools/issues/27#issuecomment-1738426603, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AANQE6QSMYP3AGYUE7KUMF3X4T6SZANCNFSM6AAAAAA4IOT26Y. You are receiving this because you commented.Message ID: @.***>

eehret commented 1 year ago

By the way, if anyone knows a better way to generate a unique name for the script file based on its context within the nxScript and Get, Test or Set property, I'd appreciate if you share how to do that. I'm not a Powershell guru by any stretch of the imagination, so I imagine the way I'm hard coding the script name above probably seems crude to those who know better :)

didayal-msft commented 7 months ago

By the way, if anyone knows a better way to generate a unique name for the script file based on its context within the nxScript and Get, Test or Set property, I'd appreciate if you share how to do that. I'm not a Powershell guru by any stretch of the imagination, so I imagine the way I'm hard coding the script name above probably seems crude to those who know better :)

image

eehret commented 5 months ago

@MutemwaRMasheke Hi, Why did you close this? Has nxtools been enhanced to support execution of bash scripts?

Note that what we have been doing described in the above comments is a hack at best, and I do not consider that a long term solution.