-
Notifications
You must be signed in to change notification settings - Fork 339
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
Traffic Ops Golang Incremental Rewrite App #729
Conversation
I'm not sure why you would couple the Golang Microservices with the Traffic Op Perl Monolith. If anything you should begin a new "rpm" that only contains the Microservices (which brings up a question about should the MS's be separated into different rpms, or even RPMs at all?) I think they need to be separated. |
The reason is to make it as operationally simple as possible. That's the only reason. We can make more RPMs, microservices, etc after we've moved away from Perl. I have no objection to microservices, I'm just afraid if we try to do both at once, we'll never get it done. |
I agree with simple, but I also don't want to "couple" the two. I don't find it egregious, to implement them as a "sidecar" rpm. We also might want to scale them differently because they are more efficient than Perl. If at one point we develop enough functionality we want to retire TO Perl, then we will have to unravel the coupling at that point in time. If the two are separate then it'll be easy to just "uninstall" the TO Monolith. |
It should be easy to retire. Once all endpoints are in Golang, simply delete the Perl from the RPM and Service files. |
Also, should |
Right, it will cause build changes, don't merge this until we do get consensus from the community on the mailing list (I sent an email to |
From a user's perspective, this creates some extra (as-yet-poorly-documented) obligations for configuration. An RPM upgrade should take care of itself. There should be enough information for the upgrade to perform all the config changes necessary to maintain nearly exactly the same set of functionality users have today. You'll need to allocate a new, high, port, but that's a fairly reasonable requirement, easily met. Notify the user via a message during upgrade and I think it would be ok. I'd love to see this merged; I think it's the right direction. I think we should attend a bit more carefully to the user experience, though. We don't want people afraid to upgrade TO because we break their installs. |
@alficles Agree, will do. It'll take me a bit though, I'm not an RPM Wizard. |
It would be nice to see some documentation included with this PR before it is merged. |
So, instead of using your own config, why not just use the existing { If you need properties that aren't in that config then you could use and groom your own |
I rolled an RPM to see how it could work, and I'm not seeing the process running. Which brought up my next question, where do the logs for troubleshooting go? |
If you didn't set up the config, it will fail to start. Right now, failure to start will be logged to the SystemD service log. I'll make log locations part of the config, consistent with our existing apps. |
Putting a reminder here: Also need to make setting up the config part of Postinstall. |
If we want to automatically set up the config, we're going to have to touch postinstall, if nothing else, to determine the new port to serve old-TO on. |
@dneuman64 I agree, I'll add docs and tests. |
We're also going to need a Perl serialized hash parser in Go, for |
From @elsloo : Need to let the Golang app run as a user and serve 443. Looks like the way to do that is to add |
@rob05c awesome, looking forward to seeing how that works, as we might want to adopt that approach for any/all of our golang components that need to open ports like this. |
} | ||
|
||
// ParseConfig validates required fields, and parses non-JSON types | ||
func ParseConfig(cfg Config) (Config, error) { |
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.
Feedback I got from the Traffic Logs Generator was each config error should be listed at once. It's painful for the developer to fix the config problems one by one when they could just look at an error list
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.
Done.
return "", fmt.Errorf("missing traffic_ops_golang_port key") | ||
} | ||
portStr, ok := portStrI.(string) | ||
if !ok { |
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.
Shouldn't the port be defined as an "int16"?
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.
It's a string just because it was easier to work with in the code, e.g. the Go HTTP server takes a string. I can make it an int
or uint
if you want. I'd rather not uint16
though, it's unusual, and even if performance mattered it's not any faster on a 64-bit processor.
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.
Was wondering why the decision was made to use a string for a port. Not what I usually see in config 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.
The reason Go uses strings for ports is to support things like "http" instead of "80". In general, you shouldn't use strconv.Atoi
to convert port strings. Take a look at https://golang.org/pkg/net/#LookupPort
d15d638
to
1c39287
Compare
Can we call |
@dewrich |
If we plan on making this a "seamless" deployment how does the |
It reads the port from |
|
||
|
||
By default, the postinstall script configures the Go application to behave and transparently serve as the old Perl Traffic Ops did in previous versions. This includes reading the old ``cdn.conf`` and ``database.conf`` config files, and logging to the old ``access.log`` location. However, if you wish to customize the Go Traffic Ops application, you can do so by running it with the ``-oldcfg=false`` argument. By default, it will then look for a config file in ``/opt/traffic_ops/conf/traffic_ops_golang.json``. The new config file location may also be customized via the ``-cfg`` flag. A sample config file is installed by the RPM at ``/opt/traffic_ops/conf/traffic_ops_golang.json``. If you wish to run the new Go Traffic Ops application as a service with a new config file, the ``-oldcfg=false`` and ``-cfg`` flags may be added to the ``start`` function in the service file, located by default at ``etc/init.d/traffic_ops``. |
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.
Should this /opt/traffic_ops/conf/traffic_ops_golang.json
be /opt/traffic_ops/conf/traffic_ops_golang.config
?
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.
conf/config
seemed redundant, whereas .json
immediately tells anyone looking at it what the format is.
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.
where do I find this /opt/traffic_ops/conf/traffic_ops_golang.json
I only see /opt/traffic_ops/conf/traffic_ops_golang.config
in the project, which is why I commented on it being improperly documented as .json
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.
Ah, you're right. I meant to rename the file and forgot. I'll change the documentation.
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.
Fixed.
@@ -95,6 +97,11 @@ func Eventf(t time.Time, format string, v ...interface{}) { | |||
Event.Printf("%.3f %s", float64(t.Unix())+(float64(t.Nanosecond())/1e9), fmt.Sprintf(format, v...)) | |||
} | |||
|
|||
// EventfRaw writes to the event log with no prefix. | |||
func EventfRaw(format string, v ...interface{}) { |
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.
Should this function be called AccessfRaw
instead of EventfRaw
? Or any of the other functions that write to the access.log
?
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.
No, it's using the Event logger for access.log
. Which seemed to make sense, accesses are events for this app.
Must be merged after #786 which fixes an ORT bug this exposes. |
Just ran a JSON comparison tool against the Golang v. Perl responses and found that the JSON keys are different. Unfortunately, this can't change until we rev the API. Golang Perl |
Per our discussion: Mojo HTTP Header is sending this back when the Golang proxy does not.
|
This Mojo HTTP Header is also coming back and I don't see it in the Golang HTTP header
|
Test cases failed:
|
Refer to this link for build results (access rights to CI server needed): |
Refer to this link for build results (access rights to CI server needed): |
"test this please" |
Refer to this link for build results (access rights to CI server needed): |
This adds an app, which serves Traffic Ops endpoints as they're written (currently, just monitoring.json), and reverse-proxies everything else to the old Perl Traffic Ops.
Includes RPM and Service files, to deploy it alongside the old TO.
This can be trivially deployed alongside the old TO with no config (Puppet) changes. It reads the old TO config, and Postinstall sets the new port it needs.
Things left before this can be merged:
/traffic_ops
dir for build.shtocookie
out of experimental.json
and without