Class: KnifeFlow::Promote

Inherits:
Chef::Knife
  • Object
show all
Defined in:
lib/chef/knife/promote.rb

Constant Summary collapse

WORKING_BRANCH =
"develop"

Instance Method Summary collapse

Instance Method Details

#check_branch(name) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/chef/knife/promote.rb', line 117

def check_branch(name)
  if (`git status` =~ /#{name}/) != nil
    return true
  else
    ui.error("USAGE: you must be in the #{name} branch.")
    exit 1
  end
end

#commit_and_push_branch(branch, comment) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/chef/knife/promote.rb', line 102

def commit_and_push_branch(branch, comment)
  print "--------------------------------- \n"
  system("git pull origin #{branch}") 
  system("git add .")
  system("git commit -am  '#{comment}'")
  system("git push origin #{branch}")
  print "--------------------------------- \n"
end

#find_version(name) ⇒ Object



135
136
137
138
# File 'lib/chef/knife/promote.rb', line 135

def find_version(name)
 loader = Chef::CookbookLoader.new(@cookbook_path)
 return loader[name].version
end

#increment_version(version) ⇒ Object



140
141
142
143
144
# File 'lib/chef/knife/promote.rb', line 140

def increment_version(version)
 current_version = version.split(".").map{|i| i.to_i}
 current_version[2] = current_version[2] + 1
 return current_version.join('.')
end

#load_env_file(env_name) ⇒ Object



93
94
95
96
97
98
99
100
# File 'lib/chef/knife/promote.rb', line 93

def load_env_file(env_name)
  if File.exist?("environments/#{env_name}.json")
    File.read("environments/#{env_name}.json")
  else
    # TODO - we should handle the creation of the environment.json file if it doesn't exist.
    raise ArgumentError, "environments/#{env_name}.json was not found; please create the environment file manually.#{env_name}"
  end
end

#parse_name_args!Object



126
127
128
129
130
131
132
133
# File 'lib/chef/knife/promote.rb', line 126

def parse_name_args!
  if name_args.empty?
    ui.error("USAGE: knife promote ENVIRONMENT COOKBOOK COOKBOOK ...")
    exit 1
  else
    return name_args
  end
end

#pull_branch(name) ⇒ Object



111
112
113
114
115
# File 'lib/chef/knife/promote.rb', line 111

def pull_branch(name)
  print "--------------------------------- \n"
  system("git pull origin #{name}")
  print "--------------------------------- \n"
end

#replace_version(search_string, replace_string, file) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/chef/knife/promote.rb', line 146

def replace_version(search_string, replace_string, file)
  open_file = File.open(file, "r")
  body_of_file = open_file.read
  open_file.close
  body_of_file.gsub!(search_string, replace_string)
  File.open(file, "w") { |file| file << body_of_file }
end

#runObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/chef/knife/promote.rb', line 34

def run


  all_args = parse_name_args!
  env_name = all_args[0]
  all_args.shift
  cookbooks = all_args
  
  self.config = Chef::Config.merge!(config)
 
  if !config[:cookbook_path]
    raise ArgumentError, "Default cookbook_path is not specified in the knife.rb config file, and a value to -o is not provided. Nowhere to write the new cookbook to." 
  end
  @cookbook_path = Array(config[:cookbook_path]).first
  

  if check_branch(WORKING_BRANCH)
    
    pull_branch(WORKING_BRANCH)

    env_json = load_env_file(env_name)
    
    env_data = JSON.parse(env_json)

    cookbooks.each do | book |
       = File.join(@cookbook_path, book, "metadata.rb")

      # 1) increase version on the metadata file
      replace_version(find_version(book), increment_version(find_version(book)),  )
  
      # 2) add or update the cookbook in the environment cookbook_versions list
      env_data.cookbook_versions.merge!(book => find_version(book))
    
    end
    
    # 3) write the environment to file
    File.open("environments/#{env_name}.json","w") do |f|
      f.write(JSON.pretty_generate(env_data))
    end
    
    # 4) upload cookbooks to chef server
    cookbook_up = Chef::Knife::CookbookUpload.new
    cookbook_up.name_args = cookbooks 
    cookbook_up.config[:freeze] = true
    cookbook_up.run  
    
    
    # 5) upload environment to chef server
    knife_environment_from_file = Chef::Knife::EnvironmentFromFile.new
    knife_environment_from_file.name_args = ["#{env_name}.json"]
    output = knife_environment_from_file.run

    # 6) commit and push all changes to develop 
    commit_and_push_branch(WORKING_BRANCH, "#{cookbooks.join(" and ").to_s} have been promoted to the #{env_name} environment")

  end

end