I have the following class which installs mysql and sets up a user called user but when the create-database commands runs the user has not been created yet.
How do i chain the commands so that the user is created before create-database tries to use it?
class { '::mysql::server':
package_name => 'mariadb-server.x86_64',
root_password => 'root',
remove_default_accounts => true,
override_options => $override_options,
restart => true,
users => {
'user#%' => {
ensure => 'present',
max_connections_per_hour => '0',
max_queries_per_hour => '0',
max_updates_per_hour => '0',
max_user_connections => '0',
password_hash => '...',
}
},
grants => {
'user#%/*.*' => {
ensure => 'present',
options => ['GRANT'],
privileges => ['ALL'],
table => '*.*',
user => 'user#%',
},
}
}->
exec { 'create-database':
creates => '/opt/dbinstalled',
command => '/usr/bin/mysql -u user -puser < /create-db.sql'
}
I am using the puppetlabs-mysql package to install mysql.
You should take a look at the documentation for the require, before, subscribe, notify metaparameters. They are used to describe resource ordering (before, notify), or resource ordering and failure if the dependency fails (require, subscribe). Note the subscribe, notify metaparameters are only available for some resource types (exec, service, etc.).
In this instance, you would do the following to chain a class:
exec { 'create-database':
creates => '/opt/dbinstalled',
command => '/usr/bin/mysql -u user -puser < /create-db.sql',
require => Class[::mysql::server],
}
But you really only need the dependency on the user resource:
exec { 'create-database':
creates => '/opt/dbinstalled',
command => '/usr/bin/mysql -u user -puser < /create-db.sql',
require => User[username or array of users],
}
Also you probably only want to create the database once, so we can give it a subscribe/refreshonly for idempotence:
exec { 'create-database':
creates => '/opt/dbinstalled',
command => '/usr/bin/mysql -u user -puser < /create-db.sql',
subscribe => User[username or array of users],
refreshonly => true,
}
Note that if you change the user resource that the create-database is subscribed to this will rerun the exec resource, so look into the unless, onlyif parameters for exec as other methods to establish idempotence.
Related
I have an electron app with multiple browserWindows.
For my own help, I spawn them with additional arguments (for example: '--renderer-mode="second-window"').
Now I want to collect Metric Data of my current electron processes.
I already have a IPC interface in my main process I call from one of my renderer.
ipcMain.handle('app-metrics', (event, message) => {
return new Promise((resolve) => {
const appMetrics = app.getAppMetrics()
resolve(appMetrics)
})
})
Here I want to add all the argv from my apps processes.
I don't know how I could get the info in this function. I only know the way with process.argv, but how could I collect these info from all the sub processes and bundle it with my appMetrics array?
I solved my question in another way. My goal was to display the "process" type (not the chromium types that already exists in the metric data).
I'm collecting the PIDs I already know and hardcode them a specific type. The next thing was to add this info into the metric object. Here is my result:
ipcMain.handle('app-metrics', (event, message) => {
return new Promise((resolve) => {
const pids = [
{
name: 'main-process',
pid: process.pid
},
{
name: 'app-gui',
pid: this.win.webContents.getOSProcessId()
},
{
name: 'popup-gui',
pid: this.winPopup.webContents.getOSProcessId()
}
]
const appMetrics = app.getAppMetrics().map((metric) => {
const pidType = pids.filter((e) => e.pid === metric.pid)
if (pidType.length > 0) {
return {
...metric,
appType: pidType[0].name
}
}
return {
...metric,
appType: ''
}
})
resolve(appMetrics)
})
})
If there is a simpler and smarter way, I'm happy to hear it. :)
I am creating a cli app using oclif. The user executes a command, and the cli asks him if wants to continue (yes/no answer).
I trying to test the command that uses the cli-ux prompt. I want to simulate the user interaction to enter the 'yes' word.
How can I do that?
I tried this:
describe('mycommand', () => {
test
.stdout()
.command(['mycommand', 'action'])
.stdin('y')
.it('it shoud do someting', ctx => {});
});
Related with Oclif prompt testing I could find a solution.
Be careful how you ask the user because you can use cli.prompt or cli.confirm. In my case, I use cli.confirm so a possible test could be:
describe('it should clean items in done list', () => {
test
.stub(cli, 'confirm', () => async () => 'Y')
.stdout()
.command(['clean', 'done'])
.it('it shoud clean items in done list', ctx => {
// test
});
});
Autofac Registration:
builder.RegisterType<RelatedTransportMangerResolver>().AsSelf();
builder.Register(context => new MapperConfiguration(cfg =>
{
cfg.AddProfile<AssetMapperProfile>();
})).AsSelf().SingleInstance();
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
.As<IMapper>()
.InstancePerLifetimeScope();
Map that uses the custom value resolver:
CreateMap<TrafficArea, TrafficAreaViewModel>()
.ForMember(ta => ta.TransportManagers,
opt => opt.MapFrom(ta =>
ta.TrafficAreaKeyContacts
.Where(kc => kc.KeyContactGroup.HasFlag(KeyContactGroup.TransportManager))
.Select(atr => atr.KeyContact)))
.ForMember(ta => ta.RelatedTransportManagers,
opt => opt.MapFrom<RelatedTransportMangerResolver>());
Error being returned is:
This resolve operation has already ended. When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c', or resolve a Func<> based factory to create subsequent components from.
Any ideas on how to fix this error?
Should of done a bit more digging myself first...
Fix here if anybody has this same issue:
builder.Register(c =>
{
//This resolves a new context that can be used later.
var context = c.Resolve<IComponentContext>();
var config = context.Resolve<MapperConfiguration>();
return config.CreateMapper(context.Resolve);
})
.As<IMapper>()
.InstancePerLifetimeScope();
My requirement is this:
Look for changes in the file /tmp/file
If there is a change, execute these in the following order:
run command3
run command2
run command1
If there is NO change in the file /tmp/file, do nothing.
My code is like this:
exec { 'exec3':
command => 'command3',
require => File['file'],
}
exec { 'exec2':
command => 'command2',
require => Exec['exec3'],
}
exec { 'exec1':
command => 'command1',
require => Exec['exec2'],
subscribe => File['file'],
refreshonly => true,
}
But, whether there is a change to /tmp/file or not, command3 and command2 always runs. How do I prevent it? I do not want "require" to be run in exec1 when there is no change to /tmp/file.
You need: firstly, for all of the execs to subscribe to the file resource; secondly, for each of those to also require their preceding exec resources; and thirdly, for each exec to be set to refreshonly.
Here is some code that does that:
file { 'file':
ensure => file,
path => '/tmp/file',
content => "some content\n",
}
exec { 'exec1':
command => 'command1',
subscribe => File['file'],
refreshonly => true,
}
exec { 'exec2':
command => 'command2',
subscribe => File['file'],
require => Exec['exec1'],
refreshonly => true,
}
exec { 'exec3':
command => 'command3',
subscribe => File['file'],
require => Exec['exec2'],
refreshonly => true,
}
How this works:
Using exec's refreshonly mechanism, exec1 is triggered only on refresh events, and a refresh event is sent if and only if there is a change in file1's content.
All of the exec events need to be similarly triggered by the changes in the file's content, thus they all subscribe to the file.
But the execs need to be ordered in a specific way, and thus exec2 requires exec1, and exec3 requires exec2.
See also reasons why refreshonly needs to be used carefully.
is there a way in Puppet to catch a failure when resource is applied, for example, when declaration like
file { '/var/tmp/test':
ensure => file,
mode => '0755',
}
fails, invoke something like
exec { 'Register some failure':
command => '/var/tmp/register failure for /var/tmp/test',
}
?
You can try this :
exec { 'Notify a failure' :
command => "/var/tmp/register failure for /var/tmp/test",
path => "/bin:",
subscribe => File["/var/tmp/test"],
}