Is there a way to edit my openshift configmap using oc command - python

I am trying to create a simple automation to replace my config map content in OpenShift from the current one to an edited yaml file, I have tried many oc commands and failed, I was wondering if any one had an idea of how to do this.
Just to make u understand:
I'm usingoc get congifmap <configmap name> to get the current configmap from my project,
Then I am using python to make my changes to the configmap data.
then I want to change the current config map to the new edited one.
I tried edit, apply, change but they all failed.
Would appreciate the help :)

There is an"oc"command for such use case:oc patch
With"oc patch"you can edit, replace, add, remove parts of any OCP object
If you google "oc patch" you'll find many example on the net
Official OCP v4.7 oc patch doc
Tons of examples here
OC patch "man" page
Other examples

You just need to work with "inputs" and "outputs".
Imagine a lighttpd.conf:
server.modules = (
"mod_scgi",
"mod_compress",
"mod_accesslog"
)
oc create cm lighttpd --from-file lighttpd.conf
So, as a example, let's change the mod_scgi to mod_fastcgi. So I wrote this script:
import fileinput
for line in fileinput.input():
if 'mod_scgi' in line:
print(line.replace('scgi', 'fastcgi').rstrip())
else:
print(line.rstrip())
So, to change the configMap, update it's value and apply again:
oc get cm -o yaml | python modify.py | oc apply -f -
get -o yaml prints all information on screen
output goes to the script modify.py
modify.py change and print the lines as they are read from standard input
output goes to oc
oc apply -f - reads from standard input and apply

Related

How can I access to a help subsection from a hydra config file in a command line?

I am currently using the hydra config file as a part of a deep learning framework, in order to declare several parameters.
I wrote a help section in my config.yaml file to declare all the parameters and describe them:
help:
header: == HYDRA CONFIG FILE ARGUMENTS DESCRIPTION ==
template: |-
${hydra.help.header}
The hydra config file is used to fill in the arguments for the segmentation monai framework.
It is split in several parts with arguments that will be used for the training:
- data
- root_path: TYPE=STR
root directory containing the data and gt folder that contains files in nifti format.
Directory must also contains the db.csv dataframe that list the patients IDs and TAGS
...
- split
- run: TYPE=BOOL
Whether to run the split part or not.
- eval_ratio: TYPE=FLOAT
Split ratio for the eval.
- test_ratio: TYPE=FLOAT
Split ratio for the test.
...
- train:
- run: TYPE=BOOL
Whether to run the train part or not.
- seed: TYPE=INT
Define a seed if you want to run deterministic training for reproductibility
...
I know that the command to display the help is the following one:
python d:/projects/my_file.py --help
The problem is that this command displays the full help section. My question is: is there a way to display only a subsection of this help message, only the "data" part for example ?
Thank you for your help.
Currently (2022-01-11) there is no smooth way to access just a sub-part of the help via the CLI. There is an open feature https://github.com/facebookresearch/hydra/issues/633 that's related to this topic.
As #Jasha mentioned, Hydra's help support is lacking.
Hydra definitely does not understand the help format you invented in order to print only a sub section of it.
One thing that can be of some use is to print a subsection of the config itself.
This will not include any of your fancy additional help though, but it will show you any sub section of the config (including the help).
$python main.py --cfg job -p foo.bar
Where foo.bar is the sub-section you want to output.

using diff util with --show-function-line for Python files

I like to compare Python sources with diff util and I have seen that git diff shows me the function name (for some files, but also not for Python) in the hunk or chunk? header. Thats why I searched to do the same with normal diff.
Then I found that there is a -p, --show-c-function param, which don't work well with Python files (I only get the class name). So I also found in the man page the param: -F, --show-function-line=RE
Now I searched for a nice RE to match python functions to include them in my diff output without luck.
I know we have def myname(): or async def myname(): ... and maybe more?
Has someone a good RegEx for it?
I found this one, but it don't work with diff util (the output has no function names):
diff -Nru -F '(?P<function>\w+)\s?\((?P<arg>(?P<args>\w+(,\s?)?)+)\)' modules/websocket/__init__.py.old modules/websocket/__init__.py
Regards,
Thomas

How to use the kubernetes-client for executing "kubectl apply"

I have a python script which basically runs the following three commands:
kubectl apply -f class.yaml
kubectl apply -f rbac.yaml
kubectl apply -f deployment-arm.yaml
I want to use the kubernetes-client written in python to replace it. My current code, loads the there yaml files (using pyyaml), edits them a bit, inserts into a file and use the command line kubectl to execute those three commands. Some of the code:
# load files, edit them and dump into new files, part ...
result = run(['kubectl', 'apply', '-f', class_file_path])
# status check part ...
result = run(['kubectl', 'apply', '-f', rbac_file_path])
# status check part ...
result = run(['kubectl', 'apply', '-f', deployment_file_path])
# status check part ...
What I want to do: Replace those three commands with the python kubernetes-client. Reading the docs and seeing the topic, I came across with the create_namespaced_deployment method which I think I need to use for the deployment_file_path file. But I can't seem to figure out what I need to do with the two other files.
Assuming that I already loaded the three yaml files (using pyyaml) and edited them (without dumping into new files) and now you have free yaml dicts deployment_dict, class_dict, and rbac_dict, How can I use the client to execute the three above methods?
EDIT: BTW if it's not possible to pass the three dicts, I could just dump them into files again but I want to use the python client instead of the kubectl. How to do it?
There is a separate function for every object and action:
from kubernetes import client, config
import yaml
body = yaml.safe_load("my_deployment.yml")
config.load_kube_config()
apps_api = client.AppsV1Api()
apps_api.create_namespaced_deployment(body=body, namespace="default")
apps_api.replace_namespaced_deployment(body=body, namespace="default")
apps_api.patch_namespaced_deployment(body=body, namespace="default")
apps_api.delete_namespaced_deployment(body=body, namespace="default")
body = yaml.safe_load("my_cluster_role.yml")
rbac_api = client.RbacAuthorizationV1Api()
rbac_api.create_cluster_role(body=body)
rbac_api.patch_cluster_role(body=body)
rbac_api.replace_cluster_role(body=body)
rbac_api.delete_cluster_role(body=body)
# And so on
When you use kubectl apply you don't care if the object already exists, what API to use, which method to apply, etc. With the client library, as you can see from the example above, you need to:
Load kube-config.
Select the right API to use.
Select the method you want to use. Note that create_something will not work if that something already exists.
I recommend you to go through the examples that the library provides, they really are great to learn the thing.

How to write OS X Finder Comments from python?

I'm working on a python script that creates numerous images files based on a variety of inputs in OS X Yosemite. I am trying to write the inputs used to create each file as 'Finder comments' as each file is created so that IF the the output is visually interesting I can look at the specific input values that generated the file. I've verified that this can be done easily with apple script.
tell application "Finder" to set comment of (POSIX file "/Users/mgarito/Desktop/Random_Pixel_Color/2015-01-03_14.04.21.png" as alias) to {Val1, Val2, Val3} as Unicode text
Afterward, upon selecting the file and showing its info (cmd+i) the Finder comments clearly display the expected text 'Val1, Val2, Val2'.
This is further confirmed by running mdls [File/Path/Name] before and after the applescript is used which clearly shows the expected text has been properly added.
The problem is I can't figure out how to incorporate this into my python script to save myself.
Im under the impression the solution should* be something to the effect of:
VarList = [Var1, Var2, Var3]
Fiele = [File/Path/Name]
file.os.system.add(kMDItemFinderComment, VarList)
As a side note I've also look at xattr -w [Attribute_Name] [Attribute_Value] [File/Path/Name] but found that though this will store the attribute, it is not stored in the desired location. Instead it ends up in an affiliated pList which is not what I'm after.
Here is my way to do that.
First you need to install applescript package using pip install applescript command.
Here is a function to add comments to a file:
def set_comment(file_path, comment_text):
import applescript
applescript.tell.app("Finder", f'set comment of (POSIX file "{file_path}" as alias) to "{comment_text}" as Unicode text')
and then I'm just using it like this:
set_comment('/Users/UserAccountName/Pictures/IMG_6860.MOV', 'my comment')
After more digging, I was able to locate a python applescript bundle: https://pypi.python.org/pypi/py-applescript
This got me to a workable answer, though I'd still prefer to do this natively in python if anyone has a better option?
import applescript
NewFile = '[File/Path/Name]' <br>
Comment = "Almost there.."
AddComment = applescript.AppleScript('''
on run {arg1, arg2}
tell application "Finder" to set comment of (POSIX file arg1 as alias) to arg2 as Unicode text
return
end run
''')
print(AddComment.run(NewFile, Comment))
print("Done")
This is the function to get comment of a file.
def get_comment(file_path):
import applescript
return applescript.tell.app("Finder", f'get comment of (POSIX file "{file_path}" as alias)').out
print(get_comment('Your Path'))
Another approach is to use appscript, a high-level Apple event bridge that is sadly no longer officially supported but still works (and saw an updated release in Jan. 2021). Here is an example of reading and setting the comment on a file:
import appscript
import mactypes
# Get a handle on the Finder.
finder = appscript.app('Finder')
# Tell Finder to select the file.
file = finder.items[mactypes.Alias("/path/to/a/file")]
# Print the current comment
comment = file.comment()
print("Current comment: " + comment)
# Set a new comment.
file.comment.set("New comment")
# Print the current comment again to verify.
comment = file.comment()
print("Current comment: " + comment)
Despite that the author of appscript recommends against using it in new projects, I used it recently to create a command-line utility called Urial for the specialized purpose of writing and updating URIs in Finder comments. Perhaps its code can serve as an an additional example of using appscript to manipulate Finder comments.

How does one add a svn repository build number to Python code?

EDIT: This question duplicates How to access the current Subversion build number? (Thanks for the heads up, Charles!)
Hi there,
This question is similar to Getting the subversion repository number into code
The differences being:
I would like to add the revision number to Python
I want the revision of the repository (not the checked out file)
I.e. I would like to extract the Revision number from the return from 'svn info', likeso:
$ svn info
Path: .
URL: svn://localhost/B/trunk
Repository Root: svn://localhost/B
Revision: 375
Node Kind: directory
Schedule: normal
Last Changed Author: bmh
Last Changed Rev: 375
Last Changed Date: 2008-10-27 12:09:00 -0400 (Mon, 27 Oct 2008)
I want a variable with 375 (the Revision). It's easy enough with put $Rev$ into a variable to keep track of changes on a file. However, I would like to keep track of the repository's version, and I understand (and it seems based on my tests) that $Rev$ only updates when the file changes.
My initial thoughts turn to using the svn/libsvn module built in to Python, though I can't find any documentation on or examples of how to use them.
Alternatively, I've thought calling 'svn info' and regex'ing the code out, though that seems rather brutal. :)
Help would be most appreciated.
Thanks & Cheers.
There is a command called svnversion which comes with subversion and is meant to solve exactly that kind of problem.
Stolen directly from django:
def get_svn_revision(path=None):
rev = None
if path is None:
path = MODULE.__path__[0]
entries_path = '%s/.svn/entries' % path
if os.path.exists(entries_path):
entries = open(entries_path, 'r').read()
# Versions >= 7 of the entries file are flat text. The first line is
# the version number. The next set of digits after 'dir' is the revision.
if re.match('(\d+)', entries):
rev_match = re.search('\d+\s+dir\s+(\d+)', entries)
if rev_match:
rev = rev_match.groups()[0]
# Older XML versions of the file specify revision as an attribute of
# the first entries node.
else:
from xml.dom import minidom
dom = minidom.parse(entries_path)
rev = dom.getElementsByTagName('entry')[0].getAttribute('revision')
if rev:
return u'SVN-%s' % rev
return u'SVN-unknown'
Adapt as appropriate. YOu might want to change MODULE for the name of one of your codemodules.
This code has the advantage of working even if the destination system does not have subversion installed.
Python has direct bindings to libsvn, so you don't need to invoke the command line client at all. See this blog post for more details.
EDIT: You can basically do something like this:
from svn import fs, repos, core
repository = repos.open(root_path)
fs_ptr = repos.fs(repository)
youngest_revision_number = fs.youngest_rev(fs_ptr)
I use a technique very similar to this in order to show the current subversion revision number in my shell:
svnRev=$(echo "$(svn info)" | grep "^Revision" | awk -F": " '{print $2};')
echo $svnRev
It works very well for me.
Why do you want the python files to change every time the version number of the entire repository is incremented? This will make doing things like doing a diff between two files annoying if one is from the repo, and the other is from a tarball..
If you want to have a variable in one source file that can be set to the current working copy revision, and does not replay on subversion and a working copy being actually available at the time you run your program, then SubWCRev my be your solution.
There also seems to be a linux port called SVNWCRev
Both perform substitution of $WCREV$ with the highest commit level of the working copy. Other information may also be provided.
Based on CesarB's response and the link Charles provided, I've done the following:
try:
from subprocess import Popen, PIPE
_p = Popen(["svnversion", "."], stdout=PIPE)
REVISION= _p.communicate()[0]
_p = None # otherwise we get a wild exception when Django auto-reloads
except Exception, e:
print "Could not get revision number: ", e
REVISION="Unknown"
Golly Python is cool. :)

Categories