THAT Conference 2018 - Continuous Learning

So once again this year the Przylucki clan loaded up and made the drive up to Wisconsin to attend That Conference.  This was our fifth year going up for a few days to spend some time at Summer Camp for geeks.

So you can go back and read some of my other blog posts from past years (and you can probably guess from the fact that this is our fifth year) to know that I think attending That Conference is really worthwhile.  I know, I know,  it's at the Kalahari, in the Wisconsin Dells, so yes, I rode many waterslides... but that is not the draw for me to keep returning (though choosing THAT Conference is certainly influenced by such family-friendliness).  Attending That Conference is my attempt to take some dedicated time to continuously be learning.  I feel like I am learning something 365 days a year.  There is always something up-and-coming, always something I need to dig deeper on, always something I can get exposed to that will make me a better consultant, better employee, better co-worker.  Attending a conference, I have found, has been a wonderful way to gain a lot of knowledge in one big dedicated chunk. It allows me to get out and get exposed to things that I might not get exposed to otherwise.  It gives me a chance to learn things.  It makes me get out and meet people.  It (in the case of That Conference) allows me to eat lots and lots of bacon.

This year I was really happy with my That Conference experience.  For me the Keynotes every morning are always a highlight, and this year they were really strong.  Lots of strong motivation to go out and be the best "me" I can.  To work together with a team.  To focus on more than just the tech.  To embrace the sense of adventure. It was really strong this year..  But I also found so many great sessions.  I ran out to grab all the Docker & DevOps related sessions I could find.  I am in the middle of working with a client that is looking to begin adopting Docker with some of their new projects, so this was PERFECT for me to get a ton of real-world knowledge and experience from the stories and ideas shared in those sessions. Could not have come at a better time for me! I also found a few challenging "Soft Skills" sessions to help me focus on things like team communication and goal setting.  Good stuff.  I have a lot to work on. 

Another thing that can not be lost is the interaction with other people in the community.  Every day I meet new people. Every day I get to hear stories about what people are doing and the problems they are facing and the solutions they are working on to get through those problems.  I've come a long way in the last five years, first at embracing that interaction, and now also at recognizing the value there.  I was listening to the Out From the Cube podcast the other day, and George was talking about the value and importance of even simply starting out with "Hi my name is _______" .. And it struck a chord with me because I spent 3-4 days doing that.  Every meal, sitting down at a new table of people.. "Hi, my name is Jeff".. walking around the booths talking to sponsors "Hi my name is Jeff".. talking to people in sessions "Hi, my name is Jeff".  That was not natural to me the first year I was doing this, but man, it was so natural now, and it just opens things up, having conversations, meeting people and doing a little networking.  

So now I am back at the office, working on my day-to-day.  BUT now, I have more knowledge than i had two weeks ago. I have more confidence in what I need to do on the Docker front.  I have been exposed to new ideas and heard about new trends.  I am feel I am stronger for it.. 

Adding Some Flexibility to Build and Release with JSON to Variables

Creating build definitions and release definitions in TFS and VSTS can become a real chore.  Have you ever wanted to give a build or a release a little bit more flexibility, so you can handle some situations based on a condition, but didn't have a great way to give the developers control of that without having to meddle with manually setting variables all the time?  

Maybe you wanted to handle creating an "alpha" or "beta" version build of a nuget package?  or perhaps you wanted a insert some control of how things deployed? Having variables to control these things is great, and can rescue you from having to clone your build and release to handle the various situations that you find yourself in.   BUT now you've just given yourself more variables to maintain, and more things to remember to set at build or release time. 

I've run into a few situations in some recent work where it just makes the most sense to give control of what happens when code is committed to the developers that own the code.  One of the most direct ways to handle some of those things can be accomplished by placing some of that variable information in the developers hands to begin with, and one of the easiest ways to do that is to give them some JSON to hold it.

Some of my current work is involving creating a deploy pipeline and workflow to help the various development teams to most easily deploy their code to the various "dev" environments that many of the teams use.  The development teams had set up a series of Web Application paths on the dev server to hold various instances of their applications, so that one team can deploy, without stepping on another team's workflow.  Now team A, can deploy to Dev server app space "F3" while team B can deploy to app space "F5" and they won't interfere with each other, and then later they can deploy to app space "Integration" and all play nicely together.  This is all great, except how can we easily get a team B to deploy over to Team A's app space without making sure they update all the right spots in the right release definitions?  Well, I suggested we find a way to standardize a "deploy" json file that could be used to control some of those things ... this isn't the first time I've had to utilize a json file in the source code to help customize the process flow of a build or release, so instead of trying to craft yet another one-off custom task, I decided to create a more flexible task that will read a JSON file and simply create Variables in the build and release for subsequent tasks to utilize.  This way, I can feed other tasks the information they need, and I never (hopefully) will have to write something to pull the data out of a JSON file for my build and release processes again.

Here's what I've got. It's in the Marketplace as "Json to Variable" and it will parse through a JSON file and generate variables with the data it finds.

So some JSON like this:


Gives me output like this, and I get four new Variables in the process for other tasks to consume


This just gives me one more tool to help make my build and release pipeline a bit more flexible.  The source code is in GitHub, and is written with Typescript to run as a node task in TFS and VSTS.   It handles JSON objects, and Arrays. Really, the goal of this is not to generate some super complex process, and a simple JSON should suffice for where I envision this working.  

For now, this will get me through some of the deploy and build versioning things that I'm working with the development teams on, and I think I will be able to use this in the future.  If you can use it, please pull it down out of the marketplace and give it a spin!


Sanity check your Web Application Release with a Smoke Test

Automated build and deployments are great right!? Write some code, commit your changes, a CI Build can fire, and a CD Release goes off and deploys that shiny new code out to your web server! Magic! 
BUT, often I find myself working on a release pipeline that could benefit from a quick sanity check that the Web site that we deployed, is ACTUALLY available and running after the Deploy steps say they succeeded.  I mean what good is a Release that shows up nice and Green in your release


Only to then go to your application to find that it is not running, or is unavailable

Yuck! I want to see if the Website I say "Deployed" is actually a "good" deploy!  Enter the Release Web Smoke Test release task for tfs and vsts.  This task will run against a specified set of URLs, and test to validate that the response that is received is the expected result.. you can set the expected return value in the advanced settings, along with setting a retry count. So if you're deploying to a web farm, you can specify the individual server urls and test each server is running well. If you have a site that has a healthcheck api already on it that returns a different code than 200, you can specify something different than 200.. 

This can be used in a stand-alone manner to allow you to see if the release is functional, or even better you could use this failure to trigger a roll-back in your release, creating a more robust release pipeline than just firing away and forgetting about it.

I tried to make it somewhat flexible, but not overly so... If there is a case that you need that isn't covered here, let me know!  The code is up on GitHub so you can see what's going on and extend the task as needed, or even better, share your updates with me and I can publish things up to the Marketplace for everybody to enjoy.

That Conference 2017 - My Experiences

Well, the Przylucki clan has returned from another fun, entertaining, informative, and enlightening excursion to Wisconsin for That Conference.  I wanted to put down some of my thoughts and what I took away from the three days here while it was still fresh in my head.

One of the big things I traditionally take away from attending That Conference has been the spotting of trends in the industry.  What is the coolest, hottest, slickest new thing that everybody is doing? It has been fairly easy to spot most years.. Microservices? Docker? Git? Cloud computing? Xamarin forms? Node.js? yup, I've seen those things come in from year to year and have a strong presence on the schedules of many of the past years.  Also, I've learned to pay attention to those things, and even make myself go attend talks on those topics, even when it may not have been something on my radar previously.  While it may not be something I'm doing today, it's a fair bet that it's something I will be better off having some familiarity with in the not too distant future.  Git? yup, I'm working on that now. Node? sure, while I'm not currently doing Node, a little background and knowledge is helping me as my current client is starting to add that, and we have to create build and releases for it... Things like Docker and Microservice architecture are not something that I've gotten my hands in to yet, but I know its coming, just a matter of time...  

So going in to this year, I was looking for "that thing" that I needed to go get my head wrapped around.  This year however, I had a hard time finding "that thing".  Not sure if there was just not one overriding thing, or if the That Conference organizers had made a more concerted effort to not have as much overlap in topics, but going in I just didn't see it.  There were topics like AI, or programming Alexa tasks, or Docker that had multiple sessions, but nothing was hitting me in the face as the thing to go do.  So I went in more loosely on my session selection this year than I have in the past, intent on looking for the thing I wanted to see more in the moment that as rigidly planned out as I had in the past.  Now looking back on things, especially after looking at all of the Open Spaces sessions that were added during the week, I think that "thing" this year may have been React.. and I didn't react fast enough to make it to a React session.

As always, I took away a good deal from the daily keynotes, and this year in particular, I really enjoyed Brian Hogan's talk on Combatting Fear.  The ideas on stepping up and recognizing where you're being held back by fear, and then leading and fostering a community that is capable of breaking through fear was energizing and inspiring.  

Some of the other top sessions that pop to the top of my head are:

  • Chris Powers' talk "TDD Like You Mean It" - talking through TDD, while actually doing it really was a great way to drive home the points of making TDD your default programming pattern. This is something I really need to practice more and work on, and even though this was not my first exposure to TDD ideas, this talk was super helpful
  • Angela Dugan's talk on agile teams and how to get them unstuck was a great look in to common pitfalls and how to identify them, and strategies for getting through them.  Always a great topic for me to hear, helpful info, lots of learning for me.
  • Cecil Phillip's talk on Microservices discovery patterns was super helpful and informative.  As somebody that's not really working in a Microservices architecture right now, I left this session feeling like I made a huge leap in understanding and knowledge on how it practically works and can be leveraged in an enterprise.
  • Scott Davis' talk entitled "He is the most Paranoid Developer in the World" lived up to its name, and was both super informative, and fascinating.  The lengths he has had to go to in order to properly safeguard and secure his mobile game showed us all just what vulnerabilities are out there, especially when building mobile apps, and gave a lot of food for thought on how to think through how and what you want to keep secret and secure.
Plenty of great take-aways from all of those, as well as the other topics on Devops, or Alexa, or JSON Web Tokens, or Waterfall to Agile transformations that I attended. Loved it all. I came out this end better prepared for life as a consultant than I started with.
 

And of course, it is That Conference, and the family aspect of this is great.. Over the years, my boys have loved intro to programming courses, minecraft hacking sessions, internet security talks, and on and on.  Now I find after going for four years on, that my now teenage boys are finding less and less that interests them.  This year the big hit was for my 13 yr old son and the "Science around the Campfire" put on by Sage Wheeler.  He saw that Oobleck was going to be in play there, and he was sold.. and he came out of that session smiling and a happy boy having had a chance to geek out playing with science.

So plenty of learning, plenty of growing, great stuff for the family, all wins, but the fun side of That Conference is also very special, whether it was running That5K, or enjoying time at ThatWaterparkParty, or playing with my boys at ThatGameNight, or just eating all the bacon, lots of great time for the week. Had all of ThatFun!

TF20507: The string argument contains a character that is not valid: U+0009

I've been working with a client on an integration between their current requirements management system in Caliber and TFS. We recently started receiving the TF20507 error after upgrading to TFS2015.  Our integration work used the TFS API, and it would go after User data in TFS as it was trying to insert records. The User Retrieval logic started throwing the TF20507, but the error doesn't tell you which user, and it doesn't tell you which field in the user record is causing the issue.  It only tells you the invalid character (U+0009, or a TAB character in this case).

Doing some searching around the interwebs for that error message returned some example code and methods for tracking down the error user.. my trouble was that the code examples I was running across were all using the TFS API for TFS 2010, and the methods they were using were not working with the newer TFS API's.

So I ended up working through the code and converting things over in a manner that would give me the SID of the user that was causing the issue, only now in a TFS API that works with newer versions.  I ended up with the code below, which will loop through all of the users in the Project Collection Valid Users group, and it tries to call the IIdentityManagementService.ReadIdentities method for each SID.  This lets me find which user SID throws the TF20507 error.

var GSS = tfs.GetService<IIdentityManagementService>();

           

 

            TeamFoundationIdentity SIDS = GSS.ReadIdentity(

Microsoft.TeamFoundation.Framework.Common.IdentitySearchFactor.General,

"Project Collection Valid Users"

Microsoft.TeamFoundation.Framework.Common.MembershipQuery.Expanded,

Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions.None);

            foreach(var member in SIDS.Members)

            {

 

                if (member.IdentityType == "System.Security.Principal.WindowsIdentity")

                {

                    string v = member.GetType().ToString();

                    string[] mIDS = { member.Identifier };

                        try {

                        TeamFoundationIdentity[][] u = GSS.ReadIdentities(IdentitySearchFactor.Identifier,

                        mIDS, MembershipQuery.Expanded, ReadIdentityOptions.ExtendedProperties);

                       // Console.WriteLine(u[0][0].UniqueName);

                            }

 

                        catch(System.Exception ex)

                        {

                            Console.WriteLine("Error :  " + ex.GetBaseException().Message);

                            Console.WriteLine("for sid :" + member.Identifier);

 

                        }

                }

               

                       

            }



This code ends up spitting out the TF20507 Error and the SID for each User that is throwing the exception/causing my troubles.

That's great and all, but knowing the SID is only half the battle.. I then needed to find which User ID's were the culprits... for that we took a peek in to the TFS Config database to find the SIDs (NOTE -- We are only SELECTING data here to find the culprit.. DON'T try to edit data in the TFS Configuration database! It won't end well for you unless you REALLY REALLY know what you're doing...)

SELECT *

  FROM [Tfs_Configuration].[dbo].[tbl_Identity]

  WHERE Sid = 'put in your SID here'


Once we found the user ID's of the user's causing the trouble, we were able to remove them from TFS.  Working with the security folks who manage the Active Directory, we found that the user's had TAB characters in a description field in Active Directory.  Having the Active Directory accounts updated to remove all the TAB's we then re-added the users to TFS... and no more issue!

Upgrading to TFS 2013 Update 4 with Bugs on the Backlog

Over time I've worked with several different companies performing customizations to their TFS Process Templates.  One topic would come up fairly regularly: "How Do I see Bugs on my Backlog?".  Companies would want to use one of the Agile-based templates, but wanted to have bugs appear on the backlog.  After some discussions on handling bugs, often we would settle on adding bugs to the backlog

Now, Microsoft must've heard a lot about this as well, and they set out to make things better.  As of TFS 2013 Update 4, each team can choose to set to have bugs display on the backlog!  There is a nice little setting in the admin section to do just that!!  Wonderful! No more manipulation of Process Templates to make this little feature work!  Or is there?

You see, I recently worked to upgrade a company from TFS 2010 to TFS 2013.4, and you guessed it, they had ALREADY had bugs on their Agile backlogs through a Process Template customization.  Now when it came time to upgrade their template, I "fixed" the template so that it would work with the new Bugs on the Backlog setting (had to take the Bug work item out of the Requirements Category).  This seemed to work out great! Each team within a Team Project could now even choose to display bugs how they wanted! All was happy... for a few minutes...

Two things made them want to change back to include Bugs as a requirement category item, and thus break the setting in the Admin section (with the nasty little note: TF400917: the current configuration is not valid for this feature).


First was a minor little nag, the company wanted to utilize Tiago Pascoal's nifty Task Board Enhancer.  One piece of that enhancer color-codes the cards on the task boards to match the Red/Blue coloring for Bugs and User Stories... BUT, that only works when there are more than one work item type in the Requirements Category.  Without setting this, there was no color-coding on the Task Board.. not a HUGE deal, but it was one of the things that a lot of people really liked about the Task Board enhancer...

The Second thing was a little bit more trouble.  The QA team started coming to me complaining that they could no longer add "Bugs" to their suites when adding Requirements to the Suite.  They would get a message stating that their query needed to return User Stories.  This was causing them trouble, because over time they had become very accustomed to putting Bugs in to their requirements-based suites.  Adding the Bug back as a requirement category item returned that functionality to them.

Those two things were more than enough for the company to be fine with the nagging TF400917 error on the Settings for their Team.  They could no longer choose to turn things on/off through a setting, but their intention was to always have it on anyway.

Attending ThatConference

Last week I had the opportunity to attend ThatConference in Wisconsin.  Sub-titled "Summer Camp for Geeks", it really is a great three days of fun, geeky, IT learning.  The schedule of sessions was really wonderfully diverse, so I was always able to find a session that was interesting, informative, and relevant.  Each day started with a Keynote (after breakfast of course! can't start your day without some bacon!) that gave me plenty to think about.  The opening day's keynote from Elizabeth Naramore was particularly inspiring.  Titled "Ripples in the Pond" she went on to challenge us in the IT community to be the best us we could be.  To be helpful, welcoming, understanding and generally "good" people to work with, instead of falling in to the traps of being negative, and critical and difficult to work with.  There were many good examples and lots of good food for thought which was really a great way to kick off everything.  Tim Huckaby's keynote on Tuesday was full of great techno-geekery that was exciting and fun.  And Mike McGee's keynote on Wednesday was inspiring and challenging, to see what is possible when you really put your mind to accomplish a big vision.  Great job was done by all of them.

Then each day we would break out for four sessions for the morning and afternoon.  There were really so many sessions to choose from it sometimes became difficult to nail down just which one I wanted to get to... But I was really happy with the sessions I ended up at.  I saw several great session on mobile development, talking through some topics like mass, cross-platform notification using Windows Azure messaging hubs, to cross-platform development with Xamarin and Azure Mobile services, to fun applications like Geo-fencing capabilities baked in to the Windows Phone development kit. Great stuff.  Then I was able to see some interesting ALM-related sessions, including one from the TFS Whisperer Angela Dugan, which was a great lesson in real-world problems and was very informative. I was also able to catch a session on Automated Build and Deployment on Wednesday.  That session covered tools that I was not really super familiar with, TeamCity for build, and Octopus for deployment.  Now, as a TFS ALM geek, I fall in to using the Microsoft tools like TFS Build, and Release Management to handle these tasks, so this was a great opportunity to get exposure to these other tools, and to see how other people are utilizing them in the real world. Very good for me.

For all of that learning and experience, there is another side to ThatConference.  I was amazed by the great group of people that were assembled for the three days.  I was able to meet, and chat with some great people doing impressive things from all over the area... Wisconsin, Illinois, Ohio, Indiana, and even Florida and Texas.  Great to be able to get to chat and learn from them.  Also ThatConference, even with the amazing set of scheduled sessions, goes above and beyond and sets up "Open Spaces", where people can sign up to have an open discussion on any given topic that they are interested in learning or talking more about.  As if it wasn't hard enough to pick a session to attend, now I had an even wider selection! I didn't end up finding my way over to any of the open spaces talks.. I really had my sessions picked out, and didn't waver, but it was really super cool to see some ever more amazing topics pop up on the schedule every time I refreshed it.

Now for all of that, it was a huge win for me to be able to attend! I got so much out of the three days.  But one other really big win for me was having my boys be able to attend the family track sessions.  I loved seeing my oldest son Jacob especially get excited about the opportunity to learn more about computers and programming.  The boys attended a Minecraft mod-ing session, and then Jacob really wanted to go learn what he could in the "Teaching Junior Campers to program with Grown Up Tools".  They were introducing the kids to using VisualStudio and C#! How cool is that! And Jacob loved it! You know that they're enjoying their time, when they want to go to a conference room to LEARN instead of running around the water park all day! Awesome! 

Also, (shhhh, my boss may be reading) there was a ton of fun things to do in the down time.. of course there is the amazing water park (including a fun late-night private party at the water park!), and pig roast, and game night! and Badge ribbon collecting! it was a total blast to be there..  we had a great time!  And there was even a group of "campers" that would get up early to go run.. they called it "That5k" and that served as an excuse to go run and exercise, so that helped keep me motivated to get out and try to keep up with my marathon training, sweet!

Here is a shot of my badge and my son Owen's badge at the end of the conference.. the ribbon collecting got infectious!


Removing SSRS Scale-Out Deployment Servers.. when the Config UI just won't do it

I am currently working on a TFS Upgrade.  We're going from an older TFS 2010 (that I think started life as something earlier than that) up to TFS 2013 (Update 3!).   We're following the ALM Ranger guidance and doing a Migration-based upgrade.  We've got a shiny new SQL Server 2014 with SSRS installed and it's time to migrate the old Reporting database over to the new hardware.  I've taken my backup from the old machines, and restored them to the new machines, then it's on to the SSRS Configuration manager to change databases over.. no troubles.. restore the old Encryption Key... and...  ahh, we find that the SSRS Server gives me this dreaded message when I try to view it:

Scale-out deployment is not supported in this edition of Reporting Services.

Yes, when I changed databases, it brought over the old server to put in the Scale-Out deployment setting.  No trouble! I can go in to the Scale Out Deployment settings through SSRS Configuration Manager and Remove the un-needed server(s)!  Except, no, I can't.. it fails to remove them.  The old SSRS installation is SQL 2008R2, and I don't think my shiny new SQL 2014 server is up to the task of communicating quite perfectly.. I see this when I try to remove one of the old servers from my Scale-Out Deployment "Removing report server <instance id Guid> from the web farm of the local instance.   --- The task failed". Great!



When looking in the Tell me more about this problem link I get some details like this:

Microsoft.ReportingServices.WmiProvider.WMIProviderException: No report servers were found. ---> System.Management.ManagementException: Invalid namespace

   at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)

   at System.Management.ManagementScope.InitializeGuts(Object o)

   at System.Management.ManagementScope.Initialize()

   at System.Management.ManagementScope.Connect()

   at ReportServicesConfigUI.WMIProvider.RSInstances.GetInstances(String machineName)

   --- End of inner exception stack trace ---


Well I HAVE to get it out of there somehow!  A little research, and a lot of asking for help, and a tip comes that I should try to use the command line to get that done.

Reading the MSDN Page Add and Remove Encryption Keys for Scale Out Deployment gets me what I need:

rskeymgmt -r <installation ID>

You can get the <installation ID> part of that from logging in to the machine you want to remove, and finding it in the rsreportserver.config file.  Or, WAY more easily, the error screen on the Configuration Manager when I tried to remove server also provides the Instance ID for me! 

Logging in to the SSRS Server, firing up the command prompt and running the command gave me no troubles.  The servers were removed from my Scale-Out Deployment, and my Report Server migration piece is crossed off!


Running BlogEngine.Net on a GoDaddy site

So I thought I'd post a little something about getting this blog up and running.  I chose to use BlogEngine.Net based on the recommendations of some colleagues, and because it had a strong set of features and it is written in .Net, which I have familiarity with.  So that's great.  I chose to set up a hosting account with that company famous for their sponsorship of the #10 NASCAR car and for their Super Bowl ads, GoDaddy. 

GoDaddy offers BlogEngine.Net as one of the applications that they can install.  That worked smoothly.  I set up a sub-domain and installed BlogEngine.Net in to the root of the new sub-domain site.  Smooth, slick, no trouble.  I waited a few minutes for everything to settle, and was greeted with a  fresh blog site. That's when the fun began.  I found that when I logged in and attempted to do any work under the Administration section I would receive an error that looked like this


Yuck... Clicking any of the Administration settings would result in that error.. Of course the GoDaddy support couldn't help me with the application error... So debug time.  I turned off the Friendly Error Messages in the site's Web.config section and was greeted by a Security Exception:

Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Source Error:



Line 4: @{
Line 5: App_Code.WebUtils.CheckRightsForAdminPagesPages(false);
Line 6: string loginUrl = Href(Utils.RelativeWebRoot + "Account/login.aspx");
Line 7: var userRights = Security.CurrentUserRights().Select(r => r.Flag).ToArray();
Line 8: }

A little help from the BlogEngine.Net forums pointed me to the IIS ASP.Net trust level.  It needed to be set to "Full", but the default was set to "Medium".  I navigated to the settings for my Sub-domain in the Plesk manager that GoDaddy uses, and found the ASP.Net settings:

And Changed the CAS Trust level to Full:


And... TADA! magic, my Admin section was now working without troubles.

From there I was able to go through and set up the blog settings I wanted, uploaded a Theme, and began blogging away!

First Post and other stuff

So This is my new blog, it's going to focus on technical computer/programming/TFS things I run in to in the course of my normal life.. you see I work as a IT Consultant for Polaris Solutions.  In that line of work, there is always something new to learn, try, or break.  So I hope to post some good information here that can help others along the way. 

I have worked as a .Net developer for many years, and more recently have been getting my hands dirty working with Team Foundation Server.  I also like to dabble on the side with some mobile development on my Windows Phone, and have had fun recently fooling around with Azure and how Microsoft's tools there can be leveraged in the Mobile development space. 

So, I think that will give me plenty of areas to draw from.  I am also starting up my training for the Chicago Marathon this October, so I'll try not to let too much complaining about training workouts bleed in to here too much!


Calendar

<<  August 2018  >>
MonTueWedThuFriSatSun
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

Category list

Page List

Month List

AuthorList