Puppet to start service if it exists on windows - puppet

I am looking for a manifest to start a service on windows server if the service exists.
I am looking to check a service with a condition if the file exists.
service { 'test service':
ensure => 'running',
enable => true,
unless => 'if((test-path "C:\Program Files\test1") -or (test-path "C:/Program Files/test2")){ exit 0 } else { exit 1 }',
provider => powershell,}
Above code returns an error that unless is an invalid parameter. Any other way to check?
Thanks a lot!!

it doesn't look like the service resource has a parameter to support conditional inclusion. Puppet also does not have an easy way to check for the existence of a file on the client that I'm aware of. I have gotten around this by creating a custom fact that checked the condition I needed and then wrapping the resource in an unless block:
unless $facts['test_file_exists'] {
service { 'test service':
ensure => 'running',
enable => true,
}
since a custom fact can be written in any language that can output "key=value" pairs to stdout you could use your existing powershell code as a fact with a small change:
if((test-path "C:\Program Files\test1") -or (test-path "C:\program Files\test2")){
write-host "test_file_exists=true
}
else{
write-host "test_file_exists=false"
}
there are a few different ways to distribute the fact out to your client systems. I prefer to put the fact into a module and let pluginsync distribute it out for me. If you don't want to include it in a module then you would have to find some way to get the powershell code into C:\ProgramData\PuppetLabs\facter\facts.d\ with the proper .ps1 extension on the end.

Related

When is ActiveStorage::IntegrityError raised?

My app (locally) raises ActiveStorage::IntegrityError error, whenever it tries to attach a file. How can I get out of this error?
I have only one has_one_attached and I don't know how that error gets in the way.
# model
has_one_attached :it_file
Tempfile.open do |temp_file|
# ...
it_file.attach(io: temp_file, filename: 'filename.csv', content_type: 'text/csv')
end
# storage.yml
local:
service: Disk
root: <%= Rails.root.join("storage") %>
EDIT: it can be related with deleting storage/ directory (it happened after I deleted that) or it can be because it's happening in a job (the full error was Error performing ActivityJob (Job ID: .. ) from Async( .. ) in .. ms: ActiveStorage::IntegrityError (ActiveStorage::IntegrityError)
And this does not add files to storage/ folder but it's generating folders under it when I tried to attach them.
As mentioned in the comments, one reason this can happen is that the file object is at the end of the file, which was the problem in this case. It could be fixed here with temp_file.rewind.
Very weird. After update to rails 6.0 I must recalculate some checksums. Yes I used dokku,docker. It was fine before update.
# Disk service is in use for ActiveStorage
class ProjectImage < ApplicationRecord
has_one_attached :attachment
end
# update all checksums
ProjectImage.all.each do |image|
blob = image.attachment.blob
blob.update_column(:checksum, Digest::MD5.base64digest(File.read(blob.service.path_for(blob.key))))
end;
This was happening to me not because of anything mentioned above.
In my case I was defining a test var using one dummy file, but I was attaching it to 2 different records.
let(:file) { File.open(Rails.root.join('spec', 'fixtures', 'files', 'en.yml')) }
let(:data) { [file, file] }
The function in question received a list of ids and data and attaching the files to the records. This is a simplified version of the code
record_0.file.attach(
io: data[0],
filename: 'en.yml',
content_type: 'application/x-yaml'
)
record_1.file.attach(
io: data[1],
filename: 'en.yml',
content_type: 'application/x-yaml'
)
Once I defined 2 test vars, one for each record, using the same file I got it to work.
let(:file_0) { File.open(Rails.root.join('spec', 'fixtures', 'files', 'en.yml')) }
let(:file_1) { File.open(Rails.root.join('spec', 'fixtures', 'files', 'en.yml')) }
let(:data) { [file_0, file_1] }
Background
In my case I faced this error when I was trying to upgrade the rails config defaults.
I was activating configs from config/initializers/new_framework_defaults_6_1.rb which was generated by rails app:update rake task.
Cause
I activated this setting
Rails.application.config.active_storage.track_variants = true
which collided with our existing mechanism to handle variant generation. We are reading variants size/types from account-settings so its complicated.
Technical cause
As mentioned above, this is causes due to mismatch in checksum of the file and checksum stored in blob record in database.
# activestorage-6.1.7.1/lib/active_storage/downloader.rb:37
def verify_integrity_of(file, checksum:)
unless Digest::MD5.file(file).base64digest == checksum
raise ActiveStorage::IntegrityError
end
end
Solution
I commented it back
To make sure its always inactive, I moved the setting to config/initializers/active_storage.rb like below
# Track Active Storage variants in the database.
# *Note*: Its Rails 6.1.0 feature and we have our own way of handling variants which also depends upon the
# thumbnail_sizes setting values and varies from account to account.
# so we are disabling it for now.
Rails.application.config.active_storage.track_variants = false
Summary
You may want to use this awesome feature so see workarounds.
In your case, causes can be something else so look deeper.
disabling this feature solves my issue.

Puppet inline template with puppet:// in URL

In my Puppet module, I have something like this:
file {'myfile':
ensure => 'file',
path => '/whatever/myfile',
content => inline_template(file(
"puppet:///modules/my_module/templates/${domain}/${::hostname}_myfile.erb",
"puppet:///modules/my_module/templates/${domain}/myfile.erb"
))
}
And my spec looks like:
require 'spec_helper'
describe 'my_module' do
context 'with defaults for all parameters' do
it { should compile }
end
end
If try to run it, I get:
Failure/Error: it { should compile }
error during compilation: Evaluation Error: Error while evaluating a Function Call, Could not find any files from puppet:///modules/my_module/templates/dev.contaazul.local/myfile.erb, puppet:///modules/my_module/templates/dev.contaazul.local/myfile.erb at /home/carlos/Code/Puppet/modules/my_module/spec/fixtures/modules/my_module/manifests/init.pp:48:33 on node becker.local
Obviously, it cannot find any of the ERB templates. If I replace the puppet:// part for /home/carlos/Code/Puppet/ (where the code actually lives), it passes, but in production it is /etc/puppet/, so, it will not work.
How can I make this work?
RI Pienaar has released a code snippet for a function with this behavior. You will need to copy this code into a file in one of your modules at the path lib/puppet/parser/functions/multi_source_template.rb.
Once you do that, you should be able to use it like so:
file {'myfile':
ensure => 'file',
path => '/whatever/myfile',
content => multi_source_template(
"my_module/${domain}/${::hostname}_myfile.erb",
"my_module/${domain}/myfile.erb"
)
}
As to why the original approach doesn't work: URLs are usually used with the source property only and transferred to the agent as is. The agent consumes the URL and makes an according request to a Puppet fileserver (which is just another master).
The file function on the other hand (as used here with the content property in conjunction with inline_template) will not process URLs and expects local paths instead.
All that being said, the issue could possibly have been side-stepped by specifying both the paths for the test box and the production system, with the latter just acknowledging that /home/carlos is missing. But that would have been far from a clean solution.

Have puppet ensure a service is running only when not in a maintenance mode

I have a basic service check in a puppet manifest I want running most of the time with just
service{ $service_name :
ensure => "running",
enable => "true",
}
The thing is there are periods of maintenance I would like to ensure puppet doesn't come along and try to start it back up.
I was thinking creating a file "no_service_start" in a specified path and do a 'creates' check like you could do with a guard for exec but it doesn't look like that's available for the service type.
My next thought was to have the actual service init script do the check for this file itself and just die early if that guard file exists.
While this works in that it prevents a service from starting it manifests itself as a big red error in puppet (as expected). Given the service not starting is a desired outcome if that file is in place I'd rather not have an error message present and have to spend time thinking about if it's "legit" or not.
Is there a more "puppet" way this should be implemented though?
Define a fact for when maintenance is happening.
Then put the service definition in an if block based off that fact.
if !maintenance
{
service{ $service_name :
ensure => "running",
enable => "true",
}
}
Then when puppet compiles the catalog if maintenance == true the service will not be managed and stay in whatever state it currently happens to be.
I don't really like this answer, but to work around puppet spitting out errors when bailing b/c of a guard file is to have to init script that's doing that check bail with an exit code as 0.
How about putting the check outside? You could do something similar to this: https://stackoverflow.com/a/20552751/1097483, except with your service check inside the if loop.
As xiankai said, you can do this on the puppetmaster. If you have a script that returns running or stopped as a string, depending on the current time or anything, you can write something like:
service{ $service_name :
ensure => generate('/usr/local/bin/maintenanceScript.sh');
}

How can I run a TYPO3 extension in cron jobs?

Can anyone tell me how to setup a cronjob in TYPO3? I've created a TYPO3 extension which I want to run once a week. I've already installed the scheduler extension, but it only allows some extensions (e.g., tt_news ) to be executed.
Thank you.
your extension must support the Scheduler - system extension (maybe you'll need to install it first). Therefore you have to register your extension in the Scheduler Service.
via your ext_localconf.php
if (!defined ('TYPO3_MODE')) die ('Access denied.');
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks']['TX_YOUR_EXTENSIONKEY'] = array(
'extension' => $_EXTKEY,
'title' => 'Some meningful Title',
'description' => 'Some Discription of the Task'
);
you need to create the file tasks/class.TX_YOUREXTENSKEY.php in your extension directory
class TX_YOUREXTENSKEY extends tx_scheduler_Task {
public function execute() {}
...
}
the execute function is called if the task gets executed. it should return true if everything went fine and false if you got some error.
at last your class needs to be loaded this can be done using ext_autoload.php (in your extension root, see TYPO3 Wiki: Autoload for more details)
<?php
return array(
'tx_sfpinger_pinger' => t3lib_extMgm::extPath('sfpinger', 'tasks/class.tx_sfpinger_pinger.php')
);
?>
Finally you need to add to your system cron command that will be running Scheduler ext periodically (you'll find it on the Scheduler's Setup check section) and also add your created task to the its tasks list.
You can check a demo task which is just a sample from which you can copy code and paste in your extension.
Also check documentation delivered with scheduler task in folder on your TYPO3 implementation: /typo3/sysext/scheduler/doc/manual.sxw

How to check if Directory already Exists in MFC(VC++)?

How to check if Directory already Exists in MFC(VC++) ?
I am using below code to get current application Path and there i am creating NDSLog folder
so that all my Logfiles should place there , now i want to check the condition if NDSLog folder already exists dont create it .How to do that ?
Thanks.
char strPathName[_MAX_PATH];
::GetModuleFileName(NULL, strPathName, _MAX_PATH);
// The following code will allow you to get the path.
CString newPath(strPathName);
int fpos = newPath.ReverseFind('\\');
if (fpos != -1)
newPath = newPath.Left(fpos+1);
newPath += "NDSLog\\" ;
CreateDirectory(newPath,NULL);
The simplest way to check if a file/directory exists is to use GetFileAttributes:
if (GetFileAttributes(newPath) == INVALID_FILE_ATTRIBUTES) {
CreateDirectory(newPath,NULL);
}
Note that the function will return INVALID_FILE_ATTRIBUTES even if it fails due to some other reason, such as not having permissions to access the file, so you should check the return value of CreateDirectory to make sure that it succeeded.
Actually, you don't need to check whether the directory already exists; CreateDirectory will set an error code if the directory already exists:
if (!CreateDirectory(newPath,NULL)) {
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// directory already exists
} else {
// creation failed due to some other reason
}
}
How about PathIsDirectory()? In the original example, you can use PathRemoveFilespec() followed by PathCombine() to add a new filename/extension. In the unlikely case that your target is only Windows 8 or later, there are safer PathCch...() flavors of these functions.
I use PathFileExists.
FindFirstFile. Despite the "File" in the name, it'll find directories perfectly well.
You can use _accees or _waccess from C runtime.
This is the msdn page and you can see sample usage
And also you don't have to wory about if directory already exist because CreateDirectory checks and returns ERROR_ALREADY_EXISTS if exists. You can see from here (Return Codes).
I must note, that GetFileAttributes work slow when file is a network path.
Actually, it works slow for the first time, and fast afterwards.

Resources