No one has been able to explain this inside my company so if you are able to solve this KUDOS to you!
Inside my puppet repo I have setup as follows:
environment/ops/modules/papertrail
├── files
│ ├── elasticsearch_log_files.yml
│ ├── log_files.yml
│ └── remote_syslog.conf
|
└── manifests
├── elasticsearch.pp
└──init.pp
└── templates
└── elasticsearch_log_files.yml.erb
MY elasticsearch.pp file contains the following:
class papertrail::elasticsearch inherits papertrail {
$source = "puppet:///modules/papertrail"
file { "/etc/log_files.yml" :
mode => 0644,
owner => root,
group => root,
ensure => present,
source => "$source/elasticsearch_log_files.yml",
}
}
Now when I try to change the last line to:
"$source/elasticsearch_log_files.yml.erb",
or
"$source/templates/elasticsearch_log_files.yml",
Puppet errors out and says that it can't locate the file:
Error: /Stage[main]/Papertrail::Elasticsearch/File[/etc/log_files.yml]: Could not evaluate: Could not retrieve information from environment ops source(s) puppet:///modules/papertrail/elasticsearch_log_files.yml.erb
What is strange is that when I use the following stanza to just include the yml file instead of erb it works fine and the file gets populated on the target:
"$source/elasticsearch_log_files.yml",
How can I include my erb? I have dynamic variables that I need to assign to the configuration file log_files.yml and I am so far unable to do so =(
This is solved. I didn't add the template directory to my git commit so once added with git add . it worked.
Related
I need to create a collection with a total of 100 NFTs, where the first 10 (IDs 0 to 9) will be minted to the same wallet from the start, and the remaining 90 will have the possibility to be minted through a web page.
I understand that the procedure would be as follows:
Create a CMv2 with a total of 10 assets.
Mint all of them (because the minting is random, it must be done before adding the remaining NFTs).
Create the second CMv2 with the remaining 90 assets. I must specify the address of the mint created in the first CMv2 (the "collection mint address") with the -m parameter.
However, I encounter several errors when doing this:
Case 1:
private.json -> "number": 10
public.json -> "number": 90
assets
├── private
│ ├── 0.json
│ ├── 0.png
│ ├── ...
│ ├── 9.json
│ └── 9.png
└── public
├── 10.json
├── 10.png
├── ...
├── 99.json
└── 99.png
config
├── private.json
└── public.json
Case 2 (same file structure as above):
private.json -> "number": 10
public.json -> "number": 100
Case 3:
private.json -> "number": 10
public.json -> "number": 90
assets
├── private
│ ├── 0.json
│ ├── 0.png
│ ├── ...
│ ├── 9.json
│ └── 9.png
└── public
├── 0.json
├── 0.png
├── ...
├── 89.json
└── 89.png
config
├── private.json
└── public.json
Case 4 (same file structure as above):
private.json -> "number": 10
public.json -> "number": 100
All 4 cases return the same error: Error Number: 6003. Error Message: Index greater than length!.
I had the same issue not to long ago take a look here: One Collection, Multiple Candy Machines
First of all, I recommend using SUGAR CLI to upload & deploy the Candy Machines - the experience is smoother. If you are on Windows you can use WSL2. I also recommend getting a custom RPC, take a look at Quiknode - it's easy to setup.
To upload and then deploy the public collection:
sugar upload assets/public -c config/public.json --cache .cache/public.json -k <WALLET KEYPAIR.json> -l debug -r <RPC ENDPOINT URL>
sugar deploy -c config/public.json --cache .cache/public.json -k <WALLET KEYPAIR.json> -l debug -r <RPC ENDPOINT URL>
Repeat the same steps as above for the private collection (just change private wherever there is public).
To set the same collection using SUGAR:
sugar collection set --cache .cache/public.json -k <WALLET KEYPAIR.json> --candy-machine <CANDY MACHINE ID> --collection-mint <COLLECTION ADDRESS> -r <RPC ENDPOINT URL>
Repeat for private assets.
I've managed to show total number of NFTs on UI by connecting to the private machine and the public machine (you however cannot mint from the private machine using the UI) - this behavior is not supported by default, you are going to have to do some coding for that.
And regarding the index problem, the different configurations should have done the trick (private.json & public.json) but if Metadata is the problem I used a python script to renumber the indexes properly - if that is something you are interested in I can provide.
Once,you have uploaded your assets and created a Candy Machine then you cannot add or remove assets from that Candy Machine So to answer this question on how to merge two Candy Machine Together you can create a Single Collection/Parent NFT and point both the Candy machine assets to that Collection/Parent NFT. You can use the tool metaboss to do that
I'm installing the ansible.posix collection to use in my playbook like this:
ansible-galaxy collection install -r ansible/requirements.yml -p ansible/collections
However, I get this warning message that I want to get rid of:
[WARNING]: The specified collections path '/home/myuser/path/to/my/repo/ansible/collections' is not part of the
configured Ansible collections paths '/home/myuser/.ansible/collections:/usr/share/ansible/collections'. The installed collection won't be
picked up in an Ansible run.
My repo is laid out like this:
├── ansible
│ ├── playbook.yml
│ ├── files
│ │ ├── ...
│ ├── tasks
│ │ ├── ...
│ ├── requirements.yml
├── ansible.cfg
...
ansible.cfg looks like this:
[defaults]
timeout = 60
callback_whitelist = profile_tasks
Here's the output of ansible --version:
ansible 2.9.17
config file = /home/myuser/path/to/my/repo/ansible.cfg
configured module search path = ['/home/myuser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.7/dist-packages/ansible
executable location = /usr/local/bin/ansible
python version = 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0]
In the docs for installing collections with ansible-galaxy, they say the following:
You can also keep a collection adjacent to the current playbook, under a collections/ansible_collections/ directory structure.
play.yml
├── collections/
│ └── ansible_collections/
│ └── my_namespace/
│ └── my_collection/<collection structure lives here>
And, like the documentation suggests, I can still use the collection just fine in my play. But this warning message is quite annoying. How do I get rid of it?
I have created ansible.cfg within the ansible project I'm working on.
You could simply cp /etc/ansible/ansible.cfg .
but since the file would look like:
[defaults]
collections_paths = ./collections/ansible_collections
It is just easier to create it.
Once there, Ansible will know about your custom configuration file.
In you project folder you will:
mkdir -p ./collections/ansible_collections
And then run the install.
If your requirements.yml contains a collection like:
collections:
- community.general
You'd have to install it as:
ansible-galaxy collection install -r requirements.yml -p ./collections/
And the output would be:
[borat#mypotatopc mycoolproject]$ ansible-galaxy collection install -r requirements.yml -p ./collections/
Process install dependency map
Starting collection install process
Installing 'community.general:3.1.0' to '/home/borat/projects/mycoolproject/collections/ansible_collections/community/general'
In case you won't setup your modified ansible.cfg, the output would be:
[borat#mypotatopc mycoolproject]$ ansible-galaxy collection install -r requirements.yml -p ./
[WARNING]: The specified collections path '/home/borat/projects/mycoolproject' is not part of the configured Ansible collections paths
'/home/borat/.ansible/collections:/usr/share/ansible/collections'. The installed collection won't be picked up in an Ansible run.
Process install dependency map
Starting collection install process
Installing 'community.general:3.1.0' to '/home/borat/projects/mycoolproject/ansible_collections/community/general'
There are other methods too, but I like this one.
How can I quickly run a custom function on any node with puppet apply ?
Let's say I have this file (test.pp)
file { "/root/files/f":
content => test('test'),
}
And this ruby file (test.rb) which only log and return the first agument.
require 'logger'
module Puppet::Parser::Functions
newfunction(:test, :type => :rvalue
) do |args|
log = Logger.new(STDOUT)
log.level = Logger::INFO
log.info(args[0])
args[0]
end
end
How does one call the ruby function test with a puppet apply test.pp?
My problem is that is take like 5minutes to run my entire puppet agent -t and I need to add a function to puppet so I would like to test it quickly instead of waiting 5minutes each time.
This will certainly work, but it's hard to maintain.
A more maintainable way to do this is to add your function to a module, then install that module on your master.
For example, create a new with the name of your module (eg. test_function):
mkdir -p test_function/lib/puppet/parser/functions
You should have the following tree in your test_function module
├── lib
│ └── puppet
│ ├── parser
│ │ └── functions
│ │ ├── test.rb
Add your test.rb code to the test.rb file
Copy this module to your master's module path (this is probably /etc/puppet/modules depending on your Puppet version, use puppet module list to find out)
After that, the puppet master will read its module list and dynamically add-in all functions it finds.
More documentation about it here:
https://docs.puppetlabs.com/guides/plugins_in_modules.html
https://docs.puppetlabs.com/guides/custom_functions.html
I just found out.
All you need to do is to add the test.rb file directly into /var/lib/puppet/lib/puppet/parser/functions/test.rb and the puppet apply will "see" the function.
I'm using puppet as my provisioner in one of my vagrant project. I'm trying to add a module for a custom bash_profile.
The module_path for puppet is set to:
puppet.module_path = "puppet/modules"
The class for my bash_profile module looks like this:
class bash_profile
{
file
{
"/home/vagrant/bash_profile":
ensure => present,
source => "puppet:///modules/bash_profile/files/bash_profile"
}
}
Here's the file structure for my puppet structure:
puppet
| manifests
| | phpbase.pp // my main manifest file that has includes for modules
| modules
| | bash_profile
| | | files
| | | | bash_profile // the actual bash_profile file I want to ensure is present on my VM
| | | manifests
| | | | init.pp // the init file included for the bash_profile class
When I run the provisioning for vagrant, I get the error
err: /Stage[main]/Bash_profile/File[/home/vagrant/bash_profile]: Could not evaluate: Could not retrieve information from environment production source(s) puppet:///modules/bash_profile/files/bash_profile at /tmp/vagrant-puppet-1/modules-0/bash_profile/manifests/init.pp:8
I'm not sure why it can't retrieve the information. The path seems to be correct. Can anyone see what I'm missing?
Yes, you are not supposed to include the literal files/ in the URL. Instead, it should just be
puppet:///modules/bash_profile/bash_profile
You may also receive this error with recurse => true if your module name is invalid. For instance, if you have this module structure:
modules
├── my-example
│ └── files
│ └── example
│ └── test.txt
and this resource:
file { "/tmp/example":
ensure => directory,
recurse => true,
source => "puppet:///modules/my-example/example",
}
you'll get this error:
==> default: Info: Could not find filesystem info for file 'my-example/example' in environment production
==> default: Error: /Stage[main]/Main/Node[default]/File[/tmp/example]: Could not evaluate: Could not retrieve information from environment production source(s) puppet:///my-example/example
The fix is to rename the module—for instance, naming it my_example fixes it. The rules for module names are documented but easy to miss.
Things to care about
The Puppet URI format puppet:///modules/name_of_module/filename
The fileserver directory to be present in the module directory
This video is an shows step-by-step guide to resolve the error
I'm just getting started with puppet (and vagrant) to set up the development environment for our team, which consists of 8+ developers, each of which have their particular bash configuration, etc. I've got all the software installed on the system to quickly deploy new development virtual machines, but I'm not sure the best way to set up the development environment for each particular user in an automated way (we will end up having several development environments and it would be convenient to write this once and be done).
For example, I'd like to set up a user joe, clone Joe's configuration repo from github, and then run a script in that github repository to set up the environment for Joe. Any suggestions for how to do this for Joe as well as Jimmy, James, Julie, Jane, Jim, Jake, and Jimbo?
In case its any help, the development machines will almost certainly be ubuntu systems.
In addition to #Matt's suggestion, I created a custom puppet module that instantiates the configuration environment for each individual based on their github preferences. The resulting puppet module users looks something like this:
users/
├── manifests
│ ├── init.pp # base level configurations for all users
│ ├── jake.pp # custom setup for jake
│ ├── james.pp # custom setup for james
│ ├── jane.pp # custom setup for jane
│ ├── jim.pp # custom setup for jim
│ ├── jimbo.pp # custom setup for joe
│ ├── jimmy.pp # custom setup for jimmy
│ ├── joe.pp # custom setup for julie
│ └── julie.pp # custom setup for jimbo
└── templates
The relevant tidbit is in the custom setup files for each user. For example, here's what jim.pp might look like:
class users::jim {
# make sure that all base configuration in init.pp is set up first
require users
# add the user here
user { 'jim':
# comment => 'Dean Malmgren',
home => '/home/jim',
shell => '/bin/bash',
uid => 201,
managehome => 'true',
groups => ['sudo', 'vagrant'],
provider => 'useradd',
password => '$6$kxHLEuHW$78m3zHVLu0XUUDaU4bT.PEg./FfcloJiWml',
}
# clone the repository the first time
exec { 'jim-clone-dotfiles':
command => 'git clone git://github.com/jim/dotfiles.git && python dotfiles/create_softlinks.py',
cwd => '/home/jim',
creates => '/home/jim/dotfiles',
user => 'jim',
group => 'jim',
require => [ Package['git'] ],
}
# fetch and update if jim decides to update his dotfiles repo
exec { 'jim-update-dotfiles':
command => 'git merge --ff-only origin/master && python create_softlinks.py',
cwd => '/home/jim/dotfiles',
unless => 'git fetch && git diff --exit-code origin/master',
user => 'jim',
group => 'jim',
require => Exec['jim-clone-dotfiles'],
}
}
You could use a puppet fact in the vagrant file to set the username and pass this through to your puppet manifests. Something like the following:
Vagrant.configure("2") do |config|
config.vm.provision :puppet do |puppet|
puppet.facter = {
"user_name" => ENV['USER']
}
end
end
This would pass the current logged in username through to puppet and then within your manifest files you could use the variable "$user_name" within your git commands to checkout the correct users repo and do any other related tasks.