Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Fix update behavior when getting a zypper-related update #134

Merged
merged 1 commit into from
Oct 30, 2017

Conversation

termdew
Copy link
Contributor

@termdew termdew commented Sep 18, 2017

Fix the semantics of 'client.go', so that a second update process is executed, when a zypper-related update (with exitcode 103) was installed.
Change the explanation of the update process in the manpage.

Fix #110 .

Signed-off-by: Fabian Baumanis fabian.baumanis@suse.com

client.go Outdated
de := err.(dockerError)
if isZypperExitCodeSevere(de.exitCode) {
if de.exitCode == zypperExitInfRestartNeeded {
goto run_cmd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure you can avoid using a goto statement 😉

Copy link
Contributor

@vrothberg vrothberg Sep 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer using a goto here. Golang doesn't support do-while loops, so an alternative to it would be using a for loop and a variable indicating another run.

client.go Outdated
run_cmd:
id, err = startContainer(id, cmd, true, dst)
return id, err
switch err.(type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this going to be called at all ? (mind the previous return statement)

Copy link
Contributor

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide a commit message describing your changes and why they are necessary. Some comments in the code would also be great. Also, the descriptions of the changed functions should be changed to reflect the new semantics. startContainer, for instance, now expects a container ID and not an image name anymore.

client.go Outdated
de := err.(dockerError)
if isZypperExitCodeSevere(de.exitCode) {
if de.exitCode == zypperExitInfRestartNeeded {
goto run_cmd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nesting of those if-branches isn't correct here. First, we need to return an error if the exit code is severe. Also the zypperExitInfRestartNeeded has the value 103, but severe ones are > 0 && < 100, so the if conditions are contradicting. What we should do instead is to return an error if the code is severe and move the run_cmd in a separate if branch.

@termdew termdew force-pushed the UpdateFix branch 2 times, most recently from 41cddc6 to 8aa353d Compare September 19, 2017 13:42
client.go Outdated
return "", err
}

run_cmd:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a regular for loop with a boolean value or something else. Please refrain from using a goto statement unless it's really necessary.

client.go Outdated
log.Println(err)
return "", err
}
func startContainer(id string, cmd []string, wait bool, dst io.Writer) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the documentation as @vrothberg said. The semantics have changed, so the expectation has changed too, and the documentation should be in sync with the semantics.

Copy link
Contributor

@vrothberg vrothberg Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startContainer(...) currently doesn't use the cmd argument. We need to fix this as the interface suggests that the passed cmd will actually be executed inside container id. Sorry for not catching this before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, cmd shouldn't be passed now that we mirror the create-start API.

Copy link
Contributor

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, this will loop forever if it keeps on failing no ?

client.go Outdated
}

error103 := false
for error103 == false {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for !error103 {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer a more intuitive identifier, for instance runCommand or execute or something that indicates the semantics behind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mssola let me explain my thoughts on this:

error103 is false, so 'startContainer' is executed the first time.
Now we assume, a 103 exitcode was returned.
So, he leaves error103 on false and startCommand will be executed again.
Now we assume, no exitcode 103 was returned.
Therefore we go in fo the default case, where error103 is set to true and startCommand won't be executed again.

If there are more zypper updates which return the exitcode 103, the for-loop runs until there is no exitcode 103 anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, i changed error103 to 'execute' as @vrothberg mentioned before.
Therefore, startCommand will be executed, as long as 'execute' is 'true'.

provided by the NEW-IMAGE argument. Note that both the IMAGE and the NEW\-IMAGE
arguments have to follow Docker's naming format.
with all the available updates. If there is a zypper-related update, which returns
the exit code 103 (zypperExitInfRestartNeeded), zypper-docker goes through the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual exit code of zypper is called ZYPPER_EXIT_INF_RESTART_NEEDED (see zypper's manpages). After that change, I think we're good to go 👍

vrothberg
vrothberg previously approved these changes Sep 20, 2017
client.go Outdated
execute = false
return id, err
}
return id, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this line mean the loop will never run more than once?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which one? the "return id, err" ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 208. To me it looks like:

for someCond {
  // some code
  return blah
}

Which will always return blah (you need to use continue or similar to make the loop not hit that return statement).

client.go Outdated
}

execute := true
for execute {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid infinite loops we could do something like

for i := 0; i < 256; i++ {
  // snip: startContainer
  switch err.(type) {
  case dockerError:
    // snip: the severe check
    if de.exitCode == zypperExitInfRestartNeeded {
      continue
    }
  default:
  }
  return id, err
}
return "", some_error_about_too_many_retries

@termdew termdew force-pushed the UpdateFix branch 2 times, most recently from 3c9ddcc to 8c593db Compare September 25, 2017 06:17
@termdew
Copy link
Contributor Author

termdew commented Oct 5, 2017

ping please review @cyphar @vrothberg @mssola

client.go Outdated
log.Println(err)
return "", err
}
func startContainer(id string, cmd []string, wait bool, dst io.Writer) (string, error) {
Copy link
Contributor

@vrothberg vrothberg Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startContainer(...) currently doesn't use the cmd argument. We need to fix this as the interface suggests that the passed cmd will actually be executed inside container id. Sorry for not catching this before.

Fix explanation of the update process in the manpage

- startContainer and createContainer are now seperated
- createContainer now only creates the container, which is started then
by startContainer.
- startContainer now only starts the container based on the container ID
created by createContainer
- after the severity check of the exit code another if-statement checks,
if the exit code is 103 (zypperExitInfRestartNeeded)

Signed-off-by: Fabian Baumanis <fabian.baumanis@suse.com>
@termdew
Copy link
Contributor Author

termdew commented Oct 5, 2017

Changes in client.go: removed the argument 'cmd' from the function 'startContainer' and from all elements which call 'startContainer'

@vrothberg
Copy link
Contributor

@mssola Any remaining or new objections?

@termdew
Copy link
Contributor Author

termdew commented Oct 30, 2017

this PR is still open, anything still wrong with it, or can it be merged?

@mssola @cyphar @vrothberg

@vrothberg vrothberg merged commit a6b7947 into SUSE:master Oct 30, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants