I want to make a script with ansible, to search on folder "/software" all the files, that were edited in the last day, then move them to "/tmp"
This my code so far (redhat 7.4):
- name: recurse path
find:
path: /software
recurse: yes
file_type: file
age: 1d
register: files
- name: copy files to tmp
copy:
src: ~/{{files}}
dest: /tmp
I get the error:
an exeption occurred during task execution ... could not find or access '~{u'files': []}, u'changed': False, 'failed': False, u'examined': 4....
The folders have full access, so I dont think its permissions.
What am I doing wrong?
As documented, the returned value of the find module is an object containing the list of found files under the files keyword.
You cannot use it directly: copy module takes only 1 file or folder as src, so you have to loop over all the files:
- name: check the content and structure of the variable
debug:
var: files
- name: copy files to tmp
copy:
src: "{{item.path}}"
dest: /tmp
with_items: "{{files.files}}"
It's always a good practice to debug a var after register while developing to check it's structure (so you can find how to use it) and it's content (in your case, looks like the file list is empty).
BTW: you need to know that the find module search on the remote host but, by default, the copy module copies from the ansible executor machine, so in your case, the src may not exists! So if you are copying from local to remote, simply add delegate_to: localhost and run_once: yes to your find task, otherwise you need to use the remote_src: yes parameter on the copy task.
Related
As far as I'm aware I'm using best practices to define paths (using raw strings) and how I go about joining them (using os.path.join()), e.g.
import os
fdir = r'C:\Code\...\samples'
fpath = os.path.join(fdir, 'fname.ext')
and doing so has not caused me any problems when running my code within a Python or command shell. If I print fpath to the console I get consistent use of \s in the path:
C:\Code...\samples\fname.ext
But when I run a Docker containerized version of the code and run the image I get the error:
FileNotFoundError: [Errno 2] No such file or directory:
'C:\Code\...\samples/fname.ext'
I don't understand why os.path.join() has used a / to join fdir and fname.ext when the rest of the path included \\. It doesn't do this when I run the code outside of the container.
I have tried using os.path.normpath():
fpath = os.path.join(fdir, 'fname.ext')
fpath = os.path.normpath(fpath)
as discussed here, and os.sep.join():
fpath = os.sep.join([fdir, 'fname.ext'])
as covered here, and Path().joinpath():
from pathlib import Path
fpath = Path(fdir).joinpath('fname.ext')
as well as Path() / 'path_to_add':
fpath = Path(fdir) / 'fname.ext'
as discussed here, but in every case I end up with the same result using os.path.join().
Can someone please help me to understand what is going on and how to create consistent paths that will work whether I run the code in Python in a Windows environment, or in a Docker container?
Update Nov. 16:
In trying to keep my question brief I think I've left out details that are crucial. Apologies to those who have kindly taken the time to offer suggestions based on my incomplete description of the problem.
My code needs to import/export files from/to directories that are defined within a user-specified configuration file.
So the configuration file has a section of code where the user defines variables and paths, e.g.
samplesDir = r"path-to-samples-directory"
The variables are stored in a dictionary of dictionaris and stored as a .json.
At the start of the code the user defines the key that selects the dictionary of interest so that at various parts in my code when a file needs to be imported/exported, the paths are at hand.
So back to my example, samplesDir is stored in the configuration dictionary, cfgDict, so all I need to do is append the file name:
sampleFpath = os.path.join(sampleDir, sampleFname)
and sampleFname is determined based on other variables.
Because of the dynamic nature of the variables (including directory paths and file paths), I think it rules out the use of static path defined in a .yml with Docker Compose.
Update Nov. 18:
It may help to include a few more details and some screenshots.
The above screenshot shows the file and folder structure of the src directory containing the source code, the main app.py script for command-line use, the Dockerfile, etc.
The configs folder contains JSON files that includes variables, paths to directories and files. The user can create configuration files either by copying an existing one and modifying the entries, or configuration files can be generated by calling config.py.
Within config.py I have pre-set variables and paths, so that the directory path to the configuration files (configs), sample files (sample_DROs) and others (e.g. fiducials) are all within src.
I don't anticipate any reason why the user would want to store the config files anywhere else, nor do I expect them to want to use different sample files (or move them elsewhere). However, they will undoubtedly create their own fiducials and may decide not to store them in the fiducials directory (i.e. somewhere not within the src directory).
Likewise I have pre-set the download directory (based on the parameters stored within the configuration files, files are fetched from a server and downloaded) to be the default Downloads directory:
rootDownloadDir = os.path.join(Path.home(), "Downloads", "xnat_downloads")
Those files are later imported, processed, and the outputs are (by default) exported into sub-directories within rootDownloadDir.
Within Dockerfile I set the working directory of the container to be that of the source code and copy all of the contents of src (with the exception of some directories defined in .dockerignore):
WORKDIR C:/Code/WP1.3_multiple_modalities/src
...
COPY . .
so that the structure of the container mimics that of WORKDIR:
Hence I have allowed for flexibility in import/export directories, and they are by default a combination of paths within and outside of the src directory. And so, the code executed within the container will need to access files both within and outside of src.
That said, I don't know what rootDownloadDir will look like when os.path.join(Path.home(), "Downloads", "xnat_downloads") is run within the container.
This has got me thinking - Is it bad practice to set the download directory outside of src?
Returning to the original error:
the sample file is in the container:
From the actual behavior I can suppose that the container is based on Unix-like image. Path separator is / in such systems.
To build an environment-independent path which works inside and outside of the container you need the following steps:
Mounting of host folder to container directory.
Environment variable inside and outside the container.
I can show an example of how this is achievable via docker-compose tool and its configuration file docker-compose.yml:
# docker-compose.yml file
version: '3'
services:
<service_name>: # your service name here
image: <image_name> # name of image your container is built on
environment:
- SAMPLES_PATH=/samples
volumes:
- C:\Code\somepath\samples:/samples
In your python code you can use the following structure:
import os
fdir = os.getenv('SAMPLES_PATH', r'C:\Code\...\samples')
fpath = os.path.join(fdir, 'fname.ext')
I'm trying to use intake and the intake-xarray to open and store remote files. I have a minimized catalog file here:
/isibhv/projects/paleo_pool/boundary_conditions/ice_sheet_reconstructions/ice_sheet_reconstructions.yaml
It looks like this:
metadata:
version: 1
sources:
glac1d:
description: The GLAC-1D Reconstruction
driver: netcdf
args:
urlpath: "https://sharebox.lsce.ipsl.fr/index.php/s/yfuUw91ruuJXroC/download?path=%2F&files=TOPicemsk.GLACD26kN9894GE90227A6005GGrBgic.nc"
cache_dir: "{{ CATALOG_DIR }}/glac1d"
cache:
- argkey: urlpath
type: file
I can open the files in Python:
import intake
cat = intake.open_catalog("ice_sheet_reconstructions.yaml")
ds = cat.glac1d.read()
This all works wonderfully; and I get the file as I would expect it. However, the cache doesn't show up where I would expect. I would have guessed a new folder is made under:
/isibhv/projects/paleo_pool/boundary_conditions/ice_sheet_reconstructions/glac1d
Instead, I get something in my home directory.
Did I specify the cache directory incorrectly?
As a second question: is it possible to directly specify how the cached files should be called when they are saved?
Thanks!
Paul
The location of the cache is specified by the config, which is a YAML file typically in ~/.intake/conf.yaml (key "cache_dir"), but can be elsewhere according to the INTAKE_CONF(_FILE) environment variable OR the metadata of the source, key "catalog_dir" (<- this may be incorrect?). The special value "catdir" means "in the directory where the catalog is".
However
With the appearance of caching in fsspec, the following will be possible:
sources:
glac1d:
description: The GLAC-1D Reconstruction
driver: netcdf
args:
urlpath: "filecache://sharebox.lsce.ipsl.fr/index.php/s/yfuUw91ruuJXroC/download?path=%2F&files=TOPicemsk.GLACD26kN9894GE90227A6005GGrBgic.nc"
storage_options:
target_protocol: https
cache_storage: "{{ CATALOG_DIR }}/glac1d"
unfortunately, the required change is not yet in intake-xarray.
I need a function in NodeJS (or an existent one, although I did't find one) that copies a folder to a diferent location but only copies the non existing files in the destination:
Folder to Copy:
-- Folder1
---- Folder1_1
------- File1_1_1
---- Folder1_2
------- File1_2_1
Destination Path has:
-- Folder1
---- Folder1_1
------- File1_1_1
So this method should only copy Folder1.2 and it's contents (File1.2.1) since all the other files are present already.
Does anyone have any idea on how to do this or if there is a module that has a method that does this?
simply use ncp and set the property options.clobber to false, then it wont replace any files already existing.
I am trying to write code with puppet and vagrant, and am unable to find how to copy a file from the directory containing the manifest to the target server.
In ansible I used this:
- name: Copy public key
copy:
src: ./myKey
dest: /home/user/.ssh/authorized_keys
I would like to do something like this with puppet
- file { 'myKey':
path => '/home/user/.ssh/authorized_keys',
ensure => file,
source => ./myKey }
I understand how to make this work using absolute path, but would like to use relative path here as my script will be pulled down with a git clone and run on another machine that will have different directory setups.
Vagrant.configure("2") do |config|
config.vm.network "private_network", ip: "192.168.1.1", auto_config: true
config.vm.box = "puppetlabs/centos-7.2-64-puppet-enterprise"
config.vm.provision "puppet" do |puppet|
puppet.manifest_file = "srv_site.pp"
end
end
In order to copy a file in puppet you need to put the file in the module path under files. So if your module is named mymodule the file should go here:
./mymodule/files/mykey
and in the module the file is copied by
file { 'mykey':
ensure => file,
path => '/home/user/.ssh/authorized_keys',
source => "puppet:///modules/${module_name}/mykey"
}
you cannot point source to a different place on the puppet master, unless you set up a file server mount point on the pupper master see https://docs.puppet.com/puppet/4.10/file_serving.html.
but the source can point to other places see https://docs.puppet.com/puppet/4.10/types/file.html#file-attribute-source.
I have a file in one branch //depot/Dest/file1.txt and other branch is //depot/Src/
I want to have a symbolic link from //depot/Src/file1.txt pointing to //depot/Dest/file1.txt by using p4v .
Can I do that using p4v ?
Option 1: Use streams. Stream definitions let you have a single depot file shared among multiple streams via the "import" path type.
Stream: //depot/Src
Paths:
share ...
Stream: //depot/Dest
Parent: //depot/Src
Paths:
share ...
import file1.txt
Option 2: Create an OS symlink and add it to the depot. I believe you can do this with a file as well as with a directory.