def set(entry)
      # Get the struct and update the updated_at attribute
      struct = entry.to_json_struct

      # Set an ID if there isn't one already set
      id     = entry.id

      @lock.synchronize do
        with_index_lock do
          # Reload so we have the latest machine data. This allows other
          # processes to update their own machines without conflicting
          # with our own.
          unlocked_reload

          # If we don't have a machine ID, try to look one up
          if !id
            self.each do |other|
              if entry.name == other.name &&
                entry.provider == other.provider &&
                entry.vagrantfile_path.to_s == other.vagrantfile_path.to_s
                id = other.id
                break
              end
            end

            # If we still don't have an ID, generate a random one
            id = SecureRandom.uuid.gsub("-", "") if !id

            # Get a lock on this machine
            lock_file = lock_machine(id)
            if !lock_file
              raise "Failed to lock new machine: #{entry.name}"
            end

            @machine_locks[id] = lock_file
          end

          if !@machine_locks[id]
            raise "Unlocked write on machine: #{id}"
          end

          # Set our machine and save
          @machines[id] = struct
          unlocked_save
        end
      end

      Entry.new(id, struct)
    end
def set(entry)
      # Get the struct and update the updated_at attribute
      struct = entry.to_json_struct

      # Set an ID if there isn't one already set
      id     = entry.id

      @lock.synchronize do
        with_index_lock do
          # Reload so we have the latest machine data. This allows other
          # processes to update their own machines without conflicting
          # with our own.
          unlocked_reload

          # If we don't have a machine ID, try to look one up
          if !id
            self.each do |other|
              if entry.name == other.name &&
                entry.provider == other.provider &&
                entry.vagrantfile_path.to_s == other.vagrantfile_path.to_s
                id = other.id
                break
              end
            end

            # If we still don't have an ID, generate a random one
            id = SecureRandom.uuid.gsub("-", "") if !id

            # Get a lock on this machine
            lock_file = lock_machine(id)
            if !lock_file
              raise "Failed to lock new machine: #{entry.name}"
            end

            @machine_locks[id] = lock_file
          end

          if !@machine_locks[id]
            raise "Unlocked write on machine: #{id}"
          end

          # Set our machine and save
          @machines[id] = struct
          unlocked_save
        end
      end

      Entry.new(id, struct)
    end
Creates/updates an entry object and returns the resulting entry.

 If the entry was new (no UUID), then the UUID will be set on the
 resulting entry and can be used. Additionally, the a lock will
 be created for the resulting entry, so you must {#release} it
 if you want others to be able to access it.

 If the entry isn't new (has a UUID). then this process must hold
 that entry's lock or else this set will fail.

 @param [Entry] entry
 @return [Entry]