Saltstack: Transfer multiple files (using wildcard?) - file

I'm new to Staltstack and I'm starting to do some tests with it, however, I'm facing a small issue and I cant find how to solve it.
I would like to transfer all the files inside a path on the master to a slave, however, I can't get it to work.
Configuration:
/destination_path_on_slave/*:
file.managed:
- source: salt://path_on_master/*
- user: root
However, when trying to apply this, I get the following error:
----------
ID: /destination_path_on_slave/*
Function: file.managed
Result: False
Comment: Source file salt://path_on_master/* not found
Changes:
----------
Any clue about how to get this working?
The destination path exists. Thank you.

I think the module you're looking for is file.recurse. It's used to recurse through a set of files whereas file.managed is for a single file.

Related

How to read a text file from resources without javaClass

I need to read a text file with readLines() and I've already found this question, but the code in the answers always uses some variation of javaClass; it seems to work only inside a class, while I'm using just a simple Kotlin file with no declared classes. Writing it like this is correct syntax-wise but it looks really ugly and it always returns null, so it must be wrong:
val lines = object {}.javaClass.getResource("file.txt")?.toURI()?.toPath()?.readLines()
Of course I could just specify the raw path like this, but I wonder if there's a better way:
val lines = File("src/main/resources/file.txt").readLines()
Thanks to this answer for providing the correct way to read the file. Currently, reading files from resources without using javaClass or similar constructs doesn't seem to be possible.
// use this if you're inside a class
val lines = this::class.java.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
// use this otherwise
val lines = object {}.javaClass.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
According to other similar questions I've found, the second way might also work within a lambda but I haven't tested it. Notice the need for the ?. operator and the lines?.let {} syntax needed from this point onward, because getResourceAsStream() returns null if no resource is found with the given name.
Kotlin doesn't have its own means of getting a resource, so you have to use Java's method Class.getResource. You should not assume that the resource is a file (i.e. don't use toPath) as it could well be an entry in a jar, and not a file on the file system. To read a resource, it is easier to get the resource as an InputStream and then read lines from it:
val lines = this::class.java.getResourceAsStream("file.txt").bufferedReader().readLines()
I'm not sure if my response attempts to answer your exact question, but perhaps you could do something like this:
I'm guessing in the final use case, the file names would be dynamic - Not statically declared. In which case, if you have access to or know the path to the folder, you could do something like this:
// Create an extension function on the String class to retrieve a list of
// files available within a folder. Though I have not added a check here
// to validate this, a condition can be added to assert if the extension
// called is executed on a folder or not
fun String.getFilesInFolder(): Array<out File>? = with(File(this)) { return listFiles() }
// Call the extension function on the String folder path wherever required
fun retrieveFiles(): Array<out File>? = [PATH TO FOLDER].getFilesInFolder()
Once you have a reference to the List<out File> object, you could do something like this:
// Create an extension function to read
fun File.retrieveContent() = readLines()
// You can can further expand this use case to conditionally return
// readLines() or entire file data using a buffered reader or convert file
// content to a Data class through GSON/whatever.
// You can use Generic Constraints
// Refer this article for possibilities
// https://kotlinlang.org/docs/generics.html#generic-constraints
// Then simply call this extension function after retrieving files in the folder.
listOfFiles?.forEach { singleFile -> println(singleFile.retrieveContent()) }
In order to have the same url that work for both Jar or in local, the url (or path) needs to be a relative path from the repository root.
..meaning, the location of your file or folder from your src folder.
could be "/main/resources/your-folder/" or "/client/notes/somefile.md"
The url must be a relative path from the repository root.
it must be "src/main/resources/your-folder/" or "src/client/notes/somefile.md"
Now you get the drill, and luckily for Intellij Idea users, you can get the correct path with a right-click on the folder or file -> copy Path/Reference.. -> Path From Repository Root (this is it)
Last, paste it and do your thing.

Change figure and table captions in blogdown

I'm tinkering with blogdown and would like to create figures and table with non-English caption headers. The following chunk
```{r label1, echo=FALSE, fig.cap="Fancy caption", fig.fullwidth=TRUE}
plot(1,1)
```
produces the plot and a caption that reads
Figure 1: Fancy caption
I'd like to be able to change the label such that, say, "Figure" becomes "Plot". I thought I could fix it in the same way as for bookdown: In the _bookdown.yml file I could have
language:
ui:
chapter_name: "Chap "
appendix_name: "App "
label:
fig: 'Plot '
tab: 'Fancy table '
but I'm not sure how to do something similar with a Hugo-based setup from blogdown. How can I add the above information to, say, the config.toml file or set it somewhere else?
First, store the _bookdown.yml file you described in the same folder as the blog post source .Rmd file, e.g. content/post/_bookdown.yml if your file is at content/post/my_post.Rmd.
Then, add _bookdown.yml to the list of ignoreFiles in your config.toml so that Hugo doesn't move _bookdown.yml to the public directory.
This works because blogdown::html_page() is based on bookdown::html_document2(), which will pick up the _bookdown.yml in the same directory of the source Rmd. I don't think it's possible to set this globally from your blogdown root dir, but if you store all your posts in content/post it's basically the same thing.

Building a Route to output differences of two files

Trying to put together a file diff route... could someone help? here is what I have ->
CsvDataFormat csv = new CsvDataFormat();
csv.setDelimiter(",");
from("file:inputdir?delete=true&sortBy=ignoreCase:file:name")
.unmarshal(csv)
.pollEnrich("file:backup?fileName=test.csv&sendEmptyMessageWhenIdle=true")
.unmarshal(csv)
// Need to aggregate here!!!!
.log("test");
A csv file gets dropped in the /input directory and then a backup file is consumed from the /backup directory. I would like to compare these two files and output the difference.
This is not a specific Camel problem. In order to solve this problem you may implement a diff functionality on your own, or you may use an existing library such as java-diff-utils.
Pseudocode:
// read file 1 into a list "list1"
// read file 2 into a list "list2"
// use java-diff-utils to calculate the difference
Patch patch = DiffUtils.diff(list1, list2);

Error while generating nodes with neo4j via neo4j-console

I'm trying to put data in my graph DB using neo4j. I'm new in the field and I don't find it easy to use the batch import tool that Michael Hunger wrote.
My goal is to generate at least 10000 nodes with just one property set. So I wrote a python script that generates 10000 lines of Cypher queries like "CREATE (:label{ number : '3796142470'})".
I put them in the console and execute them but I get this exception:
StackTrace:
scala.collection.immutable.List.take(List.scala:84)
org.neo4j.cypher.internal.compiler.v2_0.ast.SingleQuery.checkOrder(Query.scala:33)
Am I doing something wrong? In case the only way to generate those nodes is to use a batch/rest API, could you suggest me a easier way to do it?
Change:
CREATE (:label{ number : '3796142470'})
to look like:
CREATE (n1:Label { number : '3796142470'})
So you are following convention:
CREATE (n:Person { name : 'Andres', title : 'Developer' })
Put them into a file (say import.txt) and then:
bin/neo4j-shell -file import.txt
See http://blog.neo4j.org/2014/01/importing-data-to-neo4j-spreadsheet-way.html for more details.

NDB query giving different results on local versus production environment

I am banging my head into a wall over this and hoping you can tell me the very simple thing I have overlooked in my sleep deprived/noob state.
Very simply I am doing a query and the type of object returned is different on my local machine than what gets returned once I deploy the application.
match = MatchRealTimeStatsModel.queryMatch(ancestor_key)[0]
On my local machine the above produces a MatchRealTimeStatsModel object. So I can run the following to lines without a problem:
logging.info(match) # outputs a MatchRealTimeStatsModel object
logging.info(match.match) # outputs a dictionary from json data
When the above two lines are run on Goggles machines I get the following though:
logging.info(match) # outputs a dictionary from json data
logging.info(match.match) # AttributeError: 'dict' object has no attribute 'match'
Any suggestions as to what might be causing this? I cleared the data store and did everything I could think of to clean the GAE environment.
Edit #1: Adding MatchRealTimeStatsModel code:
class MatchRealTimeStatsModel(ndb.Model):
match = ndb.JsonProperty()
#classmethod
def queryMatch(cls, ancestor_key):
return cls.query(ancestor=ancestor_key).fetch()
And here is the actual call:
ancestor_key = ndb.Key('MatchRealTimeStatsModel', matchUniqueUrl)
match = MatchRealTimeStatsModel.queryMatch(ancestor_key)[0]
Perhaps you are using different versions of your code locally than in prod? Try to reset your copy of the source code in both places.

Resources