New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix shellcheck failure in gce/gci/flexvolume_node_setup.sh #81061
Fix shellcheck failure in gce/gci/flexvolume_node_setup.sh #81061
Conversation
@@ -175,8 +175,7 @@ echo "Restarting Kubelet..." | |||
echo | |||
|
|||
systemctl restart kubelet.service | |||
kubelet_wait | |||
if [ $? -eq 0 ]; then | |||
if kubelet_wait; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if [ $? -eq 0 ]; then
^-- SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
if [ -d "$driver_dir" ]; then | ||
|
||
filecount=$(ls -1 $driver_dir | wc -l) | ||
if [ $filecount -gt 1 ]; then | ||
filecount=$(find "$driver_dir" -mindepth 1 -maxdepth 1 -printf "%P\n" | grep -c -v "^\.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filecount=$(ls -1 $driver_dir | wc -l)
^---------------^ SC2012: Use find instead of ls to better handle non-alphanumeric filenames.
^---------^ SC2086: Double quote to prevent globbing and word splitting.
It is not same result with original code even if ls
is replaced with find
simply.
It uses -printf "%P\n"
to output only file name, and use grep -v "^\."
to except files starting with .
.
After changing, shellsheck says SC2126: Consider using grep -c instead of grep|wc -l
.
Therefore, it removes wc -l
and adds grep -c
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
darwin's version of find
doesn't have -printf
the original implementation is way simpler, and since this is used for counting and not the specific paths I think it's acceptable to ignore SC2012 here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we did actually want the values and not the count, we have an established pattern elsewhere:
- use a subshell
- cd to the target search directory
- use
find
against.
- trim
./
from the beginning by piping tocut
or similar
To get filename, use print0 and basename.
+1 on not needing it here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the comments.
I modified it a little as follows. As far as I run, the result is equivalent to the original way. But, more complicated and not readable.
filecount=$(cd "$driver_dir"; find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 basename | grep -c -v "^\.")
Can we ignore SC2012?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifically for getting a count, that's probably fine.
But generally speaking SC2012 exists because ls output is NOT portable or specified. We should prefer find.
Longer term we should move elaborate logic out of bash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I updated the commit using -print0
and basename
. Could you check it?
echo "ERROR: Expected 1 file in the FlexVolume directory but found $filecount." | ||
exit 1 | ||
fi | ||
|
||
driver_file=$( ls $driver_dir | head -n 1 ) | ||
driver_file=$(find "$driver_dir" -mindepth 1 -maxdepth 1 -printf "%P\n" | grep -v "^\." | head -n 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
driver_file=$( ls $driver_dir | head -n 1 )
^------------^ SC2012: Use find instead of ls to better handle non-alphanumeric filenames.
^---------^ SC2086: Double quote to prevent globbing and word splitting.
Same with line 105.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, I think it's acceptable to ignore SC2012
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of printf, use normal print, and use basename as the last step in the chain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have done.
/test pull-kubernetes-integration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the explanations
if [ -d "$driver_dir" ]; then | ||
|
||
filecount=$(ls -1 $driver_dir | wc -l) | ||
if [ $filecount -gt 1 ]; then | ||
filecount=$(find "$driver_dir" -mindepth 1 -maxdepth 1 -printf "%P\n" | grep -c -v "^\.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
darwin's version of find
doesn't have -printf
the original implementation is way simpler, and since this is used for counting and not the specific paths I think it's acceptable to ignore SC2012 here
echo "ERROR: Expected 1 file in the FlexVolume directory but found $filecount." | ||
exit 1 | ||
fi | ||
|
||
driver_file=$( ls $driver_dir | head -n 1 ) | ||
driver_file=$(find "$driver_dir" -mindepth 1 -maxdepth 1 -printf "%P\n" | grep -v "^\." | head -n 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, I think it's acceptable to ignore SC2012
if [ -d "$driver_dir" ]; then | ||
|
||
filecount=$(ls -1 $driver_dir | wc -l) | ||
if [ $filecount -gt 1 ]; then | ||
filecount=$(cd "$driver_dir"; find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 basename | grep -c -v "^\.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't need to do grep after the basename?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line counts files under $driver_dir. Therefore, I think need grep -c
to count.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can count with something like wc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered using wc -l
, but shellcheck said SC2126.
... xargs -0 -n1 basename | grep -v "^\." | wc -l)
^-----------^ SC2126: Consider using grep -c instead of grep|wc -l.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like I said up top for both of these now-find-based-implementations, I feel like the original ls-based implementations are fine; it's not clear to me what value we're getting here by adding all of this extra complexity to work around corner cases that haven't crept up thus far
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@k-toyoda-pi er right, see discussion below for if we even need to ignore files starting with .
(I don't think so, however we probably should ignore directories)
@spiffxp discussing below. #81061 (comment)
echo "ERROR: Expected 1 file in the FlexVolume directory but found $filecount." | ||
exit 1 | ||
fi | ||
|
||
driver_file=$( ls $driver_dir | head -n 1 ) | ||
driver_file=$(cd "$driver_dir"; find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 basename | grep -v "^\." | head -n 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should prefer cut to grep -v since we are removing a known fixed length prefix from all entries.
Lines 541 to 544 in 8c6c94b
function kube::util::list_staging_repos() { | |
( | |
cd "${KUBE_ROOT}/staging/src/k8s.io" && \ | |
find . -mindepth 1 -maxdepth 1 -type d | cut -c 3- | sort |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
find
reveals files starting with .
(ex. .aaa
). But ls
without -a
does not. So, grep -v
in this line excepts the files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now, we already pipe through basename which drops the ./foo/
, but do we actually need to ignore these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If find outputs the following result, I think grep -v
is needed to exclude .ddd
.
$ cd find_test; find . -mindepth 1 -print0 | xargs -0 -n1 basename
aaa
.ddd
bbb
ccc
Should we not consider these case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, I guess it depends on the data. Let's handle it for now but maybe leave a TODO about it.
also cc @msau42 ... does it make sense to ignore drivers starting with .
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
directories that start with . are reserved for the driver installation mechanism (to make sure driver installs are atomic). See here for details
directories sure, files though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like I said up top for both of these now-find-based-implementations, I feel like the original ls-based implementations are fine; it's not clear to me what value we're getting here by adding all of this extra complexity to work around corner cases that haven't crept up thus far
the ls
implementation was already not-correct I suspect. in neither of these are we currently only finding files, despite the variable name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for many comments.
I've checked flexvolume behavior.
When I placed kubelet-plugins/volume/exec/test~.aaa/.aaa
, which is dummy driver, .aaa
can work.
From the result, I think it should not except files begin with ".".
I will modify as the below.
- (line:105)
filecount=$(cd "$driver_dir"; find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 basename | wc -l)
- (line:111)
driver_file=$(cd "$driver_dir"; find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 basename | head -n 1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, thanks for being thorough!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'm done.
/retest |
/lgtm |
/test pull-kubernetes-integration |
/assign @filbranden |
/unassign Good point @BenTheElder ! Will send a PR to update OWNERS... Thanks! |
/assing @yguo0905 |
/assign @yguo0905 |
cc @verult |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: BenTheElder, k-toyoda-pi, yguo0905 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
/kind cleanup
What this PR does / why we need it:
Fix shellcheck failure of cluster/gce/gci/flexvolume_node_setup.sh.
Almost all of detected failures are
SC2086: Double quote to prevent globbing and word splitting
.Also, the below failures are detected in the file. See changed lines.
Which issue(s) this PR fixes:
Ref #72956
Special notes for your reviewer:
Does this PR introduce a user-facing change?:
/sig testing
/priority backlog